diff mbox

[Ada] Pragma Volatile_Function has no effect on subprogram body

Message ID 20151026111751.GA118581@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 26, 2015, 11:17 a.m. UTC
This patch modifies the analysis of pragmas that appear on package specs and
and subprogram bodies. The new model of analysis allows for pragmas to appear
out of order, but they are still analyzed according to internal precedence. The
patch removes the restrictions concerning the declarations order of pragmas
Abstract_State, Initial_Condition and Initializes.

------------
-- Source --
------------

--  vol_funcs.ads

package Vol_Funcs with SPARK_Mode is
   type Int is new Natural range 0 .. 5 with Volatile;

   type Rec is record
      Comp : Natural := 0;
   end record with Volatile;

   Int_Obj : Int with Volatile;
   Rec_Obj : Rec with Volatile;

   --  Completion by subprogram body

   function Func_1_Int (Val : Int) return Boolean
     with Volatile_Function;

   function Func_1_Rec (Val : Rec) return Boolean
     with Volatile_Function;

   --  Completion by expression function

   function Func_2_Int (Val : Int) return Boolean
     with Volatile_Function;

   function Func_2_Rec (Val : Rec) return Boolean
     with Volatile_Function;

   --  Stand alone expression function (no completion required)

   function Func_3_Int (Val : Int) return Boolean is (True)
     with Volatile_Function;

   function Func_3_Rec (Val : Rec) return Boolean is (True)
     with Volatile_Function;
end Vol_Funcs;

--  vol_funcs.adb

package body Vol_Funcs with SPARK_Mode is

   --  Completion by subprogram body

   function Func_1_Int (Val : Int) return Boolean is
   begin return True; end Func_1_Int;

   function Func_1_Rec (Val : Rec) return Boolean is
   begin return True; end Func_1_Rec;

   --  Completion by expression function

   function Func_2_Int (Val : Int) return Boolean is
   begin return True; end Func_2_Int;

   function Func_2_Rec (Val : Rec) return Boolean is
   begin return True; end Func_2_Rec;

   --  Stand alone subprogram body (no initial declaration)

   function Func_4_Int (Val : Int) return Boolean
     with Volatile_Function
   is begin return True; end Func_4_Int;

   function Func_4_Rec (Val : Rec) return Boolean
     with Volatile_Function
   is begin return True; end Func_4_Rec;

   Status : Boolean;

begin
   Status := Func_1_Int (Int_Obj);                                   --  Error
   Status := Func_1_Rec (Rec_Obj);                                   --  OK
   Status := Func_2_Int (Int_Obj);                                   --  Error
   Status := Func_2_Rec (Rec_Obj);                                   --  OK
   Status := Func_3_Int (Int_Obj);                                   --  Error
   Status := Func_3_Rec (Rec_Obj);                                   --  OK
   Status := Func_4_Int (Int_Obj);                                   --  Error
   Status := Func_4_Rec (Rec_Obj);                                   --  OK
end Vol_Funcs;

----------------------------
-- Compilation and output --
----------------------------

$ gcc -c vol_funcs.adb
vol_funcs.adb:32:26: volatile object cannot act as actual in a call (SPARK RM
  7.1.3(12))
vol_funcs.adb:34:26: volatile object cannot act as actual in a call (SPARK RM
  7.1.3(12))
vol_funcs.adb:36:26: volatile object cannot act as actual in a call (SPARK RM
  7.1.3(12))
vol_funcs.adb:38:26: volatile object cannot act as actual in a call (SPARK RM
  7.1.3(12))

Tested on x86_64-pc-linux-gnu, committed on trunk

2015-10-26  Hristian Kirtchev  <kirtchev@adacore.com>

	* sem_ch13.adb (Analyze_Aspect_Specifications): The processing
	for aspects Abstract_State, Ghost, Initial_Condition, Initializes
	and Refined_State no longer have to take SPARK_Mode into account.
	(Insert_After_SPARK_Mode): Removed.
	(Insert_Pragma): Update profile and comment on usage. The routine can
	now insert a pragma after the "header" of an instance.
	* sem_prag.adb (Analyze_If_Available): New routine.
	(Analyze_Pragma): Do not reset the Analyzed flag of various
	SPARK pragmas as they use the Is_Analyzed_Pragma attribute to
	avoid reanalysis. Various pragmas now trigger the analysis
	of related pragmas that depend on or are dependent on the
	current pragma. Remove the declaration order checks related
	to pragmas Abstract_State, Initial_Condition and Initializes.
	(Analyze_Pre_Post_Condition): Analyze pragmas SPARK_Mode and
	Volatile_Function prior to analyzing the pre/postcondition.
	(Check_Declaration_Order): Removed.
	(Check_Distinct_Name): Ensure that a potentially duplicated pragma
	Test_Case is not the pragma being analyzed.
	(Is_Followed_By_Pragma): Removed.
diff mbox

Patch

Index: sem_prag.adb
===================================================================
--- sem_prag.adb	(revision 229330)
+++ sem_prag.adb	(working copy)
@@ -2760,6 +2760,10 @@ 
       --  is the entity of the related subprogram. Subp_Decl is the declaration
       --  of the related subprogram. Sets flag Legal when the pragma is legal.
 
+      procedure Analyze_If_Present (Id : Pragma_Id);
+      --  Inspect the remainder of the list containing pragma N and look for
+      --  a pragma that matches Id. If found, analyze the pragma.
+
       procedure Analyze_Part_Of
         (Item_Id : Entity_Id;
          State   : Node_Id;
@@ -2888,11 +2892,6 @@ 
       --  UU_Typ is the related Unchecked_Union type. Flag In_Variant_Part
       --  should be set when Comp comes from a record variant.
 
-      procedure Check_Declaration_Order (First : Node_Id; Second : Node_Id);
-      --  Subsidiary routine to the analysis of pragmas Abstract_State,
-      --  Initial_Condition and Initializes. Determine whether pragma First
-      --  appears before pragma Second. If this is not the case, emit an error.
-
       procedure Check_Duplicate_Pragma (E : Entity_Id);
       --  Check if a rep item of the same name as the current pragma is already
       --  chained as a rep pragma to the given entity. If so give a message
@@ -3125,10 +3124,6 @@ 
       --  Determines if the placement of the current pragma is appropriate
       --  for a configuration pragma.
 
-      function Is_Followed_By_Pragma (Prag_Nam : Name_Id) return Boolean;
-      --  Determine whether pragma N is followed by another pragma denoted by
-      --  its name Prag_Nam. It is assumed that N is a list member.
-
       function Is_In_Context_Clause return Boolean;
       --  Returns True if pragma appears within the context clause of a unit,
       --  and False for any other placement (does not generate any messages).
@@ -3349,11 +3344,6 @@ 
          Subp_Decl := Empty;
          Legal     := False;
 
-         --  Reset the Analyzed flag because the pragma requires further
-         --  analysis.
-
-         Set_Analyzed (N, False);
-
          GNAT_Pragma;
          Check_Arg_Count (1);
 
@@ -3404,6 +3394,37 @@ 
          Ensure_Aggregate_Form (Get_Argument (N, Spec_Id));
       end Analyze_Depends_Global;
 
+      ------------------------
+      -- Analyze_If_Present --
+      ------------------------
+
+      procedure Analyze_If_Present (Id : Pragma_Id) is
+         Stmt : Node_Id;
+
+      begin
+         pragma Assert (Is_List_Member (N));
+
+         --  Inspect the declarations or statements following pragma N looking
+         --  for another pragma whose Id matches the caller's request. If it is
+         --  available, analyze it.
+
+         Stmt := Next (N);
+         while Present (Stmt) loop
+            if Nkind (Stmt) = N_Pragma and then Get_Pragma_Id (Stmt) = Id then
+               Analyze_Pragma (Stmt);
+               exit;
+
+            --  The first source declaration or statement immediately following
+            --  N ends the region where a pragma may appear.
+
+            elsif Comes_From_Source (Stmt) then
+               exit;
+            end if;
+
+            Next (Stmt);
+         end loop;
+      end Analyze_If_Present;
+
       ---------------------
       -- Analyze_Part_Of --
       ---------------------
@@ -3603,11 +3624,6 @@ 
          --  Post_Class.
 
       begin
-         --  Reset the Analyzed flag because the pragma requires further
-         --  analysis.
-
-         Set_Analyzed (N, False);
-
          --  Change the name of pragmas Pre, Pre_Class, Post and Post_Class to
          --  offer uniformity among the various kinds of pre/postconditions by
          --  rewriting the pragma identifier. This allows the retrieval of the
@@ -3733,6 +3749,11 @@ 
 
          Subp_Id := Defining_Entity (Subp_Decl);
 
+         --  Chain the pragma on the contract for further processing by
+         --  Analyze_Pre_Post_Condition_In_Decl_Part.
+
+         Add_Contract_Item (N, Defining_Entity (Subp_Decl));
+
          --  A pragma that applies to a Ghost entity becomes Ghost for the
          --  purposes of legality checks and removal of ignored Ghost code.
 
@@ -3744,13 +3765,14 @@ 
          if Nkind_In (Subp_Decl, N_Subprogram_Body,
                                  N_Subprogram_Body_Stub)
          then
+            --  The legality checks of pragmas Precondition and Postcondition
+            --  are affected by the SPARK mode in effect and the volatility of
+            --  the context. Analyze all pragmas in a specific order.
+
+            Analyze_If_Present (Pragma_SPARK_Mode);
+            Analyze_If_Present (Pragma_Volatile_Function);
             Analyze_Pre_Post_Condition_In_Decl_Part (N);
          end if;
-
-         --  Chain the pragma on the contract for further processing by
-         --  Analyze_Pre_Post_Condition_In_Decl_Part.
-
-         Add_Contract_Item (N, Defining_Entity (Subp_Decl));
       end Analyze_Pre_Post_Condition;
 
       -----------------------------------------
@@ -3772,11 +3794,6 @@ 
          Body_Id := Empty;
          Legal   := False;
 
-         --  Reset the Analyzed flag because the pragma requires further
-         --  analysis.
-
-         Set_Analyzed (N, False);
-
          GNAT_Pragma;
          Check_Arg_Count (1);
          Check_No_Identifiers;
@@ -4331,107 +4348,6 @@ 
          end if;
       end Check_Component;
 
-      -----------------------------
-      -- Check_Declaration_Order --
-      -----------------------------
-
-      procedure Check_Declaration_Order (First : Node_Id; Second : Node_Id) is
-         procedure Check_Aspect_Specification_Order;
-         --  Inspect the aspect specifications of the context to determine the
-         --  proper order.
-
-         --------------------------------------
-         -- Check_Aspect_Specification_Order --
-         --------------------------------------
-
-         procedure Check_Aspect_Specification_Order is
-            Asp_First  : constant Node_Id := Corresponding_Aspect (First);
-            Asp_Second : constant Node_Id := Corresponding_Aspect (Second);
-            Asp        : Node_Id;
-
-         begin
-            --  Both aspects must be part of the same aspect specification list
-
-            pragma Assert
-              (List_Containing (Asp_First) = List_Containing (Asp_Second));
-
-            --  Try to reach Second starting from First in a left to right
-            --  traversal of the aspect specifications.
-
-            Asp := Next (Asp_First);
-            while Present (Asp) loop
-
-               --  The order is ok, First is followed by Second
-
-               if Asp = Asp_Second then
-                  return;
-               end if;
-
-               Next (Asp);
-            end loop;
-
-            --  If we get here, then the aspects are out of order
-
-            SPARK_Msg_N ("aspect % cannot come after aspect %", First);
-         end Check_Aspect_Specification_Order;
-
-         --  Local variables
-
-         Stmt : Node_Id;
-
-      --  Start of processing for Check_Declaration_Order
-
-      begin
-         --  Cannot check the order if one of the pragmas is missing
-
-         if No (First) or else No (Second) then
-            return;
-         end if;
-
-         --  Set up the error names in case the order is incorrect
-
-         Error_Msg_Name_1 := Pragma_Name (First);
-         Error_Msg_Name_2 := Pragma_Name (Second);
-
-         if From_Aspect_Specification (First) then
-
-            --  Both pragmas are actually aspects, check their declaration
-            --  order in the associated aspect specification list. Otherwise
-            --  First is an aspect and Second a source pragma.
-
-            if From_Aspect_Specification (Second) then
-               Check_Aspect_Specification_Order;
-            end if;
-
-         --  Abstract_States is a source pragma
-
-         else
-            if From_Aspect_Specification (Second) then
-               SPARK_Msg_N ("pragma % cannot come after aspect %", First);
-
-            --  Both pragmas are source constructs. Try to reach First from
-            --  Second by traversing the declarations backwards.
-
-            else
-               Stmt := Prev (Second);
-               while Present (Stmt) loop
-
-                  --  The order is ok, First is followed by Second
-
-                  if Stmt = First then
-                     return;
-                  end if;
-
-                  Prev (Stmt);
-               end loop;
-
-               --  If we get here, then the pragmas are out of order
-
-               SPARK_Msg_N ("pragma % cannot come after pragma %", First);
-            end if;
-         end if;
-      end Check_Declaration_Order;
-
       ----------------------------
       -- Check_Duplicate_Pragma --
       ----------------------------
@@ -5890,39 +5806,6 @@ 
          end if;
       end Is_Configuration_Pragma;
 
-      ---------------------------
-      -- Is_Followed_By_Pragma --
-      ---------------------------
-
-      function Is_Followed_By_Pragma (Prag_Nam : Name_Id) return Boolean is
-         Stmt : Node_Id;
-
-      begin
-         pragma Assert (Is_List_Member (N));
-
-         --  Inspect the declarations or statements following pragma N looking
-         --  for another pragma whose name matches the caller's request.
-
-         Stmt := Next (N);
-         while Present (Stmt) loop
-            if Nkind (Stmt) = N_Pragma
-              and then Pragma_Name (Stmt) = Prag_Nam
-            then
-               return True;
-
-            --  The first source declaration or statement immediately following
-            --  N ends the region where a pragma may appear.
-
-            elsif Comes_From_Source (Stmt) then
-               exit;
-            end if;
-
-            Next (Stmt);
-         end loop;
-
-         return False;
-      end Is_Followed_By_Pragma;
-
       --------------------------
       -- Is_In_Context_Clause --
       --------------------------
@@ -10416,6 +10299,22 @@ 
 
             Pack_Id := Defining_Entity (Pack_Decl);
 
+            --  Chain the pragma on the contract for completeness
+
+            Add_Contract_Item (N, Pack_Id);
+
+            --  The legality checks of pragmas Abstract_State, Initializes, and
+            --  Initial_Condition are affected by the SPARK mode in effect. In
+            --  addition, these three pragmas are subject to an inherent order:
+
+            --    1) Abstract_State
+            --    2) Initializes
+            --    3) Initial_Condition
+
+            --  Analyze all these pragmas in the order outlined above
+
+            Analyze_If_Present (Pragma_SPARK_Mode);
+
             --  A pragma that applies to a Ghost entity becomes Ghost for the
             --  purposes of legality checks and removal of ignored Ghost code.
 
@@ -10452,16 +10351,8 @@ 
                Analyze_Abstract_State (States, Pack_Id);
             end if;
 
-            --  Verify the declaration order of pragmas Abstract_State and
-            --  Initializes.
-
-            Check_Declaration_Order
-              (First  => N,
-               Second => Get_Pragma (Pack_Id, Pragma_Initializes));
-
-            --  Chain the pragma on the contract for completeness
-
-            Add_Contract_Item (N, Pack_Id);
+            Analyze_If_Present (Pragma_Initializes);
+            Analyze_If_Present (Pragma_Initial_Condition);
          end Abstract_State;
 
          ------------
@@ -11001,7 +10892,7 @@ 
          --  POLICY_IDENTIFIER ::= Check | Disable | Ignore
 
          --  Note: Check and Ignore are language-defined. Disable is a GNAT
-         --  implementation defined addition that results in totally ignoring
+         --  implementation-defined addition that results in totally ignoring
          --  the corresponding assertion. If Disable is specified, then the
          --  argument of the assertion is not even analyzed. This is useful
          --  when the aspect/pragma argument references entities in a with'ed
@@ -11213,11 +11104,6 @@ 
             Obj_Id   : Entity_Id;
 
          begin
-            --  Reset the Analyzed flag because the pragma requires further
-            --  analysis.
-
-            Set_Analyzed (N, False);
-
             GNAT_Pragma;
             Check_No_Identifiers;
             Check_At_Most_N_Arguments  (1);
@@ -11244,6 +11130,11 @@ 
 
             if Ekind (Obj_Id) = E_Variable then
 
+               --  Chain the pragma on the contract for further processing by
+               --  Analyze_External_Property_In_Decl_Part.
+
+               Add_Contract_Item (N, Obj_Id);
+
                --  A pragma that applies to a Ghost entity becomes Ghost for
                --  the purposes of legality checks and removal of ignored Ghost
                --  code.
@@ -11256,11 +11147,6 @@ 
                   Check_Static_Boolean_Expression (Get_Pragma_Arg (Arg1));
                end if;
 
-               --  Chain the pragma on the contract for further processing by
-               --  Analyze_External_Property_In_Decl_Part.
-
-               Add_Contract_Item (N, Obj_Id);
-
             --  Otherwise the external property applies to a constant
 
             else
@@ -12290,11 +12176,6 @@ 
 
             Obj_Id := Defining_Entity (Obj_Decl);
 
-            --  A pragma that applies to a Ghost entity becomes Ghost for the
-            --  purposes of legality checks and removal of ignored Ghost code.
-
-            Mark_Pragma_As_Ghost (N, Obj_Id);
-
             --  The object declaration must be a library-level variable with
             --  an initialization expression. The expression must depend on
             --  a variable, parameter, or another constant_after_elaboration,
@@ -12320,15 +12201,20 @@ 
                return;
             end if;
 
+            --  Chain the pragma on the contract for completeness
+
+            Add_Contract_Item (N, Obj_Id);
+
+            --  A pragma that applies to a Ghost entity becomes Ghost for the
+            --  purposes of legality checks and removal of ignored Ghost code.
+
+            Mark_Pragma_As_Ghost (N, Obj_Id);
+
             --  Analyze the Boolean expression (if any)
 
             if Present (Arg1) then
                Check_Static_Boolean_Expression (Get_Pragma_Arg (Arg1));
             end if;
-
-            --  Chain the pragma on the contract for completeness
-
-            Add_Contract_Item (N, Obj_Id);
          end Constant_After_Elaboration;
 
          --------------------
@@ -12384,11 +12270,6 @@ 
             Check_No_Identifiers;
             Check_Arg_Count (1);
 
-            --  The pragma is analyzed at the end of the declarative part which
-            --  contains the related subprogram. Reset the analyzed flag.
-
-            Set_Analyzed (N, False);
-
             --  Ensure the proper placement of the pragma. Contract_Cases must
             --  be associated with a subprogram declaration or a body that acts
             --  as a spec.
@@ -12427,6 +12308,11 @@ 
 
             Spec_Id := Unique_Defining_Entity (Subp_Decl);
 
+            --  Chain the pragma on the contract for further processing by
+            --  Analyze_Contract_Cases_In_Decl_Part.
+
+            Add_Contract_Item (N, Defining_Entity (Subp_Decl));
+
             --  A pragma that applies to a Ghost entity becomes Ghost for the
             --  purposes of legality checks and removal of ignored Ghost code.
 
@@ -12439,13 +12325,14 @@ 
             if Nkind_In (Subp_Decl, N_Subprogram_Body,
                                     N_Subprogram_Body_Stub)
             then
+               --  The legality checks of pragma Contract_Cases are affected by
+               --  the SPARK mode in effect and the volatility of the context.
+               --  Analyze all pragmas in a specific order.
+
+               Analyze_If_Present (Pragma_SPARK_Mode);
+               Analyze_If_Present (Pragma_Volatile_Function);
                Analyze_Contract_Cases_In_Decl_Part (N);
             end if;
-
-            --  Chain the pragma on the contract for further processing by
-            --  Analyze_Contract_Cases_In_Decl_Part.
-
-            Add_Contract_Item (N, Defining_Entity (Subp_Decl));
          end Contract_Cases;
 
          ----------------
@@ -13145,7 +13032,6 @@ 
          --    the annotation must instantiate itself.
 
          when Pragma_Depends => Depends : declare
-            Global    : Node_Id;
             Legal     : Boolean;
             Spec_Id   : Entity_Id;
             Subp_Decl : Node_Id;
@@ -13166,34 +13052,20 @@ 
                if Nkind_In (Subp_Decl, N_Subprogram_Body,
                                        N_Subprogram_Body_Stub)
                then
-                  --  Pragmas Global and Depends must be analyzed in a specific
-                  --  order, as the latter depends on the former. When the two
-                  --  pragmas appear out of order, their analyis is triggered
-                  --  by pragma Global.
+                  --  The legality checks of pragmas Depends and Global are
+                  --  affected by the SPARK mode in effect and the volatility
+                  --  of the context. In addition these two pragmas are subject
+                  --  to an inherent order:
 
-                  --    pragma Depends ...;
-                  --    pragma Global  ...;  <analyze both pragmas here>
+                  --    1) Global
+                  --    2) Depends
 
-                  --  Wait until pragma Global is encountered
+                  --  Analyze all these pragmas in the order outlined above
 
-                  if Is_Followed_By_Pragma (Name_Global) then
-                     null;
-
-                  --  Otherwise pragma Depends is the last of the pair. Analyze
-                  --  both pragmas when they appear in order.
-
-                  --    pragma Global  ...;
-                  --    pragma Depends ...;  <analyze both pragmas here>
-
-                  else
-                     Global := Get_Pragma (Spec_Id, Pragma_Global);
-
-                     if Present (Global) then
-                        Analyze_Global_In_Decl_Part (Global);
-                     end if;
-
-                     Analyze_Depends_In_Decl_Part (N);
-                  end if;
+                  Analyze_If_Present (Pragma_SPARK_Mode);
+                  Analyze_If_Present (Pragma_Volatile_Function);
+                  Analyze_If_Present (Pragma_Global);
+                  Analyze_Depends_In_Decl_Part (N);
                end if;
             end if;
          end Depends;
@@ -14154,12 +14026,21 @@ 
                return;
             end if;
 
-            Spec_Id := Unique_Defining_Entity (Subp_Decl);
+            --  Chain the pragma on the contract for completeness
 
+            Add_Contract_Item (N, Defining_Entity (Subp_Decl));
+
+            --  The legality checks of pragma Extension_Visible are affected
+            --  by the SPARK mode in effect. Analyze all pragmas in specific
+            --  order.
+
+            Analyze_If_Present (Pragma_SPARK_Mode);
+
             --  Mark the pragma as Ghost if the related subprogram is also
             --  Ghost. This also ensures that any expansion performed further
             --  below will produce Ghost nodes.
 
+            Spec_Id := Unique_Defining_Entity (Subp_Decl);
             Mark_Pragma_As_Ghost (N, Spec_Id);
 
             --  Examine the formals of the related subprogram
@@ -14205,10 +14086,6 @@ 
                Check_Static_Boolean_Expression
                  (Expression (Get_Argument (N, Spec_Id)));
             end if;
-
-            --  Chain the pragma on the contract for completeness
-
-            Add_Contract_Item (N, Defining_Entity (Subp_Decl));
          end Extensions_Visible;
 
          --------------
@@ -14673,7 +14550,6 @@ 
          --    the annotation must instantiate itself.
 
          when Pragma_Global => Global : declare
-            Depends   : Node_Id;
             Legal     : Boolean;
             Spec_Id   : Entity_Id;
             Subp_Decl : Node_Id;
@@ -14694,34 +14570,20 @@ 
                if Nkind_In (Subp_Decl, N_Subprogram_Body,
                                        N_Subprogram_Body_Stub)
                then
-                  --  Pragmas Global and Depends must be analyzed in a specific
-                  --  order, as the latter depends on the former. When the two
-                  --  pragmas appear in order, their analysis is triggered by
-                  --  pragma Depends.
+                  --  The legality checks of pragmas Depends and Global are
+                  --  affected by the SPARK mode in effect and the volatility
+                  --  of the context. In addition these two pragmas are subject
+                  --  to an inherent order:
 
-                  --    pragma Global  ...;
-                  --    pragma Depends ...;  <analyze both pragmas here>
+                  --    1) Global
+                  --    2) Depends
 
-                  --  Wait until pragma Global is encountered
+                  --  Analyze all these pragmas in the order outlined above
 
-                  if Is_Followed_By_Pragma (Name_Depends) then
-                     null;
-
-                  --  Otherwise pragma Global is the last of the pair. Analyze
-                  --  both pragmas when they are out of order.
-
-                  --    pragma Depends ...;
-                  --    pragma Global  ...;  <analyze both pragmas here>
-
-                  else
-                     Analyze_Global_In_Decl_Part (N);
-
-                     Depends := Get_Pragma (Spec_Id, Pragma_Depends);
-
-                     if Present (Depends) then
-                        Analyze_Depends_In_Decl_Part (Depends);
-                     end if;
-                  end if;
+                  Analyze_If_Present (Pragma_SPARK_Mode);
+                  Analyze_If_Present (Pragma_Volatile_Function);
+                  Analyze_Global_In_Decl_Part (N);
+                  Analyze_If_Present (Pragma_Depends);
                end if;
             end if;
          end Global;
@@ -15315,11 +15177,6 @@ 
             Pack_Id   : Entity_Id;
 
          begin
-            --  Reset the Analyzed flag because the pragma requires further
-            --  analysis.
-
-            Set_Analyzed (N, False);
-
             GNAT_Pragma;
             Check_No_Identifiers;
             Check_Arg_Count (1);
@@ -15341,36 +15198,31 @@ 
                return;
             end if;
 
-            --  The pragma must be analyzed at the end of the visible
-            --  declarations of the related package. Save the pragma for later
-            --  (see Analyze_Initial_Condition_In_Decl_Part) by adding it to
-            --  the contract of the package.
-
             Pack_Id := Defining_Entity (Pack_Decl);
 
-            --  A pragma that applies to a Ghost entity becomes Ghost for the
-            --  purposes of legality checks and removal of ignored Ghost code.
+            --  Chain the pragma on the contract for further processing by
+            --  Analyze_Initial_Condition_In_Decl_Part.
 
-            Mark_Pragma_As_Ghost (N, Pack_Id);
+            Add_Contract_Item (N, Pack_Id);
 
-            --  Verify the declaration order of pragma Initial_Condition with
-            --  respect to pragmas Abstract_State and Initializes when SPARK
-            --  checks are enabled.
+            --  The legality checks of pragmas Abstract_State, Initializes, and
+            --  Initial_Condition are affected by the SPARK mode in effect. In
+            --  addition, these three pragmas are subject to an inherent order:
 
-            if SPARK_Mode /= Off then
-               Check_Declaration_Order
-                 (First  => Get_Pragma (Pack_Id, Pragma_Abstract_State),
-                  Second => N);
+            --    1) Abstract_State
+            --    2) Initializes
+            --    3) Initial_Condition
 
-               Check_Declaration_Order
-                 (First  => Get_Pragma (Pack_Id, Pragma_Initializes),
-                  Second => N);
-            end if;
+            --  Analyze all these pragmas in the order outlined above
 
-            --  Chain the pragma on the contract for further processing by
-            --  Analyze_Initial_Condition_In_Decl_Part.
+            Analyze_If_Present (Pragma_SPARK_Mode);
+            Analyze_If_Present (Pragma_Abstract_State);
+            Analyze_If_Present (Pragma_Initializes);
 
-            Add_Contract_Item (N, Pack_Id);
+            --  A pragma that applies to a Ghost entity becomes Ghost for the
+            --  purposes of legality checks and removal of ignored Ghost code.
+
+            Mark_Pragma_As_Ghost (N, Pack_Id);
          end Initial_Condition;
 
          ------------------------
@@ -15441,11 +15293,6 @@ 
             Pack_Id   : Entity_Id;
 
          begin
-            --  Reset the Analyzed flag because the pragma requires further
-            --  analysis.
-
-            Set_Analyzed (N, False);
-
             GNAT_Pragma;
             Check_No_Identifiers;
             Check_Arg_Count (1);
@@ -15469,25 +15316,31 @@ 
 
             Pack_Id := Defining_Entity (Pack_Decl);
 
+            --  Chain the pragma on the contract for further processing by
+            --  Analyze_Initializes_In_Decl_Part.
+
+            Add_Contract_Item (N, Pack_Id);
+
+            --  The legality checks of pragmas Abstract_State, Initializes, and
+            --  Initial_Condition are affected by the SPARK mode in effect. In
+            --  addition, these three pragmas are subject to an inherent order:
+
+            --    1) Abstract_State
+            --    2) Initializes
+            --    3) Initial_Condition
+
+            --  Analyze all these pragmas in the order outlined above
+
+            Analyze_If_Present (Pragma_SPARK_Mode);
+            Analyze_If_Present (Pragma_Abstract_State);
+
             --  A pragma that applies to a Ghost entity becomes Ghost for the
             --  purposes of legality checks and removal of ignored Ghost code.
 
             Mark_Pragma_As_Ghost (N, Pack_Id);
             Ensure_Aggregate_Form (Get_Argument (N, Pack_Id));
 
-            --  Verify the declaration order of pragmas Abstract_State and
-            --  Initializes when SPARK checks are enabled.
-
-            if SPARK_Mode /= Off then
-               Check_Declaration_Order
-                 (First  => Get_Pragma (Pack_Id, Pragma_Abstract_State),
-                  Second => N);
-            end if;
-
-            --  Chain the pragma on the contract for further processing by
-            --  Analyze_Initializes_In_Decl_Part.
-
-            Add_Contract_Item (N, Pack_Id);
+            Analyze_If_Present (Pragma_Initial_Condition);
          end Initializes;
 
          ------------
@@ -17760,11 +17613,17 @@ 
                Legal   => Legal);
 
             if Legal then
-               State_Id := Entity (State);
 
+               --  Add the pragma to the contract of the item. This aids with
+               --  the detection of a missing but required Part_Of indicator.
+
+               Add_Contract_Item (N, Item_Id);
+
                --  The Part_Of indicator turns an object into a constituent of
                --  the encapsulating state.
 
+               State_Id := Entity (State);
+
                if Ekind_In (Item_Id, E_Constant, E_Variable) then
                   Append_Elmt (Item_Id, Part_Of_Constituents (State_Id));
                   Set_Encapsulating_State (Item_Id, State_Id);
@@ -17778,11 +17637,6 @@ 
                      State_Id => State_Id,
                      Instance => Stmt);
                end if;
-
-               --  Add the pragma to the contract of the item. This aids with
-               --  the detection of a missing but required Part_Of indicator.
-
-               Add_Contract_Item (N, Item_Id);
             end if;
          end Part_Of;
 
@@ -18974,10 +18828,9 @@ 
          --    the related generic subprogram body is instantiated.
 
          when Pragma_Refined_Depends => Refined_Depends : declare
-            Body_Id    : Entity_Id;
-            Legal      : Boolean;
-            Ref_Global : Node_Id;
-            Spec_Id    : Entity_Id;
+            Body_Id : Entity_Id;
+            Legal   : Boolean;
+            Spec_Id : Entity_Id;
 
          begin
             Analyze_Refined_Depends_Global_Post (Spec_Id, Body_Id, Legal);
@@ -18989,34 +18842,20 @@ 
 
                Add_Contract_Item (N, Body_Id);
 
-               --  Pragmas Refined_Global and Refined_Depends must be analyzed
-               --  in a specific order, as the latter depends on the former.
-               --  When the two pragmas appear out of order, their analysis is
-               --  triggered by pragma Refined_Global.
+               --  The legality checks of pragmas Refined_Depends and
+               --  Refined_Global are affected by the SPARK mode in effect and
+               --  the volatility of the context. In addition these two pragmas
+               --  are subject to an inherent order:
 
-               --    pragma Refined_Depends ...;
-               --    pragma Refined_Global  ...;  <analyze both pragmas here>
+               --    1) Refined_Global
+               --    2) Refined_Depends
 
-               --  Wait until pragma Refined_Global is enountered
+               --  Analyze all these pragmas in the order outlined above
 
-               if Is_Followed_By_Pragma (Name_Refined_Global) then
-                  null;
-
-               --  Otherwise pragma Refined_Depends is the last of the pair.
-               --  Analyze both pragmas when they appear in order.
-
-               --    pragma Refined_Global  ...;
-               --    pragma Refined_Depends ...;  <analyze both pragmas here>
-
-               else
-                  Ref_Global := Get_Pragma (Body_Id, Pragma_Refined_Global);
-
-                  if Present (Ref_Global) then
-                     Analyze_Refined_Global_In_Decl_Part (Ref_Global);
-                  end if;
-
-                  Analyze_Refined_Depends_In_Decl_Part (N);
-               end if;
+               Analyze_If_Present (Pragma_SPARK_Mode);
+               Analyze_If_Present (Pragma_Volatile_Function);
+               Analyze_If_Present (Pragma_Refined_Global);
+               Analyze_Refined_Depends_In_Decl_Part (N);
             end if;
          end Refined_Depends;
 
@@ -19057,10 +18896,9 @@ 
          --    the related generic subprogram body is instantiated.
 
          when Pragma_Refined_Global => Refined_Global : declare
-            Body_Id     : Entity_Id;
-            Legal       : Boolean;
-            Ref_Depends : Node_Id;
-            Spec_Id     : Entity_Id;
+            Body_Id : Entity_Id;
+            Legal   : Boolean;
+            Spec_Id : Entity_Id;
 
          begin
             Analyze_Refined_Depends_Global_Post (Spec_Id, Body_Id, Legal);
@@ -19072,34 +18910,20 @@ 
 
                Add_Contract_Item (N, Body_Id);
 
-               --  Pragmas Refined_Global and Refined_Depends must be analyzed
-               --  in a specific order, as the latter depends on the former.
-               --  When the two pragmas are in order, their analysis must be
-               --  triggered by pragma Refined_Depends.
+               --  The legality checks of pragmas Refined_Depends and
+               --  Refined_Global are affected by the SPARK mode in effect and
+               --  the volatility of the context. In addition these two pragmas
+               --  are subject to an inherent order:
 
-               --    pragma Refined_Global  ...;
-               --    pragma Refined_Depends ...;  <analyze both pragmas here>
+               --    1) Refined_Global
+               --    2) Refined_Depends
 
-               --  Wait until pragma Refined_Depends is encountered
+               --  Analyze all these pragmas in the order outlined above
 
-               if Is_Followed_By_Pragma (Name_Refined_Depends) then
-                  null;
-
-               --  Otherwise pragma Refined_Global is the last of the pair.
-               --  Analyze both pragmas when they are out of order.
-
-               --    pragma Refined_Depends ...;
-               --    pragma Refined_Global  ...;  <analyze both pragmas here>
-
-               else
-                  Analyze_Refined_Global_In_Decl_Part (N);
-
-                  Ref_Depends := Get_Pragma (Body_Id, Pragma_Refined_Depends);
-
-                  if Present (Ref_Depends) then
-                     Analyze_Refined_Depends_In_Decl_Part (Ref_Depends);
-                  end if;
-               end if;
+               Analyze_If_Present (Pragma_SPARK_Mode);
+               Analyze_If_Present (Pragma_Volatile_Function);
+               Analyze_Refined_Global_In_Decl_Part (N);
+               Analyze_If_Present (Pragma_Refined_Depends);
             end if;
          end Refined_Global;
 
@@ -19140,16 +18964,23 @@ 
             --  body because it cannot benefit from forward references.
 
             if Legal then
+
+               --  Chain the pragma on the contract for completeness
+
+               Add_Contract_Item (N, Body_Id);
+
+               --  The legality checks of pragma Refined_Post are affected by
+               --  the SPARK mode in effect and the volatility of the context.
+               --  Analyze all pragmas in a specific order.
+
+               Analyze_If_Present (Pragma_SPARK_Mode);
+               Analyze_If_Present (Pragma_Volatile_Function);
                Analyze_Pre_Post_Condition_In_Decl_Part (N);
 
                --  Currently it is not possible to inline pre/postconditions on
                --  a subprogram subject to pragma Inline_Always.
 
                Check_Postcondition_Use_In_Inlined_Subprogram (N, Spec_Id);
-
-               --  Chain the pragma on the contract for completeness
-
-               Add_Contract_Item (N, Body_Id);
             end if;
          end Refined_Post;
 
@@ -19196,11 +19027,6 @@ 
             Spec_Id   : Entity_Id;
 
          begin
-            --  Reset the Analyzed flag because the pragma requires further
-            --  analysis.
-
-            Set_Analyzed (N, False);
-
             GNAT_Pragma;
             Check_No_Identifiers;
             Check_Arg_Count (1);
@@ -19222,6 +19048,16 @@ 
 
             Spec_Id := Corresponding_Spec (Pack_Decl);
 
+            --  Chain the pragma on the contract for further processing by
+            --  Analyze_Refined_State_In_Decl_Part.
+
+            Add_Contract_Item (N, Defining_Entity (Pack_Decl));
+
+            --  The legality checks of pragma Refined_State are affected by the
+            --  SPARK mode in effect. Analyze all pragmas in a specific order.
+
+            Analyze_If_Present (Pragma_SPARK_Mode);
+
             --  A pragma that applies to a Ghost entity becomes Ghost for the
             --  purposes of legality checks and removal of ignored Ghost code.
 
@@ -19241,11 +19077,6 @@ 
                   & "states", N, Spec_Id);
                return;
             end if;
-
-            --  Chain the pragma on the contract for further processing by
-            --  Analyze_Refined_State_In_Decl_Part.
-
-            Add_Contract_Item (N, Defining_Entity (Pack_Decl));
          end Refined_State;
 
          -----------------------
@@ -21092,6 +20923,7 @@ 
                   Prag := Contract_Test_Cases (Items);
                   while Present (Prag) loop
                      if Pragma_Name (Prag) = Name_Test_Case
+                       and then Prag /= N
                        and then String_Equal
                                   (Name, Get_Name_From_CTC_Pragma (Prag))
                      then
@@ -21115,11 +20947,6 @@ 
          --  Start of processing for Test_Case
 
          begin
-            --  Reset the Analyzed flag because the pragma requires further
-            --  analysis.
-
-            Set_Analyzed (N, False);
-
             GNAT_Pragma;
             Check_At_Least_N_Arguments (2);
             Check_At_Most_N_Arguments (4);
@@ -21194,7 +21021,7 @@ 
               and then Nkind_In (Context, N_Generic_Package_Declaration,
                                           N_Package_Declaration)
             then
-               Subp_Id := Defining_Entity (Subp_Decl);
+               null;
 
             --  Otherwise the placement is illegal
 
@@ -21203,6 +21030,13 @@ 
                return;
             end if;
 
+            Subp_Id := Defining_Entity (Subp_Decl);
+
+            --  Chain the pragma on the contract for further processing by
+            --  Analyze_Test_Case_In_Decl_Part.
+
+            Add_Contract_Item (N, Subp_Id);
+
             --  A pragma that applies to a Ghost entity becomes Ghost for the
             --  purposes of legality checks and removal of ignored Ghost code.
 
@@ -21239,13 +21073,14 @@ 
             if Nkind_In (Subp_Decl, N_Subprogram_Body,
                                     N_Subprogram_Body_Stub)
             then
+               --  The legality checks of pragma Test_Case are affected by the
+               --  SPARK mode in effect and the volatility of the context.
+               --  Analyze all pragmas in a specific order.
+
+               Analyze_If_Present (Pragma_SPARK_Mode);
+               Analyze_If_Present (Pragma_Volatile_Function);
                Analyze_Test_Case_In_Decl_Part (N);
             end if;
-
-            --  Chain the pragma on the contract for further processing by
-            --  Analyze_Test_Case_In_Decl_Part.
-
-            Add_Contract_Item (N, Subp_Id);
          end Test_Case;
 
          --------------------------
@@ -22113,6 +21948,16 @@ 
                return;
             end if;
 
+            --  Chain the pragma on the contract for completeness
+
+            Add_Contract_Item (N, Spec_Id);
+
+            --  The legality checks of pragma Volatile_Function are affected by
+            --  the SPARK mode in effect. Analyze all pragmas in a specific
+            --  order.
+
+            Analyze_If_Present (Pragma_SPARK_Mode);
+
             --  A pragma that applies to a Ghost entity becomes Ghost for the
             --  purposes of legality checks and removal of ignored Ghost code.
 
@@ -22147,8 +21992,6 @@ 
             if Present (Arg1) then
                Check_Static_Boolean_Expression (Get_Pragma_Arg (Arg1));
             end if;
-
-            Add_Contract_Item (N, Spec_Id);
          end Volatile_Function;
 
          ----------------------
@@ -25221,11 +25064,18 @@ 
          if Is_Entity_Name (State) then
             State_Id := Entity_Of (State);
 
+            --  When the abstract state is undefined, it appears as Any_Id. Do
+            --  not continue with the analysis of the clause.
+
+            if State_Id = Any_Id then
+               return;
+
             --  Catch any attempts to re-refine a state or refine a state that
             --  is not defined in the package declaration.
 
-            if Ekind (State_Id) = E_Abstract_State then
+            elsif Ekind (State_Id) = E_Abstract_State then
                Check_Matching_State;
+
             else
                SPARK_Msg_NE
                  ("& must denote an abstract state", State, State_Id);
Index: sem_ch13.adb
===================================================================
--- sem_ch13.adb	(revision 229328)
+++ sem_ch13.adb	(working copy)
@@ -1208,39 +1208,28 @@ 
       procedure Decorate (Asp : Node_Id; Prag : Node_Id);
       --  Establish linkages between an aspect and its corresponding pragma
 
-      procedure Insert_After_SPARK_Mode
-        (Prag    : Node_Id;
-         Ins_Nod : Node_Id;
-         Decls   : List_Id);
+      procedure Insert_Pragma
+        (Prag        : Node_Id;
+         Is_Instance : Boolean := False);
       --  Subsidiary to the analysis of aspects
       --    Abstract_State
-      --    Ghost
-      --    Initializes
-      --    Initial_Condition
-      --    Refined_State
-      --  Insert node Prag before node Ins_Nod. If Ins_Nod is for pragma
-      --  SPARK_Mode, then skip SPARK_Mode. Decls is the associated declarative
-      --  list where Prag is to reside.
-
-      procedure Insert_Pragma (Prag : Node_Id);
-      --  Subsidiary to the analysis of aspects
       --    Attach_Handler
       --    Contract_Cases
       --    Depends
+      --    Ghost
       --    Global
+      --    Initial_Condition
+      --    Initializes
       --    Post
       --    Pre
       --    Refined_Depends
       --    Refined_Global
+      --    Refined_State
       --    SPARK_Mode
       --    Warnings
       --  Insert pragma Prag such that it mimics the placement of a source
-      --  pragma of the same kind.
-      --
-      --    procedure Proc (Formal : ...) with Global => ...;
-      --
-      --    procedure Proc (Formal : ...);
-      --    pragma Global (...);
+      --  pragma of the same kind. Flag Is_Generic should be set when the
+      --  context denotes a generic instance.
 
       --------------
       -- Decorate --
@@ -1254,42 +1243,14 @@ 
          Set_Parent                    (Prag, Asp);
       end Decorate;
 
-      -----------------------------
-      -- Insert_After_SPARK_Mode --
-      -----------------------------
-
-      procedure Insert_After_SPARK_Mode
-        (Prag    : Node_Id;
-         Ins_Nod : Node_Id;
-         Decls   : List_Id)
-      is
-         Decl : Node_Id := Ins_Nod;
-
-      begin
-         --  Skip SPARK_Mode
-
-         if Present (Decl)
-           and then Nkind (Decl) = N_Pragma
-           and then Pragma_Name (Decl) = Name_SPARK_Mode
-         then
-            Decl := Next (Decl);
-         end if;
-
-         if Present (Decl) then
-            Insert_Before (Decl, Prag);
-
-         --  Aitem acts as the last declaration
-
-         else
-            Append_To (Decls, Prag);
-         end if;
-      end Insert_After_SPARK_Mode;
-
       -------------------
       -- Insert_Pragma --
       -------------------
 
-      procedure Insert_Pragma (Prag : Node_Id) is
+      procedure Insert_Pragma
+        (Prag        : Node_Id;
+         Is_Instance : Boolean := False)
+      is
          Aux   : Node_Id;
          Decl  : Node_Id;
          Decls : List_Id;
@@ -1365,8 +1326,40 @@ 
                Set_Visible_Declarations (Specification (N), Decls);
             end if;
 
-            Prepend_To (Decls, Prag);
+            --  The visible declarations of a generic instance have the
+            --  following structure:
 
+            --    <renamings of generic formals>
+            --    <renamings of internally-generated spec and body>
+            --    <first source declaration>
+
+            --  Insert the pragma before the first source declaration by
+            --  skipping the instance "header".
+
+            if Is_Instance then
+               Decl := First (Decls);
+               while Present (Decl) and then not Comes_From_Source (Decl) loop
+                  Decl := Next (Decl);
+               end loop;
+
+               --  The instance "header" is followed by at least one source
+               --  declaration.
+
+               if Present (Decl) then
+                  Insert_Before (Decl, Prag);
+
+               --  Otherwise the pragma is placed after the instance "header"
+
+               else
+                  Append_To (Decls, Prag);
+               end if;
+
+            --  Otherwise this is not a generic instance
+
+            else
+               Prepend_To (Decls, Prag);
+            end if;
+
          --  When the aspect is associated with a protected unit declaration,
          --  insert the generated pragma at the top of the visible declarations
          --  the emulate the behavior of a source pragma.
@@ -2298,8 +2291,6 @@ 
 
                when Aspect_Abstract_State => Abstract_State : declare
                   Context : Node_Id := N;
-                  Decl    : Node_Id;
-                  Decls   : List_Id;
 
                begin
                   --  When aspect Abstract_State appears on a generic package,
@@ -2318,55 +2309,13 @@ 
                           Make_Pragma_Argument_Association (Loc,
                             Expression => Relocate_Node (Expr))),
                         Pragma_Name                  => Name_Abstract_State);
+
                      Decorate (Aspect, Aitem);
+                     Insert_Pragma
+                       (Prag        => Aitem,
+                        Is_Instance =>
+                          Is_Generic_Instance (Defining_Entity (Context)));
 
-                     Decls := Visible_Declarations (Specification (Context));
-
-                     --  In general pragma Abstract_State must be at the top
-                     --  of the existing visible declarations to emulate its
-                     --  source counterpart. The only exception to this is a
-                     --  generic instance in which case the pragma must be
-                     --  inserted after the association renamings.
-
-                     if Present (Decls) then
-                        Decl := First (Decls);
-
-                        --  The visible declarations of a generic instance have
-                        --  the following structure:
-
-                        --    <renamings of generic formals>
-                        --    <renamings of internally-generated spec and body>
-                        --    <first source declaration>
-
-                        --  The pragma must be inserted before the first source
-                        --  declaration, skip the instance "header".
-
-                        if Is_Generic_Instance (Defining_Entity (Context)) then
-                           while Present (Decl)
-                             and then not Comes_From_Source (Decl)
-                           loop
-                              Decl := Next (Decl);
-                           end loop;
-                        end if;
-
-                        --  When aspects Abstract_State, Ghost,
-                        --  Initial_Condition and Initializes are out of order,
-                        --  ensure that pragma SPARK_Mode is always at the top
-                        --  of the declarations to properly enabled/suppress
-                        --  errors.
-
-                        Insert_After_SPARK_Mode
-                          (Prag    => Aitem,
-                           Ins_Nod => Decl,
-                           Decls   => Decls);
-
-                     --  Otherwise the pragma forms a new declarative list
-
-                     else
-                        Set_Visible_Declarations
-                          (Specification (Context), New_List (Aitem));
-                     end if;
-
                   else
                      Error_Msg_NE
                        ("aspect & must apply to a package declaration",
@@ -2526,10 +2475,7 @@ 
                --  declarations or after an object, a [generic] subprogram, or
                --  a type declaration.
 
-               when Aspect_Ghost => Ghost : declare
-                  Decls : List_Id;
-
-               begin
+               when Aspect_Ghost =>
                   Make_Aitem_Pragma
                     (Pragma_Argument_Associations => New_List (
                        Make_Pragma_Argument_Association (Loc,
@@ -2537,40 +2483,8 @@ 
                      Pragma_Name                  => Name_Ghost);
 
                   Decorate (Aspect, Aitem);
-
-                  --  When the aspect applies to a [generic] package, insert
-                  --  the pragma at the top of the visible declarations. This
-                  --  emulates the placement of a source pragma.
-
-                  if Nkind_In (N, N_Generic_Package_Declaration,
-                                  N_Package_Declaration)
-                  then
-                     Decls := Visible_Declarations (Specification (N));
-
-                     if No (Decls) then
-                        Decls := New_List;
-                        Set_Visible_Declarations (N, Decls);
-                     end if;
-
-                     --  When aspects Abstract_State, Ghost, Initial_Condition
-                     --  and Initializes are out of order, ensure that pragma
-                     --  SPARK_Mode is always at the top of the declarations to
-                     --  properly enabled/suppress errors.
-
-                     Insert_After_SPARK_Mode
-                       (Prag    => Aitem,
-                        Ins_Nod => First (Decls),
-                        Decls   => Decls);
-
-                  --  Otherwise the context is an object, [generic] subprogram
-                  --  or type declaration.
-
-                  else
-                     Insert_Pragma (Aitem);
-                  end if;
-
+                  Insert_Pragma (Aitem);
                   goto Continue;
-               end Ghost;
 
                --  Global
 
@@ -2604,7 +2518,6 @@ 
 
                when Aspect_Initial_Condition => Initial_Condition : declare
                   Context : Node_Id := N;
-                  Decls   : List_Id;
 
                begin
                   --  When aspect Initial_Condition appears on a generic
@@ -2618,31 +2531,21 @@ 
                   if Nkind_In (Context, N_Generic_Package_Declaration,
                                         N_Package_Declaration)
                   then
-                     Decls := Visible_Declarations (Specification (Context));
-
                      Make_Aitem_Pragma
                        (Pragma_Argument_Associations => New_List (
                           Make_Pragma_Argument_Association (Loc,
                             Expression => Relocate_Node (Expr))),
                         Pragma_Name                  =>
                           Name_Initial_Condition);
+
                      Decorate (Aspect, Aitem);
+                     Insert_Pragma
+                       (Prag        => Aitem,
+                        Is_Instance =>
+                          Is_Generic_Instance (Defining_Entity (Context)));
 
-                     if No (Decls) then
-                        Decls := New_List;
-                        Set_Visible_Declarations (Context, Decls);
-                     end if;
+                  --  Otherwise the context is illegal
 
-                     --  When aspects Abstract_State, Ghost, Initial_Condition
-                     --  and Initializes are out of order, ensure that pragma
-                     --  SPARK_Mode is always at the top of the declarations to
-                     --  properly enabled/suppress errors.
-
-                     Insert_After_SPARK_Mode
-                       (Prag    => Aitem,
-                        Ins_Nod => First (Decls),
-                        Decls   => Decls);
-
                   else
                      Error_Msg_NE
                        ("aspect & must apply to a package declaration",
@@ -2663,7 +2566,6 @@ 
 
                when Aspect_Initializes => Initializes : declare
                   Context : Node_Id := N;
-                  Decls   : List_Id;
 
                begin
                   --  When aspect Initializes appears on a generic package,
@@ -2677,30 +2579,20 @@ 
                   if Nkind_In (Context, N_Generic_Package_Declaration,
                                         N_Package_Declaration)
                   then
-                     Decls := Visible_Declarations (Specification (Context));
-
                      Make_Aitem_Pragma
                        (Pragma_Argument_Associations => New_List (
                           Make_Pragma_Argument_Association (Loc,
                             Expression => Relocate_Node (Expr))),
                         Pragma_Name                  => Name_Initializes);
+
                      Decorate (Aspect, Aitem);
+                     Insert_Pragma
+                       (Prag        => Aitem,
+                        Is_Instance =>
+                          Is_Generic_Instance (Defining_Entity (Context)));
 
-                     if No (Decls) then
-                        Decls := New_List;
-                        Set_Visible_Declarations (Context, Decls);
-                     end if;
+                  --  Otherwise the context is illegal
 
-                     --  When aspects Abstract_State, Ghost, Initial_Condition
-                     --  and Initializes are out of order, ensure that pragma
-                     --  SPARK_Mode is always at the top of the declarations to
-                     --  properly enabled/suppress errors.
-
-                     Insert_After_SPARK_Mode
-                       (Prag    => Aitem,
-                        Ins_Nod => First (Decls),
-                        Decls   => Decls);
-
                   else
                      Error_Msg_NE
                        ("aspect & must apply to a package declaration",
@@ -2813,47 +2705,31 @@ 
 
                --  Refined_State
 
-               when Aspect_Refined_State => Refined_State : declare
-                  Decls : List_Id;
+               when Aspect_Refined_State =>
 
-               begin
                   --  The corresponding pragma for Refined_State is inserted in
                   --  the declarations of the related package body. This action
                   --  synchronizes both the source and from-aspect versions of
                   --  the pragma.
 
                   if Nkind (N) = N_Package_Body then
-                     Decls := Declarations (N);
-
                      Make_Aitem_Pragma
                        (Pragma_Argument_Associations => New_List (
                           Make_Pragma_Argument_Association (Loc,
                             Expression => Relocate_Node (Expr))),
                         Pragma_Name                  => Name_Refined_State);
+
                      Decorate (Aspect, Aitem);
+                     Insert_Pragma (Aitem);
 
-                     if No (Decls) then
-                        Decls := New_List;
-                        Set_Declarations (N, Decls);
-                     end if;
+                  --  Otherwise the context is illegal
 
-                     --  Pragma Refined_State must be inserted after pragma
-                     --  SPARK_Mode in the tree. This ensures that any error
-                     --  messages dependent on SPARK_Mode will be properly
-                     --  enabled/suppressed.
-
-                     Insert_After_SPARK_Mode
-                       (Prag    => Aitem,
-                        Ins_Nod => First (Decls),
-                        Decls   => Decls);
-
                   else
                      Error_Msg_NE
                        ("aspect & must apply to a package body", Aspect, Id);
                   end if;
 
                   goto Continue;
-               end Refined_State;
 
                --  Relative_Deadline