tree-optimization/90994 - fix uninit diagnostics with EH
authorRichard Biener <rguenther@suse.de>
Wed, 31 Aug 2022 12:04:46 +0000 (14:04 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 31 Aug 2022 13:20:41 +0000 (15:20 +0200)
r12-3640-g94c12ffac234b2 sneaked in a hack to avoid the diagnostic
for the testcase in PR90994 which sees non-call EH control flow
confusing predicate analysis.  The following patch instead adjusts
the existing code handling EH to handle non-calls and do what I
think was intented.

PR tree-optimization/90994
* gimple-predicate-analysis.cc (predicate::init_from_control_deps):
Ignore exceptional control flow and skip the edge for the purpose of
predicate generation also for non-calls.

* g++.dg/torture/pr90994.C: New testcase.

gcc/gimple-predicate-analysis.cc
gcc/testsuite/g++.dg/torture/pr90994.C [new file with mode: 0644]

index 49500b7..58eade4 100644 (file)
@@ -41,6 +41,7 @@
 #include "calls.h"
 #include "value-query.h"
 #include "cfganal.h"
+#include "tree-eh.h"
 
 #include "gimple-predicate-analysis.h"
 
@@ -1709,9 +1710,6 @@ predicate::init_from_control_deps (const vec<edge> *dep_chains,
            }
          /* Get the conditional controlling the bb exit edge.  */
          gimple *cond_stmt = gsi_stmt (gsi);
-         if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2)
-           /* Ignore EH edge.  Can add assertion on the other edge's flag.  */
-           continue;
          /* Skip this edge if it is bypassing an abort - when the
             condition is not satisfied we are neither reaching the
             definition nor the use so it isn't meaningful.  Note if
@@ -1819,10 +1817,15 @@ predicate::init_from_control_deps (const vec<edge> *dep_chains,
                  has_valid_pred = true;
                }
            }
+         else if (stmt_can_throw_internal (cfun, cond_stmt)
+                  && !(e->flags & EDGE_EH))
+           /* Ignore the exceptional control flow and proceed as if
+              E were a fallthru without a controlling predicate for
+              both the USE (valid) and DEF (questionable) case.  */
+           has_valid_pred = true;
          else
            {
-             /* Disabled.  See PR 90994.
-                has_valid_pred = false;  */
+             has_valid_pred = false;
              break;
            }
        }
diff --git a/gcc/testsuite/g++.dg/torture/pr90994.C b/gcc/testsuite/g++.dg/torture/pr90994.C
new file mode 100644 (file)
index 0000000..8feb36f
--- /dev/null
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-additional-options "-fnon-call-exceptions -Wuninitialized" }
+
+extern void printval(unsigned char v);
+
+inline int readbyte(unsigned char *__restrict presult,
+                   unsigned char volatile *ptr)
+{
+  unsigned char v;
+  try {
+      v = *ptr;
+  } catch (...) {
+      return -1;
+  }
+  *presult = v;
+  return 0;
+}
+
+int incorrectWarning(unsigned char volatile *ptr)
+{
+  int error;
+  unsigned char first;
+  unsigned char second;
+
+  error = readbyte(&first, ptr);
+  asm("\n\n\n\n\n" : : "X" (error != 0));
+  if (error != 0)
+    goto err;
+
+  error = readbyte(&second, ptr);
+  if (error != 0)
+    goto err;
+
+  printval(first);   // { dg-bogus "uninitialized" }
+  printval(second);
+  return 0;
+
+err:
+  return error;
+}