diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-08-10 00:07:55 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-08-09 22:07:55 +0000 |
commit | 726540aa29ba5d46a4028852d937ab889be941d8 (patch) | |
tree | f766c9e6c63fdc2649a1496d7e34bbb9a9a0a8d1 /gcc | |
parent | 83a4216dd29316ed9a95931b306ea415664acf51 (diff) | |
download | gcc-726540aa29ba5d46a4028852d937ab889be941d8.zip gcc-726540aa29ba5d46a4028852d937ab889be941d8.tar.gz gcc-726540aa29ba5d46a4028852d937ab889be941d8.tar.bz2 |
devirt-35.C: Fix template.
* g++.dg/ipa/devirt-35.C: Fix template.
* g++.dg/ipa/devirt-36.C: Likewise.
* g++.dg/ipa/devirt-37.C: New testcase.
* ipa-devirt.c (get_dynamic_type): Handle case when instance is in
DECL correctly; do not give up on types in static storage.
From-SVN: r213781
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/ipa-devirt.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/devirt-35.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/devirt-36.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/devirt-37.C | 35 |
6 files changed, 64 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2aa721c..36619f1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-08-09 Jan Hubicka <hubicka@ucw.cz> + + * ipa-devirt.c (get_dynamic_type): Handle case when instance is in + DECL correctly; do not give up on types in static storage. + 2014-08-09 Paolo Carlini <paolo.carlini@oracle.com> * doc/invoke.texi ([Wnarrowing]): Update for non-constants in C++11. diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 8827d0e..3650b43 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -2799,10 +2799,12 @@ get_dynamic_type (tree instance, /* Finally verify that what we found looks like read from OTR_OBJECT or from INSTANCE with offset OFFSET. */ if (base_ref - && TREE_CODE (base_ref) == MEM_REF - && ((offset2 == context->offset - && TREE_OPERAND (base_ref, 0) == instance) - || (!offset2 && TREE_OPERAND (base_ref, 0) == otr_object))) + && ((TREE_CODE (base_ref) == MEM_REF + && ((offset2 == context->offset + && TREE_OPERAND (base_ref, 0) == instance) + || (!offset2 && TREE_OPERAND (base_ref, 0) == otr_object))) + || (DECL_P (instance) && base_ref == instance + && offset2 == context->offset))) { stmt = SSA_NAME_DEF_STMT (ref); instance_ref = ref_exp; @@ -2923,7 +2925,14 @@ get_dynamic_type (tree instance, && !function_entry_reached && !tci.multiple_types_encountered) { - if (!tci.speculative) + if (!tci.speculative + /* Again in instances located in static storage we are interested only + in constructor stores. */ + || (context->outer_type + && !tci.seen_unanalyzed_store + && context->offset == tci.offset + && types_same_for_odr (tci.known_current_type, + context->outer_type))) { context->outer_type = tci.known_current_type; context->offset = tci.known_current_offset; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 073f837..9fe5714 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-08-09 Jan Hubicka <hubicka@ucw.cz> + + * g++.dg/ipa/devirt-35.C: Fix template. + * g++.dg/ipa/devirt-36.C: Likewise. + * g++.dg/ipa/devirt-37.C: New testcase. + 2014-08-09 Paolo Carlini <paolo.carlini@oracle.com> * g++.dg/cpp0x/Wnarrowing1.C: Adjust for errors. diff --git a/gcc/testsuite/g++.dg/ipa/devirt-35.C b/gcc/testsuite/g++.dg/ipa/devirt-35.C index 6c30430..07383ed 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-35.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-35.C @@ -15,9 +15,9 @@ m(struct B *b) // test2 may change the type of A by placement new. // C++ standard is bit imprecise about this. } -/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */ +/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t" "fre1" } } */ /* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */ /* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */ /* { dg-final { cleanup-ipa-dump "devirt" } } */ -/* { dg-final { cleanup-tree-dump "fre" } } */ +/* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-36.C b/gcc/testsuite/g++.dg/ipa/devirt-36.C index c32531d..6d7206c 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-36.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-36.C @@ -17,9 +17,9 @@ m(struct B *b) // test2 may change the type of A by placement new. // C++ standard is bit imprecise about this. } -/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */ +/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t" "fre1" } } */ /* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */ /* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */ /* { dg-final { cleanup-ipa-dump "devirt" } } */ -/* { dg-final { cleanup-tree-dump "fre" } } */ +/* { dg-final { cleanup-tree-dump "fre1" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-37.C b/gcc/testsuite/g++.dg/ipa/devirt-37.C new file mode 100644 index 0000000..15766fe --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-37.C @@ -0,0 +1,35 @@ +/* { dg-options "-fpermissive -fno-indirect-inlining -fno-devirtualize-speculatively -fdump-tree-fre2-details" } */ +#include <stdlib.h> +struct A {virtual void test() {abort ();}}; +struct B:A + {virtual void test() {} + B(); + B(void (*test)(struct A *));}; + +void extcall(void); + +inline void tt(struct A *a) +{ + a->test(); +} + +B::B (void (*test)(struct A *)) +{ + struct B c; + struct A *a=this; + extcall(); + test(a); +} +void +t() +{ + struct B b(tt); +} +/* After inlining the call within constructor needs to be checked to not go into a basetype. + We should see the vtbl store and we should notice extcall as possibly clobbering the + type but ignore it because b is in static storage. */ +/* { dg-final { scan-tree-dump "Determined dynamic type." "fre2" } } */ +/* { dg-final { scan-tree-dump "Checking vtbl store:" "fre2" } } */ +/* { dg-final { scan-tree-dump "Function call may change dynamic type:extcall" "fre2" } } */ +/* { dg-final { scan-tree-dump "converting indirect call to function virtual void" "fre2" } } */ +/* { dg-final { cleanup-tree-dump "fre2" } } */ |