aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-04-19 09:54:25 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-04-19 09:54:25 +0200
commit8a9ce39f8bbb2ae0798bec0ed2051a5f10b21122 (patch)
treefc21a3367bf87c7264be4c8c3b30124fa1897449
parent56d207dd4003765481fb89710159d63dad571f05 (diff)
downloadgcc-8a9ce39f8bbb2ae0798bec0ed2051a5f10b21122.zip
gcc-8a9ce39f8bbb2ae0798bec0ed2051a5f10b21122.tar.gz
gcc-8a9ce39f8bbb2ae0798bec0ed2051a5f10b21122.tar.bz2
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.
-rw-r--r--gcc/d/ChangeLog10
-rw-r--r--gcc/d/d-codegen.cc6
-rw-r--r--gcc/d/d-convert.cc15
-rw-r--r--gcc/d/types.cc2
4 files changed, 27 insertions, 6 deletions
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 6544b3d..6c3eb89 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -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.
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 66af2b4..8dc1ab2 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -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;
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 533bbab..9ee149b 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -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;
}
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index e0e770a..f6ae574 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -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;