@@ -801,17 +801,21 @@ tree_ssa_dominator_optimize (void)
/* Jump threading may have created forwarder blocks from blocks
needing EH cleanup; the new successor of these blocks, which
- has inherited from the original block, needs the cleanup. */
+ has inherited from the original block, needs the cleanup.
+ Don't clear bits in the bitmap, as that can break the bitmap
+ iterator. */
EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi)
{
basic_block bb = BASIC_BLOCK (i);
- if (bb
- && single_succ_p (bb)
- && (single_succ_edge (bb)->flags & EDGE_EH) == 0)
- {
- bitmap_clear_bit (need_eh_cleanup, i);
- bitmap_set_bit (need_eh_cleanup, single_succ (bb)->index);
- }
+ if (bb == NULL)
+ continue;
+ while (single_succ_p (bb)
+ && (single_succ_edge (bb)->flags & EDGE_EH) == 0)
+ bb = single_succ (bb);
+ if (bb == EXIT_BLOCK_PTR)
+ continue;
+ if ((unsigned) bb->index != i)
+ bitmap_set_bit (need_eh_cleanup, bb->index);
}
gimple_purge_all_dead_eh_edges (need_eh_cleanup);
@@ -0,0 +1,73 @@
+// PR tree-optimization/55329
+// { dg-do compile }
+// { dg-options "-O -fno-guess-branch-probability -fnon-call-exceptions --param=early-inlining-insns=111" }
+
+void *f1 ();
+void f2 (void *);
+void f3 ();
+static inline void *
+f4 ()
+{
+ void *p = f1 ();
+ if (!p)
+ f3 ();
+ return p;
+}
+
+struct A
+{
+ int *a;
+ A ();
+ ~A () { a3 (); }
+ int a1 (int * p) { if (!p) f3 (); f2 (p); }
+ int *a2 ();
+ void a3 () { if (*a) a1 (a); }
+ int a4 (int x) { if (*a) f4 (); *a2 () += x; }
+};
+
+struct B : A
+{
+ ~B () { a3 (); }
+};
+
+template <class T>
+struct C
+{
+ T *c;
+ C ();
+ int c1 () { return *(int *) f4 (); }
+ ~C () { if (c1 ()) for (T *t = c + c2 (); t != c; t--) T (); }
+ int c2 ();
+};
+
+class D
+{
+ C <C <int> > c;
+};
+
+struct E
+{
+ int *e;
+ ~E () { delete e; }
+};
+
+struct F
+{
+ int *f1 ();
+ D f2;
+ E f3;
+ F () { f4 (); }
+};
+
+struct G : F
+{
+ B g;
+ G () { g.a4 (*g1 ()->f1 ()); g1 ()->f1 (); }
+ F *g1 ();
+};
+
+void
+foo ()
+{
+ G g;
+}