diff options
author | Hristian Kirtchev <kirtchev@adacore.com> | 2018-01-11 08:55:52 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2018-01-11 08:55:52 +0000 |
commit | 5efc1c00c88b7758d628ce8e2d1e6d54d5996216 (patch) | |
tree | ed4741920d80ba135a51595bea4de21ce8080c44 /gcc/ada | |
parent | 4dfba737a48b4a3934eabb93a406facfd148afd5 (diff) | |
download | gcc-5efc1c00c88b7758d628ce8e2d1e6d54d5996216.zip gcc-5efc1c00c88b7758d628ce8e2d1e6d54d5996216.tar.gz gcc-5efc1c00c88b7758d628ce8e2d1e6d54d5996216.tar.bz2 |
[Ada] Detection of illegal constituent assignments
This patch modifies the analysis of assignment statements to detect an illegal
attempt to alter the value of single protected type Part_Of constituent when
inside a protected function.
2018-01-11 Hristian Kirtchev <kirtchev@adacore.com>
gcc/ada/
* sem_ch5.adb (Analyze_Assignment): Assignments to variables that act
as Part_Of consituents of single protected types are illegal when they
take place inside a protected function.
(Diagnose_Non_Variable_Lhs): Use Within_Function to check for an
enclosing function.
(Is_Protected_Part_Of_Constituent): New routine.
(Within_Function): New routine.
gcc/testsuite/
* gnat.dg/protected_func.adb, gnat.dg/protected_func.ads: New testcase.
From-SVN: r256520
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/ada/sem_ch5.adb | 75 |
2 files changed, 80 insertions, 5 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 415a42c..cd66210 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,13 @@ +2018-01-11 Hristian Kirtchev <kirtchev@adacore.com> + + * sem_ch5.adb (Analyze_Assignment): Assignments to variables that act + as Part_Of consituents of single protected types are illegal when they + take place inside a protected function. + (Diagnose_Non_Variable_Lhs): Use Within_Function to check for an + enclosing function. + (Is_Protected_Part_Of_Constituent): New routine. + (Within_Function): New routine. + 2018-01-11 Arnaud Charlet <charlet@adacore.com> Bump copyright notices to 2018. diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb index 6d46d65..b94c9e8 100644 --- a/gcc/ada/sem_ch5.adb +++ b/gcc/ada/sem_ch5.adb @@ -107,6 +107,11 @@ package body Sem_Ch5 is -- N is the node for the left hand side of an assignment, and it is not -- a variable. This routine issues an appropriate diagnostic. + function Is_Protected_Part_Of_Constituent + (Nod : Node_Id) return Boolean; + -- Determine whether arbitrary node Nod denotes a Part_Of constituent of + -- a single protected type. + procedure Kill_Lhs; -- This is called to kill current value settings of a simple variable -- on the left hand side. We call it if we find any error in analyzing @@ -141,6 +146,10 @@ package body Sem_Ch5 is -- assignment statements that are really initializations. These are -- marked No_Ctrl_Actions. + function Within_Function return Boolean; + -- Determine whether the current scope is a function or appears within + -- one. + ------------------------------- -- Diagnose_Non_Variable_Lhs -- ------------------------------- @@ -170,11 +179,7 @@ package body Sem_Ch5 is -- 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)) + elsif (Is_Prival (Ent) and then Within_Function) or else (Ekind (Ent) = E_Component and then Is_Protected_Type (Scope (Ent))) @@ -222,6 +227,39 @@ package body Sem_Ch5 is Error_Msg_N ("left hand side of assignment must be a variable", N); end Diagnose_Non_Variable_Lhs; + -------------------------------------- + -- Is_Protected_Part_Of_Constituent -- + -------------------------------------- + + function Is_Protected_Part_Of_Constituent + (Nod : Node_Id) return Boolean + is + Encap_Id : Entity_Id; + Var_Id : Entity_Id; + + begin + -- Abstract states and variables may act as Part_Of constituents of + -- single protected types, however only variables can be modified by + -- an assignment. + + if Is_Entity_Name (Nod) then + Var_Id := Entity (Nod); + + if Present (Var_Id) and then Ekind (Var_Id) = E_Variable then + Encap_Id := Encapsulating_State (Var_Id); + + -- To qualify, the node must denote a reference to a variable + -- whose encapsulating state is a single protected object. + + return + Present (Encap_Id) + and then Is_Single_Protected_Object (Encap_Id); + end if; + end if; + + return False; + end Is_Protected_Part_Of_Constituent; + -------------- -- Kill_Lhs -- -------------- @@ -386,6 +424,24 @@ package body Sem_Ch5 is Insert_Action (N, Obj_Decl); end Transform_BIP_Assignment; + --------------------- + -- Within_Function -- + --------------------- + + function Within_Function return Boolean is + Scop_Id : constant Entity_Id := Current_Scope; + + begin + if Ekind (Scop_Id) = E_Function then + return True; + + elsif Ekind (Enclosing_Dynamic_Scope (Scop_Id)) = E_Function then + return True; + end if; + + return False; + end Within_Function; + -- Local variables T1 : Entity_Id; @@ -713,6 +769,15 @@ package body Sem_Ch5 is ("target of assignment operation must not be abstract", Lhs); end if; + -- Variables which are Part_Of constituents of single protected types + -- behave in similar fashion to protected components. Such variables + -- cannot be modified by protected functions. + + if Is_Protected_Part_Of_Constituent (Lhs) and then Within_Function then + Error_Msg_N + ("protected function cannot modify protected object", Lhs); + end if; + -- Resolution may have updated the subtype, in case the left-hand side -- is a private protected component. Use the correct subtype to avoid -- scoping issues in the back-end. |