diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-01-10 17:12:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-10 17:12:34 +0100 |
commit | cc7f6340664b5f4a902e54b222840bca39041451 (patch) | |
tree | 74c4c3d3425784d84630221a854df9cc475156ae | |
parent | c8b4fe3b8d44a3e7009500d919b2ab137690c669 (diff) | |
parent | 067b4c8c0715014ae6b61f6e4cb4e807c7e9be4e (diff) |
Merge pull request #56260 from cdemirer/fix-type-mutation-upon-assignment-with-operation
-rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 13 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 12 |
2 files changed, 14 insertions, 11 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 0bf4f5e1f1..9d474cd13a 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1868,13 +1868,14 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig push_error("Cannot assign a new value to a constant.", p_assignment->assignee); } - if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) { - bool compatible = true; - GDScriptParser::DataType op_type = assigned_value_type; - if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { - op_type = get_operation_type(p_assignment->variant_op, assignee_type, assigned_value_type, compatible, p_assignment->assigned_value); - } + bool compatible = true; + GDScriptParser::DataType op_type = assigned_value_type; + if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { + op_type = get_operation_type(p_assignment->variant_op, assignee_type, assigned_value_type, compatible, p_assignment->assigned_value); + } + p_assignment->set_datatype(op_type); + if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) { if (compatible) { compatible = is_type_compatible(assignee_type, op_type, true); if (!compatible) { diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index cb5ba93705..885c35c6a2 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -984,17 +984,19 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code // Perform operator if any. if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype())); GDScriptCodeGenerator::Address value = codegen.add_temporary(_gdtype_from_datatype(subscript->get_datatype())); if (subscript->is_attribute) { gen->write_get_named(value, name, prev_base); } else { gen->write_get(value, key, prev_base); } - gen->write_binary_operator(value, assignment->variant_op, value, assigned); + gen->write_binary_operator(op_result, assignment->variant_op, value, assigned); + gen->pop_temporary(); if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) { gen->pop_temporary(); } - assigned = value; + assigned = op_result; } // Perform assignment. @@ -1060,8 +1062,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name; if (has_operation) { - GDScriptCodeGenerator::Address op_result = codegen.add_temporary(); - GDScriptCodeGenerator::Address member = codegen.add_temporary(); + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype())); + GDScriptCodeGenerator::Address member = codegen.add_temporary(_gdtype_from_datatype(assignment->assignee->get_datatype())); gen->write_get_member(member, name); gen->write_binary_operator(op_result, assignment->variant_op, member, assigned_value); gen->pop_temporary(); // Pop member temp. @@ -1113,7 +1115,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE; if (has_operation) { // Perform operation. - GDScriptCodeGenerator::Address op_result = codegen.add_temporary(); + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype())); GDScriptCodeGenerator::Address og_value = _parse_expression(codegen, r_error, assignment->assignee); gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value); to_assign = op_result; |