From e034d5f764ccd9a3d7b60414240dcc9a695d3ef7 Mon Sep 17 00:00:00 2001 From: Yuri Rubinsky Date: Wed, 1 Feb 2023 09:04:10 +0300 Subject: [PATCH] Fix shader failure when using non-const initializer on a constant --- servers/rendering/shader_language.cpp | 24 +++++++++++++++++++++++- servers/rendering/shader_language.h | 2 +- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 11a9303f119..a187057859f 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -1225,7 +1225,7 @@ void ShaderLanguage::clear() { char_idx = 0; error_set = false; error_str = ""; - last_const = false; + is_const_decl = false; while (nodes) { Node *n = nodes; nodes = nodes->next; @@ -3561,6 +3561,14 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Functio return false; } + if (is_const_decl && arg->type == Node::TYPE_VARIABLE) { + const VariableNode *var = static_cast(arg); + if (!var->is_const) { + _set_error(RTR("Expected constant expression.")); + return false; + } + } + p_func->arguments.push_back(arg); tk = _get_token(); @@ -5184,6 +5192,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = func; } else { //a function call + if (p_block == nullptr) { // Non-constructor function call in global space is forbidden. + if (is_const_decl) { + _set_error(RTR("Expected constant expression.")); + } + return nullptr; + } const StringName &name = identifier; @@ -5460,6 +5474,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier))); return nullptr; } + if (is_const_decl && !is_const) { + _set_error(RTR("Expected constant expression.")); + return nullptr; + } if (ident_type == IDENTIFIER_VARYING) { TkPos prev_pos = _get_tkpos(); Token next_token = _get_token(); @@ -6977,6 +6995,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } } #endif // DEBUG_ENABLED + is_const_decl = is_const; BlockNode::Variable var; var.type = type; @@ -7233,6 +7252,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun vdnode->declarations.push_back(decl); p_block->variables[name] = var; + is_const_decl = false; if (!fixed_array_size) { array_size = 0; @@ -9101,6 +9121,7 @@ Error ShaderLanguage::_parse_shader(const HashMap &p_f constant.precision = precision; constant.initializer = nullptr; constant.array_size = array_size; + is_const_decl = true; if (tk.type == TK_BRACKET_OPEN) { Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size); @@ -9360,6 +9381,7 @@ Error ShaderLanguage::_parse_shader(const HashMap &p_f unknown_size = false; } else if (tk.type == TK_SEMICOLON) { + is_const_decl = false; break; } else { _set_expected_error(",", ";"); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 32e497aa46c..aea61e42c31 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -953,7 +953,7 @@ private: StringName shader_type_identifier; StringName current_function; - bool last_const = false; + bool is_const_decl = false; StringName last_name; bool is_shader_inc = false;