From: Rico Tzschichholz Date: Sat, 11 Dec 2021 09:34:03 +0000 (+0100) Subject: codegen: Correctly handle chain up of struct creation methods X-Git-Tag: 0.55.1~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1473f3e709e3fe930686fa7f2374ccae0f27719b;p=thirdparty%2Fvala.git codegen: Correctly handle chain up of struct creation methods Fixes https://gitlab.gnome.org/GNOME/vala/issues/1264 --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 12bd99db2..2e7df70d5 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -4977,6 +4977,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } else if (param != null) { instance = get_cvalue_ (get_parameter_cvalue (param)); } + } else if (expr.is_chainup) { + instance = get_this_cexpression (); } else { var temp_value = create_temp_value (expr.type_reference, true, expr); instance = get_cvalue_ (temp_value); @@ -5033,7 +5035,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } if ((st != null && !st.is_simple_type ()) && !(get_ccode_instance_pos (m) < 0)) { - creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); + if (expr.is_chainup) { + creation_call.add_argument (instance); + } else { + creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); + } } else if (st != null && get_ccode_name (st) == "va_list") { creation_call.add_argument (instance); if (get_ccode_name (m) == "va_start") { diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index 4bc754bb7..9da195128 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -662,7 +662,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { var vardecl = new CCodeVariableDeclarator ("self", default_value_for_type (creturn_type, true)); vardecl.init0 = true; ccode.add_declaration (get_ccode_name (creturn_type), vardecl); - } else { + } else if (!((CreationMethod) m).chain_up) { // memset needs string.h cfile.add_include ("string.h"); var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset")); diff --git a/tests/chainup/struct-base-foo.c-expected b/tests/chainup/struct-base-foo.c-expected index 635f0104e..970b3b938 100644 --- a/tests/chainup/struct-base-foo.c-expected +++ b/tests/chainup/struct-base-foo.c-expected @@ -85,9 +85,7 @@ foo_get_type (void) void bar_init (Bar *self) { - Foo _tmp0_ = {0}; - memset (self, 0, sizeof (Bar)); - foo_init_foo (&_tmp0_); + foo_init_foo (self); (*self).j = 1; } @@ -131,9 +129,12 @@ _vala_main (void) { Bar bar = {0}; Bar _tmp0_; + Bar _tmp1_; bar_init (&bar); _tmp0_ = bar; - _vala_assert (_tmp0_.j == 1, "bar.j == 1"); + _vala_assert (_tmp0_.i == 1, "bar.i == 1"); + _tmp1_ = bar; + _vala_assert (_tmp1_.j == 1, "bar.j == 1"); } int diff --git a/tests/chainup/struct-base-foo.vala b/tests/chainup/struct-base-foo.vala index 44aeb3bb1..b54bd654d 100644 --- a/tests/chainup/struct-base-foo.vala +++ b/tests/chainup/struct-base-foo.vala @@ -15,6 +15,6 @@ public struct Bar : Foo { void main () { var bar = Bar (); - //FIXME assert (bar.i == 1); + assert (bar.i == 1); assert (bar.j == 1); } diff --git a/tests/chainup/struct-base.c-expected b/tests/chainup/struct-base.c-expected index 0a89acf54..99f8f9bb6 100644 --- a/tests/chainup/struct-base.c-expected +++ b/tests/chainup/struct-base.c-expected @@ -85,7 +85,6 @@ foo_get_type (void) void bar_init (Bar *self) { - memset (self, 0, sizeof (Bar)); foo_init (self); (*self).j = 1; } diff --git a/tests/chainup/struct-this-foo.c-expected b/tests/chainup/struct-this-foo.c-expected index 8ee82754f..9c2eb3956 100644 --- a/tests/chainup/struct-this-foo.c-expected +++ b/tests/chainup/struct-this-foo.c-expected @@ -37,9 +37,7 @@ static void _vala_main (void); void foo_init (Foo *self) { - Foo _tmp0_ = {0}; - memset (self, 0, sizeof (Foo)); - foo_init_foo (&_tmp0_); + foo_init_foo (self); (*self).j = 1; } @@ -90,9 +88,12 @@ _vala_main (void) { Foo foo = {0}; Foo _tmp0_; + Foo _tmp1_; foo_init (&foo); _tmp0_ = foo; - _vala_assert (_tmp0_.j == 1, "foo.j == 1"); + _vala_assert (_tmp0_.i == 1, "foo.i == 1"); + _tmp1_ = foo; + _vala_assert (_tmp1_.j == 1, "foo.j == 1"); } int diff --git a/tests/chainup/struct-this-foo.vala b/tests/chainup/struct-this-foo.vala index c0e53beed..b4b835629 100644 --- a/tests/chainup/struct-this-foo.vala +++ b/tests/chainup/struct-this-foo.vala @@ -12,6 +12,6 @@ public struct Foo { void main () { var foo = Foo (); - //FIXME assert (foo.i == 1); + assert (foo.i == 1); assert (foo.j == 1); } diff --git a/tests/chainup/struct-this.c-expected b/tests/chainup/struct-this.c-expected index 4414aaf7a..b7092ea9a 100644 --- a/tests/chainup/struct-this.c-expected +++ b/tests/chainup/struct-this.c-expected @@ -44,7 +44,6 @@ foo_init (Foo *self) void foo_init_bar (Foo *self) { - memset (self, 0, sizeof (Foo)); foo_init (self); (*self).i = 1; } diff --git a/vala/valacallableexpression.vala b/vala/valacallableexpression.vala index 9439cd2a2..930c7a0a2 100644 --- a/vala/valacallableexpression.vala +++ b/vala/valacallableexpression.vala @@ -31,6 +31,11 @@ public interface Vala.CallableExpression : Expression { */ public abstract bool is_yield_expression { get; set; } + /** + * Whether it is a creation chain up. + */ + public abstract bool is_chainup { get; set; } + /** * Appends the specified expression to the list of arguments. * diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index aff7db77a..70ad8fb6a 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -46,7 +46,7 @@ public class Vala.MethodCall : Expression, CallableExpression { */ public bool is_constructv_chainup { get; private set; } - public bool is_chainup { get; private set; } + public bool is_chainup { get; set; } private Expression _call; @@ -319,6 +319,7 @@ public class Vala.MethodCall : Expression, CallableExpression { var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) call, source_reference); struct_creation_expression.struct_creation = true; + struct_creation_expression.is_chainup = is_chainup; foreach (Expression arg in argument_list) { struct_creation_expression.add_argument (arg); } diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index a6ce8a14f..dc2bd8f6c 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -53,6 +53,8 @@ public class Vala.ObjectCreationExpression : Expression, CallableExpression { public bool is_yield_expression { get; set; } + public bool is_chainup { get; set; } + public bool struct_creation { get; set; } private List argument_list = new ArrayList ();