This patch implements the following set of rules related to shared variables:

   1. A volatile representation aspect may only be applied to an
      object_declaration or a full_type_declaration.
   2. A component of a non-volatile type declaration shall not be volatile.
   3. A discriminant shall not be volatile.
   4. Neither a discriminated type nor an object of such a type shall be
      volatile.
   5. Neither a tagged type nor an object of such a type shall be volatile.
   6. A volatile variable shall only be declared at library-level.

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

--  shared_vars.ads

package Shared_Vars with SPARK_Mode => On is
   type T is new Integer with Volatile; -- OK
   type Colour is (Red, Green, Blue) with Volatile; -- OK
   S : Integer with Volatile; -- OK

   type R is record
      F1 : Integer;
      F2 : Integer with Volatile; -- illegal, SPARK RM C.6(1)
      F3 : Boolean;
   end record;

   type R2 is record
      F1 : Integer;
      F2 : T; -- illegal, SPARK RM C.6(2)
   end record;

   type R3 (D : Colour) is record -- illegal, SPARK RM C.6(3)
      Intensity : Natural;
   end record;

   type R4 (D : Boolean) is record
      F1 : Integer;
   end record with Volatile; -- illegal, SPARK RM C.6(4)

   type R5 (D : Boolean := False) is record
      F1 : Integer;
   end record;

   SV : R5 with Volatile; -- illegal, SPARK RM C.6(4)

   type R6 is tagged record
      F1 : Integer;
   end record with Volatile; -- illegal, SPARK RM C.6(5)

   type R7 is tagged record
      F1 : Integer;
   end record; 

   SV2 : R7 with Volatile; -- illegal, SPARK RM C.6(5)
end Shared_Vars;

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

$ gcc -c shared_vars.ads
hared_vars.ads:8:25: entity for aspect "Volatile" must denote a full type or
  object declaration
shared_vars.ads:14:07: component "F2" of non-volatile type "R2" cannot be
  volatile
shared_vars.ads:17:13: discriminant cannot be volatile
shared_vars.ads:21:09: discriminated type "R4" cannot be volatile
shared_vars.ads:29:04: discriminated object "SV" cannot be volatile
shared_vars.ads:31:09: tagged type "R6" cannot be volatile
shared_vars.ads:39:04: tagged object "SV2" cannot be volatile

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

2014-07-29  Hristian Kirtchev  <kirtc...@adacore.com>

        * freeze.adb (Freeze_Record_Type): Perform various
        volatility-related checks.

Index: freeze.adb
===================================================================
--- freeze.adb  (revision 213169)
+++ freeze.adb  (working copy)
@@ -3411,6 +3411,43 @@
             end if;
          end if;
 
+         --  The following checks are only relevant when SPARK_Mode is on as
+         --  they are not standard Ada legality rules.
+
+         if SPARK_Mode = On then
+            if Is_SPARK_Volatile (Rec) then
+
+               --  A discriminated type cannot be volatile (SPARK RM C.6(4))
+
+               if Has_Discriminants (Rec) then
+                  Error_Msg_N ("discriminated type & cannot be volatile", Rec);
+
+               --  A tagged type cannot be volatile (SPARK RM C.6(5))
+
+               elsif Is_Tagged_Type (Rec) then
+                  Error_Msg_N ("tagged type & cannot be volatile", Rec);
+               end if;
+
+            --  A non-volatile record type cannot contain volatile components
+            --  (SPARK RM C.6(2))
+
+            else
+               Comp := First_Component (Rec);
+               while Present (Comp) loop
+                  if Comes_From_Source (Comp)
+                    and then Is_SPARK_Volatile (Etype (Comp))
+                  then
+                     Error_Msg_Name_1 := Chars (Rec);
+                     Error_Msg_N
+                       ("component & of non-volatile type % cannot be "
+                        & "volatile", Comp);
+                  end if;
+
+                  Next_Component (Comp);
+               end loop;
+            end if;
+         end if;
+
          --  All done if not a full record definition
 
          if Ekind (Rec) /= E_Record_Type then

Reply via email to