[Ada] Fix internal error on allocator with function call
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 31 May 2018 10:46:52 +0000 (10:46 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Thu, 31 May 2018 10:46:52 +0000 (10:46 +0000)
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

gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c

index c29524b684fdc73094140c95ec23ae36962fa9c0..446d65267f0499d04aa514f46842ec03aaea9f13 100644 (file)
@@ -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
index 5ad480a7979b566b6440a8d0e13f735d93a29b63..1704db2c317fbd03d33c8ca49e498a6a02688cfa 100644 (file)
@@ -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