diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-04-19 09:54:25 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-04-19 09:54:25 +0200 |
commit | 8a9ce39f8bbb2ae0798bec0ed2051a5f10b21122 (patch) | |
tree | fc21a3367bf87c7264be4c8c3b30124fa1897449 | |
parent | 56d207dd4003765481fb89710159d63dad571f05 (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/d/d-codegen.cc | 6 | ||||
-rw-r--r-- | gcc/d/d-convert.cc | 15 | ||||
-rw-r--r-- | gcc/d/types.cc | 2 |
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; |