summaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-04-26 23:39:32 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-04-27 02:47:26 +0200
commit2370bdbb0b29b14401d8508d846c0e01c64d82fc (patch)
tree43016d247bb7f8fa7a5b397e862e30f29ef07456 /gcc/d
parentf82e3a12955e484b4da7fcca93655a2a2e785e5b (diff)
d: Fix ICE in assign_temp, at function.c:984 (PR94777)
Named arguments were being passed around by invisible reference, just not variadic arguments. There is a need to de-duplicate the routines that handle declaration/parameter promotion and reference checking. However for now, the parameter helper functions have just been renamed to parameter_reference_p and parameter_type, to make it more clear that it is the Parameter equivalent to declaration_reference_p and declaration_type. On writing the tests, a forward-reference bug was discovered on x86_64 during va_list type semantic. This was due to fields not having their parent set-up correctly. gcc/d/ChangeLog: PR d/94777 * d-builtins.cc (build_frontend_type): Set parent for generated fields of built-in types. * d-codegen.cc (argument_reference_p): Rename to ... (parameter_reference_p): ... this. (type_passed_as): Rename to ... (parameter_type): ... this. Make TREE_ADDRESSABLE types restrict. (d_build_call): Move handling of non-POD types here from ... * d-convert.cc (convert_for_argument): ... here. * d-tree.h (argument_reference_p): Rename declaration to ... (parameter_reference_p): ... this. (type_passed_as): Rename declaration to ... (parameter_type): ... this. * types.cc (TypeVisitor::visit (TypeFunction *)): Update caller. gcc/testsuite/ChangeLog: PR d/94777 * gdc.dg/pr94777a.d: New test. * gdc.dg/pr94777b.d: New test.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/ChangeLog17
-rw-r--r--gcc/d/d-builtins.cc1
-rw-r--r--gcc/d/d-codegen.cc32
-rw-r--r--gcc/d/d-convert.cc19
-rw-r--r--gcc/d/d-tree.h4
-rw-r--r--gcc/d/types.cc2
6 files changed, 52 insertions, 23 deletions
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index ab3028d8d75..3b5fc12a8fd 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,20 @@
+2020-04-27 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/94777
+ * d-builtins.cc (build_frontend_type): Set parent for generated
+ fields of built-in types.
+ * d-codegen.cc (argument_reference_p): Rename to ...
+ (parameter_reference_p): ... this.
+ (type_passed_as): Rename to ...
+ (parameter_type): ... this. Make TREE_ADDRESSABLE types restrict.
+ (d_build_call): Move handling of non-POD types here from ...
+ * d-convert.cc (convert_for_argument): ... here.
+ * d-tree.h (argument_reference_p): Rename declaration to ...
+ (parameter_reference_p): ... this.
+ (type_passed_as): Rename declaration to ...
+ (parameter_type): ... this.
+ * types.cc (TypeVisitor::visit (TypeFunction *)): Update caller.
+
2020-04-26 Iain Buclaw <ibuclaw@gdcproject.org>
* decl.cc (get_symbol_decl): Set DECL_DECLARED_INLINE_P or
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index cb8f43a88e5..a5654a66bf5 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -253,6 +253,7 @@ build_frontend_type (tree type)
= Identifier::idPool (IDENTIFIER_POINTER (DECL_NAME (field)));
VarDeclaration *vd = VarDeclaration::create (Loc (), ftype, fident,
NULL);
+ vd->parent = sdecl;
vd->offset = tree_to_uhwi (DECL_FIELD_OFFSET (field));
vd->semanticRun = PASSsemanticdone;
vd->csym = field;
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 8dc1ab264f8..12c6f138362 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -172,7 +172,7 @@ declaration_type (Declaration *decl)
Return TRUE if parameter ARG is a reference type. */
bool
-argument_reference_p (Parameter *arg)
+parameter_reference_p (Parameter *arg)
{
Type *tb = arg->type->toBasetype ();
@@ -186,7 +186,7 @@ argument_reference_p (Parameter *arg)
/* Returns the real type for parameter ARG. */
tree
-type_passed_as (Parameter *arg)
+parameter_type (Parameter *arg)
{
/* Lazy parameters are converted to delegates. */
if (arg->storageClass & STClazy)
@@ -207,9 +207,18 @@ type_passed_as (Parameter *arg)
tree type = build_ctype (arg->type);
/* Parameter is passed by reference. */
- if (TREE_ADDRESSABLE (type) || argument_reference_p (arg))
+ if (parameter_reference_p (arg))
return build_reference_type (type);
+ /* Pass non-POD structs by invisible reference. */
+ if (TREE_ADDRESSABLE (type))
+ {
+ type = build_reference_type (type);
+ /* There are no other pointer to this temporary. */
+ type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
+ }
+
+ /* Front-end has already taken care of type promotions. */
return type;
}
@@ -1954,6 +1963,23 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
}
+ /* Parameter is a struct passed by invisible reference. */
+ if (TREE_ADDRESSABLE (TREE_TYPE (targ)))
+ {
+ 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 (arg->op == TOKstructliteral || (!sd->postblit && !sd->dtor))
+ targ = force_target_expr (targ);
+
+ targ = convert (build_reference_type (TREE_TYPE (targ)),
+ build_address (targ));
+ }
+
vec_safe_push (args, targ);
}
}
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 9ee149b8386..e2921ec33f0 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -672,25 +672,10 @@ convert_for_argument (tree expr, Parameter *arg)
if (!POINTER_TYPE_P (TREE_TYPE (expr)))
return build_address (expr);
}
- else if (argument_reference_p (arg))
+ else if (parameter_reference_p (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 convert (parameter_type (arg), build_address (expr));
}
return expr;
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 89feb9e7010..48587d96e38 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -504,8 +504,8 @@ extern tree d_decl_context (Dsymbol *);
extern tree copy_aggregate_type (tree);
extern bool declaration_reference_p (Declaration *);
extern tree declaration_type (Declaration *);
-extern bool argument_reference_p (Parameter *);
-extern tree type_passed_as (Parameter *);
+extern bool parameter_reference_p (Parameter *);
+extern tree parameter_type (Parameter *);
extern tree build_integer_cst (dinteger_t, tree = d_int_type);
extern tree build_float_cst (const real_t &, Type *);
extern tree d_array_length (tree);
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index f6ae5740f01..59a90b49243 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -720,7 +720,7 @@ public:
for (size_t i = 0; i < n_args; i++)
{
- tree type = type_passed_as (Parameter::getNth (t->parameters, i));
+ tree type = parameter_type (Parameter::getNth (t->parameters, i));
fnparams = chainon (fnparams, build_tree_list (0, type));
}
}