https://gcc.gnu.org/g:486c32501aafce188649da2c234229dfbd2fd202

commit r12-11255-g486c32501aafce188649da2c234229dfbd2fd202
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Mon Jul 7 09:51:51 2025 +0200

    Revert "c++: Fix up cp_build_array_ref COND_EXPR handling [PR120471]"
    
    This reverts commit b5f0faa4eb71650a9dde3938c3a98eda710534de.

Diff:
---
 gcc/cp/typeck.cc                      | 130 ++--------------------------------
 gcc/testsuite/g++.dg/parse/pr120471.C |  42 -----------
 gcc/testsuite/g++.dg/ubsan/pr120471.C |  21 ------
 3 files changed, 7 insertions(+), 186 deletions(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 19dfaf18928f..89ff595ec513 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -3811,129 +3811,13 @@ cp_build_array_ref (location_t loc, tree array, tree 
idx,
       }
 
     case COND_EXPR:
-      tree op0, op1, op2;
-      op0 = TREE_OPERAND (array, 0);
-      op1 = TREE_OPERAND (array, 1);
-      op2 = TREE_OPERAND (array, 1);
-      if (TREE_SIDE_EFFECTS (idx) || !tree_invariant_p (idx))
-       {
-         /* If idx could possibly have some SAVE_EXPRs, turning
-            (op0 ? op1 : op2)[idx] into
-            op0 ? op1[idx] : op2[idx] can lead into temporaries
-            initialized in one conditional path and uninitialized
-            uses of them in the other path.
-            And if idx is a really large expression, evaluating it
-            twice is also not optimal.
-            On the other side, op0 must be sequenced before evaluation
-            of op1 and op2 and for C++17 op0, op1 and op2 must be
-            sequenced before idx.
-            If idx is INTEGER_CST, we can just do the optimization
-            without any SAVE_EXPRs, if op1 and op2 are both ARRAY_TYPE
-            VAR_DECLs or COMPONENT_REFs thereof (so their address
-            is constant or relative to frame), optimize into
-            (SAVE_EXPR <op0>, SAVE_EXPR <idx>, SAVE_EXPR <op0>)
-            ? op1[SAVE_EXPR <idx>] : op2[SAVE_EXPR <idx>]
-            Otherwise avoid this optimization.  */
-         if (flag_strong_eval_order == 2)
-           {
-             if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
-               {
-                 tree xop1 = op1;
-                 tree xop2 = op2;
-                 while (xop1 && handled_component_p (xop1))
-                   {
-                     switch (TREE_CODE (xop1))
-                       {
-                       case ARRAY_REF:
-                       case ARRAY_RANGE_REF:
-                         if (!tree_invariant_p (TREE_OPERAND (xop1, 1))
-                             || TREE_OPERAND (xop1, 2) != NULL_TREE
-                             || TREE_OPERAND (xop1, 3) != NULL_TREE)
-                           {
-                             xop1 = NULL_TREE;
-                             continue;
-                           }
-                         break;
-
-                       case COMPONENT_REF:
-                         if (TREE_OPERAND (xop1, 2) != NULL_TREE)
-                           {
-                             xop1 = NULL_TREE;
-                             continue;
-                           }
-                         break;
-
-                       default:
-                         break;
-                       }
-                     xop1 = TREE_OPERAND (xop1, 0);
-                   }
-                 if (xop1)
-                   STRIP_ANY_LOCATION_WRAPPER (xop1);
-                 while (xop2 && handled_component_p (xop2))
-                   {
-                     switch (TREE_CODE (xop2))
-                       {
-                       case ARRAY_REF:
-                       case ARRAY_RANGE_REF:
-                         if (!tree_invariant_p (TREE_OPERAND (xop2, 1))
-                             || TREE_OPERAND (xop2, 2) != NULL_TREE
-                             || TREE_OPERAND (xop2, 3) != NULL_TREE)
-                           {
-                             xop2 = NULL_TREE;
-                             continue;
-                           }
-                         break;
-
-                       case COMPONENT_REF:
-                         if (TREE_OPERAND (xop2, 2) != NULL_TREE)
-                           {
-                             xop2 = NULL_TREE;
-                             continue;
-                           }
-                         break;
-
-                       default:
-                         break;
-                       }
-                     xop2 = TREE_OPERAND (xop2, 0);
-                   }
-                 if (xop2)
-                   STRIP_ANY_LOCATION_WRAPPER (xop2);
-
-                 if (!xop1
-                     || !xop2
-                     || !(CONSTANT_CLASS_P (xop1)
-                          || decl_address_invariant_p (xop1))
-                     || !(CONSTANT_CLASS_P (xop2)
-                          || decl_address_invariant_p (xop2)))
-                   {
-                     /* Force default conversion on array if
-                        we can't optimize this and array is ARRAY_TYPE
-                        COND_EXPR, we can't leave COND_EXPRs with
-                        ARRAY_TYPE in the IL.  */
-                     array = cp_default_conversion (array, complain);
-                     if (error_operand_p (array))
-                       return error_mark_node;
-                     break;
-                   }
-               }
-             else if (!POINTER_TYPE_P (TREE_TYPE (array))
-                      || !tree_invariant_p (op1)
-                      || !tree_invariant_p (op2))
-               break;
-           }
-         if (TREE_SIDE_EFFECTS (idx))
-           {
-             idx = save_expr (idx);
-             op0 = save_expr (op0);
-             tree tem = build_compound_expr (loc, op0, idx);
-             op0 = build_compound_expr (loc, tem, op0);
-           }
-       }
-      op1 = cp_build_array_ref (loc, op1, idx, complain);
-      op2 = cp_build_array_ref (loc, op2, idx, complain);
-      ret = build_conditional_expr (loc, op0, op1, op2, complain);
+      ret = build_conditional_expr
+              (loc, TREE_OPERAND (array, 0),
+              cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
+                                  complain),
+              cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
+                                  complain),
+              complain);
       protected_set_expr_location (ret, loc);
       return ret;
 
diff --git a/gcc/testsuite/g++.dg/parse/pr120471.C 
b/gcc/testsuite/g++.dg/parse/pr120471.C
deleted file mode 100644
index ad47e380404a..000000000000
--- a/gcc/testsuite/g++.dg/parse/pr120471.C
+++ /dev/null
@@ -1,42 +0,0 @@
-// PR c++/120471
-// { dg-do compile }
-
-extern int a1[], a2[], a3[], a4[];
-
-int corge (int);
-
-int
-foo (int p)
-{
-  return (p ? a1 : a2)[1];
-}
-
-int
-bar (int p, int q)
-{
-  return (p ? a1 : a2)[q];
-}
-
-int
-garply (int p, int q)
-{
-  return (p ? a1 : a2)[corge (q)];
-}
-
-int
-baz (int p, int q)
-{
-  return (p ? q ? a1 : a2 : q ? a3 : a4)[1];
-}
-
-int
-qux (int p, int q, int r)
-{
-  return (p ? q ? a1 : a2 : q ? a3 : a4)[r];
-}
-
-int
-fred (int p, int q, int r)
-{
-  return (p ? q ? a1 : a2 : q ? a3 : a4)[corge (r)];
-}
diff --git a/gcc/testsuite/g++.dg/ubsan/pr120471.C 
b/gcc/testsuite/g++.dg/ubsan/pr120471.C
deleted file mode 100644
index 31b781f9aa7f..000000000000
--- a/gcc/testsuite/g++.dg/ubsan/pr120471.C
+++ /dev/null
@@ -1,21 +0,0 @@
-// PR c++/120471
-// { dg-do run }
-// { dg-options "-fsanitize=undefined" }
-
-volatile int b[1], a[1];
-
-void
-foo (int x)
-{
-  volatile int c = 21;
-  volatile int v = (x % 2 ? b : a)[c % 3];
-  if (v != 0)
-    __builtin_abort ();
-}
-
-int
-main ()
-{
-  foo (1);
-  foo (2);
-}

Reply via email to