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
......
...@@ -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);
...@@ -19818,11 +19822,14 @@ package body Sem_Ch3 is ...@@ -19818,11 +19822,14 @@ 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;
In_Default_Expr := Save_In_Default_Expr; Preanalyze_With_Freezing_And_Resolve (N, T);
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
Save_Full_Analysis : constant Boolean := Full_Analysis; (N : Node_Id;
T : Entity_Id;
With_Freezing : Boolean)
is
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