From 74bb77094f3b512e146f61c2e218c842f4a8d53b Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 21 Oct 2015 23:14:06 +0200 Subject: [PATCH] re PR ipa/67056 (Wrong code generated) 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. * g++.dg/ipa/pr67056.C: New testcase. From-SVN: r229148 --- gcc/ChangeLog | 8 ++++++ gcc/ipa-polymorphic-call.c | 18 +++++++++++++- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/ipa/pr67056.C | 39 ++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr67056.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 38ae32110db..bc3cfa7cb93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-10-11 Jan Hubicka + + 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 * fold-const.c (operand_equal_p): Add code matching empty diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index 99770dedf11..9ce86d1c7d4 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 4637ae747e2..d2a7da62e8c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-10-11 Jan Hubicka + + PR ipa/67056 + * g++.dg/ipa/pr67056.C: New testcase. + 2015-10-11 Jan Hubicka * gcc.dg/tree-ssa/operand-equal-1.c: Verify that empty constructors diff --git a/gcc/testsuite/g++.dg/ipa/pr67056.C b/gcc/testsuite/g++.dg/ipa/pr67056.C new file mode 100644 index 00000000000..f47323b6e5d --- /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 + +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 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" } } */ -- 2.30.2