diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-10-21 23:14:06 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-10-21 21:14:06 +0000 |
commit | 74bb77094f3b512e146f61c2e218c842f4a8d53b (patch) | |
tree | 12fd4877448080c5a10e84c2b07669d069128d20 /gcc/ipa-polymorphic-call.c | |
parent | 1567db2f02e005b7a3349aedf0afb37c36260beb (diff) | |
download | gcc-74bb77094f3b512e146f61c2e218c842f4a8d53b.zip gcc-74bb77094f3b512e146f61c2e218c842f4a8d53b.tar.gz gcc-74bb77094f3b512e146f61c2e218c842f4a8d53b.tar.bz2 |
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
Diffstat (limited to 'gcc/ipa-polymorphic-call.c')
-rw-r--r-- | gcc/ipa-polymorphic-call.c | 18 |
1 files changed, 17 insertions, 1 deletions
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; |