re PR rtl-optimization/53011 (ice in verify_loop_structure: bad sizes)
authorRichard Guenther <rguenther@suse.de>
Tue, 17 Apr 2012 13:42:48 +0000 (13:42 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 17 Apr 2012 13:42:48 +0000 (13:42 +0000)
2012-04-17  Richard Guenther  <rguenther@suse.de>

PR middle-end/53011
* tree-eh.c (cleanup_empty_eh_merge_phis): Properly discard
loops when redirecting an entry or latch edge.

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

From-SVN: r186529

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr53011.C [new file with mode: 0644]
gcc/tree-eh.c

index 7de0e0bdcf5afd065c8c7254fcb352d24bb7b016..e09d6724b6f620602b3bbdd058ab52fcf4f40100 100644 (file)
@@ -1,3 +1,9 @@
+2012-04-17  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/53011
+       * tree-eh.c (cleanup_empty_eh_merge_phis): Properly discard
+       loops when redirecting an entry or latch edge.
+
 2012-04-17  Bernd Schmidt  <bernds@codesourcery.com>
 
        * sel-sched.c (sel_global_init): Revert previous change.
index 0b6fcf503177d716eeaa8355a6a8e3cfcadeda19..e1862c65b8fd4569fbc79c2ec709d5215b279319 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-17  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/53011
+       * g++.dg/torture/pr53011.C: New testcase.
+
 2012-04-16  Jason Merrill  <jason@redhat.com>
 
        PR c++/38543
diff --git a/gcc/testsuite/g++.dg/torture/pr53011.C b/gcc/testsuite/g++.dg/torture/pr53011.C
new file mode 100644 (file)
index 0000000..2cd8a60
--- /dev/null
@@ -0,0 +1,66 @@
+// { dg-do compile }
+
+extern "C" class WvFastString;
+typedef WvFastString& WvStringParm;
+struct WvFastString {
+  ~WvFastString();
+  operator char* () {}
+};
+class WvString : WvFastString {};
+class WvAddr {};
+class WvIPAddr : WvAddr {};
+struct WvIPNet : WvIPAddr {
+  bool is_default() {}
+};
+template<class T, bool> struct WvTraits_Helper {
+  static void release(T *obj) {
+    delete obj;
+  }
+};
+template<class From> struct WvTraits {
+  static void release(From *obj) {
+    WvTraits_Helper<From, 0>::release(obj);
+  }
+};
+struct WvLink {
+  void   *data;
+  WvLink *next;
+  bool    autofree;
+  WvLink(bool, int) : autofree() {}
+  bool get_autofree() {}
+
+  void unlink() {
+    delete this;
+  }
+};
+struct WvListBase {
+  WvLink head, *tail;
+  WvListBase() : head(0, 0) {}
+};
+template<class T> struct WvList : WvListBase {
+  ~WvList() {
+    zap();
+  }
+
+  void zap(bool destroy = 1) {
+    while (head.next) unlink_after(&head, destroy);
+  }
+
+  void unlink_after(WvLink *after, bool destroy) {
+    WvLink *next = 0;
+    T *obj       = (destroy && next->get_autofree()) ? 
+                   static_cast<T*>(next->data) : 0;
+
+    if (tail) tail = after;
+    next->unlink();
+    WvTraits<T>::release(obj);
+  }
+};
+typedef WvList<WvString>WvStringListBase;
+class WvStringList : WvStringListBase {};
+class WvSubProc {
+  WvStringList last_args, env;
+};
+void addroute(WvIPNet& dest, WvStringParm table) {
+  if (dest.is_default() || (table != "default")) WvSubProc checkProc;
+}
index ba188d85a77d462ca5627d1d04c7f13e82cb50b6..0241a5f1bc43b05e34616d4ba8623d231b44875f 100644 (file)
@@ -3916,6 +3916,21 @@ cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
   for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)); )
     if (e->flags & EDGE_EH)
       {
+       /* ???  CFG manipluation routines do not try to update loop
+          form on edge redirection.  Do so manually here for now.  */
+       /* If we redirect a loop entry or latch edge that will either create
+          a multiple entry loop or rotate the loop.  If the loops merge
+          we may have created a loop with multiple latches.
+          All of this isn't easily fixed thus cancel the affected loop
+          and mark the other loop as possibly having multiple latches.  */
+       if (current_loops
+           && e->dest == e->dest->loop_father->header)
+         {
+           e->dest->loop_father->header = NULL;
+           e->dest->loop_father->latch = NULL;
+           new_bb->loop_father->latch = NULL;
+           loops_state_set (LOOPS_NEED_FIXUP|LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+         }
        redirect_eh_edge_1 (e, new_bb, change_region);
        redirect_edge_succ (e, new_bb);
        flush_pending_stmts (e);