+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
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
&& 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