OSDN Git Service

PR target/34091
[pf3gnuchains/gcc-fork.git] / gcc / ada / restrict.ads
index 47d2879..e82449e 100644 (file)
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---                            $Revision$
---                                                                          --
---          Copyright (C) 1992-2002 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2007, 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- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
 --  This package deals with the implementation of the Restrictions pragma
 
-with Rident;
+with Namet;  use Namet;
+with Rident; use Rident;
+with Table;
 with Types;  use Types;
 with Uintp;  use Uintp;
 
 package Restrict is
 
-   type Restriction_Id is new Rident.Restriction_Id;
-   --  The type Restriction_Id defines the set of restriction identifiers,
-   --  which take no parameter (i.e. they are either present or not present).
-   --  The actual definition is in the separate package Rident, so that
-   --  it can easily be accessed by the binder without dragging in lots of
-   --  stuff.
-
-   subtype All_Restrictions is
-     Restriction_Id range
-       Restriction_Id (Rident.All_Restrictions'First) ..
-       Restriction_Id (Rident.All_Restrictions'Last);
-   --  All restriction identifiers
-
-   subtype Partition_Restrictions is
-     Restriction_Id range
-       Restriction_Id (Rident.Partition_Restrictions'First) ..
-       Restriction_Id (Rident.Partition_Restrictions'Last);
-   --  Range of restriction identifiers that are checked by the binder
-
-   subtype Compilation_Unit_Restrictions is
-     Restriction_Id range
-       Restriction_Id (Rident.Compilation_Unit_Restrictions'First) ..
-       Restriction_Id (Rident.Compilation_Unit_Restrictions'Last);
-   --  Range of restriction identifiers not checked by binder
-
-   type Restriction_Parameter_Id is new Rident.Restriction_Parameter_Id;
-   --  The type Restriction_Parameter_Id records cases where a parameter is
-   --  present in the corresponding pragma. These cases are not checked for
-   --  consistency by the binder. The actual definition is in the separate
-   --  package Rident for consistency.
-
-   type Restrictions_Flags is array (Restriction_Id) of Boolean;
-   --  Type used for arrays indexed by Restriction_Id.
-
-   Restrictions : Restrictions_Flags := (others => False);
-   --  Corresponding entry is False if restriction is not active, and
-   --  True if the restriction is active, i.e. if a pragma Restrictions
-   --  has been seen anywhere. Note that we are happy to pick up any
-   --  restrictions pragmas in with'ed units, since we are required to
-   --  be consistent at link time, and we might as well find the error
-   --  at compile time. Clients must NOT use this array for checking to
-   --  see if a restriction is violated, instead it is required that the
-   --  Check_Restriction subprograms be used for this purpose. The only
-   --  legitimate direct use of this array is when the code is modified
-   --  as a result of the restriction in some way.
-
-   Restrictions_Loc : array (Restriction_Id) of Source_Ptr;
-   --  Locations of Restrictions pragmas for error message purposes.
-   --  Valid only if corresponding entry in Restrictions is set.
-
-   Main_Restrictions : Restrictions_Flags := (others => False);
-   --  This variable saves the cumulative restrictions in effect compiling
-   --  any unit that is part of the extended main unit (i.e. the compiled
-   --  unit, its spec if any, and its subunits if any). The reason we keep
-   --  track of this is for the information that goes to the binder about
-   --  restrictions that are set. The binder will identify a unit that has
-   --  a restrictions pragma for error message purposes, and we do not want
-   --  to pick up a restrictions pragma in a with'ed unit for this purpose.
-
-   Violations : Restrictions_Flags := (others => False);
-   --  Corresponding entry is False if the restriction has not been
-   --  violated in the current main unit, and True if it has been violated.
-
-   Restriction_Parameters :
-     array (Restriction_Parameter_Id) of Uint := (others => No_Uint);
-   --  This array indicates the setting of restriction parameter identifier
-   --  values. All values are initially set to No_Uint indicating that the
-   --  parameter is not set, and are set to the appropriate non-negative
-   --  value if a Restrictions pragma specifies the corresponding
-   --  restriction parameter identifier with an appropriate value.
-
-   Restriction_Parameters_Loc :
-     array (Restriction_Parameter_Id) of Source_Ptr;
+   Restrictions : Restrictions_Info := No_Restrictions;
+   --  This variable records restrictions found in any units in the main
+   --  extended unit, and in the case of restrictions checked for partition
+   --  consistency, restrictions found in any with'ed units, parent specs
+   --  etc, since we may as well check as much as we can at compile time.
+   --  These variables should not be referenced directly by clients. Instead
+   --  use Check_Restrictions to record a violation of a restriction, and
+   --  Restriction_Active to test if a given restriction is active.
+
+   Restrictions_Loc : array (All_Restrictions) of Source_Ptr :=
+                       (others => No_Location);
    --  Locations of Restrictions pragmas for error message purposes.
-   --  Valid only if corresponding entry in Restriction_Parameters is
-   --  set to a value other than No_Uint.
+   --  Valid only if corresponding entry in Restrictions is set. A value
+   --  of No_Location is used for implicit restrictions set by another
+   --  pragma, and a value of System_Location is used for restrictions
+   --  set from package Standard by the processing in Targparm.
+
+   Main_Restrictions : Restrictions_Info := No_Restrictions;
+   --  This variable records only restrictions found in any units of the
+   --  main extended unit. These are the variables used for ali file output,
+   --  since we want the binder to be able to accurately diagnose inter-unit
+   --  restriction violations.
+
+   Restriction_Warnings : Rident.Restriction_Flags;
+   --  If one of these flags is set, then it means that violation of the
+   --  corresponding restriction results only in a warning message, not
+   --  in an error message, and the restriction is not otherwise enforced.
+   --  Note that the flags in Restrictions are set to indicate that the
+   --  restriction is set in this case, but Main_Restrictions is never
+   --  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.
 
    type Unit_Entry is record
       Res_Id : Restriction_Id;
       Filenm : String (1 .. 8);
    end record;
 
-   type Unit_Array_Type is array (Positive range <>) of Unit_Entry;
-
-   Unit_Array : constant Unit_Array_Type := (
-     (No_Asynchronous_Control,    "a-astaco"),
-     (No_Calendar,                "a-calend"),
-     (No_Calendar,                "calendar"),
-     (No_Delay,                   "a-calend"),
-     (No_Delay,                   "calendar"),
-     (No_Dynamic_Priorities,      "a-dynpri"),
-     (No_IO,                      "a-direio"),
-     (No_IO,                      "directio"),
-     (No_IO,                      "a-sequio"),
-     (No_IO,                      "sequenio"),
-     (No_IO,                      "a-ststio"),
-     (No_IO,                      "a-textio"),
-     (No_IO,                      "text_io "),
-     (No_IO,                      "a-witeio"),
-     (No_Task_Attributes,         "a-tasatt"),
-     (No_Streams,                 "a-stream"),
-     (No_Unchecked_Conversion,    "a-unccon"),
-     (No_Unchecked_Conversion,    "unchconv"),
-     (No_Unchecked_Deallocation,  "a-uncdea"),
-     (No_Unchecked_Deallocation,  "unchdeal"));
-   --  This array defines the mapping between restriction identifiers and
-   --  predefined language files containing units for which the identifier
-   --  forbids semantic dependence.
-
-   type Save_Compilation_Unit_Restrictions is private;
-   --  Type used for saving and restoring compilation unit restrictions.
-   --  See Compilation_Unit_Restrictions_[Save|Restore] subprograms.
+   Unit_Array : constant array (Positive range <>) of Unit_Entry := (
+     (No_Asynchronous_Control,     "a-astaco"),
+     (No_Calendar,                 "a-calend"),
+     (No_Calendar,                 "calendar"),
+     (No_Delay,                    "a-calend"),
+     (No_Delay,                    "calendar"),
+     (No_Dynamic_Priorities,       "a-dynpri"),
+     (No_Finalization,             "a-finali"),
+     (No_IO,                       "a-direio"),
+     (No_IO,                       "directio"),
+     (No_IO,                       "a-sequio"),
+     (No_IO,                       "sequenio"),
+     (No_IO,                       "a-ststio"),
+     (No_IO,                       "a-textio"),
+     (No_IO,                       "text_io "),
+     (No_IO,                       "a-witeio"),
+     (No_Task_Attributes_Package,  "a-tasatt"),
+     (No_Unchecked_Conversion,     "a-unccon"),
+     (No_Unchecked_Conversion,     "unchconv"),
+     (No_Unchecked_Deallocation,   "a-uncdea"),
+     (No_Unchecked_Deallocation,   "unchdeal"));
 
    --  The following map has True for all GNAT pragmas. It is used to
    --  implement pragma Restrictions (No_Implementation_Restrictions)
    --  (which is why this restriction itself is excluded from the list).
 
-   Implementation_Restriction : Restrictions_Flags :=
-     (Boolean_Entry_Barriers             => True,
+   Implementation_Restriction : array (All_Restrictions) of Boolean :=
+     (Simple_Barriers                    => True,
       No_Calendar                        => True,
-      No_Dynamic_Interrupts              => True,
+      No_Dispatching_Calls               => True,
+      No_Dynamic_Attachment              => True,
       No_Enumeration_Maps                => True,
       No_Entry_Calls_In_Elaboration_Code => True,
       No_Entry_Queue                     => True,
       No_Exception_Handlers              => True,
+      No_Exception_Registration          => True,
       No_Implicit_Conditionals           => True,
       No_Implicit_Dynamic_Code           => True,
       No_Implicit_Loops                  => True,
       No_Local_Protected_Objects         => True,
       No_Protected_Type_Allocators       => True,
       No_Relative_Delay                  => True,
-      No_Requeue                         => True,
+      No_Requeue_Statements              => True,
       No_Secondary_Stack                 => True,
       No_Select_Statements               => True,
       No_Standard_Storage_Pools          => True,
       No_Streams                         => True,
-      No_Task_Attributes                 => True,
+      No_Task_Attributes_Package         => True,
       No_Task_Termination                => True,
-      No_Tasking                         => True,
       No_Wide_Characters                 => True,
       Static_Priorities                  => True,
       Static_Storage_Size                => True,
@@ -181,38 +134,72 @@ package Restrict is
       No_Elaboration_Code                => True,
       others                             => False);
 
+   --  The following table records entries made by Restrictions pragmas
+   --  that specify a parameter for No_Dependence. Each such pragma makes
+   --  an entry in this table.
+
+   --  Note: we have chosen to implement this restriction in the "syntactic"
+   --  form, where we do not check that the named package is a language defined
+   --  package, but instead we allow arbitrary package names. The discussion of
+   --  this issue is not complete in the ARG, but the sense seems to be leaning
+   --  in this direction, which makes more sense to us, since it is much more
+   --  useful, and much easier to implement.
+
+   type ND_Entry is record
+      Unit : Node_Id;
+      --  The unit parameter from the No_Dependence pragma
+
+      Warn : Boolean;
+      --  True if from Restriction_Warnings, False if from Restrictions
+   end record;
+
+   package No_Dependence is new Table.Table (
+     Table_Component_Type => ND_Entry,
+     Table_Index_Type     => Int,
+     Table_Low_Bound      => 0,
+     Table_Initial        => 200,
+     Table_Increment      => 200,
+     Table_Name           => "Name_No_Dependence");
+
    -----------------
    -- Subprograms --
    -----------------
 
+   function Abort_Allowed return Boolean;
+   pragma Inline (Abort_Allowed);
+   --  Tests to see if abort is allowed by the current restrictions settings.
+   --  For abort to be allowed, either No_Abort_Statements must be False,
+   --  or Max_Asynchronous_Select_Nesting must be non-zero.
+
+   procedure Check_Compiler_Unit (N : Node_Id);
+   --  If unit N is in a unit that has a pragma Compiler_Unit, then a message
+   --  is posted on node N noting use of a construct that is not permitted in
+   --  the compiler.
+
    procedure Check_Restricted_Unit (U : Unit_Name_Type; N : Node_Id);
    --  Checks if loading of unit U is prohibited by the setting of some
    --  restriction (e.g. No_IO restricts the loading of unit Ada.Text_IO).
    --  If a restriction exists post error message at the given node.
 
-   procedure Check_Restriction (R : Restriction_Id; N : Node_Id);
+   procedure Check_Restriction
+     (R : Restriction_Id;
+      N : Node_Id;
+      V : Uint := Uint_Minus_1);
    --  Checks that the given restriction is not set, and if it is set, an
    --  appropriate message is posted on the given node. Also records the
-   --  violation in the violations array. Note that it is mandatory to
-   --  always use this routine to check if a restriction is violated. Such
-   --  checks must never be done directly by the caller, since otherwise
-   --  they are not properly recorded in the violations array.
-
-   procedure Check_Restriction
-     (R : Restriction_Parameter_Id;
-      N : Node_Id);
-   --  Checks that the given restriction parameter identifier is not set to
-   --  zero. If it is set to zero, then the node N is replaced by a node
-   --  that raises Storage_Error, and a warning is issued.
-
-   procedure Check_Restriction
-     (R : Restriction_Parameter_Id;
-      V : Uint;
-      N : Node_Id);
-   --  Checks that the count in V does not exceed the maximum value of the
-   --  restriction parameter value corresponding to the given restriction
-   --  parameter identifier (if it has been set). If the count in V exceeds
-   --  the maximum, then post an error message on node N.
+   --  violation in the appropriate internal arrays. Note that it is
+   --  mandatory to always use this routine to check if a restriction
+   --  is violated. Such checks must never be done directly by the caller,
+   --  since otherwise violations in the absence of restrictions are not
+   --  properly recorded. The value of V is relevant only for parameter
+   --  restrictions, and in this case indicates the exact count for the
+   --  violation. If the exact count is not known, V is left at its
+   --  default value of -1 which indicates an unknown count.
+
+   procedure Check_Restriction_No_Dependence (U : Node_Id; Err : Node_Id);
+   --  Called when a dependence on a unit is created (either implicitly, or by
+   --  an explicit WITH clause). U is a node for the unit involved, and Err
+   --  is the node to which an error will be attached if necessary.
 
    procedure Check_Elaboration_Code_Allowed (N : Node_Id);
    --  Tests to see if elaboration code is allowed by the current restrictions
@@ -220,13 +207,19 @@ package Restrict is
    --  an elaboration routine. If elaboration code is not allowed, an error
    --  message is posted on the node given as argument.
 
-   function No_Exception_Handlers_Set return Boolean;
-   --  Test to see if current restrictions settings specify that no exception
-   --  handlers are present. This function is called by Gigi when it needs to
-   --  expand an AT END clean up identifier with no exception handler.
+   procedure Check_Implicit_Dynamic_Code_Allowed (N : Node_Id);
+   --  Tests to see if dynamic code generation (dynamically generated
+   --  trampolines, in particular) is allowed by the current restrictions
+   --  settings. This function is called by Gigi when it needs to generate code
+   --  that generates a trampoline. If not allowed, an error message is posted
+   --  on the node given as argument.
 
-   function Compilation_Unit_Restrictions_Save
-     return Save_Compilation_Unit_Restrictions;
+   procedure Check_No_Implicit_Heap_Alloc (N : Node_Id);
+   --  Equivalent to Check_Restriction (No_Implicit_Heap_Allocations, N).
+   --  Provided for easy use by back end, which has to check this restriction.
+
+   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
@@ -236,48 +229,75 @@ package Restrict is
    --  required to be partition wide, because it allows the restriction
    --  violation message to be given at compile time instead of link time.
 
-   procedure Compilation_Unit_Restrictions_Restore
-     (R : Save_Compilation_Unit_Restrictions);
+   procedure Cunit_Boolean_Restrictions_Restore
+     (R : Save_Cunit_Boolean_Restrictions);
    --  This is the corresponding restore procedure to restore restrictions
-   --  previously saved by Compilation_Unit_Restrictions_Save.
-
-   procedure Disallow_In_No_Run_Time_Mode (Enode : Node_Id);
-   --  If in No_Run_Time mode, then the construct represented by Enode is
-   --  not permitted, and will be appropriately flagged.
-
-   procedure Set_No_Run_Time_Mode;
-   --  Set the no run time mode, and associated restriction pragmas.
+   --  previously saved by Cunit_Boolean_Restrictions_Save.
 
    function Get_Restriction_Id
-     (N    : Name_Id)
-      return Restriction_Id;
+     (N : Name_Id) return Restriction_Id;
    --  Given an identifier name, determines if it is a valid restriction
    --  identifier, and if so returns the corresponding Restriction_Id
    --  value, otherwise returns Not_A_Restriction_Id.
 
-   function Get_Restriction_Parameter_Id
-     (N    : Name_Id)
-      return Restriction_Parameter_Id;
-   --  Given an identifier name, determines if it is a valid restriction
-   --  parameter identifier, and if so returns the corresponding
-   --  Restriction_Parameter_Id value, otherwise returns
-   --  Not_A_Restriction_Parameter_Id.
-
-   function Abort_Allowed return Boolean;
-   pragma Inline (Abort_Allowed);
-   --  Tests to see if abort is allowed by the current restrictions settings.
-   --  For abort to be allowed, either No_Abort_Statements must be False,
-   --  or Max_Asynchronous_Select_Nesting must be non-zero.
+   function No_Exception_Handlers_Set return Boolean;
+   --  Test to see if current restrictions settings specify that no exception
+   --  handlers are present. This function is called by Gigi when it needs to
+   --  expand an AT END clean up identifier with no exception handler. True
+   --  will be returned if the configurable run-time is activated, and either
+   --  of the restrictions No_Exception_Handlers or No_Exception_Propagation is
+   --  set. In the latter case, the source may contain handlers but they either
+   --  get converted using the local goto transformation or deleted.
+
+   function Process_Restriction_Synonyms (N : Node_Id) return Name_Id;
+   --  Id is a node whose Chars field contains the name of a restriction.
+   --  If it is one of synonyms that we allow for historical purposes (for
+   --  list see System.Rident), then the proper official name is returned.
+   --  Otherwise the Chars field of the argument is returned unchanged.
+
+   function Restriction_Active (R : All_Restrictions) return Boolean;
+   pragma Inline (Restriction_Active);
+   --  Determines if a given restriction is active. This call should only be
+   --  used where the compiled code depends on whether the restriction is
+   --  active. Always use Check_Restriction to record a violation. Note that
+   --  this returns False if we only have a Restriction_Warnings set, since
+   --  restriction warnings should never affect generated code.
 
    function Restricted_Profile return Boolean;
-   --  Tests to see if tasking operations follow the GNAT restricted run time
-   --  profile.
-
-   procedure Set_Ravenscar;
-   --  Sets the set of rerstrictions fro Ravenscar
-
-   procedure Set_Restricted_Profile;
-   --  Sets the set of restrictions for pragma Restricted_Run_Time
+   --  Tests if set of restrictions corresponding to Profile (Restricted) is
+   --  currently in effect (set by pragma Profile, or by an appropriate set
+   --  of individual Restrictions pragms). Returns True only if all the
+   --  required restrictions are set.
+
+   procedure Set_Profile_Restrictions
+     (P    : Profile_Name;
+      N    : Node_Id;
+      Warn : Boolean);
+   --  Sets the set of restrictions associated with the given profile
+   --  name. N is the node of the construct to which error messages
+   --  are to be attached as required. Warn is set True for the case
+   --  of Profile_Warnings where the restrictions are set as warnings
+   --  rather than legality requirements.
+
+   procedure Set_Restriction
+     (R : All_Boolean_Restrictions;
+      N : Node_Id);
+   --  N is a node (typically a pragma node) that has the effect of setting
+   --  Boolean restriction R. The restriction is set in Restrictions, and
+   --  also in Main_Restrictions if this is the main unit.
+
+   procedure Set_Restriction
+     (R : All_Parameter_Restrictions;
+      N : Node_Id;
+      V : Integer);
+   --  Similar to the above, except that this is used for the case of a
+   --  parameter restriction, and the corresponding value V is given.
+
+   procedure Set_Restriction_No_Dependence
+     (Unit : Node_Id;
+      Warn : Boolean);
+   --  Sets given No_Dependence restriction in table if not there already.
+   --  Warn is True if from Restriction_Warnings, False if from Restrictions.
 
    function Tasking_Allowed return Boolean;
    pragma Inline (Tasking_Allowed);
@@ -286,8 +306,8 @@ package Restrict is
    --  be non-zero.
 
 private
-   type Save_Compilation_Unit_Restrictions is
-     array (Compilation_Unit_Restrictions) of Boolean;
+   type Save_Cunit_Boolean_Restrictions is
+     array (Cunit_Boolean_Restrictions) of Boolean;
    --  Type used for saving and restoring compilation unit restrictions.
    --  See Compilation_Unit_Restrictions_[Save|Restore] subprograms.