diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2024-11-27 13:03:08 +0100 |
---|---|---|
committer | Marc Poulhiès <dkm@gcc.gnu.org> | 2024-12-13 09:36:00 +0100 |
commit | 82c1b037959d06a76309e4d371aba020b010d9fa (patch) | |
tree | b3b627bf32dcc5ff90ac6f01b5034ca217f66e07 /gcc | |
parent | 240b09db7e1eaa0c1cc411edb9ba67a3553e7a8b (diff) | |
download | gcc-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.adb | 36 |
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; |