aboutsummaryrefslogtreecommitdiff
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.adb149
1 files changed, 123 insertions, 26 deletions
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 930f82bef..8d9ef9b38 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -1217,8 +1217,8 @@ package body Exp_Ch6 is
and then
Present (Effective_Extra_Accessibility (Entity (Lhs)))
then
- -- Copyback target is an Ada 2012 stand-alone object
- -- of an anonymous access type
+ -- Copyback target is an Ada 2012 stand-alone object of an
+ -- anonymous access type.
pragma Assert (Ada_Version >= Ada_2012);
@@ -2392,10 +2392,6 @@ package body Exp_Ch6 is
Expand_Put_Call_With_Symbol (Call_Node);
end if;
- -- Remove the dimensions of every parameters in call
-
- Remove_Dimension_In_Call (N);
-
-- Ignore if previous error
if Nkind (Call_Node) in N_Has_Etype
@@ -3050,7 +3046,7 @@ package body Exp_Ch6 is
Set_Last_Assignment (Ent, Sav);
Set_Is_Known_Valid (Ent, False);
- -- For all other cases, just kill the current values
+ -- For all other cases, just kill the current values
else
Kill_Current_Values (Ent);
@@ -3205,7 +3201,7 @@ package body Exp_Ch6 is
end;
end if;
- -- If we are expanding a rhs of an assignment we need to check if tag
+ -- If we are expanding the RHS of an assignment we need to check if tag
-- propagation is needed. You might expect this processing to be in
-- Analyze_Assignment but has to be done earlier (bottom-up) because the
-- assignment might be transformed to a declaration for an unconstrained
@@ -3404,6 +3400,14 @@ package body Exp_Ch6 is
Expand_Actuals (Call_Node, Subp);
+ -- Verify that the actuals do not share storage. This check must be done
+ -- on the caller side rather that inside the subprogram to avoid issues
+ -- of parameter passing.
+
+ if Check_Aliasing_Of_Parameters then
+ Apply_Parameter_Aliasing_Checks (Call_Node, Subp);
+ end if;
+
-- If the subprogram is a renaming, or if it is inherited, replace it in
-- the call with the name of the actual subprogram being called. If this
-- is a dispatching call, the run-time decides what to call. The Alias
@@ -4045,7 +4049,10 @@ package body Exp_Ch6 is
Context := Parent (N);
while Present (Context) loop
- if Nkind (Context) = N_Conditional_Expression then
+ -- The following could use a comment (and why is N_Case_Expression
+ -- not treated in a similar manner ???
+
+ if Nkind (Context) = N_If_Expression then
exit;
-- Stop the search when reaching any statement because we have
@@ -4088,13 +4095,15 @@ package body Exp_Ch6 is
Remove_Side_Effects (N);
- -- The function call is part of a conditional expression alternative.
- -- The temporary result must live as long as the conditional expression
- -- itself, otherwise it will be finalized too early. Mark the transient
- -- as processed to avoid untimely finalization.
+ -- The function call is part of an if expression dependent expression.
+ -- The temporary result must live as long as the if expression itself,
+ -- otherwise it will be finalized too early. Mark the transient as
+ -- processed to avoid untimely finalization.
+
+ -- Why no special handling for case expressions here ???
if Present (Context)
- and then Nkind (Context) = N_Conditional_Expression
+ and then Nkind (Context) = N_If_Expression
and then Nkind (N) = N_Explicit_Dereference
then
Set_Is_Processed_Transient (Entity (Prefix (N)));
@@ -4210,9 +4219,7 @@ package body Exp_Ch6 is
Ret : Node_Id;
begin
- if Is_Entity_Name (N)
- and then Present (Entity (N))
- then
+ if Is_Entity_Name (N) and then Present (Entity (N)) then
E := Entity (N);
if Is_Formal (E)
@@ -4772,31 +4779,31 @@ package body Exp_Ch6 is
else
pragma Assert
(Nkind
- (First
- (Statements (Handled_Statement_Sequence (Orig_Bod))))
+ (First
+ (Statements (Handled_Statement_Sequence (Orig_Bod))))
= N_Block_Statement);
declare
Blk_Stmt : constant Node_Id :=
First
(Statements
- (Handled_Statement_Sequence (Orig_Bod)));
+ (Handled_Statement_Sequence (Orig_Bod)));
First_Stmt : constant Node_Id :=
First
(Statements
- (Handled_Statement_Sequence (Blk_Stmt)));
+ (Handled_Statement_Sequence (Blk_Stmt)));
Second_Stmt : constant Node_Id := Next (First_Stmt);
begin
pragma Assert
(Nkind (First_Stmt) = N_Procedure_Call_Statement
- and then Nkind (Second_Stmt) = Sinfo.N_Return_Statement
- and then No (Next (Second_Stmt)));
+ and then Nkind (Second_Stmt) = N_Simple_Return_Statement
+ and then No (Next (Second_Stmt)));
Bod :=
Copy_Generic_Node
(First
- (Statements (Handled_Statement_Sequence (Orig_Bod))),
+ (Statements (Handled_Statement_Sequence (Orig_Bod))),
Empty, Instantiating => True);
Blk := Bod;
@@ -5120,8 +5127,8 @@ package body Exp_Ch6 is
-- Remove the return statement
pragma Assert
- (Nkind (Last (Statements (Handled_Statement_Sequence (Blk))))
- = Sinfo.N_Return_Statement);
+ (Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
+ N_Simple_Return_Statement);
Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
end if;
@@ -9112,6 +9119,96 @@ package body Exp_Ch6 is
end if;
end Make_Build_In_Place_Call_In_Object_Declaration;
+ --------------------------------------------
+ -- Make_CPP_Constructor_Call_In_Allocator --
+ --------------------------------------------
+
+ procedure Make_CPP_Constructor_Call_In_Allocator
+ (Allocator : Node_Id;
+ Function_Call : Node_Id)
+ is
+ Loc : constant Source_Ptr := Sloc (Function_Call);
+ Acc_Type : constant Entity_Id := Etype (Allocator);
+ Function_Id : constant Entity_Id := Entity (Name (Function_Call));
+ Result_Subt : constant Entity_Id := Available_View (Etype (Function_Id));
+
+ New_Allocator : Node_Id;
+ Return_Obj_Access : Entity_Id;
+ Tmp_Obj : Node_Id;
+
+ begin
+ pragma Assert (Nkind (Allocator) = N_Allocator
+ and then Nkind (Function_Call) = N_Function_Call);
+ pragma Assert (Convention (Function_Id) = Convention_CPP
+ and then Is_Constructor (Function_Id));
+ pragma Assert (Is_Constrained (Underlying_Type (Result_Subt)));
+
+ -- Replace the initialized allocator of form "new T'(Func (...))" with
+ -- an uninitialized allocator of form "new T", where T is the result
+ -- subtype of the called function. The call to the function is handled
+ -- separately further below.
+
+ New_Allocator :=
+ Make_Allocator (Loc,
+ Expression => New_Reference_To (Result_Subt, Loc));
+ Set_No_Initialization (New_Allocator);
+
+ -- Copy attributes to new allocator. Note that the new allocator
+ -- logically comes from source if the original one did, so copy the
+ -- relevant flag. This ensures proper treatment of the restriction
+ -- No_Implicit_Heap_Allocations in this case.
+
+ Set_Storage_Pool (New_Allocator, Storage_Pool (Allocator));
+ Set_Procedure_To_Call (New_Allocator, Procedure_To_Call (Allocator));
+ Set_Comes_From_Source (New_Allocator, Comes_From_Source (Allocator));
+
+ Rewrite (Allocator, New_Allocator);
+
+ -- Create a new access object and initialize it to the result of the
+ -- new uninitialized allocator. Note: we do not use Allocator as the
+ -- Related_Node of Return_Obj_Access in call to Make_Temporary below
+ -- as this would create a sort of infinite "recursion".
+
+ Return_Obj_Access := Make_Temporary (Loc, 'R');
+ Set_Etype (Return_Obj_Access, Acc_Type);
+
+ -- Generate:
+ -- Rnnn : constant ptr_T := new (T);
+ -- Init (Rnn.all,...);
+
+ Tmp_Obj :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Return_Obj_Access,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To (Acc_Type, Loc),
+ Expression => Relocate_Node (Allocator));
+ Insert_Action (Allocator, Tmp_Obj);
+
+ Insert_List_After_And_Analyze (Tmp_Obj,
+ Build_Initialization_Call (Loc,
+ Id_Ref =>
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Reference_To (Return_Obj_Access, Loc)),
+ Typ => Etype (Function_Id),
+ Constructor_Ref => Function_Call));
+
+ -- Finally, replace the allocator node with a reference to the result of
+ -- the function call itself (which will effectively be an access to the
+ -- object created by the allocator).
+
+ Rewrite (Allocator, New_Reference_To (Return_Obj_Access, Loc));
+
+ -- Ada 2005 (AI-251): If the type of the allocator is an interface then
+ -- generate an implicit conversion to force displacement of the "this"
+ -- pointer.
+
+ if Is_Interface (Designated_Type (Acc_Type)) then
+ Rewrite (Allocator, Convert_To (Acc_Type, Relocate_Node (Allocator)));
+ end if;
+
+ Analyze_And_Resolve (Allocator, Acc_Type);
+ end Make_CPP_Constructor_Call_In_Allocator;
+
-----------------------------------
-- Needs_BIP_Finalization_Master --
-----------------------------------