diff options
author | Justin Squirek <squirek@adacore.com> | 2022-08-31 14:52:11 +0000 |
---|---|---|
committer | Marc Poulhiès <poulhies@adacore.com> | 2022-09-12 10:16:51 +0200 |
commit | a968d80d0e89e847a1928842b7de166a6d42c92e (patch) | |
tree | 4190c36a86a777293a7ca1be5847c291b1eacd8a /gcc/ada/sem_ch6.adb | |
parent | 46ba7ae3c6eea45cc03de5fb00c8084cdc760d64 (diff) | |
download | gcc-a968d80d0e89e847a1928842b7de166a6d42c92e.zip gcc-a968d80d0e89e847a1928842b7de166a6d42c92e.tar.gz gcc-a968d80d0e89e847a1928842b7de166a6d42c92e.tar.bz2 |
[Ada] Tech debt: Expansion of contracts
This patch modifies the expansion of contracts such that the statements
and declarations of a subprogram with post-execution checks get moved to
a local internally generated subprogram which the original subprogram
calls directly followed by the required post-execution checks.
This differs from the current implementation which requires delicate
machinary which coordinates with the finalization process to emulate the
desired behavior within the "at end" procedure.
gcc/ada/
* contracts.adb, contracts.ads
(Analyze_Pragmas_In_Declarations): Added to aid in the new
expansion model so that pragmas relating to contracts can get
processed early before the rest of the subprogram containing them.
(Build_Subprogram_Contract_Wrapper): Created to do the majority of
expansion for postconditions. It builds a local wrapper with the
statements and declarations within a given subprogram.
(Is_Prologue_Renaming): Moved out from Process_Preconditions to be
used generally within the contracts package.
(Build_Entry_Contract_Wrapper): Moved from exp_ch7.
(Expand_Subprogram_Contract): Add new local variable Decls to
store expanded declarations needed for evaluation of contracts.
Call new wrapper building procedure and modify comments to match
new expansion model.
(Get_Postcond_Enabled): Deleted.
(Get_Result_Object_For_Postcond): Deleted.
(Get_Return_Success_For_Postcond): Deleted.
(Process_Contract_Cases): Add new parameter to store declarations.
(Process_Postconditions): Add new parameter to store declarations.
(Process_Preconditions): Add new parameter to store declarations.
Add code to move entry-call prologue renamings
* einfo.ads: Document new field Wrapped_Statements and modify
comment for Postconditions_Proc.
* exp_attr.adb
(Analyze_Attribute): Modify expansion of the 'Old attribute to
recognize new expansion model and use Wrapped_Statements instead
of Postconditions_Proc.
* exp_ch6.adb
(Add_Return): Remove special expansion for postconditions.
(Expand_Call): Modify condition checking for calls to access
subprogram wrappers to handle new expansion models.
(Expand_Call_Helper): Remove special expansion for postconditions.
(Expand_Non_Function_Return): Remove special expansion for
postconditions.
(Expand_Simple_Function_Return): Remove special expansion for
postconditions.
* exp_ch7.adb
(Build_Finalizer): Deleted, but replaced by code in
Build_Finalizer_Helper
(Build_Finalizer_Helper): Renamed to Build_Finalizer, and special
handling of 'Old objects removed.
* exp_ch9.adb
(Build_Contract_Wrapper): Renamed and moved to contracts package.
* exp_prag.adb
(Expand_Pragma_Contract_Cases): Delay analysis of contracts since
they now instead get analyzed as part of the wrapper generation
instead of after analysis of their corresponding subprogram's
body.
(Expand_Pragma_Check): Label expanded if-statements which come
from the expansion of assertion statements as
Comes_From_Check_Or_Contract.
* freeze.adb
(Freeze_Entity): Add special case to avoid freezing when a freeze
node gets generated as part of the expansion of a postcondition
check.
* gen_il-gen-gen_nodes.adb: Add new flag
Comes_From_Check_Or_Contract.
* gen_il-fields.ads: Add new field Wrapped_Statements. Add new
flag Comes_From_Check_Or_Contract.
* gen_il-gen-gen_entities.adb: Add new field Wrapped_Statements.
* ghost.adb
(Is_OK_Declaration): Replace Name_uPostconditions with
Name_uWrapped_Statements.
(Is_OK_Statement): Simplify condition due to the loss of
Original_Node as a result of the new expansion model of contracts
and use new flag Comes_From_Check_Or_Contract in its place.
* inline.adb
(Declare_Postconditions_Result): Replace Name_uPostconditions with
Name_uWrapped_Statements.
(Expand_Inlined_Call): Replace Name_uPostconditions with
Name_uWrapped_Statements.
* lib.adb, lib.ads
(ipu): Created to aid in debugging.
* lib-xref.adb
(Generate_References): Remove special handling for postcondition
procedures.
* sem_attr.adb
(Analyze_Attribute_Old_Result): Add new context in which 'Old can
appear due to the changes in expansion. Replace
Name_uPostconditions with Name_uWrapped_Statements.
(Result): Replace Name_uPostconditions with
Name_uWrapped_Statements.
* sem_ch11.adb
(Analyze_Handled_Statements): Remove check to exclude warnings on
useless assignments within postcondition procedures since
postconditions no longer get isolated into separate subprograms.
* sem_ch6.adb
(Analyze_Generic_Subprogram_Body): Modify expansion of generic
subprogram bodies so that contracts (and their associated pragmas)
get analyzed first.
(Analyze_Subprogram_Body_Helper): Remove global HSS variable due
to the HSS of the body potentially changing during the expansion
of contracts. In cases where it was used instead directly call
Handled_Statement_Sequence. Modify expansion of subprogram bodies
so that contracts (and their associated pragmas) get analyzed
first.
(Check_Missing_Return): Create local HSS variable instead of using
a global one.
(Move_Pragmas): Use new pragma table instead of an explicit list.
* sem_elab.adb
(Is_Postconditions_Proc): Deleted since the new scheme of
expansion no longer divides postcondition checks to a separate
subprogram and so cannot be easily identified (similar to
pre-condition checks).
(Info_Call): Remove info printing for _Postconditions subprograms.
(Is_Assertion_Pragma_Target): Remove check for postconditions
procedure
(Is_Bridge_Target): Remove check for postconditions procedure.
(Get_Invocation_Attributes): Remove unneeded local variables and
check for postconditions procedure.
(Output_Call): Remove info printing for _Postconditions
subprograms.
* sem_prag.adb, sem_prag.ads: Add new Pragma table for pragmas
significant to subprograms, along with tech-debt comment.
(Check_Arg_Is_Local_Name): Modified to recognize the new
_Wrapped_Statements internal subprogram and the new expansion
model.
(Relocate_Pragmas_To_Body): Replace Name_uPostconditions with
Name_uWrapped_Statements.
* sem_res.adb
(Resolve_Entry_Call): Add conditional to detect both contract
based wrappers of entries, but also wrappers generated as part of
general contract expansion (e.g. local postconditions
subprograms).
* sem_util.adb
(Accessibility_Level): Verify 'Access is not taken based on a
component of a function result.
(Has_Significant_Contracts): Replace Name_uPostconditions with
Name_uWrapped_Statements.
(Same_Or_Aliased_Subprogram): Add conditional to detect and obtain
the original subprogram based on the new concept of
"postcondition" wrappers.
* sinfo.ads: Add documentation for new flag
Comes_From_Check_Or_Contract.
* snames.ads-tmpl: Remove Name_uPostconditions and add
Name_uWrapped_Statements
Diffstat (limited to 'gcc/ada/sem_ch6.adb')
-rw-r--r-- | gcc/ada/sem_ch6.adb | 85 |
1 files changed, 39 insertions, 46 deletions
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 93eeecb..0459058 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -1911,15 +1911,19 @@ package body Sem_Ch6 is Analyze_Aspects_On_Subprogram_Body_Or_Stub (N); end if; - Analyze_Declarations (Declarations (N)); - Check_Completion; - - -- Process the contract of the subprogram body after all declarations - -- have been analyzed. This ensures that any contract-related pragmas - -- are available through the N_Contract node of the body. + -- Process the contract of the subprogram body after analyzing all + -- the contract-related pragmas within the declarations. + Analyze_Pragmas_In_Declarations (Body_Id); Analyze_Entry_Or_Subprogram_Body_Contract (Body_Id); + -- Continue on with analyzing the declarations and statements once + -- contract expansion is done and we are done expanding contract + -- related wrappers. + + Analyze_Declarations (Declarations (N)); + Check_Completion; + Analyze (Handled_Statement_Sequence (N)); Save_Global_References (Original_Node (N)); @@ -2895,7 +2899,6 @@ package body Sem_Ch6 is Conformant : Boolean; Desig_View : Entity_Id := Empty; Exch_Views : Elist_Id := No_Elist; - HSS : Node_Id; Mask_Types : Elist_Id := No_Elist; Prot_Typ : Entity_Id := Empty; Spec_Decl : Node_Id := Empty; @@ -3530,6 +3533,8 @@ package body Sem_Ch6 is -------------------------- procedure Check_Missing_Return is + HSS : constant Node_Id := Handled_Statement_Sequence (N); + Id : Entity_Id; Missing_Ret : Boolean; @@ -3968,18 +3973,9 @@ package body Sem_Ch6 is -- Move relevant pragmas to the spec - elsif Pragma_Name_Unmapped (Decl) in Name_Depends - | Name_Ghost - | Name_Global - | Name_Pre - | Name_Precondition - | Name_Post - | Name_Refined_Depends - | Name_Refined_Global - | Name_Refined_Post - | Name_Inline - | Name_Pure_Function - | Name_Volatile_Function + elsif + Pragma_Significant_To_Subprograms + (Get_Pragma_Id (Decl)) then Remove (Decl); Insert_After (Insert_Nod, Decl); @@ -4223,7 +4219,6 @@ package body Sem_Ch6 is Analyze_Generic_Subprogram_Body (N, Spec_Id); if Nkind (N) = N_Subprogram_Body then - HSS := Handled_Statement_Sequence (N); Check_Missing_Return; end if; @@ -5157,9 +5152,27 @@ package body Sem_Ch6 is end; end if; - -- Now we can go on to analyze the body + -- Ada 2012 (AI05-0151): Incomplete types coming from a limited context + -- may now appear in parameter and result profiles. Since the analysis + -- of a subprogram body may use the parameter and result profile of the + -- spec, swap any limited views with their non-limited counterpart. + + if Ada_Version >= Ada_2012 and then Present (Spec_Id) then + Exch_Views := Exchange_Limited_Views (Spec_Id); + end if; + + -- Analyze any aspect specifications that appear on the subprogram body + + if Has_Aspects (N) then + Analyze_Aspects_On_Subprogram_Body_Or_Stub (N); + end if; + + -- Process the contract of the subprogram body after analyzing all the + -- contract-related pragmas within the declarations. + + Analyze_Pragmas_In_Declarations (Body_Id); + Analyze_Entry_Or_Subprogram_Body_Contract (Body_Id); - HSS := Handled_Statement_Sequence (N); Set_Actual_Subtypes (N, Current_Scope); -- Add a declaration for the Protection object, renaming declarations @@ -5180,15 +5193,6 @@ package body Sem_Ch6 is (Sloc (N), Spec_Id, Prot_Typ, N, Declarations (N)); end if; - -- Ada 2012 (AI05-0151): Incomplete types coming from a limited context - -- may now appear in parameter and result profiles. Since the analysis - -- of a subprogram body may use the parameter and result profile of the - -- spec, swap any limited views with their non-limited counterpart. - - if Ada_Version >= Ada_2012 and then Present (Spec_Id) then - Exch_Views := Exchange_Limited_Views (Spec_Id); - end if; - -- If the return type is an anonymous access type whose designated type -- is the limited view of a class-wide type and the non-limited view is -- available, update the return type accordingly. @@ -5225,12 +5229,6 @@ package body Sem_Ch6 is end; end if; - -- Analyze any aspect specifications that appear on the subprogram body - - if Has_Aspects (N) then - Analyze_Aspects_On_Subprogram_Body_Or_Stub (N); - end if; - Analyze_Declarations (Declarations (N)); -- Verify that the SPARK_Mode of the body agrees with that of its spec @@ -5269,17 +5267,11 @@ package body Sem_Ch6 is end if; end if; - -- A subprogram body freezes its own contract. Analyze the contract - -- after the declarations of the body have been processed as pragmas - -- are now chained on the contract of the subprogram body. - - Analyze_Entry_Or_Subprogram_Body_Contract (Body_Id); - -- Check completion, and analyze the statements Check_Completion; Inspect_Deferred_Constant_Completion (Declarations (N)); - Analyze (HSS); + Analyze (Handled_Statement_Sequence (N)); -- Add the generated minimum accessibility objects to the subprogram -- body's list of declarations after analysis of the statements and @@ -5296,7 +5288,8 @@ package body Sem_Ch6 is -- Deal with end of scope processing for the body - Process_End_Label (HSS, 't', Current_Scope); + Process_End_Label + (Handled_Statement_Sequence (N), 't', Current_Scope); Update_Use_Clause_Chain; End_Scope; @@ -5410,7 +5403,7 @@ package body Sem_Ch6 is -- the warning. declare - Stm : Node_Id := First (Statements (HSS)); + Stm : Node_Id := First (Statements (Handled_Statement_Sequence (N))); begin -- Skip call markers installed by the ABE mechanism, labels, and -- Push_xxx_Error_Label to find the first real statement. |