aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-08-10 00:07:55 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-08-09 22:07:55 +0000
commit726540aa29ba5d46a4028852d937ab889be941d8 (patch)
treef766c9e6c63fdc2649a1496d7e34bbb9a9a0a8d1 /gcc
parent83a4216dd29316ed9a95931b306ea415664acf51 (diff)
downloadgcc-726540aa29ba5d46a4028852d937ab889be941d8.zip
gcc-726540aa29ba5d46a4028852d937ab889be941d8.tar.gz
gcc-726540aa29ba5d46a4028852d937ab889be941d8.tar.bz2
devirt-35.C: Fix template.
* g++.dg/ipa/devirt-35.C: Fix template. * g++.dg/ipa/devirt-36.C: Likewise. * g++.dg/ipa/devirt-37.C: New testcase. * ipa-devirt.c (get_dynamic_type): Handle case when instance is in DECL correctly; do not give up on types in static storage. From-SVN: r213781
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/ipa-devirt.c19
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-35.C4
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-36.C4
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-37.C35
6 files changed, 64 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2aa721c..36619f1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-08-09 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-devirt.c (get_dynamic_type): Handle case when instance is in
+ DECL correctly; do not give up on types in static storage.
+
2014-08-09 Paolo Carlini <paolo.carlini@oracle.com>
* doc/invoke.texi ([Wnarrowing]): Update for non-constants in C++11.
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 8827d0e..3650b43 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2799,10 +2799,12 @@ get_dynamic_type (tree instance,
/* Finally verify that what we found looks like read from OTR_OBJECT
or from INSTANCE with offset OFFSET. */
if (base_ref
- && TREE_CODE (base_ref) == MEM_REF
- && ((offset2 == context->offset
- && TREE_OPERAND (base_ref, 0) == instance)
- || (!offset2 && TREE_OPERAND (base_ref, 0) == otr_object)))
+ && ((TREE_CODE (base_ref) == MEM_REF
+ && ((offset2 == context->offset
+ && TREE_OPERAND (base_ref, 0) == instance)
+ || (!offset2 && TREE_OPERAND (base_ref, 0) == otr_object)))
+ || (DECL_P (instance) && base_ref == instance
+ && offset2 == context->offset)))
{
stmt = SSA_NAME_DEF_STMT (ref);
instance_ref = ref_exp;
@@ -2923,7 +2925,14 @@ get_dynamic_type (tree instance,
&& !function_entry_reached
&& !tci.multiple_types_encountered)
{
- if (!tci.speculative)
+ if (!tci.speculative
+ /* Again in instances located in static storage we are interested only
+ in constructor stores. */
+ || (context->outer_type
+ && !tci.seen_unanalyzed_store
+ && context->offset == tci.offset
+ && types_same_for_odr (tci.known_current_type,
+ context->outer_type)))
{
context->outer_type = tci.known_current_type;
context->offset = tci.known_current_offset;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 073f837..9fe5714 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-08-09 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/ipa/devirt-35.C: Fix template.
+ * g++.dg/ipa/devirt-36.C: Likewise.
+ * g++.dg/ipa/devirt-37.C: New testcase.
+
2014-08-09 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/cpp0x/Wnarrowing1.C: Adjust for errors.
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-35.C b/gcc/testsuite/g++.dg/ipa/devirt-35.C
index 6c30430..07383ed 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-35.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-35.C
@@ -15,9 +15,9 @@ m(struct B *b)
// test2 may change the type of A by placement new.
// C++ standard is bit imprecise about this.
}
-/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */
+/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t" "fre1" } } */
/* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */
/* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */
/* { dg-final { cleanup-ipa-dump "devirt" } } */
-/* { dg-final { cleanup-tree-dump "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-36.C b/gcc/testsuite/g++.dg/ipa/devirt-36.C
index c32531d..6d7206c 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-36.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-36.C
@@ -17,9 +17,9 @@ m(struct B *b)
// test2 may change the type of A by placement new.
// C++ standard is bit imprecise about this.
}
-/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */
+/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t" "fre1" } } */
/* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */
/* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */
/* { dg-final { cleanup-ipa-dump "devirt" } } */
-/* { dg-final { cleanup-tree-dump "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-37.C b/gcc/testsuite/g++.dg/ipa/devirt-37.C
new file mode 100644
index 0000000..15766fe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-37.C
@@ -0,0 +1,35 @@
+/* { dg-options "-fpermissive -fno-indirect-inlining -fno-devirtualize-speculatively -fdump-tree-fre2-details" } */
+#include <stdlib.h>
+struct A {virtual void test() {abort ();}};
+struct B:A
+ {virtual void test() {}
+ B();
+ B(void (*test)(struct A *));};
+
+void extcall(void);
+
+inline void tt(struct A *a)
+{
+ a->test();
+}
+
+B::B (void (*test)(struct A *))
+{
+ struct B c;
+ struct A *a=this;
+ extcall();
+ test(a);
+}
+void
+t()
+{
+ struct B b(tt);
+}
+/* After inlining the call within constructor needs to be checked to not go into a basetype.
+ We should see the vtbl store and we should notice extcall as possibly clobbering the
+ type but ignore it because b is in static storage. */
+/* { dg-final { scan-tree-dump "Determined dynamic type." "fre2" } } */
+/* { dg-final { scan-tree-dump "Checking vtbl store:" "fre2" } } */
+/* { dg-final { scan-tree-dump "Function call may change dynamic type:extcall" "fre2" } } */
+/* { dg-final { scan-tree-dump "converting indirect call to function virtual void" "fre2" } } */
+/* { dg-final { cleanup-tree-dump "fre2" } } */