@@ -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;
@@ -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;
----------------
@@ -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
@@ -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;
@@ -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;
@@ -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
@@ -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),
@@ -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;
@@ -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
@@ -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;
@@ -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;
@@ -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
@@ -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