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;