aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-01-19 00:16:16 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-01-19 00:16:16 +0100
commitafaaa67d427a9df12d7377546a7a5dafc66ed210 (patch)
tree7b35321de8d0dd4df0dafa71e743ef081c115373
parent2d300fac7d9aaaa9f5cb63a44b3cfc130895324d (diff)
downloadgcc-afaaa67d427a9df12d7377546a7a5dafc66ed210.zip
gcc-afaaa67d427a9df12d7377546a7a5dafc66ed210.tar.gz
gcc-afaaa67d427a9df12d7377546a7a5dafc66ed210.tar.bz2
re PR tree-optimization/47290 (memory exhausted compiling a destructor with an infinite 'for (;;);' loop)
PR tree-optimization/47290 * tree-eh.c (infinite_empty_loop_p): New function. (cleanup_empty_eh): Use it. * g++.dg/torture/pr47290.C: New test. From-SVN: r168974
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr47290.C19
-rw-r--r--gcc/tree-eh.c40
4 files changed, 68 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6c72e69..c456fb3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-01-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/47290
+ * tree-eh.c (infinite_empty_loop_p): New function.
+ (cleanup_empty_eh): Use it.
+
2011-01-18 Steve Ellcey <sje@cup.hp.com>
PR target/46997
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9c3e8ba..550aee1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-01-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/47290
+ * g++.dg/torture/pr47290.C: New test.
+
2011-01-18 Janus Weil <janus@gcc.gnu.org>
PR fortran/47240
diff --git a/gcc/testsuite/g++.dg/torture/pr47290.C b/gcc/testsuite/g++.dg/torture/pr47290.C
new file mode 100644
index 0000000..b739de5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr47290.C
@@ -0,0 +1,19 @@
+// PR tree-optimization/47290
+// { dg-do compile }
+
+struct V
+{
+ V (int = 0);
+ ~V ()
+ {
+ for (;;)
+ ;
+ }
+ int size ();
+};
+
+struct S
+{
+ V a, b;
+ S () : b (a.size ()) {}
+} s;
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 270d76d..65d0ff2 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -1,5 +1,5 @@
/* Exception handling semantics and decomposition for trees.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
@@ -3724,6 +3724,42 @@ cleanup_empty_eh_unsplit (basic_block bb, edge e_out, eh_landing_pad lp)
return false;
}
+/* Return true if edge E_FIRST is part of an empty infinite loop
+ or leads to such a loop through a series of single successor
+ empty bbs. */
+
+static bool
+infinite_empty_loop_p (edge e_first)
+{
+ bool inf_loop = false;
+ edge e;
+
+ if (e_first->dest == e_first->src)
+ return true;
+
+ e_first->src->aux = (void *) 1;
+ for (e = e_first; single_succ_p (e->dest); e = single_succ_edge (e->dest))
+ {
+ gimple_stmt_iterator gsi;
+ if (e->dest->aux)
+ {
+ inf_loop = true;
+ break;
+ }
+ e->dest->aux = (void *) 1;
+ gsi = gsi_after_labels (e->dest);
+ if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
+ gsi_next_nondebug (&gsi);
+ if (!gsi_end_p (gsi))
+ break;
+ }
+ e_first->src->aux = NULL;
+ for (e = e_first; e->dest->aux; e = single_succ_edge (e->dest))
+ e->dest->aux = NULL;
+
+ return inf_loop;
+}
+
/* Examine the block associated with LP to determine if it's an empty
handler for its EH region. If so, attempt to redirect EH edges to
an outer region. Return true the CFG was updated in any way. This
@@ -3763,7 +3799,7 @@ cleanup_empty_eh (eh_landing_pad lp)
if (gsi_end_p (gsi))
{
/* For the degenerate case of an infinite loop bail out. */
- if (e_out->dest == bb)
+ if (infinite_empty_loop_p (e_out))
return false;
return cleanup_empty_eh_unsplit (bb, e_out, lp);