summaryrefslogtreecommitdiff
path: root/gcc/ada/restrict.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/restrict.adb')
-rw-r--r--gcc/ada/restrict.adb515
1 files changed, 290 insertions, 225 deletions
diff --git a/gcc/ada/restrict.adb b/gcc/ada/restrict.adb
index 2740fc67d22..2f2f15309df 100644
--- a/gcc/ada/restrict.adb
+++ b/gcc/ada/restrict.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -59,11 +59,11 @@ package body Restrict is
function Abort_Allowed return Boolean is
begin
- if Restrictions (No_Abort_Statements)
- and then Restriction_Parameters (Max_Asynchronous_Select_Nesting) = 0
+ if Restrictions.Set (No_Abort_Statements)
+ and then Restrictions.Set (Max_Asynchronous_Select_Nesting)
+ and then Restrictions.Value (Max_Asynchronous_Select_Nesting) = 0
then
return False;
-
else
return True;
end if;
@@ -79,7 +79,7 @@ package body Restrict is
-- Even in the error case it is a bit dubious, either gigi needs
-- the table locked or it does not! ???
- if Restrictions (No_Elaboration_Code)
+ if Restrictions.Set (No_Elaboration_Code)
and then not Suppress_Restriction_Message (N)
then
Namet.Unlock;
@@ -110,13 +110,12 @@ package body Restrict is
declare
Fnam : constant File_Name_Type :=
Get_File_Name (U, Subunit => False);
- R_Id : Restriction_Id;
begin
if not Is_Predefined_File_Name (Fnam) then
return;
- -- Ada child unit spec, needs checking against list
+ -- Predefined spec, needs checking against list
else
-- Pad name to 8 characters with blanks
@@ -133,30 +132,7 @@ package body Restrict is
if Name_Len = 8
and then Name_Buffer (1 .. 8) = Unit_Array (J).Filenm
then
- R_Id := Unit_Array (J).Res_Id;
- Violations (R_Id) := True;
-
- if Restrictions (R_Id) then
- declare
- S : constant String := Restriction_Id'Image (R_Id);
-
- begin
- Error_Msg_Unit_1 := U;
-
- Error_Msg_N
- ("|dependence on $ not allowed,", N);
-
- Name_Buffer (1 .. S'Last) := S;
- Name_Len := S'Length;
- Set_Casing (All_Lower_Case);
- Error_Msg_Name_1 := Name_Enter;
- Error_Msg_Sloc := Restrictions_Loc (R_Id);
-
- Error_Msg_N
- ("\|violates pragma Restriction (%) #", N);
- return;
- end;
- end if;
+ Check_Restriction (Unit_Array (J).Res_Id, N);
end if;
end loop;
end if;
@@ -168,192 +144,213 @@ package body Restrict is
-- Check_Restriction --
-----------------------
- -- Case of simple identifier (no parameter)
-
- procedure Check_Restriction (R : Restriction_Id; N : Node_Id) is
+ procedure Check_Restriction
+ (R : Restriction_Id;
+ N : Node_Id;
+ V : Uint := Uint_Minus_1)
+ is
Rimage : constant String := Restriction_Id'Image (R);
- begin
- Violations (R) := True;
+ VV : Integer;
+ -- V converted to integer form. If V is greater than Integer'Last,
+ -- it is reset to minus 1 (unknown value).
- if (Restrictions (R) or Restriction_Warnings (R))
- and then not Suppress_Restriction_Message (N)
- then
- -- Output proper message. If this is just a case of
- -- a restriction warning, then we output a warning msg
+ procedure Update_Restrictions (Info : in out Restrictions_Info);
+ -- Update violation information in Info.Violated and Info.Count
- if not Restrictions (R) then
- Restriction_Msg
- ("?violation of restriction %", Rimage, N);
+ -------------------------
+ -- Update_Restrictions --
+ -------------------------
- -- If this is a real restriction violation, then generate
- -- a non-serious message with appropriate location.
+ procedure Update_Restrictions (Info : in out Restrictions_Info) is
+ begin
+ -- If not violated, set as violated now
- else
- Error_Msg_Sloc := Restrictions_Loc (R);
+ if not Info.Violated (R) then
+ Info.Violated (R) := True;
+
+ if R in All_Parameter_Restrictions then
+ if VV < 0 then
+ Info.Unknown (R) := True;
+ Info.Count (R) := 1;
+ else
+ Info.Count (R) := VV;
+ end if;
+ end if;
+
+ -- Otherwise if violated already and a parameter restriction,
+ -- update count by maximizing or summing depending on restriction.
+
+ elsif R in All_Parameter_Restrictions then
+
+ -- If new value is unknown, result is unknown
+
+ if VV < 0 then
+ Info.Unknown (R) := True;
- -- If we have a location for the Restrictions pragma, output it
+ -- If checked by maximization, do maximization
- if Error_Msg_Sloc > No_Location
- or else Error_Msg_Sloc = System_Location
- then
- Restriction_Msg
- ("|violation of restriction %#", Rimage, N);
+ elsif R in Checked_Max_Parameter_Restrictions then
+ Info.Count (R) := Integer'Max (Info.Count (R), VV);
- -- Otherwise restriction was implicit (e.g. set by another pragma)
+ -- If checked by adding, do add, checking for overflow
+
+ elsif R in Checked_Add_Parameter_Restrictions then
+ declare
+ pragma Unsuppress (Overflow_Check);
+ begin
+ Info.Count (R) := Info.Count (R) + VV;
+ exception
+ when Constraint_Error =>
+ Info.Count (R) := Integer'Last;
+ Info.Unknown (R) := True;
+ end;
+
+ -- Should not be able to come here, known counts should only
+ -- occur for restrictions that are Checked_max or Checked_Sum.
else
- Restriction_Msg
- ("|violation of implicit restriction %", Rimage, N);
+ raise Program_Error;
end if;
end if;
- end if;
- end Check_Restriction;
+ end Update_Restrictions;
- -- Case where a parameter is present, with a count
+ -- Start of processing for Check_Restriction
- procedure Check_Restriction
- (R : Restriction_Parameter_Id;
- V : Uint;
- N : Node_Id)
- is
begin
- if Restriction_Parameters (R) /= No_Uint
- and then V > Restriction_Parameters (R)
- and then not Suppress_Restriction_Message (N)
+ if UI_Is_In_Int_Range (V) then
+ VV := Integer (UI_To_Int (V));
+ else
+ VV := -1;
+ end if;
+
+ -- Count can only be specified in the checked val parameter case
+
+ pragma Assert (VV < 0 or else R in Checked_Val_Parameter_Restrictions);
+
+ -- Nothing to do if value of zero specified for parameter restriction
+
+ if VV = 0 then
+ return;
+ end if;
+
+ -- Update current restrictions
+
+ Update_Restrictions (Restrictions);
+
+ -- If in main extended unit, update main restrictions as well
+
+ if Current_Sem_Unit = Main_Unit
+ or else In_Extended_Main_Source_Unit (N)
then
- declare
- S : constant String := Restriction_Parameter_Id'Image (R);
- begin
- Name_Buffer (1 .. S'Last) := S;
- Name_Len := S'Length;
- Set_Casing (All_Lower_Case);
- Error_Msg_Name_1 := Name_Enter;
- Error_Msg_Sloc := Restriction_Parameters_Loc (R);
- Error_Msg_N ("|maximum value exceeded for restriction %#", N);
- end;
+ Update_Restrictions (Main_Restrictions);
end if;
- end Check_Restriction;
- -- Case where a parameter is present, no count given
+ -- Nothing to do if restriction message suppressed
- procedure Check_Restriction
- (R : Restriction_Parameter_Id;
- N : Node_Id)
- is
- begin
- if Restriction_Parameters (R) = Uint_0
- and then not Suppress_Restriction_Message (N)
+ if Suppress_Restriction_Message (N) then
+ null;
+
+ -- If restriction not set, nothing to do
+
+ elsif not Restrictions.Set (R) then
+ null;
+
+ -- Here if restriction set, check for violation (either this is a
+ -- Boolean restriction, or a parameter restriction with a value of
+ -- zero and an unknown count, or a parameter restriction with a
+ -- known value that exceeds the restriction count).
+
+ elsif R in All_Boolean_Restrictions
+ or else (Restrictions.Unknown (R)
+ and then Restrictions.Value (R) = 0)
+ or else Restrictions.Count (R) > Restrictions.Value (R)
then
- declare
- S : constant String := Restriction_Parameter_Id'Image (R);
- begin
- Name_Buffer (1 .. S'Last) := S;
- Name_Len := S'Length;
- Set_Casing (All_Lower_Case);
- Error_Msg_Name_1 := Name_Enter;
- Error_Msg_Sloc := Restriction_Parameters_Loc (R);
- Error_Msg_N ("|maximum value exceeded for restriction %#", N);
- end;
+ Error_Msg_Sloc := Restrictions_Loc (R);
+
+ -- If we have a location for the Restrictions pragma, output it
+
+ if Error_Msg_Sloc > No_Location
+ or else Error_Msg_Sloc = System_Location
+ then
+ if Restriction_Warnings (R) then
+ Restriction_Msg ("|violation of restriction %#?", Rimage, N);
+ else
+ Restriction_Msg ("|violation of restriction %#", Rimage, N);
+ end if;
+
+ -- Otherwise we have the case of an implicit restriction
+ -- (e.g. a restriction implicitly set by another pragma)
+
+ else
+ Restriction_Msg
+ ("|violation of implicit restriction %", Rimage, N);
+ end if;
end if;
end Check_Restriction;
- -------------------------------------------
- -- Compilation_Unit_Restrictions_Restore --
- -------------------------------------------
+ ----------------------------------------
+ -- Cunit_Boolean_Restrictions_Restore --
+ ----------------------------------------
- procedure Compilation_Unit_Restrictions_Restore
- (R : Save_Compilation_Unit_Restrictions)
+ procedure Cunit_Boolean_Restrictions_Restore
+ (R : Save_Cunit_Boolean_Restrictions)
is
begin
- for J in Compilation_Unit_Restrictions loop
- Restrictions (J) := R (J);
+ for J in Cunit_Boolean_Restrictions loop
+ Restrictions.Set (J) := R (J);
end loop;
- end Compilation_Unit_Restrictions_Restore;
+ end Cunit_Boolean_Restrictions_Restore;
- ----------------------------------------
- -- Compilation_Unit_Restrictions_Save --
- ----------------------------------------
+ -------------------------------------
+ -- Cunit_Boolean_Restrictions_Save --
+ -------------------------------------
- function Compilation_Unit_Restrictions_Save
- return Save_Compilation_Unit_Restrictions
+ function Cunit_Boolean_Restrictions_Save
+ return Save_Cunit_Boolean_Restrictions
is
- R : Save_Compilation_Unit_Restrictions;
+ R : Save_Cunit_Boolean_Restrictions;
begin
- for J in Compilation_Unit_Restrictions loop
- R (J) := Restrictions (J);
- Restrictions (J) := False;
+ for J in Cunit_Boolean_Restrictions loop
+ R (J) := Restrictions.Set (J);
+ Restrictions.Set (J) := False;
end loop;
return R;
- end Compilation_Unit_Restrictions_Save;
+ end Cunit_Boolean_Restrictions_Save;
------------------------
-- Get_Restriction_Id --
------------------------
function Get_Restriction_Id
- (N : Name_Id)
- return Restriction_Id
+ (N : Name_Id) return Restriction_Id
is
- J : Restriction_Id;
-
begin
Get_Name_String (N);
Set_Casing (All_Upper_Case);
- J := Restriction_Id'First;
- while J /= Not_A_Restriction_Id loop
+ for J in All_Restrictions loop
declare
S : constant String := Restriction_Id'Image (J);
-
begin
- exit when S = Name_Buffer (1 .. Name_Len);
+ if S = Name_Buffer (1 .. Name_Len) then
+ return J;
+ end if;
end;
-
- J := Restriction_Id'Succ (J);
end loop;
- return J;
+ return Not_A_Restriction_Id;
end Get_Restriction_Id;
- ----------------------------------
- -- Get_Restriction_Parameter_Id --
- ----------------------------------
-
- function Get_Restriction_Parameter_Id
- (N : Name_Id)
- return Restriction_Parameter_Id
- is
- J : Restriction_Parameter_Id;
-
- begin
- Get_Name_String (N);
- Set_Casing (All_Upper_Case);
-
- J := Restriction_Parameter_Id'First;
- while J /= Not_A_Restriction_Parameter_Id loop
- declare
- S : constant String := Restriction_Parameter_Id'Image (J);
-
- begin
- exit when S = Name_Buffer (1 .. Name_Len);
- end;
-
- J := Restriction_Parameter_Id'Succ (J);
- end loop;
-
- return J;
- end Get_Restriction_Parameter_Id;
-
-------------------------------
-- No_Exception_Handlers_Set --
-------------------------------
function No_Exception_Handlers_Set return Boolean is
begin
- return Restrictions (No_Exception_Handlers);
+ return Restrictions.Set (No_Exception_Handlers);
end No_Exception_Handlers_Set;
------------------------
@@ -364,24 +361,37 @@ package body Restrict is
function Restricted_Profile return Boolean is
begin
- return Restrictions (No_Abort_Statements)
- and then Restrictions (No_Asynchronous_Control)
- and then Restrictions (No_Entry_Queue)
- and then Restrictions (No_Task_Hierarchy)
- and then Restrictions (No_Task_Allocators)
- and then Restrictions (No_Dynamic_Priorities)
- and then Restrictions (No_Terminate_Alternatives)
- and then Restrictions (No_Dynamic_Interrupts)
- and then Restrictions (No_Protected_Type_Allocators)
- and then Restrictions (No_Local_Protected_Objects)
- and then Restrictions (No_Requeue)
- and then Restrictions (No_Task_Attributes)
- and then Restriction_Parameters (Max_Asynchronous_Select_Nesting) = 0
- and then Restriction_Parameters (Max_Task_Entries) = 0
- and then Restriction_Parameters (Max_Protected_Entries) <= 1
- and then Restriction_Parameters (Max_Select_Alternatives) = 0;
+ return Restrictions.Set (No_Abort_Statements)
+ and then Restrictions.Set (No_Asynchronous_Control)
+ and then Restrictions.Set (No_Entry_Queue)
+ and then Restrictions.Set (No_Task_Hierarchy)
+ and then Restrictions.Set (No_Task_Allocators)
+ and then Restrictions.Set (No_Dynamic_Priorities)
+ and then Restrictions.Set (No_Terminate_Alternatives)
+ and then Restrictions.Set (No_Dynamic_Interrupts)
+ and then Restrictions.Set (No_Protected_Type_Allocators)
+ and then Restrictions.Set (No_Local_Protected_Objects)
+ and then Restrictions.Set (No_Requeue_Statements)
+ and then Restrictions.Set (No_Task_Attributes)
+ and then Restrictions.Set (Max_Asynchronous_Select_Nesting)
+ and then Restrictions.Set (Max_Task_Entries)
+ and then Restrictions.Set (Max_Protected_Entries)
+ and then Restrictions.Set (Max_Select_Alternatives)
+ and then Restrictions.Value (Max_Asynchronous_Select_Nesting) = 0
+ and then Restrictions.Value (Max_Task_Entries) = 0
+ and then Restrictions.Value (Max_Protected_Entries) <= 1
+ and then Restrictions.Value (Max_Select_Alternatives) = 0;
end Restricted_Profile;
+ ------------------------
+ -- Restriction_Active --
+ ------------------------
+
+ function Restriction_Active (R : All_Restrictions) return Boolean is
+ begin
+ return Restrictions.Set (R);
+ end Restriction_Active;
+
---------------------
-- Restriction_Msg --
---------------------
@@ -430,25 +440,15 @@ package body Restrict is
-------------------
procedure Set_Ravenscar (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
-
begin
Set_Restricted_Profile (N);
- Restrictions (Boolean_Entry_Barriers) := True;
- Restrictions (No_Select_Statements) := True;
- Restrictions (No_Calendar) := True;
- Restrictions (No_Entry_Queue) := True;
- Restrictions (No_Relative_Delay) := True;
- Restrictions (No_Task_Termination) := True;
- Restrictions (No_Implicit_Heap_Allocations) := True;
-
- Restrictions_Loc (Boolean_Entry_Barriers) := Loc;
- Restrictions_Loc (No_Select_Statements) := Loc;
- Restrictions_Loc (No_Calendar) := Loc;
- Restrictions_Loc (No_Entry_Queue) := Loc;
- Restrictions_Loc (No_Relative_Delay) := Loc;
- Restrictions_Loc (No_Task_Termination) := Loc;
- Restrictions_Loc (No_Implicit_Heap_Allocations) := Loc;
+ Set_Restriction (Boolean_Entry_Barriers, N);
+ Set_Restriction (No_Select_Statements, N);
+ Set_Restriction (No_Calendar, N);
+ Set_Restriction (No_Entry_Queue, N);
+ Set_Restriction (No_Relative_Delay, N);
+ Set_Restriction (No_Task_Termination, N);
+ Set_Restriction (No_Implicit_Heap_Allocations, N);
end Set_Ravenscar;
----------------------------
@@ -458,43 +458,107 @@ package body Restrict is
-- This must be coordinated with Restricted_Profile
procedure Set_Restricted_Profile (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
+ begin
+ -- Set Boolean restrictions for Restricted Profile
+
+ Set_Restriction (No_Abort_Statements, N);
+ Set_Restriction (No_Asynchronous_Control, N);
+ Set_Restriction (No_Entry_Queue, N);
+ Set_Restriction (No_Task_Hierarchy, N);
+ Set_Restriction (No_Task_Allocators, N);
+ Set_Restriction (No_Dynamic_Priorities, N);
+ Set_Restriction (No_Terminate_Alternatives, N);
+ Set_Restriction (No_Dynamic_Interrupts, N);
+ Set_Restriction (No_Protected_Type_Allocators, N);
+ Set_Restriction (No_Local_Protected_Objects, N);
+ Set_Restriction (No_Requeue_Statements, N);
+ Set_Restriction (No_Task_Attributes, N);
+
+ -- Set parameter restrictions
+
+ Set_Restriction (Max_Asynchronous_Select_Nesting, N, 0);
+ Set_Restriction (Max_Task_Entries, N, 0);
+ Set_Restriction (Max_Select_Alternatives, N, 0);
+ Set_Restriction (Max_Protected_Entries, N, 1);
+ end Set_Restricted_Profile;
+
+ ---------------------
+ -- Set_Restriction --
+ ---------------------
+
+ -- Case of Boolean restriction
+ procedure Set_Restriction
+ (R : All_Boolean_Restrictions;
+ N : Node_Id)
+ is
begin
- Restrictions (No_Abort_Statements) := True;
- Restrictions (No_Asynchronous_Control) := True;
- Restrictions (No_Entry_Queue) := True;
- Restrictions (No_Task_Hierarchy) := True;
- Restrictions (No_Task_Allocators) := True;
- Restrictions (No_Dynamic_Priorities) := True;
- Restrictions (No_Terminate_Alternatives) := True;
- Restrictions (No_Dynamic_Interrupts) := True;
- Restrictions (No_Protected_Type_Allocators) := True;
- Restrictions (No_Local_Protected_Objects) := True;
- Restrictions (No_Requeue) := True;
- Restrictions (No_Task_Attributes) := True;
-
- Restrictions_Loc (No_Abort_Statements) := Loc;
- Restrictions_Loc (No_Asynchronous_Control) := Loc;
- Restrictions_Loc (No_Entry_Queue) := Loc;
- Restrictions_Loc (No_Task_Hierarchy) := Loc;
- Restrictions_Loc (No_Task_Allocators) := Loc;
- Restrictions_Loc (No_Dynamic_Priorities) := Loc;
- Restrictions_Loc (No_Terminate_Alternatives) := Loc;
- Restrictions_Loc (No_Dynamic_Interrupts) := Loc;
- Restrictions_Loc (No_Protected_Type_Allocators) := Loc;
- Restrictions_Loc (No_Local_Protected_Objects) := Loc;
- Restrictions_Loc (No_Requeue) := Loc;
- Restrictions_Loc (No_Task_Attributes) := Loc;
-
- Restriction_Parameters (Max_Asynchronous_Select_Nesting) := Uint_0;
- Restriction_Parameters (Max_Task_Entries) := Uint_0;
- Restriction_Parameters (Max_Select_Alternatives) := Uint_0;
-
- if Restriction_Parameters (Max_Protected_Entries) /= Uint_0 then
- Restriction_Parameters (Max_Protected_Entries) := Uint_1;
+ Restrictions.Set (R) := True;
+
+ -- Set location, but preserve location of system
+ -- restriction for nice error msg with run time name
+
+ if Restrictions_Loc (R) /= System_Location then
+ Restrictions_Loc (R) := Sloc (N);
end if;
- end Set_Restricted_Profile;
+
+ -- Record the restriction if we are in the main unit,
+ -- or in the extended main unit. The reason that we
+ -- test separately for Main_Unit is that gnat.adc is
+ -- processed with Current_Sem_Unit = Main_Unit, but
+ -- nodes in gnat.adc do not appear to be the extended
+ -- main source unit (they probably should do ???)
+
+ if Current_Sem_Unit = Main_Unit
+ or else In_Extended_Main_Source_Unit (N)
+ then
+ if not Restriction_Warnings (R) then
+ Main_Restrictions.Set (R) := True;
+ end if;
+ end if;
+ end Set_Restriction;
+
+ -- Case of parameter restriction
+
+ procedure Set_Restriction
+ (R : All_Parameter_Restrictions;
+ N : Node_Id;
+ V : Integer)
+ is
+ begin
+ if Restrictions.Set (R) then
+ if V < Restrictions.Value (R) then
+ Restrictions.Value (R) := V;
+ Restrictions_Loc (R) := Sloc (N);
+ end if;
+
+ else
+ Restrictions.Set (R) := True;
+ Restrictions.Value (R) := V;
+ Restrictions_Loc (R) := Sloc (N);
+ end if;
+
+ -- Record the restriction if we are in the main unit,
+ -- or in the extended main unit. The reason that we
+ -- test separately for Main_Unit is that gnat.adc is
+ -- processed with Current_Sem_Unit = Main_Unit, but
+ -- nodes in gnat.adc do not appear to be the extended
+ -- main source unit (they probably should do ???)
+
+ if Current_Sem_Unit = Main_Unit
+ or else In_Extended_Main_Source_Unit (N)
+ then
+ if Main_Restrictions.Set (R) then
+ if V < Main_Restrictions.Value (R) then
+ Main_Restrictions.Value (R) := V;
+ end if;
+
+ elsif not Restriction_Warnings (R) then
+ Main_Restrictions.Set (R) := True;
+ Main_Restrictions.Value (R) := V;
+ end if;
+ end if;
+ end Set_Restriction;
----------------------------------
-- Suppress_Restriction_Message --
@@ -525,8 +589,9 @@ package body Restrict is
function Tasking_Allowed return Boolean is
begin
- return Restriction_Parameters (Max_Tasks) /= 0
- and then not Restrictions (No_Tasking);
+ return not Restrictions.Set (No_Tasking)
+ and then (not Restrictions.Set (Max_Tasks)
+ or else Restrictions.Value (Max_Tasks) > 0);
end Tasking_Allowed;
end Restrict;