summaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch9.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch9.adb')
-rw-r--r--gcc/ada/sem_ch9.adb137
1 files changed, 107 insertions, 30 deletions
diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index ced4d51640d..58a27c93256 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -23,7 +23,6 @@
-- --
------------------------------------------------------------------------------
-with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
@@ -263,16 +262,41 @@ package body Sem_Ch9 is
begin
-- Function calls and attribute references must be static
- if Nkind_In (N, N_Attribute_Reference, N_Function_Call)
+ if Nkind (N) = N_Attribute_Reference
and then not Is_Static_Expression (N)
then
+ if Complain then
+ Error_Msg_N
+ ("non-static attribute reference not allowed",
+ N);
+ end if;
+
+ return Abandon;
+
+ elsif Nkind (N) = N_Function_Call
+ and then not Is_Static_Expression (N)
+ then
+ if Complain then
+ Error_Msg_N ("non-static function call not allowed",
+ N);
+ end if;
+
return Abandon;
-- Loop statements and procedure calls are prohibited
- elsif Nkind_In (N, N_Loop_Statement,
- N_Procedure_Call_Statement)
- then
+ elsif Nkind (N) = N_Loop_Statement then
+ if Complain then
+ Error_Msg_N ("loop not allowed", N);
+ end if;
+
+ return Abandon;
+
+ elsif Nkind (N) = N_Procedure_Call_Statement then
+ if Complain then
+ Error_Msg_N ("procedure call not allowed", N);
+ end if;
+
return Abandon;
-- References
@@ -295,6 +319,12 @@ package body Sem_Ch9 is
and then not Scope_Within_Or_Same (Scope (Id),
Protected_Body_Subprogram (Sub_Id))
then
+ if Complain then
+ Error_Msg_NE
+ ("reference to global variable& not allowed",
+ N, Id);
+ end if;
+
return Abandon;
-- Prohibit non-scalar out parameters (scalar
@@ -305,6 +335,12 @@ package body Sem_Ch9 is
and then not Is_Elementary_Type (Etype (Id))
and then Scope_Within_Or_Same (Scope (Id), Sub_Id)
then
+ if Complain then
+ Error_Msg_NE
+ ("non-elementary out parameter& not allowed",
+ N, Id);
+ end if;
+
return Abandon;
-- A protected subprogram may reference only one
@@ -327,6 +363,13 @@ package body Sem_Ch9 is
-- body.
elsif Comp /= Id then
+ if Complain then
+ Error_Msg_N
+ ("only one protected component " &
+ "allowed",
+ N);
+ end if;
+
return Abandon;
end if;
end if;
@@ -352,6 +395,13 @@ package body Sem_Ch9 is
-- body.
elsif Comp /= Prival_Link (Id) then
+ if Complain then
+ Error_Msg_N
+ ("only one protected component " &
+ "allowed",
+ N);
+ end if;
+
return Abandon;
end if;
end if;
@@ -1375,7 +1425,6 @@ package body Sem_Ch9 is
procedure Analyze_Protected_Body (N : Node_Id) is
Body_Id : constant Entity_Id := Defining_Identifier (N);
- Aspect : Node_Id;
Last_E : Entity_Id;
Spec_Id : Entity_Id;
@@ -1390,6 +1439,50 @@ package body Sem_Ch9 is
-- differs from Spec_Id in the case of a single protected object, since
-- Spec_Id is set to the protected type in this case).
+ function Lock_Free_Disabled return Boolean;
+ -- This routine returns False if the protected object has a Lock_Free
+ -- aspect specification or a Lock_Free pragma that turns off the
+ -- lock-free implementation (e.g. whose expression is False).
+
+ ------------------------
+ -- Lock_Free_Disabled --
+ ------------------------
+
+ function Lock_Free_Disabled return Boolean is
+ Ritem : constant Node_Id :=
+ Get_Rep_Item
+ (Spec_Id, Name_Lock_Free, Check_Parents => False);
+
+ begin
+ if Present (Ritem) then
+ -- Pragma with one argument
+
+ if Nkind (Ritem) = N_Pragma
+ and then Present (Pragma_Argument_Associations (Ritem))
+ then
+ return
+ Is_False (Static_Boolean
+ (Expression (First (Pragma_Argument_Associations (Ritem)))));
+
+ -- Aspect Specification with expression present
+
+ elsif Nkind (Ritem) = N_Aspect_Specification
+ and then Present (Expression (Ritem))
+ then
+ return Is_False (Static_Boolean (Expression (Ritem)));
+
+ -- Otherwise, return False
+
+ else
+ return False;
+ end if;
+ end if;
+
+ return False;
+ end Lock_Free_Disabled;
+
+ -- Start of processing for Analyze_Protected_Body
+
begin
Tasking_Used := True;
Set_Ekind (Body_Id, E_Protected_Body);
@@ -1450,37 +1543,21 @@ package body Sem_Ch9 is
Process_End_Label (N, 't', Ref_Id);
End_Scope;
- -- Turn on/off the lock-free implementation for the protected object
-
- -- Look for a Lock_Free aspect with a False expression that disables the
- -- lock-free implementation.
-
- Aspect := First (Aspect_Specifications (Parent (Spec_Id)));
-
- while Present (Aspect) loop
- if Get_Aspect_Id (Chars (Identifier (Aspect))) = Aspect_Lock_Free
- and then Present (Expression (Aspect))
- and then Entity (Expression (Aspect)) = Standard_False
- then
- return;
- end if;
-
- Next (Aspect);
- end loop;
-
- -- When a Lock_Free aspect forces the lock-free implementation, verify
- -- the protected body meets all the restrictions, otherwise
- -- Allows_Lock_Free_Implementation issues an error message.
+ -- When a Lock_Free aspect specification/pragma forces the lock-free
+ -- implementation, verify the protected body meets all the restrictions,
+ -- otherwise Allows_Lock_Free_Implementation issues an error message.
if Uses_Lock_Free (Spec_Id) then
if not Allows_Lock_Free_Implementation (N, Complain => True) then
return;
end if;
- -- In other cases, check both the protected declaration and body satisfy
- -- the lock-free restrictions.
+ -- In other cases, if there is no aspect specification/pragma that
+ -- disables the lock-free implementation, check both the protected
+ -- declaration and body satisfy the lock-free restrictions.
- elsif Allows_Lock_Free_Implementation (Parent (Spec_Id))
+ elsif not Lock_Free_Disabled
+ and then Allows_Lock_Free_Implementation (Parent (Spec_Id))
and then Allows_Lock_Free_Implementation (N)
then
Set_Uses_Lock_Free (Spec_Id);