PR tree-optimization/55329
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Nov 2012 22:05:32 +0000 (22:05 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Nov 2012 22:05:32 +0000 (22:05 +0000)
* tree-ssa-dom.c (tree_ssa_dominator_optimize): Never clear
bits in needed_eh_cleanup while iterating over the bitmap.
Look through all forwarder blocks at once.

* g++.dg/opt/pr55329.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193577 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr55329.C [new file with mode: 0644]
gcc/tree-ssa-dom.c

index a2ba7c3..da50be3 100644 (file)
@@ -1,4 +1,11 @@
-2012-11-16  Jan HUbicka  <jh@suse.cz>
+2012-11-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/55329
+       * tree-ssa-dom.c (tree_ssa_dominator_optimize): Never clear
+       bits in needed_eh_cleanup while iterating over the bitmap.
+       Look through all forwarder blocks at once.
+
+2012-11-16  Jan Hubicka  <jh@suse.cz>
 
        * params.def (max-peeled-insns, max-completely-peeled-insns): Reduce to 100.
 
index 7606bac..9cb21c7 100644 (file)
@@ -1,3 +1,8 @@
+2012-11-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/55329
+       * g++.dg/opt/pr55329.C: New test.
+
 2012-11-16  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/55297
diff --git a/gcc/testsuite/g++.dg/opt/pr55329.C b/gcc/testsuite/g++.dg/opt/pr55329.C
new file mode 100644 (file)
index 0000000..3646785
--- /dev/null
@@ -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;
+}
index 7322b58..7d015b7 100644 (file)
@@ -1,6 +1,6 @@
 /* SSA Dominator optimizations for trees
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011, 2012 Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -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);