aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-polymorphic-call.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-10-21 23:14:06 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2015-10-21 21:14:06 +0000
commit74bb77094f3b512e146f61c2e218c842f4a8d53b (patch)
tree12fd4877448080c5a10e84c2b07669d069128d20 /gcc/ipa-polymorphic-call.c
parent1567db2f02e005b7a3349aedf0afb37c36260beb (diff)
downloadgcc-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.c18
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;