This patch extends the functionality of routine Is_Variable to avoid duplicating part of its code in routine Side_Effect_Free.
No functionality change. Tested on x86_64-pc-linux-gnu, committed on trunk 2011-08-02 Javier Miranda <mira...@adacore.com> * sem_util.ads, sem_util.adb (Is_Variable): Add a new formal to determine if the analysis is performed using N or Original_Node (N). * exp_util.adb (Side_Effect_Free): Code cleanup since the new functionality of routine Is_Variable avoids code duplication. * checks.adb (Determine_Range): Handle temporaries generated by Remove_Side_Effects.
Index: exp_util.adb =================================================================== --- exp_util.adb (revision 177129) +++ exp_util.adb (working copy) @@ -4692,32 +4692,12 @@ if Is_Entity_Name (N) then - -- If the entity is a constant, it is definitely side effect free. - -- Note that the test of Is_Variable (N) below might be expected - -- to catch this case, but it does not, because this test goes to - -- the original tree, and we may have already rewritten a variable - -- node with a constant as a result of an earlier Force_Evaluation - -- call. - - if Ekind_In (Entity (N), E_Constant, E_In_Parameter) then - return True; - - -- Functions are not side effect free - - elsif Ekind (Entity (N)) = E_Function then - return False; - -- Variables are considered to be a side effect if Variable_Ref -- is set or if we have a volatile reference and Name_Req is off. -- If Name_Req is True then we can't help returning a name which -- effectively allows multiple references in any case. - -- Need comment for Is_True_Constant test below ??? - - elsif Is_Variable (N) - or else (Ekind (Entity (N)) = E_Variable - and then not Is_True_Constant (Entity (N))) - then + if Is_Variable (N, Use_Original_Node => False) then return not Variable_Ref and then (not Is_Volatile_Reference (N) or else Name_Req); Index: checks.adb =================================================================== --- checks.adb (revision 177053) +++ checks.adb (working copy) @@ -3087,6 +3087,20 @@ -- Start of processing for Determine_Range begin + -- For temporary constants internally generated to remove side effects + -- we must use the corresponding expression to determine the range of + -- the expression. + + if Is_Entity_Name (N) + and then Nkind (Parent (Entity (N))) = N_Object_Declaration + and then Ekind (Entity (N)) = E_Constant + and then Is_Internal_Name (Chars (Entity (N))) + then + Determine_Range + (Expression (Parent (Entity (N))), OK, Lo, Hi, Assume_Valid); + return; + end if; + -- Prevent junk warnings by initializing range variables Lo := No_Uint; Index: sem_util.adb =================================================================== --- sem_util.adb (revision 177127) +++ sem_util.adb (working copy) @@ -7508,15 +7508,12 @@ -- Is_Variable -- ----------------- - function Is_Variable (N : Node_Id) return Boolean is + function Is_Variable + (N : Node_Id; + Use_Original_Node : Boolean := True) return Boolean + is + Orig_Node : Node_Id; - Orig_Node : constant Node_Id := Original_Node (N); - -- We do the test on the original node, since this is basically a test - -- of syntactic categories, so it must not be disturbed by whatever - -- rewriting might have occurred. For example, an aggregate, which is - -- certainly NOT a variable, could be turned into a variable by - -- expansion. - function In_Protected_Function (E : Entity_Id) return Boolean; -- Within a protected function, the private components of the enclosing -- protected type are constants. A function nested within a (protected) @@ -7580,6 +7577,18 @@ -- Start of processing for Is_Variable begin + -- Check if we perform the test on the original node since this may be a + -- test of syntactic categories which must not be disturbed by whatever + -- rewriting might have occurred. For example, an aggregate, which is + -- certainly NOT a variable, could be turned into a variable by + -- expansion. + + if Use_Original_Node then + Orig_Node := Original_Node (N); + else + Orig_Node := N; + end if; + -- Definitely OK if Assignment_OK is set. Since this is something that -- only gets set for expanded nodes, the test is on N, not Orig_Node. Index: sem_util.ads =================================================================== --- sem_util.ads (revision 177127) +++ sem_util.ads (working copy) @@ -866,13 +866,18 @@ -- object used to represent access-to-subprogram types. This is only -- relevant to CIL, will always return false for other targets. - function Is_Variable (N : Node_Id) return Boolean; + function Is_Variable + (N : Node_Id; + Use_Original_Node : Boolean := True) return Boolean; -- Determines if the tree referenced by N represents a variable, i.e. can -- appear on the left side of an assignment. There is one situation (formal -- parameters) in which non-tagged type conversions are also considered -- variables, but Is_Variable returns False for such cases, since it has -- no knowledge of the context. Note that this is the point at which -- Assignment_OK is checked, and True is returned for any tree thus marked. + -- Use_Original_Node is used to perform the test on Original_Node (N). By + -- default is True since this routine is commonly invoked as part of the + -- semantic analysis and it must not be disturbed by the rewriten nodes. function Is_Visibly_Controlled (T : Entity_Id) return Boolean; -- Check whether T is derived from a visibly controlled type. This is true