aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2024-11-27 13:03:08 +0100
committerMarc Poulhiès <dkm@gcc.gnu.org>2024-12-13 09:36:00 +0100
commit82c1b037959d06a76309e4d371aba020b010d9fa (patch)
treeb3b627bf32dcc5ff90ac6f01b5034ca217f66e07 /gcc
parent240b09db7e1eaa0c1cc411edb9ba67a3553e7a8b (diff)
downloadgcc-82c1b037959d06a76309e4d371aba020b010d9fa.zip
gcc-82c1b037959d06a76309e4d371aba020b010d9fa.tar.gz
gcc-82c1b037959d06a76309e4d371aba020b010d9fa.tar.bz2
ada: Fix dangling reference with user-defined indexing of function call
This happens with a noncontrolled type because the user-defined indexing is expanded into a function call that binds the lifetime of the original call to its return value. The temporary must be created explicitly in this case, so that the front-end can control its lifetime. gcc/ada/ChangeLog: * exp_ch6.adb (Expand_Call_Helper): Also create a temporary in the case of a noncontrolled user-defined indexing.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/exp_ch6.adb36
1 files changed, 36 insertions, 0 deletions
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 20ce7a5..945f446 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -5314,6 +5314,42 @@ package body Exp_Ch6 is
Establish_Transient_Scope
(Call_Node, Needs_Secondary_Stack (Etype (Call_Node)));
end if;
+
+ -- Functions returning noncontrolled objects that may be subject to
+ -- user-defined indexing also need special attention. The problem
+ -- is that, when a call to such a function is directly passed as an
+ -- actual in a call to the Constant_Indexing function, the latter
+ -- call effectively binds the lifetime of the actual to that of its
+ -- return value, thus extending it beyond the call. This cannot be
+ -- directly supported by code generators, for which the lifetime of
+ -- temporaries created for actuals ends immediately after the call.
+ -- Therefore we force the creation of a temporary in this case, as
+ -- the above code would have done in the controlled case; note that,
+ -- in this latter case, the temporary cannot be finalized just after
+ -- the call as would naturally be done, and Is_Finalizable_Transient
+ -- also has a special processing for it (see Is_Indexed_Container).
+
+ elsif Nkind (Call_Node) = N_Function_Call
+ and then Nkind (Parent (Call_Node)) = N_Function_Call
+ then
+ declare
+ Aspect : constant Node_Id :=
+ Find_Value_Of_Aspect
+ (Etype (Call_Node), Aspect_Constant_Indexing);
+
+ begin
+ if Present (Aspect)
+ and then Is_Entity_Name (Name (Parent (Call_Node)))
+ and then Entity (Name (Parent (Call_Node))) = Entity (Aspect)
+ then
+ -- Resolution is now finished, make sure we don't start
+ -- analysis again because of the duplication.
+
+ Set_Analyzed (Call_Node);
+
+ Remove_Side_Effects (Call_Node);
+ end if;
+ end;
end if;
end Expand_Call_Helper;