diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2022-06-03 10:27:33 +0200 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2022-07-05 08:28:18 +0000 |
commit | 4844a259b41b4f31940b478216d6dc9faa2bcbca (patch) | |
tree | aeea40a56d2cf8ef46bab4833a8808775b3e269e /gcc/ada/sem_ch3.adb | |
parent | 9fde6c7114f079b38ebee420a541e14387bcc928 (diff) | |
download | gcc-4844a259b41b4f31940b478216d6dc9faa2bcbca.zip gcc-4844a259b41b4f31940b478216d6dc9faa2bcbca.tar.gz gcc-4844a259b41b4f31940b478216d6dc9faa2bcbca.tar.bz2 |
[Ada] Fix dangling bounds for array result of BIP functions
The implementation of the build-in-place return protocol for functions
whose result type is an unconstrained array type generates dangling
references to local bounds built on the stack for the result as soon as
these bounds are not static. The reason is that the implementation
treats the return object, either explicitly present in the source or
synthesized by the compiler, as a regular constrained object until very
late in the game, although it needs to be ultimately rewritten as the
renaming of the dereference of an allocator with unconstrained designated
type in order for the bounds to be part of the allocation.
Recently a partial fix was implemented for the case where the result is an
aggregate, by preventing the return object from being expanded after it has
been analyzed. However, it does not work for the general case of extended
return statements, because the statements therein are still analyzed with
the constrained version of the return object so, after it is changed into
the unconstrained renaming, this yields (sub)type mismatches.
Therefore this change goes the other way around: it rolls back the partial
fix and instead performs the transformation of the return object into the
unconstrained renaming during the expansion of its declaration, in other
words before statements referencing it, if any, are analyzed, thus ensuring
that they see the final version of the object.
gcc/ada/
* exp_aggr.adb (Expand_Array_Aggregate): Remove obsolete code.
Delay the expansion of aggregates initializing return objects of
build-in-place functions.
* exp_ch3.ads (Ensure_Activation_Chain_And_Master): Delete.
* exp_ch3.adb (Ensure_Activation_Chain_And_Master): Fold back to...
(Expand_N_Object_Declaration): ...here.
Perform the expansion of return objects of build-in-place functions
here instead of...
* exp_ch6.ads (Is_Build_In_Place_Return_Object): Declare.
* exp_ch6.adb (Expand_N_Extended_Return_Statement): ...here.
(Is_Build_In_Place_Result_Type): Alphabetize.
(Is_Build_In_Place_Return_Object): New predicate.
* exp_ch7.adb (Enclosing_Function): Delete.
(Process_Object_Declaration): Tidy up handling of return objects.
* sem_ch3.adb (Analyze_Object_Declaration): Do not decorate and
freeze the actual type if it is the same as the nominal type.
* sem_ch6.adb: Remove use and with clauses for Exp_Ch3.
(Analyze_Function_Return): Analyze again all return objects.
(Create_Extra_Formals): Do not force the definition of an Itype
if the subprogram is a compilation unit.
Diffstat (limited to 'gcc/ada/sem_ch3.adb')
-rw-r--r-- | gcc/ada/sem_ch3.adb | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 93aa2ca..29969b3 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -4043,7 +4043,6 @@ package body Sem_Ch3 is Prev_Entity : Entity_Id := Empty; Related_Id : Entity_Id; - Full_View_Present : Boolean := False; -- Start of processing for Analyze_Object_Declaration @@ -4732,28 +4731,32 @@ package body Sem_Ch3 is Act_T := Find_Type_Of_Object (Object_Definition (N), N); end if; - -- Propagate attributes to full view when needed + if Act_T /= T then + declare + Full_View_Present : constant Boolean := + Is_Private_Type (Act_T) + and then Present (Full_View (Act_T)); + -- Propagate attributes to full view when needed - Set_Is_Constr_Subt_For_U_Nominal (Act_T); + begin + Set_Is_Constr_Subt_For_U_Nominal (Act_T); - if Is_Private_Type (Act_T) and then Present (Full_View (Act_T)) - then - Full_View_Present := True; - end if; + if Full_View_Present then + Set_Is_Constr_Subt_For_U_Nominal (Full_View (Act_T)); + end if; - if Full_View_Present then - Set_Is_Constr_Subt_For_U_Nominal (Full_View (Act_T)); - end if; + if Aliased_Present (N) then + Set_Is_Constr_Subt_For_UN_Aliased (Act_T); - if Aliased_Present (N) then - Set_Is_Constr_Subt_For_UN_Aliased (Act_T); + if Full_View_Present then + Set_Is_Constr_Subt_For_UN_Aliased (Full_View (Act_T)); + end if; + end if; - if Full_View_Present then - Set_Is_Constr_Subt_For_UN_Aliased (Full_View (Act_T)); - end if; + Freeze_Before (N, Act_T); + end; end if; - Freeze_Before (N, Act_T); Freeze_Before (N, T); end if; |