Hello,

This is the 2nd version of the patch. Changes made since the initial version:
  - Implemented Jason's suggestions, move the declaration of first down.
  - Add signed-off-by to the commit.

Tested on x86_64-linux.

Signed-off-by: Sirui Mu <[email protected]>
---
 gcc/cp/typeck.cc                              | 31 +++++++++++--------
 .../g++.dg/cpp1z/array-condition-expr.C       | 26 ++++++++++++++++
 2 files changed, 44 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/array-condition-expr.C

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 41a3f4cb7cb..ccfe50d3c37 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -3973,7 +3973,6 @@ tree
 cp_build_array_ref (location_t loc, tree array, tree idx,
                    tsubst_flags_t complain)
 {
-  tree first = NULL_TREE;
   tree ret;
 
   if (idx == 0)
@@ -3987,6 +3986,21 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
       || TREE_TYPE (idx) == error_mark_node)
     return error_mark_node;
 
+  /* 0[array] */
+  if (TREE_CODE (TREE_TYPE (idx)) == ARRAY_TYPE)
+    {
+      std::swap (array, idx);
+
+      tree first = NULL_TREE;
+      if (flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (array))
+       idx = first = save_expr (idx);
+      ret = cp_build_array_ref (loc, array, idx, complain);
+
+      if (first)
+       ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
+      return ret;
+    }
+
   /* If ARRAY is a COMPOUND_EXPR or COND_EXPR, move our reference
      inside it.  */
   switch (TREE_CODE (array))
@@ -4066,14 +4080,6 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 
   bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);
 
-  /* 0[array] */
-  if (TREE_CODE (TREE_TYPE (idx)) == ARRAY_TYPE)
-    {
-      std::swap (array, idx);
-      if (flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (array))
-       idx = first = save_expr (idx);
-    }
-
   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {
       tree rval, type;
@@ -4149,17 +4155,16 @@ cp_build_array_ref (location_t loc, tree array, tree 
idx,
       protected_set_expr_location (ret, loc);
       if (non_lvalue)
        ret = non_lvalue_loc (loc, ret);
-      if (first)
-       ret = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (ret), first, ret);
       return ret;
     }
 
   {
     tree ar = cp_default_conversion (array, complain);
     tree ind = cp_default_conversion (idx, complain);
+    tree first = NULL_TREE;
 
-    if (!processing_template_decl
-       && !first && flag_strong_eval_order == 2 && TREE_SIDE_EFFECTS (ind))
+    if (!processing_template_decl && flag_strong_eval_order == 2
+       && TREE_SIDE_EFFECTS (ind))
       ar = first = save_expr (ar);
 
     /* Put the integer in IND to simplify error checking.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/array-condition-expr.C 
b/gcc/testsuite/g++.dg/cpp1z/array-condition-expr.C
new file mode 100644
index 00000000000..6b59d7c9fe4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/array-condition-expr.C
@@ -0,0 +1,26 @@
+// { dg-do run { target c++17 } }
+
+int x[10];
+int y[10];
+bool c() { return true; }
+
+void f(int i, int v)
+{
+  (c() ? x : y)[i] = v;
+}
+
+void g(int i, int v)
+{
+  i[c() ? x : y] = v;
+}
+
+int main()
+{
+  f(0, 1);
+  if (x[0] != 1)
+    __builtin_abort();
+
+  g(0, 2);
+  if (x[0] != 2)
+    __builtin_abort();
+}
-- 
2.51.0

Reply via email to