From: Eric Botcazou <[email protected]>
A qualified expression around a function call may cause a temporary to be
created and, therefore, cannot be bypassed in Expand_Ctrl_Function_Call.
gcc/ada/ChangeLog:
* exp_util.ads (Unqualified_Unconditional_Parent): New function.
* exp_util.adb (Unconditional_Parent): Do not look through qualified
expressions.
(Unqualified_Unconditional_Parent): New function identical to the
original Unconditional_Parent.
* exp_aggr.adb (Convert_To_Assignments): Replace Unconditional_Parent
with Unqualified_Unconditional_Parent.
(Expand_Array_Aggregate): Likewse.
* exp_ch4.adb (Expand_N_Case_Expression): Likewise.
(Expand_N_If_Expression): Likewise.
* exp_ch6.adb (Expand_Ctrl_Function_Call): Do not bypass an enclosing
qualified expression in the parent chain.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_aggr.adb | 4 ++--
gcc/ada/exp_ch4.adb | 6 ++++--
gcc/ada/exp_ch6.adb | 5 ++++-
gcc/ada/exp_util.adb | 33 ++++++++++++++++++++++++++++++++-
gcc/ada/exp_util.ads | 4 ++++
5 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 6b4f4a19d1f9..d62b7351e862 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -4283,7 +4283,7 @@ package body Exp_Aggr is
-- Set the Expansion_Delayed flag in the cases where the transformation
-- will be done top down from above.
- Parent_Node := Unconditional_Parent (N);
+ Parent_Node := Unqualified_Unconditional_Parent (N);
if
-- Internal aggregates (transformed when expanding the parent),
@@ -6254,7 +6254,7 @@ package body Exp_Aggr is
-- Set the Expansion_Delayed flag in the cases where the transformation
-- will be done top down from above.
- Parent_Node := Unconditional_Parent (N);
+ Parent_Node := Unqualified_Unconditional_Parent (N);
if
-- Internal aggregates (transformed when expanding the parent),
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 23a59de6f872..8fba1c4e71fa 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -5198,7 +5198,8 @@ package body Exp_Ch4 is
if not Expansion_Delayed (N) then
declare
- Uncond_Par : constant Node_Id := Unconditional_Parent (N);
+ Uncond_Par : constant Node_Id :=
+ Unqualified_Unconditional_Parent (N);
begin
if Nkind (Uncond_Par) = N_Simple_Return_Statement
or else Is_Optimizable_Declaration (Uncond_Par)
@@ -5807,7 +5808,8 @@ package body Exp_Ch4 is
if not Expansion_Delayed (N) then
declare
- Uncond_Par : constant Node_Id := Unconditional_Parent (N);
+ Uncond_Par : constant Node_Id :=
+ Unqualified_Unconditional_Parent (N);
begin
if Nkind (Uncond_Par) = N_Simple_Return_Statement
or else Is_Optimizable_Declaration (Uncond_Par)
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 32e96bed2349..5056b1f990fa 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -5793,11 +5793,14 @@ package body Exp_Ch6 is
is
Par : constant Node_Id := Parent (N);
Uncond_Par : constant Node_Id := Unconditional_Parent (N);
+ -- Beware that a qualified expression around a function call cannot be
+ -- considered as transparent (like around an aggregate) because it may
+ -- cause a temporary to be created.
begin
-- Optimization: if the returned value is returned again, then no need
-- to copy/readjust/finalize, we can just pass the value through (see
- -- Expand_N_Simple_Return_Statement), and thus no attachment is needed.
+ -- Expand_Simple_Function_Return), and thus no attachment is needed.
-- Note that simple return statements are distributed into conditional
-- expressions, but we may be invoked before this distribution is done.
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 6ce6c0cd81d6..4135e24424d3 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -14903,6 +14903,37 @@ package body Exp_Util is
Node : Node_Id := N;
Parent_Node : Node_Id := Parent (Node);
+ begin
+ loop
+ case Nkind (Parent_Node) is
+ when N_Case_Expression_Alternative =>
+ null;
+
+ when N_Case_Expression =>
+ exit when Node = Expression (Parent_Node);
+
+ when N_If_Expression =>
+ exit when Node = First (Expressions (Parent_Node));
+
+ when others =>
+ exit;
+ end case;
+
+ Node := Parent_Node;
+ Parent_Node := Parent (Node);
+ end loop;
+
+ return Parent_Node;
+ end Unconditional_Parent;
+
+ --------------------------------------
+ -- Unqualified_Unconditional_Parent --
+ --------------------------------------
+
+ function Unqualified_Unconditional_Parent (N : Node_Id) return Node_Id is
+ Node : Node_Id := N;
+ Parent_Node : Node_Id := Parent (Node);
+
begin
loop
case Nkind (Parent_Node) is
@@ -14927,7 +14958,7 @@ package body Exp_Util is
end loop;
return Parent_Node;
- end Unconditional_Parent;
+ end Unqualified_Unconditional_Parent;
-------------------------------
-- Update_Primitives_Mapping --
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 4226fcc93777..b7d8a185f4bd 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -1344,6 +1344,10 @@ package Exp_Util is
function Unconditional_Parent (N : Node_Id) return Node_Id;
-- Return the first parent of arbitrary node N that is not a conditional
+ -- expression, one of whose dependent expressions is N, recursively.
+
+ function Unqualified_Unconditional_Parent (N : Node_Id) return Node_Id;
+ -- Return the first parent of arbitrary node N that is not a conditional
-- expression, one of whose dependent expressions is N, and that is not
-- a qualified expression, whose expression is N, recursively.
--
2.43.0