Skip to content

Commit 77e18da

Browse files
authored
Merge pull request #94674 from dalexeev/gds-fix-incorrect-setter-call-for-ref-types
GDScript: Fix incorrect setter call for reference types
2 parents 543e438 + 8c82fd1 commit 77e18da

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

modules/gdscript/gdscript_compiler.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
10641064

10651065
// Get at (potential) root stack pos, so it can be returned.
10661066
GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, chain.back()->get()->base);
1067+
const bool base_known_type = base.type.has_type;
1068+
const bool base_is_shared = Variant::is_type_shared(base.type.builtin_type);
10671069

10681070
if (r_error) {
10691071
return GDScriptCodeGenerator::Address();
@@ -1074,7 +1076,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
10741076
// In case the base has a setter, don't use the address directly, as we want to call that setter.
10751077
// So use a temp value instead and call the setter at the end.
10761078
GDScriptCodeGenerator::Address base_temp;
1077-
if (base.mode == GDScriptCodeGenerator::Address::MEMBER && member_property_has_setter && !member_property_is_in_setter) {
1079+
if ((!base_known_type || !base_is_shared) && base.mode == GDScriptCodeGenerator::Address::MEMBER && member_property_has_setter && !member_property_is_in_setter) {
10781080
base_temp = codegen.add_temporary(base.type);
10791081
gen->write_assign(base_temp, base);
10801082
prev_base = base_temp;
@@ -1229,8 +1231,14 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
12291231
}
12301232
}
12311233
} else if (base_temp.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
1234+
if (!base_known_type) {
1235+
gen->write_jump_if_shared(base);
1236+
}
12321237
// Save the temp value back to the base by calling its setter.
12331238
gen->write_call(GDScriptCodeGenerator::Address(), base, member_property_setter_function, { assigned });
1239+
if (!base_known_type) {
1240+
gen->write_end_jump_if_shared();
1241+
}
12341242
}
12351243

12361244
if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# GH-94667
2+
3+
class Inner:
4+
var subprop: Vector2:
5+
set(value):
6+
prints("subprop setter", value)
7+
subprop = value
8+
get:
9+
print("subprop getter")
10+
return subprop
11+
12+
func _to_string() -> String:
13+
return "<Inner>"
14+
15+
var prop1:
16+
set(value):
17+
prints("prop1 setter", value)
18+
prop1 = value
19+
20+
var prop2: Inner:
21+
set(value):
22+
prints("prop2 setter", value)
23+
prop2 = value
24+
25+
var prop3:
26+
set(value):
27+
prints("prop3 setter", value)
28+
prop3 = value
29+
get:
30+
print("prop3 getter")
31+
return prop3
32+
33+
var prop4: Inner:
34+
set(value):
35+
prints("prop4 setter", value)
36+
prop4 = value
37+
get:
38+
print("prop4 getter")
39+
return prop4
40+
41+
func test():
42+
print("===")
43+
prop1 = Vector2()
44+
prop1.x = 1.0
45+
print("---")
46+
prop1 = Inner.new()
47+
prop1.subprop.x = 1.0
48+
49+
print("===")
50+
prop2 = Inner.new()
51+
prop2.subprop.x = 1.0
52+
53+
print("===")
54+
prop3 = Vector2()
55+
prop3.x = 1.0
56+
print("---")
57+
prop3 = Inner.new()
58+
prop3.subprop.x = 1.0
59+
60+
print("===")
61+
prop4 = Inner.new()
62+
prop4.subprop.x = 1.0
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
GDTEST_OK
2+
===
3+
prop1 setter (0, 0)
4+
prop1 setter (1, 0)
5+
---
6+
prop1 setter <Inner>
7+
subprop getter
8+
subprop setter (1, 0)
9+
===
10+
prop2 setter <Inner>
11+
subprop getter
12+
subprop setter (1, 0)
13+
===
14+
prop3 setter (0, 0)
15+
prop3 getter
16+
prop3 setter (1, 0)
17+
---
18+
prop3 setter <Inner>
19+
prop3 getter
20+
subprop getter
21+
subprop setter (1, 0)
22+
===
23+
prop4 setter <Inner>
24+
prop4 getter
25+
subprop getter
26+
subprop setter (1, 0)

0 commit comments

Comments
 (0)