re PR ipa/60965 (IPA: Devirtualization versus placement new)
authorJan Hubicka <hubicka@ucw.cz>
Mon, 5 May 2014 23:27:40 +0000 (01:27 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 5 May 2014 23:27:40 +0000 (23:27 +0000)
PR ipa/60965
* ipa-devirt.c (get_class_context): Allow POD to change to non-POD.
* g++.dg/ipa/devirt-32.C: New testcase.

From-SVN: r210086

gcc/ChangeLog
gcc/ipa-devirt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/devirt-32.C [new file with mode: 0644]

index 0a5bd037420479d69cee8a4668eb2c3a254485a7..41dee8fac68bf93ec5700b87dc1a92ea495ea7bc 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/60965
+       * ipa-devirt.c (get_class_context): Allow POD to change to non-POD.
+
 2014-05-05  Radovan Obradovic  <robradovic@mips.com>
             Tom de Vries  <tom@codesourcery.com>
 
index 4ff31fc6638c8aae61fb8b4b97ab48d2c5b809a8..5cd4c832d2c6fd369ba399c8441f178daa86d85c 100644 (file)
@@ -1137,6 +1137,17 @@ give_up:
   context->outer_type = expected_type;
   context->offset = 0;
   context->maybe_derived_type = true;
+  context->maybe_in_construction = true;
+  /* POD can be changed to an instance of a polymorphic type by
+     placement new.  Here we play safe and assume that any
+     non-polymorphic type is POD.  */
+  if ((TREE_CODE (type) != RECORD_TYPE
+       || !TYPE_BINFO (type)
+       || !polymorphic_type_binfo_p (TYPE_BINFO (type)))
+      && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
+         || (offset + tree_to_uhwi (TYPE_SIZE (expected_type)) <=
+             tree_to_uhwi (TYPE_SIZE (type)))))
+    return true;
   return false;
 }
 
index 1c9d4d31c662b1d7aceb102e795c7ba4baf5f703..a3dd81c0864e8b3d759d95a75d43b5902441b3f8 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/60965
+       * g++.dg/ipa/devirt-32.C: New testcase.
+
 2014-05-05  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/61010
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-32.C b/gcc/testsuite/g++.dg/ipa/devirt-32.C
new file mode 100644 (file)
index 0000000..64c44ba
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-options "-O2 -std=c++11 -fdump-ipa-inline"  } */
+#include <new>
+
+class EmbeddedObject {
+public:
+  virtual int val() { return 2; }
+};
+
+class Container {
+  alignas(EmbeddedObject) char buffer[sizeof(EmbeddedObject)];
+public:
+  EmbeddedObject *obj() { return (EmbeddedObject*)buffer; }
+  Container() { new (buffer) EmbeddedObject(); }
+};
+
+Container o;
+
+int main()
+{
+  __builtin_printf("%d\n", o.obj()->val());
+}
+/* { dg-final { scan-ipa-dump-not "__builtin_unreachable"  "inline"  } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */