-- and Decl is the enclosing synchronized type declaration at whose
-- freeze point the generated body is analyzed.
+ function Build_Renamed_Formal_Declaration
+ (New_F : Entity_Id;
+ Formal : Entity_Id;
+ Comp : Entity_Id;
+ Renamed_Formal : Node_Id) return Node_Id;
+ -- Create a renaming declaration for a formal, within a protected entry
+ -- body or an accept body. The renamed object is a component of the
+ -- parameter block that is a parameter in the entry call.
+
+ -- In Ada2012, If the formal is an incomplete tagged type, the renaming
+ -- does not dereference the corresponding component to prevent an illegal
+ -- use of the incomplete type (AI05-0151).
+
procedure Build_Wrapper_Bodies
(Loc : Source_Ptr;
Typ : Entity_Id;
-- The name of the formal that holds the address of the parameter block
-- for the call.
- Comp : Entity_Id;
- Decl : Node_Id;
- Formal : Entity_Id;
- New_F : Entity_Id;
+ Comp : Entity_Id;
+ Decl : Node_Id;
+ Formal : Entity_Id;
+ New_F : Entity_Id;
+ Renamed_Formal : Node_Id;
begin
Formal := First_Formal (Ent);
Set_Actual_Subtype (New_F, Actual_Subtype (Formal));
+ Renamed_Formal :=
+ Make_Selected_Component (Loc,
+ Prefix =>
+ Unchecked_Convert_To (Entry_Parameters_Type (Ent),
+ Make_Identifier (Loc, Chars (Ptr))),
+ Selector_Name => New_Reference_To (Comp, Loc));
+
Decl :=
- Make_Object_Renaming_Declaration (Loc,
- Defining_Identifier => New_F,
- Subtype_Mark =>
- New_Reference_To (Etype (Formal), Loc),
- Name =>
- Make_Explicit_Dereference (Loc,
- Make_Selected_Component (Loc,
- Prefix =>
- Unchecked_Convert_To (Entry_Parameters_Type (Ent),
- Make_Identifier (Loc, Chars (Ptr))),
- Selector_Name => New_Reference_To (Comp, Loc))));
+ Build_Renamed_Formal_Declaration
+ (New_F, Formal, Comp, Renamed_Formal);
Append (Decl, Decls);
Set_Renamed_Object (Formal, New_F);
return Rec_Nam;
end Build_Parameter_Block;
+ --------------------------------------
+ -- Build_Renamed_Formal_Declaration --
+ --------------------------------------
+
+ function Build_Renamed_Formal_Declaration
+ (New_F : Entity_Id;
+ Formal : Entity_Id;
+ Comp : Entity_Id;
+ Renamed_Formal : Node_Id) return Node_Id
+ is
+ Loc : constant Source_Ptr := Sloc (New_F);
+ Decl : Node_Id;
+
+ begin
+ -- If the formal is a tagged incomplete type, it is already passed
+ -- by reference, so it is sufficient to rename the pointer component
+ -- that corresponds to the actual. Otherwise we need to dereference
+ -- the pointer component to obtain the actual.
+
+ if Is_Incomplete_Type (Etype (Formal))
+ and then Is_Tagged_Type (Etype (Formal))
+ then
+ Decl :=
+ Make_Object_Renaming_Declaration (Loc,
+ Defining_Identifier => New_F,
+ Subtype_Mark => New_Reference_To (Etype (Comp), Loc),
+ Name => Renamed_Formal);
+
+ else
+ Decl :=
+ Make_Object_Renaming_Declaration (Loc,
+ Defining_Identifier => New_F,
+ Subtype_Mark => New_Reference_To (Etype (Formal), Loc),
+ Name =>
+ Make_Explicit_Dereference (Loc, Renamed_Formal));
+ end if;
+
+ return Decl;
+ end Build_Renamed_Formal_Declaration;
+
-----------------------
-- Build_PPC_Wrapper --
-----------------------
and then Present (Handled_Statement_Sequence (N))
then
declare
- Comp : Entity_Id;
- Decl : Node_Id;
- Formal : Entity_Id;
- New_F : Entity_Id;
+ Comp : Entity_Id;
+ Decl : Node_Id;
+ Formal : Entity_Id;
+ New_F : Entity_Id;
+ Renamed_Formal : Node_Id;
begin
Push_Scope (Ent);
Set_Actual_Subtype (New_F, Actual_Subtype (Formal));
+ Renamed_Formal :=
+ Make_Selected_Component (Loc,
+ Prefix =>
+ Unchecked_Convert_To (
+ Entry_Parameters_Type (Ent),
+ New_Reference_To (Ann, Loc)),
+ Selector_Name =>
+ New_Reference_To (Comp, Loc));
+
Decl :=
- Make_Object_Renaming_Declaration (Loc,
- Defining_Identifier =>
- New_F,
- Subtype_Mark =>
- New_Reference_To (Etype (Formal), Loc),
- Name =>
- Make_Explicit_Dereference (Loc,
- Make_Selected_Component (Loc,
- Prefix =>
- Unchecked_Convert_To (
- Entry_Parameters_Type (Ent),
- New_Reference_To (Ann, Loc)),
- Selector_Name =>
- New_Reference_To (Comp, Loc))));
+ Build_Renamed_Formal_Declaration
+ (New_F, Formal, Comp, Renamed_Formal);
if No (Declarations (N)) then
Set_Declarations (N, New_List);