From: Eric Botcazou <ebotca...@adacore.com>

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

Reply via email to