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))
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. */
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
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