aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch5.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch5.adb')
-rw-r--r--gcc/ada/sem_ch5.adb122
1 files changed, 82 insertions, 40 deletions
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 3f39aca..c569a28 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2008, 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- --
@@ -118,31 +118,40 @@ package body Sem_Ch5 is
-- Some special bad cases of entity names
elsif Is_Entity_Name (N) then
- if Ekind (Entity (N)) = E_In_Parameter then
- Error_Msg_N
- ("assignment to IN mode parameter not allowed", N);
-
- -- Private declarations in a protected object are turned into
- -- constants when compiling a protected function.
+ declare
+ Ent : constant Entity_Id := Entity (N);
- elsif Present (Scope (Entity (N)))
- and then Is_Protected_Type (Scope (Entity (N)))
- and then
- (Ekind (Current_Scope) = E_Function
- or else
- Ekind (Enclosing_Dynamic_Scope (Current_Scope)) = E_Function)
- then
- Error_Msg_N
- ("protected function cannot modify protected object", N);
+ begin
+ if Ekind (Ent) = E_In_Parameter then
+ Error_Msg_N
+ ("assignment to IN mode parameter not allowed", N);
+
+ -- Renamings of protected private components are turned into
+ -- constants when compiling a protected function. In the case
+ -- of single protected types, the private component appears
+ -- directly.
+
+ elsif (Is_Prival (Ent)
+ and then
+ (Ekind (Current_Scope) = E_Function
+ or else Ekind (Enclosing_Dynamic_Scope (
+ Current_Scope)) = E_Function))
+ or else
+ (Ekind (Ent) = E_Component
+ and then Is_Protected_Type (Scope (Ent)))
+ then
+ Error_Msg_N
+ ("protected function cannot modify protected object", N);
- elsif Ekind (Entity (N)) = E_Loop_Parameter then
- Error_Msg_N
- ("assignment to loop parameter not allowed", N);
+ elsif Ekind (Ent) = E_Loop_Parameter then
+ Error_Msg_N
+ ("assignment to loop parameter not allowed", N);
- else
- Error_Msg_N
- ("left hand side of assignment must be a variable", N);
- end if;
+ else
+ Error_Msg_N
+ ("left hand side of assignment must be a variable", N);
+ end if;
+ end;
-- For indexed components or selected components, test prefix
@@ -430,6 +439,15 @@ package body Sem_Ch5 is
("left hand of assignment must not be limited type", Lhs);
Explain_Limited_Type (T1, Lhs);
return;
+
+ -- Enforce RM 3.9.3 (8): left-hand side cannot be abstract
+
+ elsif Is_Interface (T1)
+ and then not Is_Class_Wide_Type (T1)
+ then
+ Error_Msg_N
+ ("target of assignment operation may not be abstract", Lhs);
+ return;
end if;
-- Resolution may have updated the subtype, in case the left-hand
@@ -469,6 +487,7 @@ package body Sem_Ch5 is
-- This is the point at which we check for an unset reference
Check_Unset_Reference (Rhs);
+ Check_Unprotected_Access (Lhs, Rhs);
-- Remaining steps are skipped if Rhs was syntactically in error
@@ -588,7 +607,7 @@ package body Sem_Ch5 is
-- We still mark this as a possible modification, that's necessary
-- to reset Is_True_Constant, and desirable for xref purposes.
- Note_Possible_Modification (Lhs);
+ Note_Possible_Modification (Lhs, Sure => True);
return;
-- If we know the right hand side is non-null, then we convert to the
@@ -635,7 +654,7 @@ package body Sem_Ch5 is
-- Note: modifications of the Lhs may only be recorded after
-- checks have been applied.
- Note_Possible_Modification (Lhs);
+ Note_Possible_Modification (Lhs, Sure => True);
-- ??? a real accessibility check is needed when ???
@@ -1901,20 +1920,36 @@ package body Sem_Ch5 is
Analyze (Id);
Ent := Entity (Id);
- Generate_Reference (Ent, Loop_Statement, ' ');
- Generate_Definition (Ent);
- -- If we found a label, mark its type. If not, ignore it, since it
- -- means we have a conflicting declaration, which would already have
- -- been diagnosed at declaration time. Set Label_Construct of the
- -- implicit label declaration, which is not created by the parser
- -- for generic units.
+ -- Guard against serious error (typically, a scope mismatch when
+ -- semantic analysis is requested) by creating loop entity to
+ -- continue analysis.
- if Ekind (Ent) = E_Label then
- Set_Ekind (Ent, E_Loop);
+ if No (Ent) then
+ if Total_Errors_Detected /= 0 then
+ Ent :=
+ New_Internal_Entity
+ (E_Loop, Current_Scope, Sloc (Loop_Statement), 'L');
+ else
+ raise Program_Error;
+ end if;
+
+ else
+ Generate_Reference (Ent, Loop_Statement, ' ');
+ Generate_Definition (Ent);
- if Nkind (Parent (Ent)) = N_Implicit_Label_Declaration then
- Set_Label_Construct (Parent (Ent), Loop_Statement);
+ -- If we found a label, mark its type. If not, ignore it, since it
+ -- means we have a conflicting declaration, which would already
+ -- have been diagnosed at declaration time. Set Label_Construct
+ -- of the implicit label declaration, which is not created by the
+ -- parser for generic units.
+
+ if Ekind (Ent) = E_Label then
+ Set_Ekind (Ent, E_Loop);
+
+ if Nkind (Parent (Ent)) = N_Implicit_Label_Declaration then
+ Set_Label_Construct (Parent (Ent), Loop_Statement);
+ end if;
end if;
end if;
@@ -1928,10 +1963,10 @@ package body Sem_Ch5 is
Set_Parent (Ent, Loop_Statement);
end if;
- -- Kill current values on entry to loop, since statements in body
- -- of loop may have been executed before the loop is entered.
- -- Similarly we kill values after the loop, since we do not know
- -- that the body of the loop was executed.
+ -- Kill current values on entry to loop, since statements in body of
+ -- loop may have been executed before the loop is entered. Similarly we
+ -- kill values after the loop, since we do not know that the body of the
+ -- loop was executed.
Kill_Current_Values;
Push_Scope (Ent);
@@ -1941,6 +1976,13 @@ package body Sem_Ch5 is
End_Scope;
Kill_Current_Values;
Check_Infinite_Loop_Warning (N);
+
+ -- Code after loop is unreachable if the loop has no WHILE or FOR
+ -- and contains no EXIT statements within the body of the loop.
+
+ if No (Iter) and then not Has_Exit (Ent) then
+ Check_Unreachable_Code (N);
+ end if;
end Analyze_Loop_Statement;
----------------------------