aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-04-17 13:42:48 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-04-17 13:42:48 +0000
commitefa26eaae377bf2a5ce9b02b84f3963a0166e280 (patch)
treea481bf2c7620ac00b781d4d362582751514e3c3f
parentd51e8a2df2f9eadb6aa8a1bcf00d62e17b6ef4cf (diff)
downloadgcc-efa26eaae377bf2a5ce9b02b84f3963a0166e280.zip
gcc-efa26eaae377bf2a5ce9b02b84f3963a0166e280.tar.gz
gcc-efa26eaae377bf2a5ce9b02b84f3963a0166e280.tar.bz2
re PR rtl-optimization/53011 (ice in verify_loop_structure: bad sizes)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr53011.C66
-rw-r--r--gcc/tree-eh.c15
4 files changed, 92 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7de0e0b..e09d672 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0b6fcf5..e1862c6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..2cd8a60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr53011.C
@@ -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;
+}
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index ba188d8..0241a5f 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -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);