===================================================================
@@ -346,29 +346,20 @@
Push_Scope (Spec_Id);
- -- Set SPARK_Mode from private part of spec if it has a SPARK pragma.
- -- Note that in the default case, SPARK_Aux_Pragma will be a copy of
- -- SPARK_Pragma in the spec, so this properly handles the case where
- -- there is no explicit SPARK_Pragma mode in the private part.
+ -- Set SPARK_Mode only for non-generic package
- if Present (SPARK_Pragma (Spec_Id)) then
- SPARK_Mode_Pragma := SPARK_Aux_Pragma (Spec_Id);
- SPARK_Mode := Get_SPARK_Mode_From_Pragma (SPARK_Mode_Pragma);
+ if Ekind (Spec_Id) = E_Package then
+ -- Set SPARK_Mode from context
+
Set_SPARK_Pragma (Body_Id, SPARK_Mode_Pragma);
Set_SPARK_Pragma_Inherited (Body_Id, True);
- -- Otherwise set from context
+ -- Set elaboration code SPARK mode the same for now
- else
- Set_SPARK_Pragma (Body_Id, SPARK_Mode_Pragma);
- Set_SPARK_Pragma_Inherited (Body_Id, True);
+ Set_SPARK_Aux_Pragma (Body_Id, SPARK_Pragma (Body_Id));
+ Set_SPARK_Aux_Pragma_Inherited (Body_Id, True);
end if;
- -- Set elaboration code SPARK mode the same for now
-
- Set_SPARK_Aux_Pragma (Body_Id, SPARK_Pragma (Body_Id));
- Set_SPARK_Aux_Pragma_Inherited (Body_Id, True);
-
Set_Categorization_From_Pragmas (N);
Install_Visible_Declarations (Spec_Id);
@@ -400,6 +391,32 @@
Inspect_Deferred_Constant_Completion (Declarations (N));
end if;
+ -- After declarations have been analyzed, the body has been set
+ -- its final value of SPARK_Mode. Check that SPARK_Mode for body
+ -- is consistent with SPARK_Mode for spec.
+
+ if Present (SPARK_Pragma (Body_Id)) then
+ if Present (SPARK_Aux_Pragma (Spec_Id)) then
+ if Get_SPARK_Mode_From_Pragma (SPARK_Aux_Pragma (Spec_Id)) = Off
+ and then
+ Get_SPARK_Mode_From_Pragma (SPARK_Pragma (Body_Id)) = On
+ then
+ Error_Msg_Sloc := Sloc (SPARK_Pragma (Body_Id));
+ Error_Msg_N ("incorrect application of SPARK_Mode#", N);
+ Error_Msg_Sloc := Sloc (SPARK_Aux_Pragma (Spec_Id));
+ Error_Msg_NE ("\value Off was set for SPARK_Mode on & #",
+ N, Spec_Id);
+ end if;
+
+ else
+ Error_Msg_Sloc := Sloc (SPARK_Pragma (Body_Id));
+ Error_Msg_N ("incorrect application of SPARK_Mode#", N);
+ Error_Msg_Sloc := Sloc (Spec_Id);
+ Error_Msg_NE ("\no value was set for SPARK_Mode on & #",
+ N, Spec_Id);
+ end if;
+ end if;
+
-- Analyze_Declarations has caused freezing of all types. Now generate
-- bodies for RACW primitives and stream attributes, if any.
@@ -814,12 +831,14 @@
Set_Etype (Id, Standard_Void_Type);
Set_Contract (Id, Make_Contract (Sloc (Id)));
- -- Inherit spark mode from context for now
+ -- Set SPARK_Mode from context only for non-generic package
- Set_SPARK_Pragma (Id, SPARK_Mode_Pragma);
- Set_SPARK_Aux_Pragma (Id, SPARK_Mode_Pragma);
- Set_SPARK_Pragma_Inherited (Id, True);
- Set_SPARK_Aux_Pragma_Inherited (Id, True);
+ if Ekind (Id) = E_Package then
+ Set_SPARK_Pragma (Id, SPARK_Mode_Pragma);
+ Set_SPARK_Aux_Pragma (Id, SPARK_Mode_Pragma);
+ Set_SPARK_Pragma_Inherited (Id, True);
+ Set_SPARK_Aux_Pragma_Inherited (Id, True);
+ end if;
-- Analyze aspect specifications immediately, since we need to recognize
-- things like Pure early enough to diagnose violations during analysis.
===================================================================
@@ -18597,14 +18597,26 @@
Spec_Id : Entity_Id;
Stmt : Node_Id;
- procedure Check_Pragma_Conformance (Old_Pragma : Node_Id);
- -- Verify the monotonicity of SPARK modes between the new pragma
- -- N, and the old pragma, Old_Pragma, that was inherited. If
- -- Old_Pragma is Empty, the call has no effect, otherwise we
- -- verify that the new mode is less restrictive than the old mode.
- -- For example, if the old mode is ON, then the new mode can be
- -- anything. But if the old mode is OFF, then the only allowed
- -- new mode is also OFF.
+ procedure Check_Pragma_Conformance
+ (Context_Pragma : Node_Id;
+ Entity_Pragma : Node_Id;
+ Entity : Entity_Id);
+ -- If Context_Pragma is not Empty, verify that the new pragma N
+ -- is compatible with the pragma Context_Pragma that was inherited
+ -- from the context:
+ -- . if Context_Pragma is ON, then the new mode can be anything
+ -- . if Context_Pragma is OFF, then the only allowed new mode is
+ -- also OFF.
+ --
+ -- If Entity is not Empty, verify that the new pragma N is
+ -- compatible with Entity_Pragma, the SPARK_Mode previously set
+ -- for Entity (which may be Empty):
+ -- . if Entity_Pragma is ON, then the new mode can be anything
+ -- . if Entity_Pragma is OFF, then the only allowed new mode is
+ -- also OFF.
+ -- . if Entity_Pragma is Empty, we always issue an error, as this
+ -- corresponds to a case where a previous section of Entity
+ -- had no SPARK_Mode set.
procedure Check_Library_Level_Entity (E : Entity_Id);
-- Verify that pragma is applied to library-level entity E
@@ -18613,23 +18625,47 @@
-- Check_Pragma_Conformance --
------------------------------
- procedure Check_Pragma_Conformance (Old_Pragma : Node_Id) is
+ procedure Check_Pragma_Conformance
+ (Context_Pragma : Node_Id;
+ Entity_Pragma : Node_Id;
+ Entity : Entity_Id) is
begin
- if Present (Old_Pragma) then
- pragma Assert (Nkind (Old_Pragma) = N_Pragma);
+ if Present (Context_Pragma) then
+ pragma Assert (Nkind (Context_Pragma) = N_Pragma);
-- New mode less restrictive than the established mode
- if Get_SPARK_Mode_From_Pragma (Old_Pragma) = Off
+ if Get_SPARK_Mode_From_Pragma (Context_Pragma) = Off
and then Mode_Id = On
then
Error_Msg_N
- ("cannot change 'S'P'A'R'K_Mode from Off to On", Arg1);
+ ("cannot change SPARK_Mode from Off to On", Arg1);
Error_Msg_Sloc := Sloc (SPARK_Mode_Pragma);
- Error_Msg_N ("\'S'P'A'R'K_Mode was set to Off#", Arg1);
+ Error_Msg_N ("\SPARK_Mode was set to Off#", Arg1);
raise Pragma_Exit;
end if;
end if;
+
+ if Present (Entity) then
+ if Present (Entity_Pragma) then
+ if Get_SPARK_Mode_From_Pragma (Entity_Pragma) = Off
+ and then Mode_Id = On
+ then
+ Error_Msg_N ("incorrect use of SPARK_Mode", Arg1);
+ Error_Msg_Sloc := Sloc (Entity_Pragma);
+ Error_Msg_NE
+ ("\value Off was set for SPARK_Mode on & #",
+ Arg1, Entity);
+ raise Pragma_Exit;
+ end if;
+ else
+ Error_Msg_N ("incorrect use of SPARK_Mode", Arg1);
+ Error_Msg_Sloc := Sloc (Entity);
+ Error_Msg_NE ("\no value was set for SPARK_Mode on & #",
+ Arg1, Entity);
+ raise Pragma_Exit;
+ end if;
+ end if;
end Check_Pragma_Conformance;
--------------------------------
@@ -18733,7 +18769,10 @@
then
Spec_Id := Defining_Entity (Stmt);
Check_Library_Level_Entity (Spec_Id);
- Check_Pragma_Conformance (SPARK_Pragma (Spec_Id));
+ Check_Pragma_Conformance
+ (Context_Pragma => SPARK_Pragma (Spec_Id),
+ Entity_Pragma => Empty,
+ Entity => Empty);
Set_SPARK_Pragma (Spec_Id, N);
Set_SPARK_Pragma_Inherited (Spec_Id, False);
@@ -18748,7 +18787,10 @@
then
Spec_Id := Defining_Entity (Stmt);
Check_Library_Level_Entity (Spec_Id);
- Check_Pragma_Conformance (SPARK_Pragma (Spec_Id));
+ Check_Pragma_Conformance
+ (Context_Pragma => SPARK_Pragma (Spec_Id),
+ Entity_Pragma => Empty,
+ Entity => Empty);
Set_SPARK_Pragma (Spec_Id, N);
Set_SPARK_Pragma_Inherited (Spec_Id, False);
@@ -18804,7 +18846,10 @@
if List_Containing (N) = Private_Declarations (Context) then
Check_Library_Level_Entity (Spec_Id);
- Check_Pragma_Conformance (SPARK_Aux_Pragma (Spec_Id));
+ Check_Pragma_Conformance
+ (Context_Pragma => Empty,
+ Entity_Pragma => SPARK_Pragma (Spec_Id),
+ Entity => Spec_Id);
SPARK_Mode_Pragma := N;
SPARK_Mode := Mode_Id;
@@ -18815,7 +18860,10 @@
else
Check_Library_Level_Entity (Spec_Id);
- Check_Pragma_Conformance (SPARK_Pragma (Spec_Id));
+ Check_Pragma_Conformance
+ (Context_Pragma => SPARK_Pragma (Spec_Id),
+ Entity_Pragma => Empty,
+ Entity => Empty);
SPARK_Mode_Pragma := N;
SPARK_Mode := Mode_Id;
@@ -18834,8 +18882,10 @@
then
Spec_Id := Defining_Entity (Context);
Check_Library_Level_Entity (Spec_Id);
- Check_Pragma_Conformance (SPARK_Pragma (Spec_Id));
-
+ Check_Pragma_Conformance
+ (Context_Pragma => SPARK_Pragma (Spec_Id),
+ Entity_Pragma => Empty,
+ Entity => Empty);
Set_SPARK_Pragma (Spec_Id, N);
Set_SPARK_Pragma_Inherited (Spec_Id, False);
@@ -18848,7 +18898,10 @@
Spec_Id := Corresponding_Spec (Context);
Body_Id := Defining_Entity (Context);
Check_Library_Level_Entity (Body_Id);
- Check_Pragma_Conformance (SPARK_Pragma (Body_Id));
+ Check_Pragma_Conformance
+ (Context_Pragma => SPARK_Pragma (Body_Id),
+ Entity_Pragma => SPARK_Aux_Pragma (Spec_Id),
+ Entity => Spec_Id);
SPARK_Mode_Pragma := N;
SPARK_Mode := Mode_Id;
@@ -18867,7 +18920,19 @@
Context := Specification (Context);
Body_Id := Defining_Entity (Context);
Check_Library_Level_Entity (Body_Id);
- Check_Pragma_Conformance (SPARK_Pragma (Body_Id));
+
+ if Present (Spec_Id) then
+ Check_Pragma_Conformance
+ (Context_Pragma => SPARK_Pragma (Body_Id),
+ Entity_Pragma => SPARK_Pragma (Spec_Id),
+ Entity => Spec_Id);
+ else
+ Check_Pragma_Conformance
+ (Context_Pragma => SPARK_Pragma (Body_Id),
+ Entity_Pragma => Empty,
+ Entity => Empty);
+ end if;
+
SPARK_Mode_Pragma := N;
SPARK_Mode := Mode_Id;
@@ -18887,7 +18952,10 @@
Spec_Id := Corresponding_Spec (Context);
Body_Id := Defining_Entity (Context);
Check_Library_Level_Entity (Body_Id);
- Check_Pragma_Conformance (SPARK_Aux_Pragma (Body_Id));
+ Check_Pragma_Conformance
+ (Context_Pragma => Empty,
+ Entity_Pragma => SPARK_Pragma (Body_Id),
+ Entity => Body_Id);
SPARK_Mode_Pragma := N;
SPARK_Mode := Mode_Id;
===================================================================
@@ -2999,35 +2999,11 @@
Push_Scope (Spec_Id);
- -- Set SPARK_Mode
+ -- Set SPARK_Mode from context
- -- For internally generated subprogram, always off. But generic
- -- instances are not generated implicitly, so are never considered
- -- as internal, even though Comes_From_Source is false.
+ Set_SPARK_Pragma (Body_Id, SPARK_Mode_Pragma);
+ Set_SPARK_Pragma_Inherited (Body_Id, True);
- if not Comes_From_Source (Spec_Id)
- and then not Is_Generic_Instance (Spec_Id)
- then
- SPARK_Mode := Off;
- SPARK_Mode_Pragma := Empty;
-
- -- Inherited from spec
-
- elsif Present (SPARK_Pragma (Spec_Id))
- and then not SPARK_Pragma_Inherited (Spec_Id)
- then
- SPARK_Mode_Pragma := SPARK_Pragma (Spec_Id);
- SPARK_Mode := Get_SPARK_Mode_From_Pragma (SPARK_Mode_Pragma);
- Set_SPARK_Pragma (Body_Id, SPARK_Pragma (Spec_Id));
- Set_SPARK_Pragma_Inherited (Body_Id, True);
-
- -- Otherwise set from context
-
- else
- Set_SPARK_Pragma (Body_Id, SPARK_Mode_Pragma);
- Set_SPARK_Pragma_Inherited (Body_Id, True);
- end if;
-
-- Make sure that the subprogram is immediately visible. For
-- child units that have no separate spec this is indispensable.
-- Otherwise it is safe albeit redundant.
@@ -3076,17 +3052,10 @@
Push_Scope (Body_Id);
- -- Set SPARK_Mode from context or OFF for internal routine
+ -- Set SPARK_Mode from context
- if Comes_From_Source (Body_Id) then
- Set_SPARK_Pragma (Body_Id, SPARK_Mode_Pragma);
- Set_SPARK_Pragma_Inherited (Body_Id, True);
- else
- Set_SPARK_Pragma (Body_Id, Empty);
- Set_SPARK_Pragma_Inherited (Body_Id, False);
- SPARK_Mode := Off;
- SPARK_Mode_Pragma := Empty;
- end if;
+ Set_SPARK_Pragma (Body_Id, SPARK_Mode_Pragma);
+ Set_SPARK_Pragma_Inherited (Body_Id, True);
end if;
-- For stubs and bodies with no previous spec, generate references to
@@ -3277,6 +3246,35 @@
Analyze_Declarations (Declarations (N));
+ -- After declarations have been analyzed, the body has been set
+ -- its final value of SPARK_Mode. Check that SPARK_Mode for body
+ -- is consistent with SPARK_Mode for spec.
+
+ if Present (Spec_Id) and then Present (SPARK_Pragma (Body_Id)) then
+ if Present (SPARK_Pragma (Spec_Id)) then
+ if Get_SPARK_Mode_From_Pragma (SPARK_Pragma (Spec_Id)) = Off
+ and then
+ Get_SPARK_Mode_From_Pragma (SPARK_Pragma (Body_Id)) = On
+ then
+ Error_Msg_Sloc := Sloc (SPARK_Pragma (Body_Id));
+ Error_Msg_N ("incorrect application of SPARK_Mode#", N);
+ Error_Msg_Sloc := Sloc (SPARK_Pragma (Spec_Id));
+ Error_Msg_NE
+ ("\value Off was set for SPARK_Mode on & #", N, Spec_Id);
+ end if;
+
+ elsif Nkind (Parent (Parent (Spec_Id))) = N_Subprogram_Body_Stub then
+ null;
+
+ else
+ Error_Msg_Sloc := Sloc (SPARK_Pragma (Body_Id));
+ Error_Msg_N ("incorrect application of SPARK_Mode#", N);
+ Error_Msg_Sloc := Sloc (Spec_Id);
+ Error_Msg_NE
+ ("\no value was set for SPARK_Mode on & #", N, Spec_Id);
+ end if;
+ end if;
+
-- Check completion, and analyze the statements
Check_Completion;
@@ -3632,16 +3630,11 @@
Generate_Definition (Designator);
- -- Set SPARK mode, always off for internal routines, otherwise set
- -- from current context (may be overwritten later with explicit pragma)
+ -- Set SPARK mode from current context (may be overwritten later with
+ -- explicit pragma).
- if Comes_From_Source (Designator) then
- Set_SPARK_Pragma (Designator, SPARK_Mode_Pragma);
- Set_SPARK_Pragma_Inherited (Designator, True);
- else
- Set_SPARK_Pragma (Designator, Empty);
- Set_SPARK_Pragma_Inherited (Designator, False);
- end if;
+ Set_SPARK_Pragma (Designator, SPARK_Mode_Pragma);
+ Set_SPARK_Pragma_Inherited (Designator, True);
if Debug_Flag_C then
Write_Str ("==> subprogram spec ");