Commit e4d29736 by Javier Miranda Committed by Pierre-Marie de Rodat

[Ada] Crash processing abstract state aspect of a package

The compiler may crash processing an aspect Part_Of used in a
package spec which has also an Initial_Condition aspect. After
this patch the following test compiles fine.

package P
with
  SPARK_Mode => On,
  Abstract_State => (Count_State),
  Initial_Condition => (Get_Count = 0)              -- Test
is
   type Count_Type is range 0 .. 16;

   function Get_Count return Count_Type;

   procedure Dummy;

private
   C: Count_Type := 0 with Part_Of => Count_State;  -- Test

   function Get_Count return Count_Type is (C);
end P;

package body P
with
  SPARK_Mode => On,
  Refined_State => (Count_State => C)
is
  procedure Dummy is null;
end P;

Command: gcc -c p.adb

2018-07-17  Javier Miranda  <miranda@adacore.com>

gcc/ada/

	* exp_ch13.adb (Expand_N_Freeze_Entity): Handle subtype declared for an
	iterator.
	* freeze.adb (Freeze_Expression): Handle freeze of an entity defined
	outside of a subprogram body. This case was previously handled during
	preanalysis; the frozen entities were remembered and left pending until
	we continued freezeing entities outside of the subprogram. Now, when
	climbing the parents chain to locate the correct placement for the
	freezeing node, we check if the entity can be frozen and only when no
	enclosing node is marked as Must_Not_Freeze the entity is frozen.
	* sem_ch3.ads (Preanalyze_Default_Expression): Declaration moved to the
	package body.
	* sem_ch3.adb (Preanalyze_Default_Expression): Code adjusted to invoke
	the new subprogram Preanalyze_With_Freezing_And_Resolve.
	* sem_ch6.adb (Preanalyze_Formal_Expression): New subprogram.
	(Analyze_Expression_Function, Process_Formals): Invoke
	Preanalyze_Formal_Expression instead of Preanalyze_Spec_Expression
	since the analysis of the formals may freeze entities.
	(Analyze_Subprogram_Body_Helper): Skip building the body of the
	class-wide clone for eliminated subprograms.
	* sem_res.ads, sem_res.adb (Preanalyze_And_Resolve): New subprogram.
	Its code is basically the previous version of this routine but extended
	with an additional parameter which is used to specify if during
	preanalysis we are allowed to freeze entities.  If the new parameter is
	True then the subtree root node is marked as Must_Not_Freeze and no
	entities are frozen during preanalysis.
	(Preanalyze_And_Resolve): Invokes the internal version of
	Preanalyze_And_Resolve without entity freezing.
	(Preanalyze_With_Freezing_And_Resolve): Invokes the internal version of
	Prenalyze_And_Resolve with freezing enabled.

From-SVN: r262785
parent 52afb186
2018-07-17 Javier Miranda <miranda@adacore.com>
* exp_ch13.adb (Expand_N_Freeze_Entity): Handle subtype declared for an
iterator.
* freeze.adb (Freeze_Expression): Handle freeze of an entity defined
outside of a subprogram body. This case was previously handled during
preanalysis; the frozen entities were remembered and left pending until
we continued freezeing entities outside of the subprogram. Now, when
climbing the parents chain to locate the correct placement for the
freezeing node, we check if the entity can be frozen and only when no
enclosing node is marked as Must_Not_Freeze the entity is frozen.
* sem_ch3.ads (Preanalyze_Default_Expression): Declaration moved to the
package body.
* sem_ch3.adb (Preanalyze_Default_Expression): Code adjusted to invoke
the new subprogram Preanalyze_With_Freezing_And_Resolve.
* sem_ch6.adb (Preanalyze_Formal_Expression): New subprogram.
(Analyze_Expression_Function, Process_Formals): Invoke
Preanalyze_Formal_Expression instead of Preanalyze_Spec_Expression
since the analysis of the formals may freeze entities.
(Analyze_Subprogram_Body_Helper): Skip building the body of the
class-wide clone for eliminated subprograms.
* sem_res.ads, sem_res.adb (Preanalyze_And_Resolve): New subprogram.
Its code is basically the previous version of this routine but extended
with an additional parameter which is used to specify if during
preanalysis we are allowed to freeze entities. If the new parameter is
True then the subtree root node is marked as Must_Not_Freeze and no
entities are frozen during preanalysis.
(Preanalyze_And_Resolve): Invokes the internal version of
Preanalyze_And_Resolve without entity freezing.
(Preanalyze_With_Freezing_And_Resolve): Invokes the internal version of
Prenalyze_And_Resolve with freezing enabled.
2018-07-17 Piotr Trojanek <trojanek@adacore.com> 2018-07-17 Piotr Trojanek <trojanek@adacore.com>
* einfo.ads, libgnat/g-comlin.ads: Minor change "ie" to "i.e." in docs * einfo.ads, libgnat/g-comlin.ads: Minor change "ie" to "i.e." in docs
......
...@@ -470,6 +470,11 @@ package body Exp_Ch13 is ...@@ -470,6 +470,11 @@ package body Exp_Ch13 is
and then Ekind (E_Scope) not in Concurrent_Kind and then Ekind (E_Scope) not in Concurrent_Kind
then then
E_Scope := Scope (E_Scope); E_Scope := Scope (E_Scope);
-- The entity may be a subtype declared for an iterator.
elsif Ekind (E_Scope) = E_Loop then
E_Scope := Scope (E_Scope);
end if; end if;
-- Remember that we are processing a freezing entity and its freezing -- Remember that we are processing a freezing entity and its freezing
......
...@@ -6936,20 +6936,6 @@ package body Freeze is ...@@ -6936,20 +6936,6 @@ package body Freeze is
----------------------- -----------------------
procedure Freeze_Expression (N : Node_Id) is procedure Freeze_Expression (N : Node_Id) is
In_Spec_Exp : constant Boolean := In_Spec_Expression;
Typ : Entity_Id;
Nam : Entity_Id;
Desig_Typ : Entity_Id;
P : Node_Id;
Parent_P : Node_Id;
Freeze_Outside : Boolean := False;
-- This flag is set true if the entity must be frozen outside the
-- current subprogram. This happens in the case of expander generated
-- subprograms (_Init_Proc, _Input, _Output, _Read, _Write) which do
-- not freeze all entities like other bodies, but which nevertheless
-- may reference entities that have to be frozen before the body and
-- obviously cannot be frozen inside the body.
function Find_Aggregate_Component_Desig_Type return Entity_Id; function Find_Aggregate_Component_Desig_Type return Entity_Id;
-- If the expression is an array aggregate, the type of the component -- If the expression is an array aggregate, the type of the component
...@@ -7038,6 +7024,29 @@ package body Freeze is ...@@ -7038,6 +7024,29 @@ package body Freeze is
end if; end if;
end In_Expanded_Body; end In_Expanded_Body;
-- Local variables
In_Spec_Exp : constant Boolean := In_Spec_Expression;
Typ : Entity_Id;
Nam : Entity_Id;
Desig_Typ : Entity_Id;
P : Node_Id;
Parent_P : Node_Id;
Freeze_Outside : Boolean := False;
-- This flag is set true if the entity must be frozen outside the
-- current subprogram. This happens in the case of expander generated
-- subprograms (_Init_Proc, _Input, _Output, _Read, _Write) which do
-- not freeze all entities like other bodies, but which nevertheless
-- may reference entities that have to be frozen before the body and
-- obviously cannot be frozen inside the body.
Freeze_Outside_Subp : Entity_Id := Empty;
-- This entity is set if we are inside a subprogram body and the frozen
-- entity is defined in the enclosing scope of this subprogram. In such
-- case we must skip the subprogram body when climbing the parents chain
-- to locate the correct placement for the freezing node.
-- Start of processing for Freeze_Expression -- Start of processing for Freeze_Expression
begin begin
...@@ -7181,22 +7190,98 @@ package body Freeze is ...@@ -7181,22 +7190,98 @@ package body Freeze is
return; return;
end if; end if;
-- Examine the enclosing context by climbing the parent chain. The -- Check if we are inside a subprogram body and the frozen entity is
-- traversal serves two purposes - to detect scenarios where freezeing -- defined in the enclosing scope of this subprogram. In such case we
-- is not needed and to find the proper insertion point for the freeze -- must skip the subprogram when climbing the parents chain to locate
-- nodes. Although somewhat similar to Insert_Actions, this traversal -- the correct placement for the freezing node.
-- is freezing semantics-sensitive. Inserting freeze nodes blindly in
-- the tree may result in types being frozen too early. -- This is not needed for default expressions and other spec expressions
-- in generic units since the Move_Freeze_Nodes mechanism (sem_ch12.adb)
-- takes care of placing them at the proper place, after the generic
-- unit.
if Present (Nam)
and then Scope (Nam) /= Current_Scope
and then not (In_Spec_Exp and then Inside_A_Generic)
then
declare
S : Entity_Id := Current_Scope;
begin
while Present (S)
and then In_Same_Source_Unit (Nam, S)
loop
if Scope (S) = Scope (Nam) then
if Is_Subprogram (S) and then Has_Completion (S) then
Freeze_Outside_Subp := S;
end if;
exit;
end if;
S := Scope (S);
end loop;
end;
end if;
-- Examine the enclosing context by climbing the parent chain.
-- If we identified that we must freeze the entity outside of a given
-- subprogram then we just climb up to that subprogram checking if some
-- enclosing node is marked as Must_Not_Freeze (since in such case we
-- must not freeze yet this entity).
P := N; P := N;
if Present (Freeze_Outside_Subp) then
loop loop
-- Do not freeze the current expression if another expression in
-- the chain of parents must not be frozen.
if Nkind (P) in N_Subexpr and then Must_Not_Freeze (P) then
return;
end if;
Parent_P := Parent (P); Parent_P := Parent (P);
-- If we don't have a parent, then we are not in a well-formed tree. -- If we don't have a parent, then we are not in a well-formed
-- This is an unusual case, but there are some legitimate situations -- tree. This is an unusual case, but there are some legitimate
-- in which this occurs, notably when the expressions in the range of -- situations in which this occurs, notably when the expressions
-- a type declaration are resolved. We simply ignore the freeze -- in the range of a type declaration are resolved. We simply
-- request in this case. Is this right ??? -- ignore the freeze request in this case.
if No (Parent_P) then
return;
end if;
exit when Nkind (Parent_P) = N_Subprogram_Body
and then Unique_Defining_Entity (Parent_P) = Freeze_Outside_Subp;
P := Parent_P;
end loop;
-- Otherwise the traversal serves two purposes - to detect scenarios
-- where freezeing is not needed and to find the proper insertion point
-- for the freeze nodes. Although somewhat similar to Insert_Actions,
-- this traversal is freezing semantics-sensitive. Inserting freeze
-- nodes blindly in the tree may result in types being frozen too early.
else
loop
-- Do not freeze the current expression if another expression in
-- the chain of parents must not be frozen.
if Nkind (P) in N_Subexpr and then Must_Not_Freeze (P) then
return;
end if;
Parent_P := Parent (P);
-- If we don't have a parent, then we are not in a well-formed
-- tree. This is an unusual case, but there are some legitimate
-- situations in which this occurs, notably when the expressions
-- in the range of a type declaration are resolved. We simply
-- ignore the freeze request in this case. Is this right ???
if No (Parent_P) then if No (Parent_P) then
return; return;
...@@ -7206,19 +7291,20 @@ package body Freeze is ...@@ -7206,19 +7291,20 @@ package body Freeze is
case Nkind (Parent_P) is case Nkind (Parent_P) is
-- A special test for the exception of (RM 13.14(8)) for the case -- A special test for the exception of (RM 13.14(8)) for the
-- of per-object expressions (RM 3.8(18)) occurring in component -- case of per-object expressions (RM 3.8(18)) occurring in
-- definition or a discrete subtype definition. Note that we test -- component definition or a discrete subtype definition. Note
-- for a component declaration which includes both cases we are -- that we test for a component declaration which includes both
-- interested in, and furthermore the tree does not have explicit -- cases we are interested in, and furthermore the tree does
-- nodes for either of these two constructs. -- not have explicit nodes for either of these two constructs.
when N_Component_Declaration => when N_Component_Declaration =>
-- The case we want to test for here is an identifier that is -- The case we want to test for here is an identifier that
-- a per-object expression, this is either a discriminant that -- is a per-object expression, this is either a discriminant
-- appears in a context other than the component declaration -- that appears in a context other than the component
-- or it is a reference to the type of the enclosing construct. -- declaration or it is a reference to the type of the
-- enclosing construct.
-- For either of these cases, we skip the freezing -- For either of these cases, we skip the freezing
...@@ -7242,15 +7328,15 @@ package body Freeze is ...@@ -7242,15 +7328,15 @@ package body Freeze is
end if; end if;
end if; end if;
-- If we have an enumeration literal that appears as the choice in -- If we have an enumeration literal that appears as the choice
-- the aggregate of an enumeration representation clause, then -- in the aggregate of an enumeration representation clause,
-- freezing does not occur (RM 13.14(10)). -- then freezing does not occur (RM 13.14(10)).
when N_Enumeration_Representation_Clause => when N_Enumeration_Representation_Clause =>
-- The case we are looking for is an enumeration literal -- The case we are looking for is an enumeration literal
if (Nkind (N) = N_Identifier or Nkind (N) = N_Character_Literal) if Nkind_In (N, N_Identifier, N_Character_Literal)
and then Is_Enumeration_Type (Etype (N)) and then Is_Enumeration_Type (Etype (N))
then then
-- If enumeration literal appears directly as the choice, -- If enumeration literal appears directly as the choice,
...@@ -7264,8 +7350,8 @@ package body Freeze is ...@@ -7264,8 +7350,8 @@ package body Freeze is
-- If enumeration literal appears as the name of function -- If enumeration literal appears as the name of function
-- which is the choice, then also do not freeze. This -- which is the choice, then also do not freeze. This
-- happens in the overloaded literal case, where the -- happens in the overloaded literal case, where the
-- enumeration literal is temporarily changed to a function -- enumeration literal is temporarily changed to a
-- call for overloading analysis purposes. -- function call for overloading analysis purposes.
elsif Nkind (Parent (N)) = N_Function_Call elsif Nkind (Parent (N)) = N_Function_Call
and then and then
...@@ -7283,11 +7369,11 @@ package body Freeze is ...@@ -7283,11 +7369,11 @@ package body Freeze is
when N_Handled_Sequence_Of_Statements => when N_Handled_Sequence_Of_Statements =>
-- An exception occurs when the sequence of statements is for -- An exception occurs when the sequence of statements is
-- an expander generated body that did not do the usual freeze -- for an expander generated body that did not do the usual
-- all operation. In this case we usually want to freeze -- freeze all operation. In this case we usually want to
-- outside this body, not inside it, and we skip past the -- freeze outside this body, not inside it, and we skip
-- subprogram body that we are inside. -- past the subprogram body that we are inside.
if In_Expanded_Body (Parent_P) then if In_Expanded_Body (Parent_P) then
declare declare
...@@ -7295,12 +7381,13 @@ package body Freeze is ...@@ -7295,12 +7381,13 @@ package body Freeze is
Spec : Entity_Id; Spec : Entity_Id;
begin begin
-- Freeze the entity only when it is declared inside the -- Freeze the entity only when it is declared inside
-- body of the expander generated procedure. This case -- the body of the expander generated procedure.
-- is recognized by the scope of the entity or its type, -- This case is recognized by the scope of the entity
-- which is either the spec for some enclosing body, or -- or its type, which is either the spec for some
-- (in the case of init_procs, for which there are no -- enclosing body, or (in the case of init_procs,
-- separate specs) the current scope. -- for which there are no separate specs) the current
-- scope.
if Nkind (Subp) = N_Subprogram_Body then if Nkind (Subp) = N_Subprogram_Body then
Spec := Corresponding_Spec (Subp); Spec := Corresponding_Spec (Subp);
...@@ -7329,14 +7416,14 @@ package body Freeze is ...@@ -7329,14 +7416,14 @@ package body Freeze is
-- function Hidden return ...; -- function Hidden return ...;
-- function F return ... is (Hidden); -- 2 -- function F return ... is (Hidden); -- 2
-- Refering to the example above, freezing the expression -- Refering to the example above, freezing the
-- of F (2) would place Hidden's freeze node (1) in the -- expression of F (2) would place Hidden's freeze
-- wrong place. Avoid explicit freezing and let the usual -- node (1) in the wrong place. Avoid explicit
-- scenarios do the job - for example, reaching the end -- freezing and let the usual scenarios do the job
-- of the private declarations, or a call to F. -- (for example, reaching the end of the private
-- declarations, or a call to F.)
if Nkind (Original_Node (Subp)) = if Nkind (Original_Node (Subp)) = N_Expression_Function
N_Expression_Function
then then
null; null;
...@@ -7355,9 +7442,9 @@ package body Freeze is ...@@ -7355,9 +7442,9 @@ package body Freeze is
exit; exit;
end if; end if;
-- If parent is a body or a spec or a block, then the current node -- If parent is a body or a spec or a block, then the current
-- is a statement or declaration and we can insert the freeze node -- node is a statement or declaration and we can insert the
-- before it. -- freeze node before it.
when N_Block_Statement when N_Block_Statement
| N_Entry_Body | N_Entry_Body
...@@ -7369,9 +7456,10 @@ package body Freeze is ...@@ -7369,9 +7456,10 @@ package body Freeze is
=> =>
exit; exit;
-- The expander is allowed to define types in any statements list, -- The expander is allowed to define types in any statements
-- so any of the following parent nodes also mark a freezing point -- list, so any of the following parent nodes also mark a
-- if the actual node is in a list of statements or declarations. -- freezing point if the actual node is in a list of
-- statements or declarations.
when N_Abortable_Part when N_Abortable_Part
| N_Accept_Alternative | N_Accept_Alternative
...@@ -7392,11 +7480,11 @@ package body Freeze is ...@@ -7392,11 +7480,11 @@ package body Freeze is
=> =>
exit when Is_List_Member (P); exit when Is_List_Member (P);
-- Freeze nodes produced by an expression coming from the Actions -- Freeze nodes produced by an expression coming from the
-- list of a N_Expression_With_Actions node must remain within the -- Actions list of a N_Expression_With_Actions node must remain
-- Actions list. Inserting the freeze nodes further up the tree -- within the Actions list. Inserting the freeze nodes further
-- may lead to use before declaration issues in the case of array -- up the tree may lead to use before declaration issues in the
-- types. -- case of array types.
when N_Expression_With_Actions => when N_Expression_With_Actions =>
if Is_List_Member (P) if Is_List_Member (P)
...@@ -7405,13 +7493,13 @@ package body Freeze is ...@@ -7405,13 +7493,13 @@ package body Freeze is
exit; exit;
end if; end if;
-- Note: N_Loop_Statement is a special case. A type that appears -- Note: N_Loop_Statement is a special case. A type that
-- in the source can never be frozen in a loop (this occurs only -- appears in the source can never be frozen in a loop (this
-- because of a loop expanded by the expander), so we keep on -- occurs only because of a loop expanded by the expander), so
-- going. Otherwise we terminate the search. Same is true of any -- we keep on going. Otherwise we terminate the search. Same
-- entity which comes from source. (if they have predefined type, -- is true of any entity which comes from source. (if they
-- that type does not appear to come from source, but the entity -- have predefined type, that type does not appear to come
-- should not be frozen here). -- from source, but the entity should not be frozen here).
when N_Loop_Statement => when N_Loop_Statement =>
exit when not Comes_From_Source (Etype (N)) exit when not Comes_From_Source (Etype (N))
...@@ -7428,6 +7516,7 @@ package body Freeze is ...@@ -7428,6 +7516,7 @@ package body Freeze is
P := Parent_P; P := Parent_P;
end loop; end loop;
end if;
-- If the expression appears in a record or an initialization procedure, -- If the expression appears in a record or an initialization procedure,
-- the freeze nodes are collected and attached to the current scope, to -- the freeze nodes are collected and attached to the current scope, to
......
...@@ -605,6 +605,10 @@ package body Sem_Ch3 is ...@@ -605,6 +605,10 @@ package body Sem_Ch3 is
-- Create a new ordinary fixed point type, and apply the constraint to -- Create a new ordinary fixed point type, and apply the constraint to
-- obtain subtype of it. -- obtain subtype of it.
procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id);
-- Wrapper on Preanalyze_Spec_Expression for default expressions, so that
-- In_Default_Expr can be properly adjusted.
procedure Prepare_Private_Subtype_Completion procedure Prepare_Private_Subtype_Completion
(Id : Entity_Id; (Id : Entity_Id;
Related_Nod : Node_Id); Related_Nod : Node_Id);
...@@ -19819,10 +19823,13 @@ package body Sem_Ch3 is ...@@ -19819,10 +19823,13 @@ package body Sem_Ch3 is
procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id) is procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id) is
Save_In_Default_Expr : constant Boolean := In_Default_Expr; Save_In_Default_Expr : constant Boolean := In_Default_Expr;
Save_In_Spec_Expression : constant Boolean := In_Spec_Expression;
begin begin
In_Default_Expr := True; In_Default_Expr := True;
Preanalyze_Spec_Expression (N, T); In_Spec_Expression := True;
Preanalyze_With_Freezing_And_Resolve (N, T);
In_Default_Expr := Save_In_Default_Expr; In_Default_Expr := Save_In_Default_Expr;
In_Spec_Expression := Save_In_Spec_Expression;
end Preanalyze_Default_Expression; end Preanalyze_Default_Expression;
-------------------------------- --------------------------------
......
...@@ -250,10 +250,6 @@ package Sem_Ch3 is ...@@ -250,10 +250,6 @@ package Sem_Ch3 is
-- Wrapper on Preanalyze_Spec_Expression for assertion expressions, so that -- Wrapper on Preanalyze_Spec_Expression for assertion expressions, so that
-- In_Assertion_Expr can be properly adjusted. -- In_Assertion_Expr can be properly adjusted.
procedure Preanalyze_Default_Expression (N : Node_Id; T : Entity_Id);
-- Wrapper on Preanalyze_Spec_Expression for default expressions, so that
-- In_Default_Expr can be properly adjusted.
procedure Process_Full_View (N : Node_Id; Full_T, Priv_T : Entity_Id); procedure Process_Full_View (N : Node_Id; Full_T, Priv_T : Entity_Id);
-- Process some semantic actions when the full view of a private type is -- Process some semantic actions when the full view of a private type is
-- encountered and analyzed. The first action is to create the full views -- encountered and analyzed. The first action is to create the full views
......
...@@ -206,6 +206,10 @@ package body Sem_Ch6 is ...@@ -206,6 +206,10 @@ package body Sem_Ch6 is
-- Create the declaration for an inequality operator that is implicitly -- Create the declaration for an inequality operator that is implicitly
-- created by a user-defined equality operator that yields a boolean. -- created by a user-defined equality operator that yields a boolean.
procedure Preanalyze_Formal_Expression (N : Node_Id; T : Entity_Id);
-- Preanalysis of default expressions of subprogram formals. N is the
-- expression to be analyzed and T is the expected type.
procedure Set_Formal_Validity (Formal_Id : Entity_Id); procedure Set_Formal_Validity (Formal_Id : Entity_Id);
-- Formal_Id is an formal parameter entity. This procedure deals with -- Formal_Id is an formal parameter entity. This procedure deals with
-- setting the proper validity status for this entity, which depends on -- setting the proper validity status for this entity, which depends on
...@@ -761,7 +765,7 @@ package body Sem_Ch6 is ...@@ -761,7 +765,7 @@ package body Sem_Ch6 is
if not Inside_A_Generic then if not Inside_A_Generic then
Push_Scope (Def_Id); Push_Scope (Def_Id);
Install_Formals (Def_Id); Install_Formals (Def_Id);
Preanalyze_Spec_Expression (Expr, Typ); Preanalyze_Formal_Expression (Expr, Typ);
Check_Limited_Return (Original_Node (N), Expr, Typ); Check_Limited_Return (Original_Node (N), Expr, Typ);
End_Scope; End_Scope;
end if; end if;
...@@ -3862,12 +3866,14 @@ package body Sem_Ch6 is ...@@ -3862,12 +3866,14 @@ package body Sem_Ch6 is
-- If the subprogram has a class-wide clone, build its body as a copy -- If the subprogram has a class-wide clone, build its body as a copy
-- of the original body, and rewrite body of original subprogram as a -- of the original body, and rewrite body of original subprogram as a
-- wrapper that calls the clone. If N is a stub, this construction will -- wrapper that calls the clone. If N is a stub, this construction will
-- take place when the proper body is analyzed. -- take place when the proper body is analyzed. No action needed if this
-- subprogram has been eliminated.
if Present (Spec_Id) if Present (Spec_Id)
and then Present (Class_Wide_Clone (Spec_Id)) and then Present (Class_Wide_Clone (Spec_Id))
and then (Comes_From_Source (N) or else Was_Expression_Function (N)) and then (Comes_From_Source (N) or else Was_Expression_Function (N))
and then Nkind (N) /= N_Subprogram_Body_Stub and then Nkind (N) /= N_Subprogram_Body_Stub
and then not (Expander_Active and then Is_Eliminated (Spec_Id))
then then
Build_Class_Wide_Clone_Body (Spec_Id, N); Build_Class_Wide_Clone_Body (Spec_Id, N);
...@@ -11333,6 +11339,18 @@ package body Sem_Ch6 is ...@@ -11333,6 +11339,18 @@ package body Sem_Ch6 is
end if; end if;
end New_Overloaded_Entity; end New_Overloaded_Entity;
----------------------------------
-- Preanalyze_Formal_Expression --
----------------------------------
procedure Preanalyze_Formal_Expression (N : Node_Id; T : Entity_Id) is
Save_In_Spec_Expression : constant Boolean := In_Spec_Expression;
begin
In_Spec_Expression := True;
Preanalyze_With_Freezing_And_Resolve (N, T);
In_Spec_Expression := Save_In_Spec_Expression;
end Preanalyze_Formal_Expression;
--------------------- ---------------------
-- Process_Formals -- -- Process_Formals --
--------------------- ---------------------
...@@ -11625,7 +11643,7 @@ package body Sem_Ch6 is ...@@ -11625,7 +11643,7 @@ package body Sem_Ch6 is
-- Do the special preanalysis of the expression (see section on -- Do the special preanalysis of the expression (see section on
-- "Handling of Default Expressions" in the spec of package Sem). -- "Handling of Default Expressions" in the spec of package Sem).
Preanalyze_Spec_Expression (Default, Formal_Type); Preanalyze_Formal_Expression (Default, Formal_Type);
-- An access to constant cannot be the default for -- An access to constant cannot be the default for
-- an access parameter that is an access to variable. -- an access parameter that is an access to variable.
......
...@@ -142,6 +142,12 @@ package body Sem_Res is ...@@ -142,6 +142,12 @@ package body Sem_Res is
-- a call, so such an operator is not treated as predefined by this -- a call, so such an operator is not treated as predefined by this
-- predicate. -- predicate.
procedure Preanalyze_And_Resolve
(N : Node_Id;
T : Entity_Id;
With_Freezing : Boolean);
-- Subsidiary of public versions of Preanalyze_And_Resolve.
procedure Replace_Actual_Discriminants (N : Node_Id; Default : Node_Id); procedure Replace_Actual_Discriminants (N : Node_Id; Default : Node_Id);
-- If a default expression in entry call N depends on the discriminants -- If a default expression in entry call N depends on the discriminants
-- of the task, it must be replaced with a reference to the discriminant -- of the task, it must be replaced with a reference to the discriminant
...@@ -1660,10 +1666,21 @@ package body Sem_Res is ...@@ -1660,10 +1666,21 @@ package body Sem_Res is
-- Preanalyze_And_Resolve -- -- Preanalyze_And_Resolve --
---------------------------- ----------------------------
procedure Preanalyze_And_Resolve (N : Node_Id; T : Entity_Id) is procedure Preanalyze_And_Resolve
(N : Node_Id;
T : Entity_Id;
With_Freezing : Boolean)
is
Save_Full_Analysis : constant Boolean := Full_Analysis; Save_Full_Analysis : constant Boolean := Full_Analysis;
Save_Must_Not_Freeze : constant Boolean := Must_Not_Freeze (N);
begin begin
pragma Assert (Nkind (N) in N_Subexpr);
if not With_Freezing then
Set_Must_Not_Freeze (N);
end if;
Full_Analysis := False; Full_Analysis := False;
Expander_Mode_Save_And_Set (False); Expander_Mode_Save_And_Set (False);
...@@ -1690,6 +1707,16 @@ package body Sem_Res is ...@@ -1690,6 +1707,16 @@ package body Sem_Res is
Expander_Mode_Restore; Expander_Mode_Restore;
Full_Analysis := Save_Full_Analysis; Full_Analysis := Save_Full_Analysis;
Set_Must_Not_Freeze (N, Save_Must_Not_Freeze);
end Preanalyze_And_Resolve;
----------------------------
-- Preanalyze_And_Resolve --
----------------------------
procedure Preanalyze_And_Resolve (N : Node_Id; T : Entity_Id) is
begin
Preanalyze_And_Resolve (N, T, With_Freezing => False);
end Preanalyze_And_Resolve; end Preanalyze_And_Resolve;
-- Version without context type -- Version without context type
...@@ -1708,6 +1735,16 @@ package body Sem_Res is ...@@ -1708,6 +1735,16 @@ package body Sem_Res is
Full_Analysis := Save_Full_Analysis; Full_Analysis := Save_Full_Analysis;
end Preanalyze_And_Resolve; end Preanalyze_And_Resolve;
------------------------------------------
-- Preanalyze_With_Freezing_And_Resolve --
------------------------------------------
procedure Preanalyze_With_Freezing_And_Resolve (N : Node_Id; T : Entity_Id)
is
begin
Preanalyze_And_Resolve (N, T, With_Freezing => True);
end Preanalyze_With_Freezing_And_Resolve;
---------------------------------- ----------------------------------
-- Replace_Actual_Discriminants -- -- Replace_Actual_Discriminants --
---------------------------------- ----------------------------------
......
...@@ -93,6 +93,9 @@ package Sem_Res is ...@@ -93,6 +93,9 @@ package Sem_Res is
procedure Preanalyze_And_Resolve (N : Node_Id); procedure Preanalyze_And_Resolve (N : Node_Id);
-- Same, but use type of node because context does not impose a single type -- Same, but use type of node because context does not impose a single type
procedure Preanalyze_With_Freezing_And_Resolve (N : Node_Id; T : Entity_Id);
-- Same, but perform freezing of static expressions of N or its children.
procedure Resolve (N : Node_Id; Typ : Entity_Id); procedure Resolve (N : Node_Id; Typ : Entity_Id);
procedure Resolve (N : Node_Id; Typ : Entity_Id; Suppress : Check_Id); procedure Resolve (N : Node_Id; Typ : Entity_Id; Suppress : Check_Id);
-- Top-level type-checking procedure, called in a complete context. The -- Top-level type-checking procedure, called in a complete context. The
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment