-- We analyze by hand the new internal allocator to avoid any
-- recursion and inappropriate call to Initialize.
- -- We don't want to remove side effects when the expression must be
- -- built in place and we don't need it when there is no storage pool
- -- or this is a return/secondary stack allocation.
-
- if not Aggr_In_Place
- and then not Delayed_Cond_Expr
- and then Present (Storage_Pool (N))
- and then not Is_RTE (Storage_Pool (N), RE_RS_Pool)
- and then not Is_RTE (Storage_Pool (N), RE_SS_Pool)
- then
- Remove_Side_Effects (Exp);
- end if;
-
Temp := Make_Temporary (Loc, 'P', N);
-- For a class wide allocation generate the following code:
Displace_Allocator_Pointer (N);
end if;
+ -- Case of aggregate built in place
+
elsif Aggr_In_Place then
Temp := Make_Temporary (Loc, 'P', N);
Build_Aggregate_In_Place (Temp, PtrT);
Analyze_And_Resolve (N, PtrT);
Apply_Predicate_Check (N, T, Deref => True);
- elsif Is_Access_Type (T) and then Can_Never_Be_Null (T) then
- Install_Null_Excluding_Check (Exp);
+ -- Default case
- elsif Is_Access_Type (DesigT)
- and then Nkind (Exp) = N_Allocator
- and then Nkind (Expression (Exp)) /= N_Qualified_Expression
- then
- -- Apply constraint to designated subtype indication
+ else
+ if Is_Access_Type (T) and then Can_Never_Be_Null (T) then
+ Install_Null_Excluding_Check (Exp);
+ end if;
- Apply_Constraint_Check
- (Expression (Exp), Designated_Type (DesigT), No_Sliding => True);
+ if Is_Access_Type (DesigT)
+ and then Nkind (Exp) = N_Allocator
+ and then Nkind (Expression (Exp)) /= N_Qualified_Expression
+ then
+ -- Apply constraint to designated subtype indication
- if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
+ Apply_Constraint_Check
+ (Expression (Exp), Designated_Type (DesigT), No_Sliding => True);
- -- Propagate constraint_error to enclosing allocator
+ -- Propagate Constraint_Error to enclosing allocator
- Rewrite (Exp, New_Copy (Expression (Exp)));
+ if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
+ Rewrite (Exp, New_Copy (Expression (Exp)));
+ end if;
end if;
- else
Build_Allocate_Deallocate_Proc (N);
-- For an access-to-unconstrained-packed-array type, build an
Unchecked_Convert_To (RTE (RE_Storage_Offset),
Make_Attribute_Reference (Loc,
Prefix =>
- (if No (Alloc_Expr) then
- Make_Explicit_Dereference (Loc, Relocate_Node (Expr))
+ (if Is_Allocate then
+ Duplicate_Subexpr_No_Checks (Expression (Alloc_Expr))
else
- Relocate_Node (Expression (Alloc_Expr))),
+ Make_Explicit_Dereference (Loc,
+ Duplicate_Subexpr_No_Checks (Expr))),
Attribute_Name => Name_Alignment)));
end if;
Flag_Expr : Node_Id;
Param : Node_Id;
- Pref : Node_Id;
Temp : Node_Id;
begin
if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
Param :=
Make_Explicit_Dereference (Loc,
- Prefix => Relocate_Node (Temp));
+ Prefix => Duplicate_Subexpr_No_Checks (Temp));
-- In the default case, obtain the tag of the object about
-- to be allocated / deallocated. Generate:
-- in the code that follows.
else
- Pref := Temp;
-
- if Nkind (Parent (Pref)) = N_Unchecked_Type_Conversion
+ if Nkind (Parent (Temp)) = N_Unchecked_Type_Conversion
then
- Pref := Parent (Pref);
+ Temp := Parent (Temp);
end if;
Param :=
Make_Attribute_Reference (Loc,
- Prefix => Relocate_Node (Pref),
+ Prefix => Duplicate_Subexpr_No_Checks (Temp),
Attribute_Name => Name_Tag);
end if;