aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-11-13 00:09:15 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-11-13 00:09:15 +0100
commitabb502071166f1eee1869cd5304d30d6763979f9 (patch)
tree0a91fe6829441e9337146867d824a26d24912a60 /gcc
parentf03cee1186e8cf919af19e5941492d20bdcfa860 (diff)
downloadgcc-abb502071166f1eee1869cd5304d30d6763979f9.zip
gcc-abb502071166f1eee1869cd5304d30d6763979f9.tar.gz
gcc-abb502071166f1eee1869cd5304d30d6763979f9.tar.bz2
re PR ipa/63838 (ipa-pure-const miscomputes can_throw)
PR ipa/63838 * ipa-pure-const.c (propagate_nothrow): Walk w->indirect_calls chain instead of node->indirect_calls. Put !can_throw into conditions of all the loops. * g++.dg/ipa/pr63838.C: New test. From-SVN: r217449
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/ipa-pure-const.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr63838.C56
4 files changed, 72 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 15a55c0..458773e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2014-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/63838
+ * ipa-pure-const.c (propagate_nothrow): Walk w->indirect_calls
+ chain instead of node->indirect_calls. Put !can_throw into
+ conditions of all the loops.
+
2014-11-12 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (x86_output_mi_thunk): Use gen_rtx_REG to
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index d6999fa..6f7b32c 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -1448,7 +1448,7 @@ propagate_nothrow (void)
/* Find the worst state for any node in the cycle. */
w = node;
- while (w)
+ while (w && !can_throw)
{
struct cgraph_edge *e, *ie;
funct_state w_l = get_function_state (w);
@@ -1457,10 +1457,7 @@ propagate_nothrow (void)
|| w->get_availability () == AVAIL_INTERPOSABLE)
can_throw = true;
- if (can_throw)
- break;
-
- for (e = w->callees; e; e = e->next_callee)
+ for (e = w->callees; e && !can_throw; e = e->next_callee)
{
enum availability avail;
struct cgraph_node *y = e->callee->function_symbol (&avail);
@@ -1469,8 +1466,6 @@ propagate_nothrow (void)
{
funct_state y_l = get_function_state (y);
- if (can_throw)
- break;
if (y_l->can_throw && !TREE_NOTHROW (w->decl)
&& e->can_throw_external)
can_throw = true;
@@ -1478,12 +1473,9 @@ propagate_nothrow (void)
else if (e->can_throw_external && !TREE_NOTHROW (y->decl))
can_throw = true;
}
- for (ie = node->indirect_calls; ie; ie = ie->next_callee)
+ for (ie = w->indirect_calls; ie && !can_throw; ie = ie->next_callee)
if (ie->can_throw_external)
- {
- can_throw = true;
- break;
- }
+ can_throw = true;
w_info = (struct ipa_dfs_info *) w->aux;
w = w_info->next_cycle;
}
@@ -1794,5 +1786,3 @@ make_pass_warn_function_noreturn (gcc::context *ctxt)
{
return new pass_warn_function_noreturn (ctxt);
}
-
-
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c2cbfe8..66c66c4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR ipa/63838
+ * g++.dg/ipa/pr63838.C: New test.
+
2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com>
* gcc.target/mips/args-1.c: Handle __mips_fpr == 0.
diff --git a/gcc/testsuite/g++.dg/ipa/pr63838.C b/gcc/testsuite/g++.dg/ipa/pr63838.C
new file mode 100644
index 0000000..d673649
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr63838.C
@@ -0,0 +1,56 @@
+// PR ipa/63838
+// { dg-do run }
+// { dg-options "-O2 -fdump-ipa-pure-const" }
+// { dg-final { scan-ipa-dump-not "Function found to be nothrow: void foo" "pure-const" } }
+// { dg-final { scan-ipa-dump-not "Function found to be nothrow: void bar" "pure-const" } }
+// { dg-final { cleanup-ipa-dump "pure-const" } }
+
+__attribute__((noinline, noclone)) static void bar (int);
+volatile int v;
+void (*fn) ();
+struct S { S () { v++; } ~S () { v++; } };
+
+__attribute__((noinline, noclone)) static void
+foo (int x)
+{
+ v++;
+ if (x == 5)
+ bar (x);
+}
+
+__attribute__((noinline, noclone)) static void
+bar (int x)
+{
+ v++;
+ if (x == 6)
+ foo (x);
+ else if (x == 5)
+ fn ();
+}
+
+__attribute__((noinline, noclone)) int
+baz (int x)
+{
+ S s;
+ foo (x);
+}
+
+void
+throw0 ()
+{
+ throw 0;
+}
+
+int
+main ()
+{
+ fn = throw0;
+ asm volatile ("" : : : "memory");
+ try
+ {
+ baz (5);
+ }
+ catch (int)
+ {
+ }
+}