diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-12-12 21:59:28 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-12-12 21:59:28 +0100 |
commit | c88388e6745fb65bbc41c1e941c41f02ff27e4b7 (patch) | |
tree | d9ebb1c9ea36d449c1e94f5161ff2d92f15b634d | |
parent | 9c3b03463a63d80970178d7df77bb36e19ee9e0b (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr51481.c | 33 |
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); +} |