|
@@ -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<const VariableNode *>(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<StringName, FunctionInfo> &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<StringName, FunctionInfo> &p_f
|
|
|
unknown_size = false;
|
|
|
|
|
|
} else if (tk.type == TK_SEMICOLON) {
|
|
|
+ is_const_decl = false;
|
|
|
break;
|
|
|
} else {
|
|
|
_set_expected_error(",", ";");
|