tree: Fix up get_narrower [PR94724]
authorJakub Jelinek <jakub@redhat.com>
Thu, 23 Apr 2020 19:11:36 +0000 (21:11 +0200)
committerJakub Jelinek <jakub@redhat.com>
Thu, 23 Apr 2020 19:11:36 +0000 (21:11 +0200)
In the recent get_narrower change, I wanted it to be efficient and avoid
recursion if there are many nested COMPOUND_EXPRs.  That builds the
COMPOUND_EXPR nest with the right arguments, but as build2_loc computes some
flags like TREE_SIDE_EFFECTS, TREE_CONSTANT and TREE_READONLY, when it
is called with something that will not be the argument in the end, those
flags are computed incorrectly.
So, this patch instead uses an auto_vec and builds them in the reverse order
so when they are built, they are built with the correct operands.

2020-04-23  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/94724
* tree.c (get_narrower): Instead of creating COMPOUND_EXPRs
temporarily with non-final second operand and updating it later,
push COMPOUND_EXPRs into a vector and process it in reverse,
creating COMPOUND_EXPRs with the final operands.

* gcc.c-torture/execute/pr94724.c: New test.

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr94724.c [new file with mode: 0644]
gcc/tree.c

index c806e5e..5ddb433 100644 (file)
@@ -1,3 +1,11 @@
+2020-04-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/94724
+       * tree.c (get_narrower): Instead of creating COMPOUND_EXPRs
+       temporarily with non-final second operand and updating it later,
+       push COMPOUND_EXPRs into a vector and process it in reverse,
+       creating COMPOUND_EXPRs with the final operands.
+
 2020-04-23  Szabolcs Nagy  <szabolcs.nagy@arm.com>
 
        PR target/94697
index 25515c9..c6ae489 100644 (file)
@@ -1,9 +1,14 @@
+2020-04-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/94724
+       * gcc.c-torture/execute/pr94724.c: New test.
+
 2020-04-23  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/93956
        * gfortran.dg/pointer_assign_13.f90: New test.
 
-       2020-04-23 Iain Sandoe <iain@sandoe.co.uk>
+2020-04-23 Iain Sandoe <iain@sandoe.co.uk>
 
        * g++.dg/coroutines/coro-bad-alloc-00-bad-op-new.C: Adjust for
        changed inline namespace.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94724.c b/gcc/testsuite/gcc.c-torture/execute/pr94724.c
new file mode 100644 (file)
index 0000000..7c260f1
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR middle-end/94724 */
+
+short a, b;
+
+int
+main ()
+{
+  (0, (0, (a = 0 >= 0, b))) != 53601;
+  if (a != 1)
+    __builtin_abort ();
+  return 0;
+}
index fa956da..da6b8e2 100644 (file)
@@ -8881,18 +8881,22 @@ get_narrower (tree op, int *unsignedp_ptr)
 
   if (TREE_CODE (op) == COMPOUND_EXPR)
     {
-      while (TREE_CODE (op) == COMPOUND_EXPR)
+      do
        op = TREE_OPERAND (op, 1);
+      while (TREE_CODE (op) == COMPOUND_EXPR);
       tree ret = get_narrower (op, unsignedp_ptr);
       if (ret == op)
        return win;
-      op = win;
-      for (tree *p = &win; TREE_CODE (op) == COMPOUND_EXPR;
-          op = TREE_OPERAND (op, 1), p = &TREE_OPERAND (*p, 1))
-       *p = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR,
-                        TREE_TYPE (ret), TREE_OPERAND (op, 0),
-                        ret);
-      return win;
+      auto_vec <tree, 16> v;
+      unsigned int i;
+      for (tree op = win; TREE_CODE (op) == COMPOUND_EXPR;
+          op = TREE_OPERAND (op, 1))
+       v.safe_push (op);
+      FOR_EACH_VEC_ELT_REVERSE (v, i, op)
+       ret = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR,
+                         TREE_TYPE (win), TREE_OPERAND (op, 0),
+                         ret);
+      return ret;
     }
   while (TREE_CODE (op) == NOP_EXPR)
     {