d: Fix FAIL in gdc.dg/runnable.d on X32 targets (PR94609)
Patch fixes test failure seen on X32 where a nested struct was passed in registers, rather than via invisible reference. Now, all non-POD structs are passed by invisible reference, not just those with a user-defined copy constructor/destructor. gcc/d/ChangeLog: PR d/94609 * d-codegen.cc (argument_reference_p): Don't check TREE_ADDRESSABLE. (type_passed_as): Build reference type if TREE_ADDRESSABLE. * d-convert.cc (convert_for_argument): Build explicit TARGET_EXPR if needed for arguments passed by invisible reference. * types.cc (TypeVisitor::visit (TypeStruct *)): Mark all structs that are not POD as TREE_ADDRESSABLE.
This commit is contained in:
parent
56d207dd40
commit
8a9ce39f8b
@ -1,3 +1,13 @@
|
||||
2020-04-19 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
PR d/94609
|
||||
* d-codegen.cc (argument_reference_p): Don't check TREE_ADDRESSABLE.
|
||||
(type_passed_as): Build reference type if TREE_ADDRESSABLE.
|
||||
* d-convert.cc (convert_for_argument): Build explicit TARGET_EXPR if
|
||||
needed for arguments passed by invisible reference.
|
||||
* types.cc (TypeVisitor::visit (TypeStruct *)): Mark all structs that
|
||||
are not POD as TREE_ADDRESSABLE.
|
||||
|
||||
2020-04-13 Iain Buclaw <ibuclaw@gdcproject.org>
|
||||
|
||||
* Make-lang.in (D_FRONTEND_OBJS): Remove d/argtypes.o.
|
||||
|
@ -180,10 +180,6 @@ argument_reference_p (Parameter *arg)
|
||||
if (tb->ty == Treference || arg->storageClass & (STCout | STCref))
|
||||
return true;
|
||||
|
||||
tree type = build_ctype (arg->type);
|
||||
if (TREE_ADDRESSABLE (type))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -211,7 +207,7 @@ type_passed_as (Parameter *arg)
|
||||
tree type = build_ctype (arg->type);
|
||||
|
||||
/* Parameter is passed by reference. */
|
||||
if (argument_reference_p (arg))
|
||||
if (TREE_ADDRESSABLE (type) || argument_reference_p (arg))
|
||||
return build_reference_type (type);
|
||||
|
||||
return type;
|
||||
|
@ -677,6 +677,21 @@ convert_for_argument (tree expr, Parameter *arg)
|
||||
/* Front-end shouldn't automatically take the address. */
|
||||
return convert (type_passed_as (arg), build_address (expr));
|
||||
}
|
||||
else if (TREE_ADDRESSABLE (TREE_TYPE (expr)))
|
||||
{
|
||||
/* Type is a struct passed by invisible reference. */
|
||||
Type *t = arg->type->toBasetype ();
|
||||
gcc_assert (t->ty == Tstruct);
|
||||
StructDeclaration *sd = ((TypeStruct *) t)->sym;
|
||||
|
||||
/* Nested structs also have ADDRESSABLE set, but if the type has
|
||||
neither a copy constructor nor a destructor available, then we
|
||||
need to take care of copying its value before passing it. */
|
||||
if (!sd->postblit && !sd->dtor)
|
||||
expr = force_target_expr (expr);
|
||||
|
||||
return convert (type_passed_as (arg), build_address (expr));
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
@ -915,7 +915,7 @@ public:
|
||||
/* For structs with a user defined postblit or a destructor,
|
||||
also set TREE_ADDRESSABLE on the type and all variants.
|
||||
This will make the struct be passed around by reference. */
|
||||
if (t->sym->postblit || t->sym->dtor)
|
||||
if (!t->sym->isPOD ())
|
||||
{
|
||||
for (tree tv = t->ctype; tv != NULL_TREE; tv = TYPE_NEXT_VARIANT (tv))
|
||||
TREE_ADDRESSABLE (tv) = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user