diff mbox

[Ada] Use of SPARK_Mode with front end inlining (-gnatN)

Message ID 20141023102010.GA20686@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 23, 2014, 10:20 a.m. UTC
This patch modifies the front end inlining mechanism to ensure that a package
body is always analyzed with the SPARK_Mode of the enclosing context.

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

--  front_end_inlining.adc

pragma SPARK_Mode (On);

--  front_end_inlining.ads

package Front_End_Inlining is
   procedure P;
end Front_End_Inlining;

--  front_end_inlining.adb

with Ada.Text_IO; use Ada.Text_IO;

package body Front_End_Inlining with SPARK_Mode => Off is
   subtype Small_Int is Integer range 0 .. 3;

   procedure P is
      package Small_Int_IO is new Integer_IO (Small_Int);
   begin
      null;
   end P;
end Front_End_Inlining;

-----------------
-- Compilation --
-----------------

$ gcc -c -gnatec=front_end_inlining.adc -gnatN front_end_inlining.adb

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

2014-10-23  Hristian Kirtchev  <kirtchev@adacore.com>

	* sem_ch12.adb (Inline_Instance_Body): Alphabetize
	local variables and constants. Add constants Save_SM and Save_SMP
	to capture SPARK_Mode-related attributes.  Compile the inlined
	body with the SPARK_Mode of the enclosing context.
diff mbox

Patch

Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb	(revision 216583)
+++ sem_ch12.adb	(working copy)
@@ -4425,25 +4425,31 @@ 
       Gen_Unit : Entity_Id;
       Act_Decl : Node_Id)
    is
-      Vis          : Boolean;
-      Gen_Comp     : constant Entity_Id :=
-                      Cunit_Entity (Get_Source_Unit (Gen_Unit));
-      Curr_Comp    : constant Node_Id := Cunit (Current_Sem_Unit);
-      Curr_Scope   : Entity_Id := Empty;
-      Curr_Unit    : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
-      Removed      : Boolean := False;
-      Num_Scopes   : Int := 0;
+      Curr_Comp : constant Node_Id   := Cunit (Current_Sem_Unit);
+      Curr_Unit : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
+      Gen_Comp  : constant Entity_Id :=
+                    Cunit_Entity (Get_Source_Unit (Gen_Unit));
 
+      Save_SM  : constant SPARK_Mode_Type := SPARK_Mode;
+      Save_SMP : constant Node_Id         := SPARK_Mode_Pragma;
+      --  Save all SPARK_Mode-related attributes as removing enclosing scopes
+      --  to provide a clean environment for analysis of the inlined body will
+      --  eliminate any previously set SPARK_Mode.
+
       Scope_Stack_Depth : constant Int :=
                             Scope_Stack.Last - Scope_Stack.First + 1;
 
       Use_Clauses  : array (1 .. Scope_Stack_Depth) of Node_Id;
       Instances    : array (1 .. Scope_Stack_Depth) of Entity_Id;
       Inner_Scopes : array (1 .. Scope_Stack_Depth) of Entity_Id;
+      Curr_Scope   : Entity_Id := Empty;
       List         : Elist_Id;
       Num_Inner    : Int := 0;
+      Num_Scopes   : Int := 0;
       N_Instances  : Int := 0;
+      Removed      : Boolean := False;
       S            : Entity_Id;
+      Vis          : Boolean;
 
    begin
       --  Case of generic unit defined in another unit. We must remove the
@@ -4574,6 +4580,10 @@ 
 
          pragma Assert (Num_Inner < Num_Scopes);
 
+         --  The inlined package body must be analyzed with the SPARK_Mode of
+         --  the enclosing context, otherwise the body may cause bogus errors
+         --  if a configuration SPARK_Mode pragma in in effect.
+
          Push_Scope (Standard_Standard);
          Scope_Stack.Table (Scope_Stack.Last).Is_Active_Stack_Base := True;
          Instantiate_Package_Body
@@ -4587,8 +4597,8 @@ 
                Version                  => Ada_Version,
                Version_Pragma           => Ada_Version_Pragma,
                Warnings                 => Save_Warnings,
-               SPARK_Mode               => SPARK_Mode,
-               SPARK_Mode_Pragma        => SPARK_Mode_Pragma)),
+               SPARK_Mode               => Save_SM,
+               SPARK_Mode_Pragma        => Save_SMP)),
             Inlined_Body => True);
 
          Pop_Scope;
@@ -4692,7 +4702,9 @@ 
             end loop;
          end;
 
-      --  If generic unit is in current unit, current context is correct
+      --  If generic unit is in current unit, current context is correct. Note
+      --  that the context is guaranteed to carry the correct SPARK_Mode as no
+      --  enclosing scopes were removed.
 
       else
          Instantiate_Package_Body