aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-05-31 10:46:52 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-05-31 10:46:52 +0000
commit1b6f8e9778b58e190f40a1137eaba618c529110f (patch)
tree304e0a126a9af3e6c8f2caff389caa00785eb4e9
parent3c5d07ab057a1cbe23ca655d172bfb53581be960 (diff)
downloadgcc-1b6f8e9778b58e190f40a1137eaba618c529110f.zip
gcc-1b6f8e9778b58e190f40a1137eaba618c529110f.tar.gz
gcc-1b6f8e9778b58e190f40a1137eaba618c529110f.tar.bz2
[Ada] Fix internal error on allocator with function call
2018-05-31 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * gcc-interface/trans.c (Call_to_gnu): If this is a function call and there is no target, also create a temporary for the return value for an allocator if the type is an unconstrained record type with default discriminant. From-SVN: r261007
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/gcc-interface/trans.c16
2 files changed, 17 insertions, 6 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c29524b..446d652 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2018-05-31 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (Call_to_gnu): If this is a function call and
+ there is no target, also create a temporary for the return value for
+ an allocator if the type is an unconstrained record type with default
+ discriminant.
+
2018-05-31 Hristian Kirtchev <kirtchev@adacore.com>
* exp_ch7.adb (Find_Transient_Context): An iteration scheme is a valid
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 5ad480a..1704db2 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -4355,12 +4355,15 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
because we need to preserve the return value before copying back the
parameters.
- 2. There is no target and the call is made for neither an object nor a
+ 2. There is no target and the call is made for neither an object, nor a
renaming declaration, nor a return statement, nor an allocator, and
the return type has variable size because in this case the gimplifier
- cannot create the temporary, or more generally is simply an aggregate
- type, because the gimplifier would then create the temporary in the
- outermost scope instead of locally.
+ cannot create the temporary, or more generally is an aggregate type,
+ because the gimplifier would create the temporary in the outermost
+ scope instead of locally. But there is an exception for an allocator
+ of an unconstrained record type with default discriminant because we
+ allocate the actual size in this case, unlike the other 3 cases, so
+ we need a temporary to fetch the discriminant and we create it here.
3. There is a target and it is a slice or an array with fixed size,
and the return type has variable size, because the gimplifier
@@ -4379,8 +4382,9 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
&& Nkind (Parent (gnat_node)) != N_Object_Declaration
&& Nkind (Parent (gnat_node)) != N_Object_Renaming_Declaration
&& Nkind (Parent (gnat_node)) != N_Simple_Return_Statement
- && !(Nkind (Parent (gnat_node)) == N_Qualified_Expression
- && Nkind (Parent (Parent (gnat_node))) == N_Allocator)
+ && (!(Nkind (Parent (gnat_node)) == N_Qualified_Expression
+ && Nkind (Parent (Parent (gnat_node))) == N_Allocator)
+ || type_is_padding_self_referential (gnu_result_type))
&& AGGREGATE_TYPE_P (gnu_result_type)
&& !TYPE_IS_FAT_POINTER_P (gnu_result_type))
|| (gnu_target