ipa-prop.c (update_jump_functions_after_inlining): When type is not preserverd by...
authorJan Hubicka <hubicka@ucw.cz>
Sun, 2 Feb 2014 18:56:33 +0000 (19:56 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 2 Feb 2014 18:56:33 +0000 (18:56 +0000)
* ipa-prop.c (update_jump_functions_after_inlining): When type is not
preserverd by passthrough, do not propagate the type.
* g++.dg/ipa/devirt-23.C: New testcase.

From-SVN: r207405

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

index af84338..09b1208 100644 (file)
@@ -1,3 +1,8 @@
+2014-02-02  Jan Hubicka  <hubicka@ucw.cz>
+
+       * ipa-prop.c (update_jump_functions_after_inlining): When type is not
+       preserverd by passthrough, do not propagate the type.
+
 2014-02-02  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * config/mips/mips.c (MIPS_GET_FCSR, MIPS_SET_FCSR): New macros.
index af2e223..f8a1ca4 100644 (file)
@@ -2359,10 +2359,13 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
                  dst->type = IPA_JF_UNKNOWN;
                  break;
                case IPA_JF_KNOWN_TYPE:
-                 ipa_set_jf_known_type (dst,
-                                        ipa_get_jf_known_type_offset (src),
-                                        ipa_get_jf_known_type_base_type (src),
-                                        ipa_get_jf_known_type_base_type (src));
+                 if (ipa_get_jf_pass_through_type_preserved (dst))
+                   ipa_set_jf_known_type (dst,
+                                          ipa_get_jf_known_type_offset (src),
+                                          ipa_get_jf_known_type_base_type (src),
+                                          ipa_get_jf_known_type_base_type (src));
+                 else
+                   dst->type = IPA_JF_UNKNOWN;
                  break;
                case IPA_JF_CONST:
                  ipa_set_jf_cst_copy (dst, src);
index 1f27d7e..0e17c17 100644 (file)
@@ -1,3 +1,7 @@
+2014-02-02  Jan Hubicka  <hubicka@ucw.cz>
+
+       * g++.dg/ipa/devirt-23.C: New testcase.
+
 2014-02-02  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gcc.target/mips/get-fcsr-1.c, gcc.target/mips/get-fcsr-2.c,
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-21.C b/gcc/testsuite/g++.dg/ipa/devirt-21.C
new file mode 100644 (file)
index 0000000..99f60af
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-early-inlining -fno-ipa-sra -fdump-ipa-cp"  } */
+/* Main purpose is to verify that we do not produce wrong devirtualization to
+   C::m_fn1.  We currently devirtualize to B::m_fn1, so check that. */
+#include <stdlib.h>
+class A {
+public:
+  unsigned length;
+};
+class B {};
+class MultiTermDocs : public virtual B {
+protected:
+  A readerTermDocs;
+  A subReaders;
+  virtual B *m_fn1(int *) {}
+  virtual inline  ~MultiTermDocs();
+  void wrap(void)
+  {
+  m_fn1(NULL);
+  }
+};
+class C : MultiTermDocs {
+  B *m_fn1(int *);
+};
+MultiTermDocs::~MultiTermDocs() {
+  wrap ();
+  if (&readerTermDocs) {
+    B *a;
+    for (unsigned i = 0; i < subReaders.length; i++)
+      (a != 0);
+  }
+}
+
+B *C::m_fn1(int *) { abort (); }
+
+main()
+{
+  class C c;
+}
+/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */
+/* { dg-final { cleanup-ipa-dump "cp" } } */