aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-12-12 21:59:28 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-12-12 21:59:28 +0100
commitc88388e6745fb65bbc41c1e941c41f02ff27e4b7 (patch)
treed9ebb1c9ea36d449c1e94f5161ff2d92f15b634d /gcc
parent9c3b03463a63d80970178d7df77bb36e19ee9e0b (diff)
downloadgcc-c88388e6745fb65bbc41c1e941c41f02ff27e4b7.zip
gcc-c88388e6745fb65bbc41c1e941c41f02ff27e4b7.tar.gz
gcc-c88388e6745fb65bbc41c1e941c41f02ff27e4b7.tar.bz2
re PR tree-optimization/51481 (ice: dead STMT in EH table)
PR tree-optimization/51481 * gimple-fold.c (gimple_fold_call): Call maybe_clean_or_replace_eh_stmt. Avoid optimization if stmt has EH edges, but gimple_fold_builtin result can't throw. * gcc.dg/pr51481.c: New test. From-SVN: r182264
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gimple-fold.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr51481.c33
4 files changed, 57 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9de9571..68d354d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2011-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/51481
+ * gimple-fold.c (gimple_fold_call): Call
+ maybe_clean_or_replace_eh_stmt. Avoid optimization if stmt has EH
+ edges, but gimple_fold_builtin result can't throw.
+
2011-12-12 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/21617
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 91dd8fc..4afced8 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1117,10 +1117,21 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
if (callee && DECL_BUILT_IN (callee))
{
tree result = gimple_fold_builtin (stmt);
- if (result)
+ if (result
+ /* Disallow EH edge removal here. We can't call
+ gimple_purge_dead_eh_edges here. */
+ && (lookup_stmt_eh_lp (stmt) == 0
+ || tree_could_throw_p (result)))
{
if (!update_call_from_tree (gsi, result))
gimplify_and_update_call_from_tree (gsi, result);
+ if (!gsi_end_p (*gsi))
+ {
+ gimple new_stmt = gsi_stmt (*gsi);
+ bool update_eh ATTRIBUTE_UNUSED
+ = maybe_clean_or_replace_eh_stmt (stmt, new_stmt);
+ gcc_assert (!update_eh);
+ }
changed = true;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 39e301a..5f0f195 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/51481
+ * gcc.dg/pr51481.c: New test.
+
2011-12-12 Georg-Johann Lay <avr@gjlay.de>
PR tree-optimization/45830
diff --git a/gcc/testsuite/gcc.dg/pr51481.c b/gcc/testsuite/gcc.dg/pr51481.c
new file mode 100644
index 0000000..d883d47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51481.c
@@ -0,0 +1,33 @@
+/* PR tree-optimization/51481 */
+/* { dg-do compile } */
+/* { dg-options "-O -fexceptions -fipa-cp -fipa-cp-clone" } */
+
+extern const unsigned short int **foo (void)
+ __attribute__ ((__nothrow__, __const__));
+struct S { unsigned short s1; int s2; };
+extern struct S *s[26];
+
+void
+bar (int x, struct S *y, ...)
+{
+ static struct S *t;
+ __builtin_va_list ap;
+ __builtin_va_start (ap, y);
+ if (t != s[7])
+ {
+ const char *p = "aAbBc";
+ t = s[7];
+ while ((*foo ())[(unsigned char) *p])
+ p++;
+ }
+ __builtin_printf (x == 0 ? "abc\n" : "def\n");
+ if (y != 0)
+ __builtin_printf ("ghi %d %d", y->s2, y->s1);
+ __builtin_va_end (ap);
+}
+
+void
+baz (char *x)
+{
+ bar (1, 0, x);
+}