diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index 66ba73226ed07d73ace1e2f0cf563aba5133e3d1..69d6e25794e803ccf001afb66e4021857b768c81 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -7708,20 +7708,20 @@ package body Exp_Util is return; end if; - -- Insert the action when the context is "Handling of Default and Per- - -- Object Expressions" only when requested by the caller. - - if Spec_Expr_OK then - null; - -- Ignore insert of actions from inside default expression (or other -- similar "spec expression") in the special spec-expression analyze -- mode. Any insertions at this point have no relevance, since we are -- only doing the analyze to freeze the types of any static expressions. -- See section "Handling of Default and Per-Object Expressions" in the - -- spec of package Sem for further details. + -- spec of package Sem for further details. However, if the user does + -- nevertheless request the insert, then obey it. + + -- Under strict preanalysis we cannot ignore insert of actions because + -- we may be adding to the tree a subtype declaration that is required + -- for proper preanalysis (see Sem_Ch3.Find_Type_Of_Object). - elsif In_Spec_Expression then + if In_Spec_Expression and then not Spec_Expr_OK then + pragma Assert (not In_Strict_Preanalysis); return; end if; diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb index a7e3df9f06e999a3d70463bab424be8eeb438fa2..9b013995b8a8843af3619252ce58db79b2027daa 100644 --- a/gcc/ada/sem.adb +++ b/gcc/ada/sem.adb @@ -1338,13 +1338,22 @@ package body Sem is Scope_Stack.Locked := True; end Lock; + --------------------------- + -- In_Strict_Preanalysis -- + --------------------------- + + function In_Strict_Preanalysis return Boolean is + begin + return Preanalysis_Active and then not In_Spec_Expression; + end In_Strict_Preanalysis; + ------------------------ -- Preanalysis_Active -- ------------------------ function Preanalysis_Active return Boolean is begin - return not Full_Analysis and not Expander_Active; + return not Full_Analysis and then not Expander_Active; end Preanalysis_Active; ---------------- diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads index 89b616f0bd42e31cf73ef6880702aa2584162cd4..f317479d4618f96aa40983c844d3bb904806915a 100644 --- a/gcc/ada/sem.ads +++ b/gcc/ada/sem.ads @@ -703,6 +703,11 @@ package Sem is -- This function returns True if an explicit pragma Suppress for check C -- is present in the package defining E. + function In_Strict_Preanalysis return Boolean; + pragma Inline (In_Strict_Preanalysis); + -- Determine whether preanalysis is active at the point of invocation + -- and we are not processing a Spec Expression. + function Preanalysis_Active return Boolean; pragma Inline (Preanalysis_Active); -- Determine whether preanalysis is active at the point of invocation diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index 39725d23442b23aa46409ad4490de82bf35ae8d2..e74d3051b34f76e9447b87cd463ad14745890d0b 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -2106,11 +2106,12 @@ package body Sem_Attr is -- designated type of the access type, since the type of the -- referenced array is this type (see AI95-00106). - -- As done elsewhere, freezing must not happen when preanalyzing - -- a pre- or postcondition or a default value for an object or for - -- a formal parameter. + -- However, we must not freeze the designated type during + -- preanalysis; neither under strict preanalysis nor when + -- preanalyzing a pre- or postcondition or a default value + -- for an object or for a formal parameter. - if not In_Spec_Expression then + if not Preanalysis_Active then Freeze_Before (N, Designated_Type (P_Type)); end if; @@ -8139,6 +8140,13 @@ package body Sem_Attr is if Nkind (N) /= N_Attribute_Reference then return; + + -- No evaluation required under strict preanalysis because locating + -- static expressions is not needed; this also minimizes making tree + -- modifications during strict preanalysis. + + elsif In_Strict_Preanalysis then + return; end if; Aname := Attribute_Name (N); @@ -11342,10 +11350,11 @@ package body Sem_Attr is end loop; -- If Prefix is a subprogram name, this reference freezes, - -- but not if within spec expression mode. The profile of - -- the subprogram is not frozen at this point. + -- but not during preanalysis (including preanalysis of + -- spec expressions). The profile of the subprogram is not + -- frozen at this point. - if not In_Spec_Expression then + if not Preanalysis_Active then Freeze_Before (N, Entity (P), Do_Freeze_Profile => False); end if; @@ -11354,7 +11363,7 @@ package body Sem_Attr is -- If it is an object, complete its resolution. elsif Is_Overloadable (Entity (P)) then - if not In_Spec_Expression then + if not Preanalysis_Active then Freeze_Before (N, Entity (P), Do_Freeze_Profile => False); end if; diff --git a/gcc/ada/sem_cat.adb b/gcc/ada/sem_cat.adb index d89281195125b1e6af212985190ab2af5f79ec0a..0bd976cbf655e9f4e7a93c01f542c5327192e560 100644 --- a/gcc/ada/sem_cat.adb +++ b/gcc/ada/sem_cat.adb @@ -2177,6 +2177,7 @@ package body Sem_Cat is or else not Comes_From_Source (N) or else In_Subprogram_Or_Concurrent_Unit or else Ekind (Current_Scope) = E_Block + or else In_Strict_Preanalysis then return; diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb index a9aba1de6e481a1fc53c023cf39c64cd63eda9c5..2beb6b95daf3f485ae94b615ebcb465c53c29690 100644 --- a/gcc/ada/sem_ch13.adb +++ b/gcc/ada/sem_ch13.adb @@ -10039,7 +10039,7 @@ package body Sem_Ch13 is -- If the predicate pragma comes from an aspect, replace the -- saved expression because we need the subtype references - -- replaced for the calls to Preanalyze_Spec_Expression in + -- replaced for the calls to Preanalyze_And_Resolve in -- Check_Aspect_At_xxx routines. if Present (Asp) then @@ -10853,12 +10853,12 @@ package body Sem_Ch13 is | Aspect_Static_Predicate then Push_Type (Ent); - Preanalyze_Spec_Expression (Freeze_Expr, Standard_Boolean); + Preanalyze_And_Resolve (Freeze_Expr, Standard_Boolean); Pop_Type (Ent); elsif A_Id = Aspect_Priority then Push_Type (Ent); - Preanalyze_Spec_Expression (Freeze_Expr, Any_Integer); + Preanalyze_And_Resolve (Freeze_Expr, Any_Integer); Pop_Type (Ent); else @@ -10916,13 +10916,14 @@ package body Sem_Ch13 is | Aspect_Static_Predicate then Push_Type (Ent); - Preanalyze_Spec_Expression (End_Decl_Expr, T); + Preanalyze_And_Resolve (End_Decl_Expr, T); Pop_Type (Ent); elsif A_Id = Aspect_Predicate_Failure then - Preanalyze_Spec_Expression (End_Decl_Expr, Standard_String); + Preanalyze_And_Resolve (End_Decl_Expr, Standard_String); + elsif Present (End_Decl_Expr) then - Preanalyze_Spec_Expression (End_Decl_Expr, T); + Preanalyze_And_Resolve (End_Decl_Expr, T); end if; Err := @@ -11346,7 +11347,7 @@ package body Sem_Ch13 is -- Do the preanalyze call if Present (Expression (ASN)) then - Preanalyze_Spec_Expression (Expression (ASN), T); + Preanalyze_And_Resolve (Expression (ASN), T); end if; end Check_Aspect_At_Freeze_Point; @@ -16341,19 +16342,16 @@ package body Sem_Ch13 is -- name resolution errors if the predicate function has -- not been built yet. - -- Note that we cannot use Preanalyze_Spec_Expression + -- Note that we cannot use Preanalyze_And_Resolve -- directly because of the special handling required for -- quantifiers (see comments on Resolve_Aspect_Expression -- above) but we need to emulate it properly. if No (Predicate_Function (E)) then declare - Save_In_Spec_Expression : constant Boolean := - In_Spec_Expression; Save_Full_Analysis : constant Boolean := Full_Analysis; begin - In_Spec_Expression := True; Full_Analysis := False; Expander_Mode_Save_And_Set (False); Push_Type (E); @@ -16361,7 +16359,6 @@ package body Sem_Ch13 is Pop_Type (E); Expander_Mode_Restore; Full_Analysis := Save_Full_Analysis; - In_Spec_Expression := Save_In_Spec_Expression; end; end if; @@ -16404,7 +16401,7 @@ package body Sem_Ch13 is | Aspect_Priority => Push_Type (E); - Preanalyze_Spec_Expression (Expr, Any_Integer); + Preanalyze_And_Resolve (Expr, Any_Integer); Pop_Type (E); -- Ditto for Storage_Size. Any other aspects that carry @@ -16412,7 +16409,7 @@ package body Sem_Ch13 is -- relevant to the misuse of deferred constants. when Aspect_Storage_Size => - Preanalyze_Spec_Expression (Expr, Any_Integer); + Preanalyze_And_Resolve (Expr, Any_Integer); when others => if Present (Expr) then diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb index 7bedc043c8d4fc9b44ddc02e69a98219e7402edd..f0ce27b5e23af5f5ed9d41374e5872ad764d0a84 100644 --- a/gcc/ada/sem_ch3.adb +++ b/gcc/ada/sem_ch3.adb @@ -4575,7 +4575,8 @@ package body Sem_Ch3 is and then Is_Itype (T) then Set_Has_Delayed_Freeze (T); - elsif not In_Spec_Expression then + + elsif not Preanalysis_Active then Freeze_Before (N, T); end if; end if; @@ -18796,7 +18797,9 @@ package body Sem_Ch3 is end if; -- When generating code, insert subtype declaration ahead of - -- declaration that generated it. + -- declaration that generated it. Similar behavior required under + -- preanalysis (including strict preanalysis) to perform the + -- minimum decoration, and avoid reporting spurious errors. Insert_Action (Obj_Def, Make_Subtype_Declaration (Sloc (P), diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb index 7bd30d6993e208d2ba4edb5b3b5cb2320273aa7e..6ec351e42a6f6a7c7759a2b6e75a6e16fb56b3f4 100644 --- a/gcc/ada/sem_ch4.adb +++ b/gcc/ada/sem_ch4.adb @@ -1795,7 +1795,7 @@ package body Sem_Ch4 is if Is_OK_Static_Subtype (Exp_Type) and then Has_Static_Predicate_Aspect (Exp_Type) - and then In_Spec_Expression + and then Preanalysis_Active then null; diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index d81bdc50ee0d9606bcee9227c79965d76a9f6fb8..9cd135d48ceb6293f913f26066e84c5a6c1f8074 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -533,29 +533,6 @@ package body Sem_Ch6 is Set_Corresponding_Body (N, Defining_Entity (New_Body)); Set_Corresponding_Spec (New_Body, Def_Id); - -- Within a generic preanalyze the original expression for name - -- capture. The body is also generated but plays no role in - -- this because it is not part of the original source. - -- If this is an ignored Ghost entity, analysis of the generated - -- body is needed to hide external references (as is done in - -- Analyze_Subprogram_Body) after which the subprogram profile - -- can be frozen, which is needed to expand calls to such an ignored - -- Ghost subprogram. - - if Inside_A_Generic then - Set_Has_Completion (Def_Id, not Is_Ignored_Ghost_Entity (Def_Id)); - Push_Scope (Def_Id); - Install_Formals (Def_Id); - Preanalyze_Spec_Expression (Expr, Typ); - End_Scope; - else - Push_Scope (Def_Id); - Install_Formals (Def_Id); - Preanalyze_Spec_Expression (Expr, Typ); - Check_Limited_Return (Orig_N, Expr, Typ); - End_Scope; - end if; - -- If this is a wrapper created in an instance for a formal -- subprogram, insert body after declaration, to be analyzed when the -- enclosing instance is analyzed. @@ -591,6 +568,29 @@ package body Sem_Ch6 is end; end if; + -- Within a generic preanalyze the original expression for name + -- capture. The body is also generated but plays no role in + -- this because it is not part of the original source. + -- If this is an ignored Ghost entity, analysis of the generated + -- body is needed to hide external references (as is done in + -- Analyze_Subprogram_Body) after which the subprogram profile + -- can be frozen, which is needed to expand calls to such an ignored + -- Ghost subprogram. + + if Inside_A_Generic then + Set_Has_Completion (Def_Id, not Is_Ignored_Ghost_Entity (Def_Id)); + Push_Scope (Def_Id); + Install_Formals (Def_Id); + Preanalyze_Spec_Expression (Expr, Typ); + End_Scope; + else + Push_Scope (Def_Id); + Install_Formals (Def_Id); + Preanalyze_Spec_Expression (Expr, Typ); + Check_Limited_Return (Orig_N, Expr, Typ); + End_Scope; + end if; + -- In the case of an expression function marked with the aspect -- Static, we need to check the requirement that the function's -- expression is a potentially static expression. This is done diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb index 414caf2edaaf0bf948b6fb2be216cb8be653371c..1fa714d229e8eb4f51cc41b8565dac7b89df5620 100644 --- a/gcc/ada/sem_elab.adb +++ b/gcc/ada/sem_elab.adb @@ -17389,7 +17389,7 @@ package body Sem_Elab is -- Nothing to do if call is being preanalyzed, as when within a -- pre/postcondition, a predicate, or an invariant. - elsif In_Spec_Expression then + elsif Preanalysis_Active then return; end if; diff --git a/gcc/ada/sem_elim.adb b/gcc/ada/sem_elim.adb index d553950dbd726c3f4267bed32a15eaef6e33496a..2bff3dc4ae240542578ad5cd3b4694bfa43e49d0 100644 --- a/gcc/ada/sem_elim.adb +++ b/gcc/ada/sem_elim.adb @@ -728,9 +728,10 @@ package body Sem_Elim is begin -- No check needed within a default expression for a formal, since this -- is not really a use, and the expression (a call or attribute) may - -- never be used if the enclosing subprogram is itself eliminated. + -- never be used if the enclosing subprogram is itself eliminated. Same + -- under strict preanalysis. - if In_Spec_Expression then + if Preanalysis_Active then return; end if; diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb index c55e4d3bb24bb4cb6f0f98690f7c1f2fa3924791..399b22d0c52b630d6a4c0c45e2257cfd75473e3b 100644 --- a/gcc/ada/sem_eval.adb +++ b/gcc/ada/sem_eval.adb @@ -2927,7 +2927,7 @@ package body Sem_Eval is | Name_Source_Location => if Inside_A_Generic - or else In_Spec_Expression + or else Preanalysis_Active then null; else diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb index 889cbd307b4c3dbffad5e14b484c0286d2b56af7..5f990f3dc4ebb9e2e20947926c6cbe4182ab3d42 100644 --- a/gcc/ada/sem_res.adb +++ b/gcc/ada/sem_res.adb @@ -8147,7 +8147,7 @@ package body Sem_Res is and then Comes_From_Source (E) and then No (Constant_Value (E)) and then Is_Frozen (Etype (E)) - and then not In_Spec_Expression + and then not Preanalysis_Active and then not Is_Imported (E) and then Nkind (Parent (E)) /= N_Object_Renaming_Declaration then