aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-05-06 01:27:40 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-05-05 23:27:40 +0000
commite400f0815936f54b1993e6ea64316327baa75253 (patch)
treed33b6cc729efd20b1314e56cca509a2cbe6c85a9 /gcc
parentaaeaa9a91c6166d095b0b128315290b538080fac (diff)
downloadgcc-e400f0815936f54b1993e6ea64316327baa75253.zip
gcc-e400f0815936f54b1993e6ea64316327baa75253.tar.gz
gcc-e400f0815936f54b1993e6ea64316327baa75253.tar.bz2
re PR ipa/60965 (IPA: Devirtualization versus placement new)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/ipa-devirt.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-32.C23
4 files changed, 44 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a5bd03..41dee8f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 4ff31fc..5cd4c83 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1c9d4d3..a3dd81c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..64c44ba
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-32.C
@@ -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" } } */