Commit 78d432da by Hristian Kirtchev Committed by Arnaud Charlet

einfo.adb (Get_Pragma): Handle the retrieval of delayed pragmas stored in N_Contract nodes.

2013-07-08  Hristian Kirtchev  <kirtchev@adacore.com>

	* einfo.adb (Get_Pragma): Handle the retrieval of delayed
	pragmas stored in N_Contract nodes.
	* einfo.ads (Get_Pragma): Update the comment on usage.
	* sem_prag.adb (Check_Precondition_Postcondition): Retain a copy
	of the pragma when it applies to a body that acts as a spec. The
	copy is preanalyzed and chained on the contract of the body.

From-SVN: r200774
parent 5884c232
2013-07-08 Hristian Kirtchev <kirtchev@adacore.com>
* einfo.adb (Get_Pragma): Handle the retrieval of delayed
pragmas stored in N_Contract nodes.
* einfo.ads (Get_Pragma): Update the comment on usage.
* sem_prag.adb (Check_Precondition_Postcondition): Retain a copy
of the pragma when it applies to a body that acts as a spec. The
copy is preanalyzed and chained on the contract of the body.
2013-07-08 Robert Dewar <dewar@adacore.com> 2013-07-08 Robert Dewar <dewar@adacore.com>
* rtsfind.adb: Minor comment fix. * rtsfind.adb: Minor comment fix.
......
...@@ -6280,19 +6280,58 @@ package body Einfo is ...@@ -6280,19 +6280,58 @@ package body Einfo is
-- Get_Pragma -- -- Get_Pragma --
---------------- ----------------
function Get_Pragma (E : Entity_Id; Id : Pragma_Id) return Node_Id function Get_Pragma (E : Entity_Id; Id : Pragma_Id) return Node_Id is
is Is_CDG : constant Boolean :=
N : Node_Id; Id = Pragma_Depends or else Id = Pragma_Global;
Is_CTC : constant Boolean :=
Id = Pragma_Contract_Cases or else Id = Pragma_Test_Case;
Is_PPC : constant Boolean :=
Id = Pragma_Precondition or else Id = Pragma_Postcondition;
Delayed : constant Boolean := Is_CDG or else Is_CTC or else Is_PPC;
Item : Node_Id;
Items : Node_Id;
begin begin
N := First_Rep_Item (E); -- Handle delayed pragmas that appear in N_Contract nodes. Those have to
while Present (N) loop -- be extracted from their specialized list.
if Nkind (N) = N_Pragma
and then Get_Pragma_Id (Pragma_Name (N)) = Id if Delayed then
Items := Contract (E);
if No (Items) then
return Empty;
elsif Is_CDG then
Item := Classifications (Items);
elsif Is_CTC then
Item := Contract_Test_Cases (Items);
else
Item := Pre_Post_Conditions (Items);
end if;
-- Regular pragmas
else
Item := First_Rep_Item (E);
end if;
while Present (Item) loop
if Nkind (Item) = N_Pragma
and then Get_Pragma_Id (Pragma_Name (Item)) = Id
then then
return N; return Item;
-- All nodes in N_Contract are chained using Next_Pragma
elsif Delayed then
Item := Next_Pragma (Item);
-- Regular pragmas
else else
Next_Rep_Item (N); Next_Rep_Item (Item);
end if; end if;
end loop; end loop;
......
...@@ -7375,7 +7375,9 @@ package Einfo is ...@@ -7375,7 +7375,9 @@ package Einfo is
function Get_Pragma (E : Entity_Id; Id : Pragma_Id) return Node_Id; function Get_Pragma (E : Entity_Id; Id : Pragma_Id) return Node_Id;
-- Searches the Rep_Item chain for a given entity E, for an instance of -- Searches the Rep_Item chain for a given entity E, for an instance of
-- a pragma with the given pragma Id. If found, the value returned is the -- a pragma with the given pragma Id. If found, the value returned is the
-- N_Pragma node, otherwise Empty is returned. -- N_Pragma node, otherwise Empty is returned. Delayed pragmas such as
-- Precondition, Postcondition, Contract_Cases, Depends and Global appear
-- in the N_Contract node of entity E and are also handled by this routine.
function Get_Record_Representation_Clause (E : Entity_Id) return Node_Id; function Get_Record_Representation_Clause (E : Entity_Id) return Node_Id;
-- Searches the Rep_Item chain for a given entity E, for a record -- Searches the Rep_Item chain for a given entity E, for a record
......
...@@ -3565,12 +3565,13 @@ package body Sem_Prag is ...@@ -3565,12 +3565,13 @@ package body Sem_Prag is
-- If we fall through loop, pragma is at start of list, so see if it -- If we fall through loop, pragma is at start of list, so see if it
-- is at the start of declarations of a subprogram body. -- is at the start of declarations of a subprogram body.
if Nkind (Parent (N)) = N_Subprogram_Body PO := Parent (N);
and then List_Containing (N) = Declarations (Parent (N))
if Nkind (PO) = N_Subprogram_Body
and then List_Containing (N) = Declarations (PO)
then then
if Operating_Mode /= Generate_Code if Operating_Mode /= Generate_Code or else Inside_A_Generic then
or else Inside_A_Generic
then
-- Analyze pragma expression for correctness and for ASIS use -- Analyze pragma expression for correctness and for ASIS use
Preanalyze_Assert_Expression Preanalyze_Assert_Expression
...@@ -3585,22 +3586,56 @@ package body Sem_Prag is ...@@ -3585,22 +3586,56 @@ package body Sem_Prag is
end if; end if;
end if; end if;
-- Retain a copy of the pre- or postcondition pragma for formal
-- verification purposes. The copy is needed because the pragma is
-- expanded into other constructs which are not acceptable in the
-- N_Contract node.
if Acts_As_Spec (PO)
and then (SPARK_Mode or else Formal_Extensions)
then
declare
Prag : constant Node_Id := New_Copy_Tree (N);
begin
-- Preanalyze the pragma
Preanalyze_Assert_Expression
(Get_Pragma_Arg
(First (Pragma_Argument_Associations (Prag))),
Standard_Boolean);
-- Preanalyze the corresponding aspect (if any)
if Present (Corresponding_Aspect (Prag)) then
Preanalyze_Assert_Expression
(Expression (Corresponding_Aspect (Prag)),
Standard_Boolean);
end if;
-- Chain the copy on the contract of the body
Add_Contract_Item
(Prag, Defining_Unit_Name (Specification (PO)));
end;
end if;
In_Body := True; In_Body := True;
return; return;
-- See if it is in the pragmas after a library level subprogram -- See if it is in the pragmas after a library level subprogram
elsif Nkind (Parent (N)) = N_Compilation_Unit_Aux then elsif Nkind (PO) = N_Compilation_Unit_Aux then
-- In formal verification mode, analyze pragma expression for -- In formal verification mode, analyze pragma expression for
-- correctness, as it is not expanded later. -- correctness, as it is not expanded later.
if SPARK_Mode then if SPARK_Mode then
Analyze_PPC_In_Decl_Part Analyze_PPC_In_Decl_Part
(N, Defining_Entity (Unit (Parent (Parent (N))))); (N, Defining_Entity (Unit (Parent (PO))));
end if; end if;
Chain_PPC (Unit (Parent (Parent (N)))); Chain_PPC (Unit (Parent (PO)));
return; return;
end if; end if;
......
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