frontend.adb (Frontend): Capture restrictions from config files
authorRobert Dewar <dewar@adacore.com>
Mon, 21 Nov 2011 11:45:44 +0000 (11:45 +0000)
committerArnaud Charlet <charlet@gcc.gnu.org>
Mon, 21 Nov 2011 11:45:44 +0000 (12:45 +0100)
2011-11-21  Robert Dewar  <dewar@adacore.com>

* frontend.adb (Frontend): Capture restrictions from config files
* lib-load.adb (Load_Unit): Save/set/restore restriction pragma
information
* lib-xref.adb (Generate_Reference): Fix handling of obsolescent
references. This was noticed during debugging, but it is not
known if it causes real bugs.
* restrict.ads, restrict.adb: New routines to save/set/restore
non-partition-wide restrictions.
* s-rident.ads: Comment changes for new handling of
No_Elaboration_Code
* sem.adb (Sem): Save/Set/Restore non-partition-wide restrictions
* sem_ch10.adb (Analyze_Compilation_Unit): Remove incomplete
attempt to save/restore non-partition-wide restrictions (now
this work is all done in Sem).
* sem_prag.adb (Process_Restrictions_Or_Restriction_Warnings):
Special handling for restriction No_Elaboration_Code.

2011-11-21  Robert Dewar  <dewar@adacore.com>

* gnat_ugn.texi: Document new handling of restrictions pragmas.

From-SVN: r181566

gcc/ada/ChangeLog
gcc/ada/frontend.adb
gcc/ada/gnat_ugn.texi
gcc/ada/lib-load.adb
gcc/ada/lib-xref.adb
gcc/ada/restrict.adb
gcc/ada/restrict.ads
gcc/ada/s-rident.ads
gcc/ada/sem.adb
gcc/ada/sem_ch10.adb
gcc/ada/sem_prag.adb

index 4ba28bdbdefe22d018e488bf187d634d4b7a5e24..75806a6de23c670536d51db5d139ce765bb8797c 100644 (file)
@@ -1,3 +1,26 @@
+2011-11-21  Robert Dewar  <dewar@adacore.com>
+
+       * frontend.adb (Frontend): Capture restrictions from config files
+       * lib-load.adb (Load_Unit): Save/set/restore restriction pragma
+       information
+       * lib-xref.adb (Generate_Reference): Fix handling of obsolescent
+       references. This was noticed during debugging, but it is not
+       known if it causes real bugs.
+       * restrict.ads, restrict.adb: New routines to save/set/restore
+       non-partition-wide restrictions.
+       * s-rident.ads: Comment changes for new handling of
+       No_Elaboration_Code
+       * sem.adb (Sem): Save/Set/Restore non-partition-wide restrictions
+       * sem_ch10.adb (Analyze_Compilation_Unit): Remove incomplete
+       attempt to save/restore non-partition-wide restrictions (now
+       this work is all done in Sem).
+       * sem_prag.adb (Process_Restrictions_Or_Restriction_Warnings):
+       Special handling for restriction No_Elaboration_Code.
+
+2011-11-21  Robert Dewar  <dewar@adacore.com>
+
+       * gnat_ugn.texi: Document new handling of restrictions pragmas.
+
 2011-11-21  Pascal Obry  <obry@adacore.com>
 
        * s-taprop-linux.adb (Initialize_Lock): Do not allocate a cond
index 2dad57a3b3b18909f389466e3e0b08a20fc157a9..35e7d9e769b0ac4bcaacacd7f2cb8106ec400f03 100644 (file)
@@ -226,6 +226,12 @@ begin
       Opt.Suppress_Options := Scope_Suppress;
    end;
 
+   --  This is where we can capture the value of the compilation unit specific
+   --  restrictions that have been set by the config pragma files (or from
+   --  Targparm), for later restoration when processing e.g. subunits.
+
+   Save_Config_Cunit_Boolean_Restrictions;
+
    --  If there was a -gnatem switch, initialize the mappings of unit names to
    --  file names and of file names to path names from the mapping file.
 
index f9ad16fbc57aba5f27f4a697a37c89f1ee80081b..266aa7d8f1571f1e7800bcc77b4166ae4723e819 100644 (file)
@@ -11805,7 +11805,7 @@ recognized by GNAT:
 @section Handling of Configuration Pragmas
 
 Configuration pragmas may either appear at the start of a compilation
-unit, in which case they apply only to that unit, or they may apply to
+unit, or they can appear in a configuration pragma file to apply to
 all compilations performed in a given compilation environment.
 
 GNAT also provides the @code{gnatchop} utility to provide an automatic
@@ -11816,6 +11816,30 @@ However, for most purposes, it will be more convenient to edit the
 @file{gnat.adc} file that contains configuration pragmas directly,
 as described in the following section.
 
+In the case of @code{Restrictions} pragmas appearing as configuration
+pragmas in individual compilation units, the exact handling depends on
+the type of restriction.
+
+Restrictions that require partition-wide consistency (like
+@code{No_Tasking}) are
+recognized wherever they appear
+and can be freely inherited, e.g. from a with'ed unit to the with'ing
+unit. This makes sense since the binder will in any case insist on seeing
+consistent use, so any unit not conforming to any restrictions that are
+anywhere in the partition will be rejected, and you might as well find
+that out at compile time rather than at bind time.
+
+For restrictions that do not require partition-wide consistency, e.g.
+SPARK or No_Implementation_Attributes, in general the restriction applies
+only to the unit in which the pragma appears, and not to any other units.
+
+The exception is No_Elaboration_Code which always applies to the entire
+object file from a compilation, i.e. to the body, spec, and all subunits.
+This restriction can be specified in a configuration pragma file, or it
+can be on the body and/or the spec (in eithe case it applies to all the
+relevant units). It can appear on a subunit only if it has previously
+appeared in the body of spec.
+
 @node The Configuration Pragmas Files
 @section The Configuration Pragmas Files
 @cindex @file{gnat.adc}
index 894c76017d994124aa8b3e2995a61cde2dc0f455..0ac729ece6c4f209855e6bb7bd24e91008d548fa 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -359,9 +359,25 @@ package body Lib.Load is
       Src_Ind      : Source_File_Index;
       Save_PMES    : constant Boolean := Parsing_Main_Extended_Source;
 
+      Save_Cunit_Restrictions : constant Save_Cunit_Boolean_Restrictions :=
+                                  Cunit_Boolean_Restrictions_Save;
+      --  Save current restrictions for restore at end
+
    begin
       Parsing_Main_Extended_Source := PMES;
 
+      --  Initialize restrictions to config restrictions for unit to load if
+      --  it is part of the main extended source, otherwise reset them.
+
+      --  Note: it's a bit odd but PMES is False for subunits, which is why
+      --  we have the OR here. Should be investigated some time???
+
+      if PMES or Subunit then
+         Restore_Config_Cunit_Boolean_Restrictions;
+      else
+         Reset_Cunit_Boolean_Restrictions;
+      end if;
+
       --  If renamings are allowed and we have a child unit name, then we
       --  must first load the parent to deal with finding the real name.
       --  Retain the with_clause that names the child, so that if it is
@@ -782,6 +798,7 @@ package body Lib.Load is
 
       <<Done>>
       Parsing_Main_Extended_Source := Save_PMES;
+      Cunit_Boolean_Restrictions_Restore (Save_Cunit_Restrictions);
       return Unum;
    end Load_Unit;
 
index 83a06e452f3aab06643d79c21fdf3dc5de9e3fa6..0e8337f70c6d1a734781e0d1c434104a898f0d82 100644 (file)
@@ -577,14 +577,16 @@ package body Lib.Xref is
       --  doing in such cases. For example the calls in Ada.Characters.Handling
       --  to its own obsolescent subprograms are just fine.
 
-      --  In any case we do not generate warnings within the extended source
-      --  unit of the entity in question, since we assume the source unit
-      --  itself knows what is going on (and for sure we do not want silly
-      --  warnings, e.g. on the end line of an obsolescent procedure body).
+      --  In any case we only generate warnings if we are in the extended main
+      --  source unit, and the entity itself is not in the extended main source
+      --  unit, since we assume the source unit itself knows what is going on
+      --  (and for sure we do not want silly warnings, e.g. on the end line of
+      --  an obsolescent procedure body).
 
       if Is_Obsolescent (E)
         and then not GNAT_Mode
         and then not In_Extended_Main_Source_Unit (E)
+        and then In_Extended_Main_Source_Unit (N)
       then
          Check_Restriction (No_Obsolescent_Features, N);
 
index 399547c61dbff480b2c3387beda27e1319eba9b3..df2ec7a888c25160530aa3ce731193422ef810f5 100644 (file)
@@ -41,6 +41,9 @@ with Uname;    use Uname;
 
 package body Restrict is
 
+   Config_Cunit_Boolean_Restrictions : Save_Cunit_Boolean_Restrictions;
+   --  Save compilation unit restrictions set by config pragma files
+
    Restricted_Profile_Result : Boolean := False;
    --  This switch memoizes the result of Restricted_Profile function calls for
    --  improved efficiency. Valid only if Restricted_Profile_Cached is True.
@@ -100,6 +103,17 @@ package body Restrict is
       end if;
    end Abort_Allowed;
 
+   ----------------------------------------
+   -- Add_To_Config_Boolean_Restrictions --
+   ----------------------------------------
+
+   procedure Add_To_Config_Boolean_Restrictions (R : Restriction_Id) is
+   begin
+      Config_Cunit_Boolean_Restrictions (R) := True;
+   end Add_To_Config_Boolean_Restrictions;
+   --  Add specified restriction to stored configuration boolean restrictions.
+   --  This is used for handling the special case of No_Elaboration_Code.
+
    -------------------------
    -- Check_Compiler_Unit --
    -------------------------
@@ -498,7 +512,9 @@ package body Restrict is
 
       Update_Restrictions (Restrictions);
 
-      --  If in main extended unit, update main restrictions as well
+      --  If in main extended unit, update main restrictions as well. Note
+      --  that as usual we check for Main_Unit explicitly to deal with the
+      --  case of configuration pragma files.
 
       if Current_Sem_Unit = Main_Unit
         or else In_Extended_Main_Source_Unit (N)
@@ -642,6 +658,16 @@ package body Restrict is
       for J in Cunit_Boolean_Restrictions loop
          Restrictions.Set (J) := R (J);
       end loop;
+
+      --  If No_Elaboration_Code set in configuration restrictions, and we
+      --  in the main extended source, then set it here now. This is part of
+      --  the special processing for No_Elaboration_Code.
+
+      if In_Extended_Main_Source_Unit (Cunit_Entity (Current_Sem_Unit))
+        and then Config_Cunit_Boolean_Restrictions (No_Elaboration_Code)
+      then
+         Restrictions.Set (No_Elaboration_Code) := True;
+      end if;
    end Cunit_Boolean_Restrictions_Restore;
 
    -------------------------------------
@@ -656,7 +682,6 @@ package body Restrict is
    begin
       for J in Cunit_Boolean_Restrictions loop
          R (J) := Restrictions.Set (J);
-         Restrictions.Set (J) := False;
       end loop;
 
       return R;
@@ -772,6 +797,26 @@ package body Restrict is
       return New_Name;
    end Process_Restriction_Synonyms;
 
+   --------------------------------------
+   -- Reset_Cunit_Boolean_Restrictions --
+   --------------------------------------
+
+   procedure Reset_Cunit_Boolean_Restrictions is
+   begin
+      for J in Cunit_Boolean_Restrictions loop
+         Restrictions.Set (J) := False;
+      end loop;
+   end Reset_Cunit_Boolean_Restrictions;
+
+   -----------------------------------------------
+   -- Restore_Config_Cunit_Boolean_Restrictions --
+   -----------------------------------------------
+
+   procedure Restore_Config_Cunit_Boolean_Restrictions is
+   begin
+      Cunit_Boolean_Restrictions_Restore (Config_Cunit_Boolean_Restrictions);
+   end Restore_Config_Cunit_Boolean_Restrictions;
+
    ------------------------
    -- Restricted_Profile --
    ------------------------
@@ -1004,6 +1049,15 @@ package body Restrict is
       end if;
    end Same_Unit;
 
+   --------------------------------------------
+   -- Save_Config_Cunit_Boolean_Restrictions --
+   --------------------------------------------
+
+   procedure Save_Config_Cunit_Boolean_Restrictions is
+   begin
+      Config_Cunit_Boolean_Restrictions := Cunit_Boolean_Restrictions_Save;
+   end Save_Config_Cunit_Boolean_Restrictions;
+
    ------------------------------
    -- Set_Hidden_Part_In_SPARK --
    ------------------------------
@@ -1070,23 +1124,6 @@ package body Restrict is
       N : Node_Id)
    is
    begin
-      --  Restriction No_Elaboration_Code must be enforced on a unit by unit
-      --  basis. Hence, we avoid setting the restriction when processing an
-      --  unit which is not the main one being compiled (or its corresponding
-      --  spec). It can happen, for example, when processing an inlined body
-      --  (the package containing the inlined subprogram is analyzed,
-      --  including its pragma Restrictions).
-
-      --  This seems like a very nasty kludge??? This is not the only per unit
-      --  restriction why is this treated specially ???
-
-      if R = No_Elaboration_Code
-        and then Current_Sem_Unit /= Main_Unit
-        and then Cunit (Current_Sem_Unit) /= Library_Unit (Cunit (Main_Unit))
-      then
-         return;
-      end if;
-
       Restrictions.Set (R) := True;
 
       if Restricted_Profile_Cached and Restricted_Profile_Result then
index 681a2c1d7d910f358e6ffe57c092eaf49b38d1da..5d03f831267c1a97ddfd785e25a8d2e594c24557 100644 (file)
@@ -71,10 +71,6 @@ package Restrict is
    --  set if Restriction_Warnings is set, so this does not look like a
    --  restriction to the binder.
 
-   type Save_Cunit_Boolean_Restrictions is private;
-   --  Type used for saving and restoring compilation unit restrictions.
-   --  See Cunit_Boolean_Restrictions_[Save|Restore] subprograms.
-
    --  The following declarations establish a mapping between restriction
    --  identifiers, and the names of corresponding restriction library units.
 
@@ -312,22 +308,6 @@ package Restrict is
    --  [Wide_]Wide_Character or [Wide_]Wide_String, then the restriction
    --  violation is recorded, and an appropriate message given.
 
-   function Cunit_Boolean_Restrictions_Save
-     return Save_Cunit_Boolean_Restrictions;
-   --  This function saves the compilation unit restriction settings, and
-   --  resets them to False. This is used e.g. when compiling a with'ed
-   --  unit to avoid incorrectly propagating restrictions. Note that it
-   --  would not be wrong to also save and reset the partition restrictions,
-   --  since the binder would catch inconsistencies, but actually it is a
-   --  good thing to acquire restrictions from with'ed units if they are
-   --  required to be partition wide, because it allows the restriction
-   --  violation message to be given at compile time instead of link time.
-
-   procedure Cunit_Boolean_Restrictions_Restore
-     (R : Save_Cunit_Boolean_Restrictions);
-   --  This is the corresponding restore procedure to restore restrictions
-   --  previously saved by Cunit_Boolean_Restrictions_Save.
-
    function Get_Restriction_Id
      (N : Name_Id) return Restriction_Id;
    --  Given an identifier name, determines if it is a valid restriction
@@ -435,6 +415,71 @@ package Restrict is
    --  Tests if tasking operations are allowed by the current restrictions
    --  settings. For tasking to be allowed Max_Tasks must be non-zero.
 
+   ----------------------------------------------
+   -- Handling of Boolean Compilation Switches --
+   ----------------------------------------------
+
+   --  The following declarations are used for proper saving and restoring of
+   --  restrictions for separate compilation units. There are two cases:
+
+   --    For partition-wide restrictions, we just let the restrictions pragmas
+   --    pile up, and we never reset them. We might as well detect what we can
+   --    at compile time. If e.g. a with'ed unit has a restriction for one of
+   --    the partition-wide restrictions, then the binder will enforce it on
+   --    all units in the partition, including the unit with the WITH. Although
+   --    it would not be wrong to leave this till bind time, we might as well
+   --    flag it earlier at compile time.
+
+   --    For non-partition-wide restrictions, we have quite a different state
+   --    of affairs. Here it would be quite wrong to carry a restriction from
+   --    a with'ed unit to another with'ed unit, or from a package spec to the
+   --    package body. This means that we have to reset these non-partition
+   --    wide restrictions at the start of each separate compilation unit. For
+   --    units in the extended main program, we need to reset them all to the
+   --    values set by the configuration pragma file(s). For units not in the
+   --    extended main program, e.g. with'ed units, we might as well reset all
+   --    of these restrictions to off (False). The actual initial values will
+   --    be taken from the config files active when those units are compiled
+   --    as main units.
+
+   type Save_Cunit_Boolean_Restrictions is private;
+   --  Type used for saving and restoring compilation unit restrictions.
+
+   function Cunit_Boolean_Restrictions_Save
+     return Save_Cunit_Boolean_Restrictions;
+   --  This function saves the compilation unit restriction settings, leaving
+   --  then unchanged. This is used e.g. at the start of processing a context
+   --  clause, so that the main unit restrictions can be restored after all
+   --  the with'ed units have been processed.
+
+   procedure Cunit_Boolean_Restrictions_Restore
+     (R : Save_Cunit_Boolean_Restrictions);
+   --  This is the corresponding restore procedure to restore restrictions
+   --  previously saved by Cunit_Boolean_Restrictions_Save. However it does
+   --  not reset No_Elaboration_Code, this stays set if it was set before
+   --  the call, and also if it is set before the call, then the Config
+   --  setting is also updated to include this restriction. This is what
+   --  implements the special handling of No_Elaboration_Code.
+
+   procedure Save_Config_Cunit_Boolean_Restrictions;
+   --  This saves the current compilation unit restrictions in an internal
+   --  variable, and leaves them unchanged. This is called immediately after
+   --  processing the configuration file pragmas, to record the restrictions
+   --  set by these configuration file pragmas.
+
+   procedure Restore_Config_Cunit_Boolean_Restrictions;
+   --  This restores the value saved by the previous call to save config values
+   --  saved by Save_Config_Cunit_Boolean_Restrictions. It is called at the
+   --  start of processing a new unit that is part of the main sources (e.g.
+   --  a package spec when the main unit is a package body).
+
+   procedure Reset_Cunit_Boolean_Restrictions;
+   --  Turns off all non-partition-wide boolean restrictions
+
+   procedure Add_To_Config_Boolean_Restrictions (R : Restriction_Id);
+   --  Add specified restriction to stored configuration boolean restrictions.
+   --  This is used for handling the special case of No_Elaboration_Code.
+
 private
    type Save_Cunit_Boolean_Restrictions is
      array (Cunit_Boolean_Restrictions) of Boolean;
index 1c306e3466422c4d12347e2cd9a9e6315a6e2819..d067f3d7f4feebe661195abec7806f180524d015 100644 (file)
@@ -124,7 +124,15 @@ package System.Rident is
 
       No_Default_Initialization,               -- GNAT
 
-      --  The following cases do not require consistency checking
+      --  The following cases do not require consistency checking and if used
+      --  as a configuration pragma within a specific unit, apply only to that
+      --  unit (e.g. if used in the package spec, do not apply to the body)
+
+      --  Note: No_Elaboration_Code is handled specially. Like the other
+      --  non-partition-wide restrictions, it can only be set in a unit that
+      --  is part of the extended main source unit (body/spec/subunits). But
+      --  it is sticky, in that if it is found anywhere within any of these
+      --  units, it applies to all units in this extended main source.
 
       Immediate_Reclamation,                   -- (RM H.4(10))
       No_Implementation_Aspect_Specifications, -- Ada 2012 AI-241
@@ -202,7 +210,7 @@ package System.Rident is
    --  Boolean restrictions that are not checked for partition consistency
    --  and that thus apply only to the current unit. Note that for these
    --  restrictions, the compiler does not apply restrictions found in
-   --  with'ed units, parent specs etc. to the main unit.
+   --  with'ed units, parent specs etc. to the main unit, and vice versa.
 
    subtype All_Parameter_Restrictions is
      Restriction_Id range
index b463d37a938a741a08e3424a30e1e1623580bd47..2a273609a09b9f4aca795ec46be86f152aab4943 100644 (file)
@@ -35,6 +35,7 @@ with Lib;      use Lib;
 with Lib.Load; use Lib.Load;
 with Nlists;   use Nlists;
 with Output;   use Output;
+with Restrict; use Restrict;
 with Sem_Attr; use Sem_Attr;
 with Sem_Ch2;  use Sem_Ch2;
 with Sem_Ch3;  use Sem_Ch3;
@@ -1361,6 +1362,11 @@ package body Sem is
       --  Variable used to save values of config switches while we analyze the
       --  new unit, to be restored on exit for proper recursive behavior.
 
+      Save_Cunit_Restrictions : Save_Cunit_Boolean_Restrictions;
+      --  Used to save non-partition wide restrictions before processing new
+      --  unit. All with'ed units are analyzed with config restrictions reset
+      --  and we need to restore these saved values at the end.
+
       procedure Do_Analyze;
       --  Procedure to analyze the compilation unit. This is called more than
       --  once when the high level optimizer is activated.
@@ -1442,11 +1448,27 @@ package body Sem is
       In_Spec_Expression := False;
 
       Set_Comes_From_Source_Default (False);
+
+      --  Save current config switches and reset then appropriately
+
       Save_Opt_Config_Switches (Save_Config_Switches);
       Set_Opt_Config_Switches
         (Is_Internal_File_Name (Unit_File_Name (Current_Sem_Unit)),
          Current_Sem_Unit = Main_Unit);
 
+      --  Save current non-partition-wide restrictions
+
+      Save_Cunit_Restrictions := Cunit_Boolean_Restrictions_Save;
+
+      --  For unit in main extended unit, we reset the configuration values
+      --  for the non-partition-wide restrictions. For other units reset them.
+
+      if In_Extended_Main_Source_Unit (Comp_Unit) then
+         Restore_Config_Cunit_Boolean_Restrictions;
+      else
+         Reset_Cunit_Boolean_Restrictions;
+      end if;
+
       --  Only do analysis of unit that has not already been analyzed
 
       if not Analyzed (Comp_Unit) then
@@ -1511,6 +1533,11 @@ package body Sem is
       Outer_Generic_Scope  := S_Outer_Gen_Scope;
 
       Restore_Opt_Config_Switches (Save_Config_Switches);
+
+      --  Deal with restore of restrictions
+
+      Cunit_Boolean_Restrictions_Restore (Save_Cunit_Restrictions);
+
       Expander_Mode_Restore;
 
       if Debug_Unit_Walk then
index 34346e39925a3cf1fa83b8adc01daed783e3ba5b..e5afc1b8b2f3f40536726f82dc637f3ca6b4e58c 100644 (file)
@@ -467,7 +467,6 @@ package body Sem_Ch10 is
                --  generated with clauses or limited with clauses. Note that
                --  we examine with clauses having pragmas Elaborate or
                --  Elaborate_All applied to them due to cases such as:
-               --
 
                --     with Pack;
                --     with Pack;
@@ -725,7 +724,12 @@ package body Sem_Ch10 is
             return;
 
          else
+            --  Analyze the package spec
+
             Semantics (Lib_Unit);
+
+            --  Check for unused with's
+
             Check_Unused_Withs (Get_Cunit_Unit_Number (Lib_Unit));
 
             --  Verify that the library unit is a package declaration
@@ -857,8 +861,6 @@ package body Sem_Ch10 is
 
          declare
             Save_Style_Check : constant Boolean := Style_Check;
-            Save_C_Restrict  : constant Save_Cunit_Boolean_Restrictions :=
-                                 Cunit_Boolean_Restrictions_Save;
 
          begin
             if not GNAT_Mode then
@@ -867,8 +869,10 @@ package body Sem_Ch10 is
 
             Semantics (Parent_Spec (Unit_Node));
             Version_Update (N, Parent_Spec (Unit_Node));
+
+            --  Restore style check settings
+
             Style_Check := Save_Style_Check;
-            Cunit_Boolean_Restrictions_Restore (Save_C_Restrict);
          end;
       end if;
 
@@ -1052,8 +1056,6 @@ package body Sem_Ch10 is
             Un    : Unit_Number_Type;
 
             Save_Style_Check : constant Boolean := Style_Check;
-            Save_C_Restrict  : constant Save_Cunit_Boolean_Restrictions :=
-                                 Cunit_Boolean_Restrictions_Save;
 
          begin
             Item := First (Context_Items (N));
@@ -1122,8 +1124,9 @@ package body Sem_Ch10 is
                Next (Item);
             end loop;
 
+            --  Restore style checks settings
+
             Style_Check := Save_Style_Check;
-            Cunit_Boolean_Restrictions_Restore (Save_C_Restrict);
          end;
       end if;
 
@@ -1641,7 +1644,7 @@ package body Sem_Ch10 is
       --  subunit, and that the current unit is one of its parents which was
       --  being analyzed to provide the needed context for the analysis of the
       --  subunit. In this case we analyze the subunit and continue with the
-      --  parent, without looking a subsequent subunits.
+      --  parent, without looking at subsequent subunits.
 
       if Is_Loaded (Subunit_Name) then
 
@@ -2351,7 +2354,6 @@ package body Sem_Ch10 is
       --  warnings if we have this definite error.
 
       Save_Style_Check : constant Boolean := Opt.Style_Check;
-      Save_C_Restrict  : Save_Cunit_Boolean_Restrictions;
 
    begin
       U := Unit (Library_Unit (N));
@@ -2388,10 +2390,6 @@ package body Sem_Ch10 is
          end if;
       end if;
 
-      --  Save current restriction set, does not apply to with'ed unit
-
-      Save_C_Restrict := Cunit_Boolean_Restrictions_Save;
-
       --  Several actions are skipped for dummy packages (those supplied for
       --  with's where no matching file could be found). Such packages are
       --  identified by the Sloc value being set to No_Location.
@@ -2591,10 +2589,9 @@ package body Sem_Ch10 is
          end if;
       end if;
 
-      --  Restore style checks and restrictions
+      --  Restore style checks
 
       Style_Check := Save_Style_Check;
-      Cunit_Boolean_Restrictions_Restore (Save_C_Restrict);
 
       --  Record the reference, but do NOT set the unit as referenced, we want
       --  to consider the unit as unreferenced if this is the only reference
index 5211d88815d6c4dfd239fcce1e06c59de501523f..14961cbb940e4daa6cebe67c632712e11465073e 100644 (file)
@@ -5350,6 +5350,46 @@ package body Sem_Prag is
                   Check_Restriction (No_Implementation_Restrictions, Arg);
                end if;
 
+               --  Special processing for No_Elaboration_Code restriction
+
+               if R_Id = No_Elaboration_Code then
+
+                  --  Restriction is only recognized within a configuration
+                  --  pragma file, or within a unit of the main extended
+                  --  program. Note: the test for Main_Unit is needed to
+                  --  properly include the case of configuration pragma files.
+
+                  if not (Current_Sem_Unit = Main_Unit
+                           or else In_Extended_Main_Source_Unit (N))
+                  then
+                     return;
+
+                  --  Don't allow in a subunit unless already specified in
+                  --  body or spec.
+
+                  elsif Nkind (Parent (N)) = N_Compilation_Unit
+                    and then Nkind (Unit (Parent (N))) = N_Subunit
+                    and then not Restriction_Active (No_Elaboration_Code)
+                  then
+                     Error_Msg_N
+                       ("invalid specification of ""No_Elaboration_Code""",
+                        N);
+                     Error_Msg_N
+                       ("\restriction cannot be specified in a subunit", N);
+                     Error_Msg_N
+                       ("\unless also specified in body or spec", N);
+                     return;
+
+                  --  If we have a No_Elaboration_Code pragma that we
+                  --  accept, then it needs to be added to the configuration
+                  --  restrcition set so that we get proper application to
+                  --  other units in the main extended source as required.
+
+                  else
+                     Add_To_Config_Boolean_Restrictions (No_Elaboration_Code);
+                  end if;
+               end if;
+
                --  If this is a warning, then set the warning unless we already
                --  have a real restriction active (we never want a warning to
                --  override a real restriction).