aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-polymorphic-call.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr67056.C39
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" } } */