mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 23:25:24 +02:00
d: internal compiler error: in convert_move, at expr.cc:227
This was caused by a forward reference of a nested struct changing the TYPE_MODE of its enclosing struct type to be incorrectly inferred as an integer mode. Fixed by setting TREE_ADDRESSABLE early, and moving the mode setting and propagation to finish_aggregate_mode and finish_aggregate_type respectively, rather than at the end of the visitor method for TypeStruct. PR d/125089 gcc/d/ChangeLog: * types.cc (finish_aggregate_mode): Explicitly set TYPE_MODE of non-POD types here. (finish_aggregate_type): Propagate TREE_ADDRESSABLE to all variants. (TypeVisitor::visit (TypeStruct *)): Set TREE_ADDRESSABLE before visiting struct members. gcc/testsuite/ChangeLog: * gdc.dg/pr125089.d: New test.
This commit is contained in:
@@ -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
|
||||
|
||||
20
gcc/testsuite/gdc.dg/pr125089.d
Normal file
20
gcc/testsuite/gdc.dg/pr125089.d
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user