+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
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
&& 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;
+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
--- /dev/null
+/* { 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" } } */