From 1b6f8e9778b58e190f40a1137eaba618c529110f Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 31 May 2018 10:46:52 +0000 Subject: [PATCH] [Ada] Fix internal error on allocator with function call 2018-05-31 Eric Botcazou 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 | 7 +++++++ gcc/ada/gcc-interface/trans.c | 16 ++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c29524b684f..446d65267f0 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2018-05-31 Eric Botcazou + + * 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 * exp_ch7.adb (Find_Transient_Context): An iteration scheme is a valid diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 5ad480a7979..1704db2c317 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -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 -- 2.30.2