diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ipa-polymorphic-call.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr67056.C | 39 |
4 files changed, 69 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 38ae321..bc3cfa7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2015-10-11 Jan Hubicka <hubicka@ucw.cz> + PR ipa/67056 + * ipa-polymorphic-call.c (possible_placement_new): If cur_offset + is negative we don't know the type. + (check_stmt_for_type_change): Skip constructors of non-polymorphic + types as those won't help devirutalization. + +2015-10-11 Jan Hubicka <hubicka@ucw.cz> + * fold-const.c (operand_equal_p): Add code matching empty constructors. diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index 99770de..9ce86d1 100644 --- a/gcc/ipa-polymorphic-call.c +++ b/gcc/ipa-polymorphic-call.c @@ -99,6 +99,8 @@ bool possible_placement_new (tree type, tree expected_type, HOST_WIDE_INT cur_offset) { + if (cur_offset < 0) + return true; return ((TREE_CODE (type) != RECORD_TYPE || !TYPE_BINFO (type) || cur_offset >= POINTER_SIZE @@ -1418,7 +1420,21 @@ check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data) && TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST && tree_fits_shwi_p (TYPE_SIZE (type)) - && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset) + && tree_to_shwi (TYPE_SIZE (type)) + offset > tci->offset + /* Some inlined constructors may look as follows: + _3 = operator new (16); + MEM[(struct &)_3] ={v} {CLOBBER}; + MEM[(struct CompositeClass *)_3]._vptr.CompositeClass + = &MEM[(void *)&_ZTV14CompositeClass + 16B]; + _7 = &MEM[(struct CompositeClass *)_3].object; + EmptyClass::EmptyClass (_7); + + When determining dynamic type of _3 and because we stop at first + dynamic type found, we would stop on EmptyClass::EmptyClass (_7). + In this case the emptyclass is not even polymorphic and we miss + it is contained in an outer type that is polymorphic. */ + + && (tci->offset == offset || contains_polymorphic_type_p (type))) { record_known_type (tci, type, tci->offset - offset); return true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4637ae7..d2a7da6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2015-10-11 Jan Hubicka <hubicka@ucw.cz> + PR ipa/67056 + * g++.dg/ipa/pr67056.C: New testcase. + +2015-10-11 Jan Hubicka <hubicka@ucw.cz> + * gcc.dg/tree-ssa/operand-equal-1.c: Verify that empty constructors are matched. diff --git a/gcc/testsuite/g++.dg/ipa/pr67056.C b/gcc/testsuite/g++.dg/ipa/pr67056.C new file mode 100644 index 0000000..f47323b --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr67056.C @@ -0,0 +1,39 @@ +/* { dg-do run } */ +/* { dg-options "-std=c++11 -O3 -fdump-ipa-cp" } */ +/* { dg-additional-options "-fPIC" { target fpic } } */ +#include <memory> + +class EmptyClass { +public: + EmptyClass(); +}; + +EmptyClass::EmptyClass() { +} + +class CompositeClass { +public: + CompositeClass() {} + virtual ~CompositeClass() {} + EmptyClass object; + bool bool1; + bool bool2; +}; + +bool boolFunc() { + return true; +} + +static bool staticBoolFunc(CompositeClass * ptr) { + std::unique_ptr<CompositeClass> up(ptr); + (void)up; + + return boolFunc(); +} + +int main(int, char **) { + staticBoolFunc(new CompositeClass); + return 0; +} + +/* { dg-final { scan-ipa-dump "Speculative outer type:struct CompositeClass" "cp" } } */ |