]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: trans.c (Call_to_gnu): If this is a function call and there is no target...
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 2 Jun 2018 09:52:57 +0000 (09:52 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 2 Jun 2018 09:52:57 +0000 (09:52 +0000)
Backport from mainline
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.

From-SVN: r261104

gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/discr53.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/discr53.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/discr53_pkg.ads [new file with mode: 0644]

index da154469753315ef79730546c7d6c7d6c5ea37ad..55523a51be098c5a824e2c944f1f506fb75e1394 100644 (file)
@@ -1,3 +1,13 @@
+2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       Backport from mainline
+       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-04-12  Sebastian Huber  <sebastian.huber@embedded-brains.de>
 
        Backport from mainline
index eaad084959cd4f9e71b96298ce30c9060b51b2b3..47c8a286220e44c40b2a30131eebd9a98d8470fc 100644 (file)
@@ -4326,12 +4326,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
@@ -4350,8 +4353,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
index f7a33f936b196732b2ddf57c455d010fcd022a51..ee115c5c73d4a53887109dc888634791c64669df 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/discr53.ad[sb]: New test.
+       * gnat.dg/discr53_pkg.ads: New helper.
+
 2018-05-25  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/85543
diff --git a/gcc/testsuite/gnat.dg/discr53.adb b/gcc/testsuite/gnat.dg/discr53.adb
new file mode 100644 (file)
index 0000000..2e362a7
--- /dev/null
@@ -0,0 +1,19 @@
+--  { dg-do compile }
+
+package body Discr53 is
+
+   function F return Rec is
+      Data : Rec;
+   begin
+      return Data;
+   end;
+
+   type Ptr is access Rec;
+
+   procedure Proc is
+      Local : Ptr;
+   begin
+      Local := new Rec'(F);
+   end;
+
+end Discr53;
diff --git a/gcc/testsuite/gnat.dg/discr53.ads b/gcc/testsuite/gnat.dg/discr53.ads
new file mode 100644 (file)
index 0000000..3fa9f0f
--- /dev/null
@@ -0,0 +1,16 @@
+with Discr53_Pkg;
+
+package Discr53 is
+
+   type Rec (D : Boolean := False) is record
+      case D is
+         when True  => S : String (1 .. Discr53_Pkg.Max);
+         when False => null;
+      end case;
+   end record;
+
+   function F return Rec;
+
+   procedure Proc;
+
+end Discr53;
diff --git a/gcc/testsuite/gnat.dg/discr53_pkg.ads b/gcc/testsuite/gnat.dg/discr53_pkg.ads
new file mode 100644 (file)
index 0000000..d36e1ba
--- /dev/null
@@ -0,0 +1,5 @@
+package Discr53_Pkg is
+
+  function Max return Natural;
+
+end Discr53_Pkg;