Unverified Commit ef51726f by Yuri Roubinsky Committed by GitHub

Merge pull request #36176 from Chaosus/shader_fix_const_crash

Fix shader crash if pass const argument to 'out/inout' parameter
parents dcfe44f4 516aa46f
...@@ -903,6 +903,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String ...@@ -903,6 +903,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String
if (r_data_type) { if (r_data_type) {
*r_data_type = p_builtin_types[p_identifier].type; *r_data_type = p_builtin_types[p_identifier].type;
} }
if (r_is_const) {
*r_is_const = p_builtin_types[p_identifier].constant;
}
if (r_type) { if (r_type) {
*r_type = IDENTIFIER_BUILTIN_VAR; *r_type = IDENTIFIER_BUILTIN_VAR;
} }
...@@ -3066,6 +3069,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ...@@ -3066,6 +3069,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
Token tk = _get_token(); Token tk = _get_token();
TkPos pos = _get_tkpos(); TkPos pos = _get_tkpos();
bool is_const = false;
if (tk.type == TK_PARENTHESIS_OPEN) { if (tk.type == TK_PARENTHESIS_OPEN) {
//handle subexpression //handle subexpression
...@@ -3457,7 +3462,46 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ...@@ -3457,7 +3462,46 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
for (int i = 0; i < call_function->arguments.size(); i++) { for (int i = 0; i < call_function->arguments.size(); i++) {
int argidx = i + 1; int argidx = i + 1;
if (argidx < func->arguments.size() && is_sampler_type(call_function->arguments[i].type)) { if (argidx < func->arguments.size()) {
if (call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT) {
bool error = false;
Node *n = func->arguments[argidx];
if (n->type == Node::TYPE_CONSTANT || n->type == Node::TYPE_OPERATOR) {
error = true;
} else if (n->type == Node::TYPE_ARRAY) {
ArrayNode *an = static_cast<ArrayNode *>(n);
if (an->call_expression != NULL) {
error = true;
}
} else if (n->type == Node::TYPE_VARIABLE) {
VariableNode *vn = static_cast<VariableNode *>(n);
if (vn->is_const) {
error = true;
} else {
StringName varname = vn->name;
if (shader->uniforms.has(varname)) {
error = true;
} else {
if (p_builtin_types.has(varname)) {
BuiltInInfo info = p_builtin_types[varname];
if (info.constant) {
error = true;
}
}
}
}
} else if (n->type == Node::TYPE_MEMBER) {
MemberNode *mn = static_cast<MemberNode *>(n);
if (mn->basetype_const) {
error = true;
}
}
if (error) {
_set_error(vformat("Constant value cannot be passed for '%s' parameter!", _get_qualifier_str(call_function->arguments[i].qualifier)));
return NULL;
}
}
if (is_sampler_type(call_function->arguments[i].type)) {
//let's see where our argument comes from //let's see where our argument comes from
Node *n = func->arguments[argidx]; Node *n = func->arguments[argidx];
ERR_CONTINUE(n->type != Node::TYPE_VARIABLE); //bug? this should always be a variable ERR_CONTINUE(n->type != Node::TYPE_VARIABLE); //bug? this should always be a variable
...@@ -3492,6 +3536,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ...@@ -3492,6 +3536,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
ERR_CONTINUE(!found); ERR_CONTINUE(!found);
} }
} }
} else {
break;
}
} }
} }
} }
...@@ -3504,7 +3551,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ...@@ -3504,7 +3551,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
DataType data_type; DataType data_type;
IdentifierType ident_type; IdentifierType ident_type;
bool is_const = false;
int array_size = 0; int array_size = 0;
StringName struct_name; StringName struct_name;
...@@ -3812,6 +3858,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons ...@@ -3812,6 +3858,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
MemberNode *mn = alloc_node<MemberNode>(); MemberNode *mn = alloc_node<MemberNode>();
mn->basetype = dt; mn->basetype = dt;
mn->basetype_const = is_const;
mn->datatype = member_type; mn->datatype = member_type;
mn->base_struct_name = st; mn->base_struct_name = st;
mn->struct_name = member_struct_name; mn->struct_name = member_struct_name;
...@@ -5359,6 +5406,18 @@ String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types) ...@@ -5359,6 +5406,18 @@ String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types)
return valid_types; return valid_types;
} }
String ShaderLanguage::_get_qualifier_str(ArgumentQualifier p_qualifier) const {
switch (p_qualifier) {
case ArgumentQualifier::ARGUMENT_QUALIFIER_IN:
return "in";
case ArgumentQualifier::ARGUMENT_QUALIFIER_OUT:
return "out";
case ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT:
return "inout";
}
return "";
}
Error ShaderLanguage::_validate_datatype(DataType p_type) { Error ShaderLanguage::_validate_datatype(DataType p_type) {
if (VisualServer::get_singleton()->is_low_end()) { if (VisualServer::get_singleton()->is_low_end()) {
bool invalid_type = false; bool invalid_type = false;
......
...@@ -529,6 +529,7 @@ public: ...@@ -529,6 +529,7 @@ public:
struct MemberNode : public Node { struct MemberNode : public Node {
DataType basetype; DataType basetype;
bool basetype_const;
StringName base_struct_name; StringName base_struct_name;
DataPrecision precision; DataPrecision precision;
DataType datatype; DataType datatype;
...@@ -544,6 +545,7 @@ public: ...@@ -544,6 +545,7 @@ public:
MemberNode() : MemberNode() :
Node(TYPE_MEMBER), Node(TYPE_MEMBER),
basetype(TYPE_VOID), basetype(TYPE_VOID),
basetype_const(false),
datatype(TYPE_VOID), datatype(TYPE_VOID),
array_size(0), array_size(0),
owner(NULL), owner(NULL),
...@@ -866,6 +868,7 @@ private: ...@@ -866,6 +868,7 @@ private:
Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false); Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
String _get_shader_type_list(const Set<String> &p_shader_types) const; String _get_shader_type_list(const Set<String> &p_shader_types) const;
String _get_qualifier_str(ArgumentQualifier p_qualifier) const;
Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types); Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment