aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-02-02 19:56:33 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2014-02-02 18:56:33 +0000
commit2ace77c21a7f35b9d98b8a6ecd7d95f5b0c30b1a (patch)
treedf688f58672abd79650138829dcf8c5fc787554b /gcc
parente738433e45336d14904a8142169bbbf4dd7faa28 (diff)
downloadgcc-2ace77c21a7f35b9d98b8a6ecd7d95f5b0c30b1a.zip
gcc-2ace77c21a7f35b9d98b8a6ecd7d95f5b0c30b1a.tar.gz
gcc-2ace77c21a7f35b9d98b8a6ecd7d95f5b0c30b1a.tar.bz2
ipa-prop.c (update_jump_functions_after_inlining): When type is not preserverd by passthrough, do not propagate the type.
* ipa-prop.c (update_jump_functions_after_inlining): When type is not preserverd by passthrough, do not propagate the type. * g++.dg/ipa/devirt-23.C: New testcase. From-SVN: r207405
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/ipa-prop.c11
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-21.C41
4 files changed, 57 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index af84338..09b1208 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-02-02 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-prop.c (update_jump_functions_after_inlining): When type is not
+ preserverd by passthrough, do not propagate the type.
+
2014-02-02 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (MIPS_GET_FCSR, MIPS_SET_FCSR): New macros.
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index af2e223..f8a1ca4 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2359,10 +2359,13 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
dst->type = IPA_JF_UNKNOWN;
break;
case IPA_JF_KNOWN_TYPE:
- ipa_set_jf_known_type (dst,
- ipa_get_jf_known_type_offset (src),
- ipa_get_jf_known_type_base_type (src),
- ipa_get_jf_known_type_base_type (src));
+ if (ipa_get_jf_pass_through_type_preserved (dst))
+ ipa_set_jf_known_type (dst,
+ ipa_get_jf_known_type_offset (src),
+ ipa_get_jf_known_type_base_type (src),
+ ipa_get_jf_known_type_base_type (src));
+ else
+ dst->type = IPA_JF_UNKNOWN;
break;
case IPA_JF_CONST:
ipa_set_jf_cst_copy (dst, src);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1f27d7e..0e17c17 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-02-02 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/ipa/devirt-23.C: New testcase.
+
2014-02-02 Richard Sandiford <rdsandiford@googlemail.com>
* gcc.target/mips/get-fcsr-1.c, gcc.target/mips/get-fcsr-2.c,
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-21.C b/gcc/testsuite/g++.dg/ipa/devirt-21.C
new file mode 100644
index 0000000..99f60af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-21.C
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-early-inlining -fno-ipa-sra -fdump-ipa-cp" } */
+/* Main purpose is to verify that we do not produce wrong devirtualization to
+ C::m_fn1. We currently devirtualize to B::m_fn1, so check that. */
+#include <stdlib.h>
+class A {
+public:
+ unsigned length;
+};
+class B {};
+class MultiTermDocs : public virtual B {
+protected:
+ A readerTermDocs;
+ A subReaders;
+ virtual B *m_fn1(int *) {}
+ virtual inline ~MultiTermDocs();
+ void wrap(void)
+ {
+ m_fn1(NULL);
+ }
+};
+class C : MultiTermDocs {
+ B *m_fn1(int *);
+};
+MultiTermDocs::~MultiTermDocs() {
+ wrap ();
+ if (&readerTermDocs) {
+ B *a;
+ for (unsigned i = 0; i < subReaders.length; i++)
+ (a != 0);
+ }
+}
+
+B *C::m_fn1(int *) { abort (); }
+
+main()
+{
+ class C c;
+}
+/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */