]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
devirt-35.C: Fix template.
authorJan Hubicka <hubicka@ucw.cz>
Sat, 9 Aug 2014 22:07:55 +0000 (00:07 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 9 Aug 2014 22:07:55 +0000 (22:07 +0000)
* 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

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

index 2aa721c9ce26d82c82c79d04ed7ead7ff6ab4c1c..36619f1b1a13e38015c697ea98650cadcfe5db69 100644 (file)
@@ -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.
index 8827d0ecb523db8b585a2074896cac75829dd8c9..3650b43e8a123211d9e41961110add708c4b7eae 100644 (file)
@@ -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;
index 073f83780b871f5958f5b9cf0b1ad850cd1ba63b..9fe57147ca5f8987e992a7b1ad91c26a784864be 100644 (file)
@@ -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.
index 6c304304f29674bd4a900858bd7d472b6e2c9dd0..07383ed795bf6e15bc71bbd9f7728770e41c97ea 100644 (file)
@@ -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" } } */
 
index c32531ded585598ccd2132ab8ba4c615c800d3d1..6d7206c11603ea5e468fd2efc9c7ec58a7ef3e40 100644 (file)
@@ -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 (file)
index 0000000..15766fe
--- /dev/null
@@ -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" } } */