summaryrefslogtreecommitdiffstats
path: root/gcc/ada/exp_ch6.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_ch6.adb')
-rw-r--r--gcc/ada/exp_ch6.adb147
1 files changed, 84 insertions, 63 deletions
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 1bfb5c1c86d..c9d59c22d49 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -1626,9 +1626,8 @@ package body Exp_Ch6 is
Get_Remotely_Callable
(Duplicate_Subexpr_Move_Checks (Actual))),
Then_Statements => New_List (
- Make_Procedure_Call_Statement (Loc,
- New_Occurrence_Of (RTE
- (RE_Raise_Program_Error_For_E_4_18), Loc)))));
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Illegal_RACW_E_4_18))));
end if;
Next_Actual (Actual);
@@ -2459,18 +2458,19 @@ package body Exp_Ch6 is
declare
Original_Assignment : constant Node_Id := Parent (N);
- Saved_Assignment : constant Node_Id :=
- Relocate_Node (Original_Assignment);
- pragma Warnings (Off, Saved_Assignment);
+
+ begin
-- Preserve the original assignment node to keep the
-- complete assignment subtree consistent enough for
- -- Analyze_Assignment to proceed. We do not use the
- -- saved value, the point was just to do the relocation.
+ -- Analyze_Assignment to proceed (specifically, the
+ -- original Lhs node must still have an assignment
+ -- statement as its parent).
+
-- We cannot rely on Original_Node to go back from the
-- block node to the assignment node, because the
-- assignment might already be a rewrite substitution.
- begin
+ Discard_Node (Relocate_Node (Original_Assignment));
Rewrite (Original_Assignment, Blk);
end;
@@ -2766,11 +2766,16 @@ package body Exp_Ch6 is
----------------------------
procedure Expand_N_Function_Call (N : Node_Id) is
- Typ : constant Entity_Id := Etype (N);
+ Typ : constant Entity_Id := Etype (N);
function Returned_By_Reference return Boolean;
-- If the return type is returned through the secondary stack. that is
-- by reference, we don't want to create a temp to force stack checking.
+ -- Shouldn't this function be moved to exp_util???
+
+ ---------------------------
+ -- Returned_By_Reference --
+ ---------------------------
function Returned_By_Reference return Boolean is
S : Entity_Id := Current_Scope;
@@ -2816,68 +2821,84 @@ package body Exp_Ch6 is
or else Expression (Parent (N)) /= N)
and then not Returned_By_Reference
then
- -- Note: it might be thought that it would be OK to use a call to
- -- Force_Evaluation here, but that's not good enough, because that
- -- results in a 'Reference construct that may still need a temporary.
+ if Stack_Checking_Enabled then
- declare
- Loc : constant Source_Ptr := Sloc (N);
- Temp_Obj : constant Entity_Id :=
- Make_Defining_Identifier (Loc,
- Chars => New_Internal_Name ('F'));
- Temp_Typ : Entity_Id := Typ;
- Decl : Node_Id;
- A : Node_Id;
- F : Entity_Id;
- Proc : Entity_Id;
+ -- Note: it might be thought that it would be OK to use a call
+ -- to Force_Evaluation here, but that's not good enough, because
+ -- that can results in a 'Reference construct that may still
+ -- need a temporary.
- begin
- if Is_Tagged_Type (Typ)
- and then Present (Controlling_Argument (N))
- then
- if Nkind (Parent (N)) /= N_Procedure_Call_Statement
- and then Nkind (Parent (N)) /= N_Function_Call
+ declare
+ Loc : constant Source_Ptr := Sloc (N);
+ Temp_Obj : constant Entity_Id :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_Internal_Name ('F'));
+ Temp_Typ : Entity_Id := Typ;
+ Decl : Node_Id;
+ A : Node_Id;
+ F : Entity_Id;
+ Proc : Entity_Id;
+
+ begin
+ if Is_Tagged_Type (Typ)
+ and then Present (Controlling_Argument (N))
then
- -- If this is a tag-indeterminate call, the object must
- -- be classwide.
+ if Nkind (Parent (N)) /= N_Procedure_Call_Statement
+ and then Nkind (Parent (N)) /= N_Function_Call
+ then
+ -- If this is a tag-indeterminate call, the object must
+ -- be classwide.
- if Is_Tag_Indeterminate (N) then
- Temp_Typ := Class_Wide_Type (Typ);
- end if;
+ if Is_Tag_Indeterminate (N) then
+ Temp_Typ := Class_Wide_Type (Typ);
+ end if;
- else
- -- If this is a dispatching call that is itself the
- -- controlling argument of an enclosing call, the nominal
- -- subtype of the object that replaces it must be classwide,
- -- so that dispatching will take place properly. If it is
- -- not a controlling argument, the object is not classwide.
-
- Proc := Entity (Name (Parent (N)));
- F := First_Formal (Proc);
- A := First_Actual (Parent (N));
-
- while A /= N loop
- Next_Formal (F);
- Next_Actual (A);
- end loop;
+ else
+ -- If this is a dispatching call that is itself the
+ -- controlling argument of an enclosing call, the
+ -- nominal subtype of the object that replaces it must
+ -- be classwide, so that dispatching will take place
+ -- properly. If it is not a controlling argument, the
+ -- object is not classwide.
+
+ Proc := Entity (Name (Parent (N)));
+ F := First_Formal (Proc);
+ A := First_Actual (Parent (N));
+
+ while A /= N loop
+ Next_Formal (F);
+ Next_Actual (A);
+ end loop;
- if Is_Controlling_Formal (F) then
- Temp_Typ := Class_Wide_Type (Typ);
+ if Is_Controlling_Formal (F) then
+ Temp_Typ := Class_Wide_Type (Typ);
+ end if;
end if;
end if;
- end if;
- Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp_Obj,
- Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
- Constant_Present => True,
- Expression => Relocate_Node (N));
- Set_Assignment_OK (Decl);
-
- Insert_Actions (N, New_List (Decl));
- Rewrite (N, New_Occurrence_Of (Temp_Obj, Loc));
- end;
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp_Obj,
+ Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
+ Constant_Present => True,
+ Expression => Relocate_Node (N));
+ Set_Assignment_OK (Decl);
+
+ Insert_Actions (N, New_List (Decl));
+ Rewrite (N, New_Occurrence_Of (Temp_Obj, Loc));
+ end;
+
+ else
+ -- If stack-checking is not enabled, increment serial number
+ -- for internal names, so that subsequent symbols are consistent
+ -- with and without stack-checking.
+
+ Synchronize_Serial_Number;
+
+ -- Now we can expand the call with consistent symbol names
+
+ Expand_Call (N);
+ end if;
-- Normal case, expand the call
OpenPOWER on IntegriCloud