This is a regression present on all active branches.  The compiler aborts on 
an allocator taking a function call in the qualified expression when the 
result type is a discriminated record type with defaulted discriminants and a 
variant part, and whose maximal size is not statically known.

Fixed thusly, tested on x86-64/Linux, applied on all active branches.


2018-06-02  Eric Botcazou  <ebotca...@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-06-02  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/discr53.ad[sb]: New test.
        * gnat.dg/discr53_pkg.ads: New helper.

-- 
Eric Botcazou
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 261006)
+++ gcc-interface/trans.c	(revision 261007)
@@ -4355,12 +4355,15 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
 	  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 *gn
 	      && 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
package Discr53_Pkg is

  function Max return Natural;

end Discr53_Pkg;
--  { 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;
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;

Reply via email to