Folding during gimplification can invoke the devirt machinery which
doesn't deal with errorneous state.  Thus avoid ICEing by not folding
from gimplification in case we've seen errors.

Similarly do not build cgraph edges in those cases as that invokes
the devirt machinery as well (we stop compilation after lowering anyway
in case errors were reported).

The patch also fixes ordering of passes.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2017-06-08  Richard Biener  <rguent...@suse.de>

        PR middle-end/81007
        * gimplify.c (maybe_fold_stmt): Do not fold after errors.
        * cgraphbuild.c: Include diagnostic-core.h.
        (pass_build_cgraph_edges::gate): Add, do not run after errors.
        * passes.def (all_lowering_passes): Run pass_build_cgraph_edges
        last again.

        * g++.dg/pr81007.C: New testcase.

Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c      (revision 249003)
+++ gcc/gimplify.c      (working copy)
@@ -3067,6 +3067,10 @@ gimplify_arg (tree *arg_p, gimple_seq *p
 static bool
 maybe_fold_stmt (gimple_stmt_iterator *gsi)
 {
+  /* Do not fold if we may have invalid IL somewhere.  */
+  if (seen_error ())
+    return false;
+
   struct gimplify_omp_ctx *ctx;
   for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
     if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
Index: gcc/cgraphbuild.c
===================================================================
--- gcc/cgraphbuild.c   (revision 249003)
+++ gcc/cgraphbuild.c   (working copy)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.
 #include "gimple-walk.h"
 #include "ipa-utils.h"
 #include "except.h"
+#include "diagnostic-core.h"
 
 /* Context of record_reference.  */
 struct record_reference_ctx
@@ -305,6 +306,7 @@ public:
   /* opt_pass methods: */
   virtual unsigned int execute (function *);
 
+  virtual bool gate (function *) { return ! seen_error (); }
 }; // class pass_build_cgraph_edges
 
 unsigned int
Index: gcc/passes.def
===================================================================
--- gcc/passes.def      (revision 249003)
+++ gcc/passes.def      (working copy)
@@ -42,9 +42,9 @@ along with GCC; see the file COPYING3.
   NEXT_PASS (pass_build_cfg);
   NEXT_PASS (pass_warn_function_return);
   NEXT_PASS (pass_expand_omp);
-  NEXT_PASS (pass_build_cgraph_edges);
   NEXT_PASS (pass_sprintf_length, false);
   NEXT_PASS (pass_walloca, /*strict_mode_p=*/true);
+  NEXT_PASS (pass_build_cgraph_edges);
   TERMINATE_PASS_LIST (all_lowering_passes)
 
   /* Interprocedural optimization passes.  */
Index: gcc/testsuite/g++.dg/pr81007.C
===================================================================
--- gcc/testsuite/g++.dg/pr81007.C      (nonexistent)
+++ gcc/testsuite/g++.dg/pr81007.C      (working copy)
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+struct A
+{
+  A p; // { dg-error "incomplete" }
+  virtual void foo();
+};
+
+struct B : A {};
+
+void bar(B& b)
+{
+  b.foo();
+}

Reply via email to