summaryrefslogtreecommitdiff
path: root/gcc/ada/sem.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem.adb')
-rw-r--r--gcc/ada/sem.adb263
1 files changed, 163 insertions, 100 deletions
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index 34e090761a9..7dab13496c1 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -53,6 +53,8 @@ with Sinfo; use Sinfo;
with Stand; use Stand;
with Uintp; use Uintp;
+with Unchecked_Deallocation;
+
pragma Warnings (Off, Sem_Util);
-- Suppress warnings of unused with for Sem_Util (used only in asserts)
@@ -448,8 +450,8 @@ package body Sem is
when N_Requeue_Statement =>
Analyze_Requeue (N);
- when N_Return_Statement =>
- Analyze_Return_Statement (N);
+ when N_Simple_Return_Statement =>
+ Analyze_Simple_Return_Statement (N);
when N_Selected_Component =>
Find_Selected_Component (N);
@@ -724,65 +726,73 @@ package body Sem is
From : Entity_Id;
To : Entity_Id)
is
+ Found : Boolean;
+
+ procedure Search_Stack
+ (Top : Suppress_Stack_Entry_Ptr;
+ Found : out Boolean);
+ -- Search given suppress stack for matching entry for entity. If found
+ -- then set Checks_May_Be_Suppressed on To, and push an appropriate
+ -- entry for To onto the local suppress stack.
+
+ ------------------
+ -- Search_Stack --
+ ------------------
+
+ procedure Search_Stack
+ (Top : Suppress_Stack_Entry_Ptr;
+ Found : out Boolean)
+ is
+ Ptr : Suppress_Stack_Entry_Ptr;
+
+ begin
+ Ptr := Top;
+ while Ptr /= null loop
+ if Ptr.Entity = From
+ and then (Ptr.Check = All_Checks or else Ptr.Check = C)
+ then
+ if Ptr.Suppress then
+ Set_Checks_May_Be_Suppressed (To, True);
+ Push_Local_Suppress_Stack_Entry
+ (Entity => To,
+ Check => C,
+ Suppress => True);
+ Found := True;
+ return;
+ end if;
+ end if;
+
+ Ptr := Ptr.Prev;
+ end loop;
+
+ Found := False;
+ return;
+ end Search_Stack;
+
+ -- Start of processing for Copy_Suppress_Status
+
begin
if not Checks_May_Be_Suppressed (From) then
return;
end if;
- -- First search the local entity suppress table, we search this in
+ -- First search the local entity suppress stack, we search this in
-- reverse order so that we get the innermost entry that applies to
-- this case if there are nested entries. Note that for the purpose
-- of this procedure we are ONLY looking for entries corresponding
-- to a two-argument Suppress, where the second argument matches From.
- for J in
- reverse Local_Entity_Suppress.First .. Local_Entity_Suppress.Last
- loop
- declare
- R : Entity_Check_Suppress_Record
- renames Local_Entity_Suppress.Table (J);
+ Search_Stack (Global_Suppress_Stack_Top, Found);
- begin
- if R.Entity = From
- and then (R.Check = All_Checks or else R.Check = C)
- then
- if R.Suppress then
- Set_Checks_May_Be_Suppressed (To, True);
- Local_Entity_Suppress.Append
- ((Entity => To,
- Check => C,
- Suppress => True));
- return;
- end if;
- end if;
- end;
- end loop;
+ if Found then
+ return;
+ end if;
-- Now search the global entity suppress table for a matching entry
-- We also search this in reverse order so that if there are multiple
-- pragmas for the same entity, the last one applies.
- for J in
- reverse Global_Entity_Suppress.First .. Global_Entity_Suppress.Last
- loop
- declare
- R : Entity_Check_Suppress_Record
- renames Global_Entity_Suppress.Table (J);
-
- begin
- if R.Entity = From
- and then (R.Check = All_Checks or else R.Check = C)
- then
- if R.Suppress then
- Set_Checks_May_Be_Suppressed (To, True);
- Local_Entity_Suppress.Append
- ((Entity => To,
- Check => C,
- Suppress => True));
- end if;
- end if;
- end;
- end loop;
+ Search_Stack (Local_Suppress_Stack_Top, Found);
end Copy_Suppress_Status;
-------------------------
@@ -812,29 +822,26 @@ package body Sem is
-----------------------
function Explicit_Suppress (E : Entity_Id; C : Check_Id) return Boolean is
+ Ptr : Suppress_Stack_Entry_Ptr;
+
begin
if not Checks_May_Be_Suppressed (E) then
return False;
else
- for J in
- reverse Global_Entity_Suppress.First .. Global_Entity_Suppress.Last
- loop
- declare
- R : Entity_Check_Suppress_Record
- renames Global_Entity_Suppress.Table (J);
-
- begin
- if R.Entity = E
- and then (R.Check = All_Checks or else R.Check = C)
- then
- return R.Suppress;
- end if;
- end;
- end loop;
+ Ptr := Global_Suppress_Stack_Top;
+ while Ptr /= null loop
+ if Ptr.Entity = E
+ and then (Ptr.Check = All_Checks or else Ptr.Check = C)
+ then
+ return Ptr.Suppress;
+ end if;
- return False;
+ Ptr := Ptr.Prev;
+ end loop;
end if;
+
+ return False;
end Explicit_Suppress;
-----------------------------
@@ -880,9 +887,26 @@ package body Sem is
----------------
procedure Initialize is
+ Next : Suppress_Stack_Entry_Ptr;
+
+ procedure Free is new Unchecked_Deallocation
+ (Suppress_Stack_Entry, Suppress_Stack_Entry_Ptr);
+
begin
- Local_Entity_Suppress.Init;
- Global_Entity_Suppress.Init;
+ -- Free any global suppress stack entries from a previous invocation
+ -- of the compiler (in the normal case this loop does nothing).
+
+ while Suppress_Stack_Entries /= null loop
+ Next := Global_Suppress_Stack_Top.Next;
+ Free (Suppress_Stack_Entries);
+ Suppress_Stack_Entries := Next;
+ end loop;
+
+ Local_Suppress_Stack_Top := null;
+ Global_Suppress_Stack_Top := null;
+
+ -- Clear scope stack, and reset global variables
+
Scope_Stack.Init;
Unloaded_Subunits := False;
end Initialize;
@@ -1136,53 +1160,52 @@ package body Sem is
-------------------------
function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean is
- begin
- -- First search the local entity suppress table, we search this in
- -- reverse order so that we get the innermost entry that applies to
- -- this case if there are nested entries.
- for J in
- reverse Local_Entity_Suppress.First .. Local_Entity_Suppress.Last
- loop
- declare
- R : Entity_Check_Suppress_Record
- renames Local_Entity_Suppress.Table (J);
+ Ptr : Suppress_Stack_Entry_Ptr;
- begin
- if (R.Entity = Empty or else R.Entity = E)
- and then (R.Check = All_Checks or else R.Check = C)
- then
- return R.Suppress;
- end if;
- end;
+ begin
+ -- First search the local entity suppress stack, we search this from the
+ -- top of the stack down, so that we get the innermost entry that
+ -- applies to this case if there are nested entries.
+
+ Ptr := Local_Suppress_Stack_Top;
+ while Ptr /= null loop
+ if (Ptr.Entity = Empty or else Ptr.Entity = E)
+ and then (Ptr.Check = All_Checks or else Ptr.Check = C)
+ then
+ return Ptr.Suppress;
+ end if;
+
+ Ptr := Ptr.Prev;
end loop;
-- Now search the global entity suppress table for a matching entry
- -- We also search this in reverse order so that if there are multiple
+ -- We also search this from the top down so that if there are multiple
-- pragmas for the same entity, the last one applies (not clear what
-- or whether the RM specifies this handling, but it seems reasonable).
- for J in
- reverse Global_Entity_Suppress.First .. Global_Entity_Suppress.Last
- loop
- declare
- R : Entity_Check_Suppress_Record
- renames Global_Entity_Suppress.Table (J);
+ Ptr := Global_Suppress_Stack_Top;
+ while Ptr /= null loop
+ if (Ptr.Entity = Empty or else Ptr.Entity = E)
+ and then (Ptr.Check = All_Checks or else Ptr.Check = C)
+ then
+ return Ptr.Suppress;
+ end if;
- begin
- if R.Entity = E
- and then (R.Check = All_Checks or else R.Check = C)
- then
- return R.Suppress;
- end if;
- end;
+ Ptr := Ptr.Prev;
end loop;
-- If we did not find a matching entry, then use the normal scope
-- suppress value after all (actually this will be the global setting
- -- since it clearly was not overridden at any point)
+ -- since it clearly was not overridden at any point). For a predefined
+ -- check, we test the specific flag. For a user defined check, we check
+ -- the All_Checks flag.
- return Scope_Suppress (C);
+ if C in Predefined_Check_Id then
+ return Scope_Suppress (C);
+ else
+ return Scope_Suppress (All_Checks);
+ end if;
end Is_Check_Suppressed;
----------
@@ -1191,14 +1214,54 @@ package body Sem is
procedure Lock is
begin
- Local_Entity_Suppress.Locked := True;
- Global_Entity_Suppress.Locked := True;
Scope_Stack.Locked := True;
- Local_Entity_Suppress.Release;
- Global_Entity_Suppress.Release;
Scope_Stack.Release;
end Lock;
+ --------------------------------------
+ -- Push_Global_Suppress_Stack_Entry --
+ --------------------------------------
+
+ procedure Push_Global_Suppress_Stack_Entry
+ (Entity : Entity_Id;
+ Check : Check_Id;
+ Suppress : Boolean)
+ is
+ begin
+ Global_Suppress_Stack_Top :=
+ new Suppress_Stack_Entry'
+ (Entity => Entity,
+ Check => Check,
+ Suppress => Suppress,
+ Prev => Global_Suppress_Stack_Top,
+ Next => Suppress_Stack_Entries);
+ Suppress_Stack_Entries := Global_Suppress_Stack_Top;
+ return;
+
+ end Push_Global_Suppress_Stack_Entry;
+
+ -------------------------------------
+ -- Push_Local_Suppress_Stack_Entry --
+ -------------------------------------
+
+ procedure Push_Local_Suppress_Stack_Entry
+ (Entity : Entity_Id;
+ Check : Check_Id;
+ Suppress : Boolean)
+ is
+ begin
+ Local_Suppress_Stack_Top :=
+ new Suppress_Stack_Entry'
+ (Entity => Entity,
+ Check => Check,
+ Suppress => Suppress,
+ Prev => Local_Suppress_Stack_Top,
+ Next => Suppress_Stack_Entries);
+ Suppress_Stack_Entries := Local_Suppress_Stack_Top;
+
+ return;
+ end Push_Local_Suppress_Stack_Entry;
+
---------------
-- Semantics --
---------------