--- sem_attr.adb (revision 130883)
+++ sem_attr.adb (working copy)
@@ -3509,6 +3509,68 @@
("?attribute Old applied to constant has no effect", P);
end if;
+ -- Check that the expression does not refer to local entities
+
+ Check_Local : declare
+ Subp : Entity_Id := Current_Subprogram;
+
+ function Process (N : Node_Id) return Traverse_Result;
+ -- Check that N does not contain references to local variables
+ -- or other local entities of Subp.
+
+ -------------
+ -- Process --
+ -------------
+
+ function Process (N : Node_Id) return Traverse_Result is
+ begin
+ if Is_Entity_Name (N)
+ and then not Is_Formal (Entity (N))
+ and then Enclosing_Subprogram (Entity (N)) = Subp
+ then
+ Error_Msg_Node_1 := Entity (N);
+ Error_Attr
+ ("attribute % cannot refer to local variable&", N);
+ end if;
+
+ return OK;
+ end Process;
+
+ procedure Check_No_Local is new Traverse_Proc;
+
+ -- Start of processing for Check_Local
+
+ begin
+ Check_No_Local (P);
+
+ if In_Parameter_Specification (P) then
+
+ -- We have additional restrictions on using 'Old in parameter
+ -- specifications.
+
+ if Present (Enclosing_Subprogram (Current_Subprogram)) then
+
+ -- Check that there is no reference to the enclosing
+ -- subprogram local variables. Otherwise, we might end
+ -- up being called from the enclosing subprogram and thus
+ -- using 'Old on a local variable which is not defined
+ -- at entry time.
+
+ Subp := Enclosing_Subprogram (Current_Subprogram);
+ Check_No_Local (P);
+
+ else
+ -- We must prevent default expression of library-level
+ -- subprogram from using 'Old, as the subprogram may be
+ -- used in elaboration code for which there is no enclosing
+ -- subprogram.
+
+ Error_Attr
+ ("attribute % can only appear within subprogram", N);
+ end if;
+ end if;
+ end Check_Local;
+
------------
-- Output --
------------
--- sem_util.adb (revision 130946)
+++ sem_util.adb (working copy)
@@ -5029,6 +5029,26 @@
return False;
end In_Package_Body;
+ --------------------------------
+ -- In_Parameter_Specification --
+ --------------------------------
+
+ function In_Parameter_Specification (N : Node_Id) return Boolean is
+ PN : Node_Id;
+
+ begin
+ PN := Parent (N);
+ while Present (PN) loop
+ if Nkind (PN) = N_Parameter_Specification then
+ return True;
+ end if;
+
+ PN := Parent (PN);
+ end loop;
+
+ return False;
+ end In_Parameter_Specification;
+
--------------------------------------
-- In_Subprogram_Or_Concurrent_Unit --
--------------------------------------