Fix type mutation upon compound assignment
This commit is contained in:
parent
28174d531b
commit
067b4c8c07
@ -1834,13 +1834,14 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
|
|||||||
push_error("Cannot assign a new value to a constant.", p_assignment->assignee);
|
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;
|
||||||
bool compatible = true;
|
GDScriptParser::DataType op_type = assigned_value_type;
|
||||||
GDScriptParser::DataType op_type = assigned_value_type;
|
if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
|
||||||
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);
|
||||||
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) {
|
if (compatible) {
|
||||||
compatible = is_type_compatible(assignee_type, op_type, true);
|
compatible = is_type_compatible(assignee_type, op_type, true);
|
||||||
if (!compatible) {
|
if (!compatible) {
|
||||||
|
@ -969,17 +969,19 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|||||||
|
|
||||||
// Perform operator if any.
|
// Perform operator if any.
|
||||||
if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
|
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()));
|
GDScriptCodeGenerator::Address value = codegen.add_temporary(_gdtype_from_datatype(subscript->get_datatype()));
|
||||||
if (subscript->is_attribute) {
|
if (subscript->is_attribute) {
|
||||||
gen->write_get_named(value, name, prev_base);
|
gen->write_get_named(value, name, prev_base);
|
||||||
} else {
|
} else {
|
||||||
gen->write_get(value, key, prev_base);
|
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) {
|
if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
||||||
gen->pop_temporary();
|
gen->pop_temporary();
|
||||||
}
|
}
|
||||||
assigned = value;
|
assigned = op_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform assignment.
|
// Perform assignment.
|
||||||
@ -1035,8 +1037,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|||||||
StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
|
StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
|
||||||
|
|
||||||
if (has_operation) {
|
if (has_operation) {
|
||||||
GDScriptCodeGenerator::Address op_result = codegen.add_temporary();
|
GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype()));
|
||||||
GDScriptCodeGenerator::Address member = codegen.add_temporary();
|
GDScriptCodeGenerator::Address member = codegen.add_temporary(_gdtype_from_datatype(assignment->assignee->get_datatype()));
|
||||||
gen->write_get_member(member, name);
|
gen->write_get_member(member, name);
|
||||||
gen->write_binary_operator(op_result, assignment->variant_op, member, assigned_value);
|
gen->write_binary_operator(op_result, assignment->variant_op, member, assigned_value);
|
||||||
gen->pop_temporary(); // Pop member temp.
|
gen->pop_temporary(); // Pop member temp.
|
||||||
@ -1092,7 +1094,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|||||||
bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE;
|
bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE;
|
||||||
if (has_operation) {
|
if (has_operation) {
|
||||||
// Perform 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);
|
GDScriptCodeGenerator::Address og_value = _parse_expression(codegen, r_error, assignment->assignee);
|
||||||
gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value);
|
gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value);
|
||||||
to_assign = op_result;
|
to_assign = op_result;
|
||||||
|
Loading…
Reference in New Issue
Block a user