diff --git a/gcc/d/types.cc b/gcc/d/types.cc index b5658b6e8f4..d79a8972b5c 100644 --- a/gcc/d/types.cc +++ b/gcc/d/types.cc @@ -593,7 +593,12 @@ finish_aggregate_mode (tree type) return; } - compute_record_mode (type); + /* Force mode of non-trivially copyable structs to be BLKmode, preventing it + from being returned in a register. */ + if (TREE_ADDRESSABLE (type)) + SET_TYPE_MODE (type, BLKmode); + else + compute_record_mode (type); /* Propagate computed mode to all variants of this aggregate type. */ for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) @@ -715,6 +720,7 @@ finish_aggregate_type (unsigned structsize, unsigned alignsize, tree type) TYPE_PACKED (t) = TYPE_PACKED (type); SET_TYPE_ALIGN (t, TYPE_ALIGN (type)); TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type); + TREE_ADDRESSABLE (t) = TREE_ADDRESSABLE (type); } /* Complete any other forward-referenced fields of this aggregate type. */ @@ -1236,6 +1242,12 @@ public: TYPE_LANG_SPECIFIC (t->ctype) = build_lang_type (t); TYPE_CXX_ODR_P (t->ctype) = 1; + /* For structs with a user defined postblit, copy constructor, or a + destructor, also set TREE_ADDRESSABLE on the type and all variants. + This will make the struct be passed around by reference. */ + if (!dmd::isPOD (t->sym)) + TREE_ADDRESSABLE (t->ctype) = 1; + if (t->sym->members) { /* Must set up the overall size and alignment before determining @@ -1257,18 +1269,6 @@ public: build_type_decl (t->ctype, t->sym); apply_user_attributes (t->sym, t->ctype); } - - /* For structs with a user defined postblit, copy constructor, or a - destructor, also set TREE_ADDRESSABLE on the type and all variants. - This will make the struct be passed around by reference. */ - if (!dmd::isPOD (t->sym)) - { - for (tree tv = t->ctype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv)) - { - TREE_ADDRESSABLE (tv) = 1; - SET_TYPE_MODE (tv, BLKmode); - } - } } /* Build a class type. Whereas structs are value types, classes are diff --git a/gcc/testsuite/gdc.dg/pr125089.d b/gcc/testsuite/gdc.dg/pr125089.d new file mode 100644 index 00000000000..6936cf6e949 --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr125089.d @@ -0,0 +1,20 @@ +// { dg-do compile } +struct R125089 +{ + S125089.T st; +} + +struct S125089 +{ + struct T + { + void* v; + ~this() {} + } + + T t; + this(R125089 r) + { + this.t = r.st; + } +}