godotengine / godotengine/godot
GDShader parser should give errors in incorrect usage of `const` and certain array type declarations
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
Tested versions
Reproducible in:
- v4.2.2.stable.flathub [15073afe3]
- v4.0.4.stable.mono.official [fc0b241c9]
In Godot 3, some constructs are not allowed, so it seems to only have the const function issue.
So, partially reproducible in:
- v3.5.3.stable.official [6c814135b]
- v3.3.stable.official
System information
Godot v4.2.2.stable (15073afe3) - Freedesktop SDK 23.08 (Flatpak runtime) - X11 - Vulkan (Forward+) - integrated Intel(R) HD Graphics 5500 (BDW GT2) () - Intel(R) Core(TM) i5-5300U CPU @ 2.30GHz (4 Threads)
Issue description
The Shader code below should give errors of various types, but it's being parsed as valid.
Problems:
- Functions allowing
constqualifier before return type - Array of void being allowed at all
- Local variables of implied array size allowing non-arrays indirectly
buggy.gdshader
shader_type canvas_item;
// Allowing const here has to be a bug; it doesn't seem to mean anything.
const int const_returned() { return 0; }
// Adding const even causes an error to not trigger. Without const, this gives ERROR:
// "Unknown array size is forbidden in that context".
const bool[] unknown_array_return_being_allowed_with_const() { return true; }
// It's weird that such "unknown array size" allows non-arrays too.
bool bool_fn() { return true; }
uniform int int_var;
void unknown_array_vars_allowing_non_arrays() {
bool[] a = bool_fn();
int b[] = int_var;
// This seems to be a bug, as the line below is an error:
//bool[] c = true; // Gives ERROR: Expected a '{'
// Is this form allowed in other contexts, apart from local vars? If so, I didn't test.
// In fact, why is this form even allowed at all? It's better to always require the size.
// If functions, fields, etc. need to specify size, then it's always known statically, no?
// It's not useful even as syntatic sugar, as you cannot mix different sizes anyway.
//int[] d = {2}, e = {3, 4}; // Gives ERROR: Array size mismatch
// If the purpose is to allow specifying values without having to count them manually,
// then I suggest instead telling the expected count in the error message
//int[1] f = {1, 2, 3}; // Could be ERROR: Array size mismatch, expected int[3]
}
// I guess an array of nothings is also nothing. Still, there's no reason to allow it.
// Expected ERROR like "Type void cannot be an array" or "Expected function identifier".
void[2] nothings() { return; }
Steps to reproduce
Simply create a Shader file with the code above and note it shows no errors in Godot's Shader code editor.
I did not make any tests whatsoever involving Visual Shader, I don't know if it's applicable.
Minimal reproduction project (MRP)
N/A
I was told to report the bug by @Chaosus on devel chat.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the buggy.gdshader example in the issue and load it in Godot's Shader code editor to confirm which marked constructs are accepted. Trace the GDShader parser and its diagnostics for the const qualifier, array declarations, and void arrays; done means each invalid construct reports an appropriate parse or type error without regressing the valid cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100