---------
when Attribute_Old => Old : declare
- CW_Temp : Entity_Id;
- CW_Typ : Entity_Id;
- Decl : Node_Id;
- Ins_Nod : Node_Id;
- Temp : Entity_Id;
+ CW_Temp : Entity_Id;
+ CW_Typ : Entity_Id;
+ Decl : Node_Id;
+ Ins_Nod : Node_Id;
+ Temp : Entity_Id;
use Old_Attr_Util.Conditional_Evaluation;
use Old_Attr_Util.Indirect_Temps;
+
+ Cond_Eval : constant Boolean :=
+ Eligible_For_Conditional_Evaluation (N);
+
begin
-- 'Old can only appear in the case where local contract-related
-- wrapper has been generated with the purpose of wrapping the
Ins_Nod := Last (Declarations (Ins_Nod));
- if Eligible_For_Conditional_Evaluation (N) then
+ -- The code that builds declarations for always evaluated 'Old
+ -- constants doesn't handle the anonymous access type case correctly.
+ -- Indirect temporaries do, so we avoid that problem by going through
+ -- the same code as for conditionally evaluated constants.
+
+ if Cond_Eval or else Is_Anonymous_Access_Type (Etype (N)) then
declare
Eval_Stmts : constant List_Id := New_List;
Declare_Indirect_Temporary
(Attr_Prefix => Pref, Indirect_Temp => Temp);
- Insert_After_And_Analyze (
- Ins_Nod,
- Make_If_Statement
- (Sloc => Loc,
- Condition => Conditional_Evaluation_Condition (N),
- Then_Statements => Eval_Stmts));
+ -- Prefixes with anonymous access type might be unconditionally
+ -- evaluated.
+
+ if Cond_Eval then
+ Insert_After_And_Analyze (
+ Ins_Nod,
+ Make_If_Statement
+ (Sloc => Loc,
+ Condition => Conditional_Evaluation_Condition (N),
+ Then_Statements => Eval_Stmts));
+ else
+ Insert_List_After_And_Analyze (Ins_Nod, Eval_Stmts);
+ end if;
Rewrite (N, Indirect_Temp_Value
(Temp => Temp,
Result : Node_Id :=
New_Occurrence_Of (Standard_True, Loc);
begin
- pragma Assert (Determiners'Length > 0 or else
- Is_Anonymous_Access_Type (Etype (Expr)));
+ pragma Assert (Determiners'Length > 0);
for I in Determiners'Range loop
Result := Make_And_Then
(Expr : Node_Id) return Boolean
is
begin
- if Is_Anonymous_Access_Type (Etype (Expr)) then
- -- The code in exp_attr.adb that also builds declarations
- -- for 'Old constants doesn't handle the anonymous access
- -- type case correctly, so we avoid that problem by
- -- returning True here.
- return True;
-
- elsif Ada_Version < Ada_2022 then
+ if Ada_Version < Ada_2022 then
return False;
elsif Inside_Class_Condition_Preanalysis then
-- - its determining expressions are all known on entry; and
-- - Ada_Version >= Ada_2022.
-- See RM 6.1.1 for definitions of these terms.
- --
- -- Also returns True if Expr is of an anonymous access type;
- -- this is just because we want the code that knows how to build
- -- 'Old temps in that case to reside in only one place.
function Conditional_Evaluation_Condition
(Expr : Node_Id) return Node_Id;