From: Rico Tzschichholz Date: Sun, 11 Apr 2021 16:05:08 +0000 (+0200) Subject: codegen: Don't free temp-var for element-access to array with boxed structs X-Git-Tag: 0.50.7~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21fbdb95aecf9ea723a48d47c3a8369cfbb94bf4;p=thirdparty%2Fvala.git codegen: Don't free temp-var for element-access to array with boxed structs Regression of 63551acaf0d83fac8b50904c2759c1098fbfaa71 Fixes https://gitlab.gnome.org/GNOME/vala/issues/1174 --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index c9874ee7d..7466d5cec 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -5423,7 +5423,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { while (inner_expr is CastExpression) { inner_expr = ((CastExpression) inner_expr).inner; } - if (!(inner_expr.symbol_reference is Variable)) { + if (!(inner_expr.symbol_reference is Variable || inner_expr is ElementAccess)) { // heap allocated struct leaked, destroy it var value = new GLibValue (new PointerType (new VoidType ()), innercexpr); temp_ref_values.insert (0, value); diff --git a/tests/Makefile.am b/tests/Makefile.am index f0823d83e..03b221b9c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -99,6 +99,7 @@ TESTS = \ constants/strings.vala \ namespace/unique.vala \ arrays/cast-silent-invalid.test \ + arrays/cast-struct-boxed-element-access.vala \ arrays/class-field-initializer.vala \ arrays/class-field-length-cname.vala \ arrays/constant-element-access.vala \ @@ -323,6 +324,7 @@ TESTS = \ enums/bug673879.vala \ enums/bug763831.vala \ enums/bug780050.vala \ + structs/cast-struct-boxed.vala \ structs/struct_only.vala \ structs/struct-base-types.vala \ structs/struct-boxed-cast.vala \ diff --git a/tests/arrays/cast-struct-boxed-element-access.vala b/tests/arrays/cast-struct-boxed-element-access.vala new file mode 100644 index 000000000..fc2b77b9b --- /dev/null +++ b/tests/arrays/cast-struct-boxed-element-access.vala @@ -0,0 +1,124 @@ +struct Foo { + public int i; +} + +Foo?[] foo_array; + +Foo?[] foo_array_owned () { + return new Foo?[] { { 23 }, { 42 }, { 4711 } }; +} + +unowned Foo?[] foo_array_unowned () { + foo_array = new Foo?[] { { 23 }, { 42 }, { 4711 } }; + return foo_array; +} + +void test_without_destroy () { + { + var foo = new Foo?[] { { 23 }, { 42 }, { 4711 } }; + { + Foo f = foo[0]; + assert (f.i == 23); + assert (foo[0].i == 23); + } + { + Foo f = (Foo) foo[1]; + assert (f.i == 42); + assert (foo[1].i == 42); + } + { + Foo f = (!) foo[2]; + assert (f.i == 4711); + assert (foo[2].i == 4711); + } + } + { + Foo f = foo_array_owned ()[0]; + assert (f.i == 23); + } + { + Foo f = (Foo) foo_array_owned ()[1]; + assert (f.i == 42); + } + { + Foo f = (!) foo_array_owned ()[2]; + assert (f.i == 4711); + } + { + Foo f = foo_array_unowned ()[0]; + assert (f.i == 23); + } + { + Foo f = (Foo) foo_array_unowned ()[1]; + assert (f.i == 42); + } + { + Foo f = (!) foo_array_unowned ()[2]; + assert (f.i == 4711); + } +} + +struct Bar { + public string s; +} + +Bar?[] bar_array; + +Bar?[] bar_array_owned () { + return new Bar?[] { { "foo" }, { "bar" }, { "manam" } }; +} + +unowned Bar?[] bar_array_unowned () { + bar_array = new Bar?[] { { "foo" }, { "bar" }, { "manam" } }; + return bar_array; +} + +void test_with_destroy () { + { + var bar = new Bar?[] { { "foo" }, { "bar" }, { "manam" } }; + { + Bar b = bar[0]; + assert (b.s == "foo"); + assert (bar[0].s == "foo"); + } + { + Bar b = (Bar) bar[1]; + assert (b.s == "bar"); + assert (bar[1].s == "bar"); + } + { + Bar b = (!) bar[2]; + assert (b.s == "manam"); + assert (bar[2].s == "manam"); + } + } + { + Bar b = bar_array_owned ()[0]; + assert (b.s == "foo"); + } + { + Bar b = (Bar) bar_array_owned ()[1]; + assert (b.s == "bar"); + } + { + Bar b = (!) bar_array_owned ()[2]; + assert (b.s == "manam"); + } + { + Bar b = bar_array_unowned ()[0]; + assert (b.s == "foo"); + } + { + Bar b = (Bar) bar_array_unowned ()[1]; + assert (b.s == "bar"); + } + { + Bar b = (!) bar_array_unowned ()[2]; + assert (b.s == "manam"); + } +} + +void main () { + test_without_destroy (); + test_with_destroy (); +} diff --git a/tests/structs/cast-struct-boxed.vala b/tests/structs/cast-struct-boxed.vala new file mode 100644 index 000000000..97ccd1d7d --- /dev/null +++ b/tests/structs/cast-struct-boxed.vala @@ -0,0 +1,56 @@ +struct Foo { + public int i; +} + +Foo? foo; + +Foo? foo_heap_owned () { + foo = { 23 }; + return foo; +} + +void test_without_destroy () { + { + Foo f = foo_heap_owned (); + assert (f.i == 23); + } + { + Foo f = (Foo) foo_heap_owned (); + assert (f.i == 23); + } + { + Foo f = (!) foo_heap_owned (); + assert (f.i == 23); + } +} + +struct Bar { + public string s; +} + +Bar? bar; + +Bar? bar_heap_owned () { + bar = { "bar" }; + return bar; +} + +void test_with_destroy () { + { + Bar b = bar_heap_owned (); + assert (b.s == "bar"); + } + { + Bar b = (Bar) bar_heap_owned (); + assert (b.s == "bar"); + } + { + Bar b = (!) bar_heap_owned (); + assert (b.s == "bar"); + } +} + +void main () { + test_without_destroy (); + test_with_destroy (); +}