diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-02-02 19:56:33 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-02-02 18:56:33 +0000 |
commit | 2ace77c21a7f35b9d98b8a6ecd7d95f5b0c30b1a (patch) | |
tree | df688f58672abd79650138829dcf8c5fc787554b /gcc | |
parent | e738433e45336d14904a8142169bbbf4dd7faa28 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/devirt-21.C | 41 |
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" } } */ |