]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-family: Fix PR94272 -fcompare-debug issue even for C [PR99230]
authorJakub Jelinek <jakub@redhat.com>
Sat, 20 Mar 2021 16:02:06 +0000 (17:02 +0100)
committerJakub Jelinek <jakub@redhat.com>
Sat, 20 Mar 2021 16:02:06 +0000 (17:02 +0100)
The following testcase results in -fcompare-debug failure.
The problem is the similar like in PR94272
https://gcc.gnu.org/pipermail/gcc-patches/2020-March/542562.html
When genericizing, with -g0 we have just a TREE_SIDE_EFFECTS DO_STMT
in a branch of if, while with -g we have that wrapped into
TREE_SIDE_EFFECTS STATEMENT_LIST containing DEBUG_BEGIN_STMT and that
DO_STMT.
The do loop is empty with 0 condition, so c_genericize_control_stmt
turns it into an empty statement (without TREE_SIDE_EFFECTS).
For -g0 that means that suddenly the if branch doesn't have side effects
and is expanded differently.  But with -g we still have TREE_SIDE_EFFECTS
STATEMENT_LIST containing DEBUG_BEGIN_STMT and non-TREE_SIDE_EFFECTS stmt.
The following patch fixes that by detecting this case and removing
TREE_SIDE_EFFECTS.

And, so that we don't duplicate the same code, changes the C++ FE to
just call the c_genericize_control_stmt function that can now handle it.

2021-03-20  Jakub Jelinek  <jakub@redhat.com>

PR debug/99230
* c-gimplify.c (c_genericize_control_stmt): Handle STATEMENT_LIST.

* cp-gimplify.c (cp_genericize_r) <case STATEMENT_LIST>: Remove
special code, instead call c_genericize_control_stmt.

* gcc.dg/pr99230.c: New test.

gcc/c-family/c-gimplify.c
gcc/cp/cp-gimplify.c
gcc/testsuite/gcc.dg/pr99230.c [new file with mode: 0644]

index e1dfca268163ba109f8664f9d74e789328fd699f..39c969d8f40d28e175edc9f3ce2d9e96411a5f88 100644 (file)
@@ -497,6 +497,35 @@ c_genericize_control_stmt (tree *stmt_p, int *walk_subtrees, void *data,
       genericize_omp_for_stmt (stmt_p, walk_subtrees, data, func, lh);
       break;
 
+    case STATEMENT_LIST:
+      if (TREE_SIDE_EFFECTS (stmt))
+       {
+         tree_stmt_iterator i;
+         int nondebug_stmts = 0;
+         bool clear_side_effects = true;
+         /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
+            transforming an IF_STMT into COND_EXPR.  If such stmt
+            appears in a STATEMENT_LIST that contains only that
+            stmt and some DEBUG_BEGIN_STMTs, without -g where the
+            STATEMENT_LIST wouldn't be present at all the resulting
+            expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
+            to clear it even on the STATEMENT_LIST in such cases.  */
+         for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
+           {
+             tree t = tsi_stmt (i);
+             if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
+               nondebug_stmts++;
+             walk_tree_1 (tsi_stmt_ptr (i), func, data, NULL, lh);
+             if (TREE_CODE (t) != DEBUG_BEGIN_STMT
+                 && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
+               clear_side_effects = false;
+           }
+         if (clear_side_effects)
+           TREE_SIDE_EFFECTS (stmt) = 0;
+         *walk_subtrees = 0;
+       }
+      break;
+
     default:
       break;
     }
index df89ff3815b7f49ed09714f8fa410bda1254215e..4baa3368f7a992402a931cc583878fd17bccac37 100644 (file)
@@ -1464,35 +1464,6 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
       walk_subtrees = 0;
       break;
 
-    case STATEMENT_LIST:
-      if (TREE_SIDE_EFFECTS (stmt))
-       {
-         tree_stmt_iterator i;
-         int nondebug_stmts = 0;
-         bool clear_side_effects = true;
-         /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
-            transforming an IF_STMT into COND_EXPR.  If such stmt
-            appears in a STATEMENT_LIST that contains only that
-            stmt and some DEBUG_BEGIN_STMTs, without -g where the
-            STATEMENT_LIST wouldn't be present at all the resulting
-            expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
-            to clear it even on the STATEMENT_LIST in such cases.  */
-         for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
-           {
-             tree t = tsi_stmt (i);
-             if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
-               nondebug_stmts++;
-             cp_walk_tree (tsi_stmt_ptr (i), cp_genericize_r, data, NULL);
-             if (TREE_CODE (t) != DEBUG_BEGIN_STMT
-                 && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
-               clear_side_effects = false;
-           }
-         if (clear_side_effects)
-           TREE_SIDE_EFFECTS (stmt) = 0;
-         *walk_subtrees = 0;
-       }
-      break;
-
     case OMP_DISTRIBUTE:
       /* Need to explicitly instantiate copy ctors on class iterators of
         composite distribute parallel for.  */
@@ -1566,6 +1537,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
     case OMP_SIMD:
     case OMP_LOOP:
     case OACC_LOOP:
+    case STATEMENT_LIST:
       /* These cases are handled by shared code.  */
       c_genericize_control_stmt (stmt_p, walk_subtrees, data,
                                 cp_genericize_r, cp_walk_subtrees);
diff --git a/gcc/testsuite/gcc.dg/pr99230.c b/gcc/testsuite/gcc.dg/pr99230.c
new file mode 100644 (file)
index 0000000..eb3f982
--- /dev/null
@@ -0,0 +1,40 @@
+/* PR debug/99230 */
+/* { dg-do compile } */
+/* { dg-options "-O2 --param logical-op-non-short-circuit=0 -fcompare-debug --param=jump-table-max-growth-ratio-for-speed=5000" } */
+
+extern void fn2 (void);
+extern void fn3 (int);
+int a, b;
+void
+fn1 (void)
+{
+  int c;
+  short d;
+  switch (a) {
+  case 22000:
+    fn2 ();
+  case 22300:
+    b = 0;
+  case 22600:
+  case 22601:
+  case 22900:
+    fn3 (1);
+  case 20100:
+    fn3 (2);
+  case 20200:
+    fn3 (3);
+  case 20300:
+    fn3 (4);
+  case 20400:
+    fn3 (5);
+  case 20310:
+    fn3 (4);
+  case 20410:
+    fn3 (5);
+  }
+  if (d || c) {
+    do
+      ;
+    while (0);
+  }
+}