Hi,
since we hit can of worms here, I decided to decompose the changes into minimal 
patches.
This is first one fixing small bug introduced last July in Martin's change to 
add
a flags to passthrough about the type preservation.  This does not affect 
gcc-4.8

Bootstrapped/regtested x86_64-linux, will comit it shortly.

        * ipa-prop.c (update_jump_functions_after_inlining): When type is not
        preserverd by passthrough, do not propagate the type.
Index: ipa-prop.c
===================================================================
--- ipa-prop.c  (revision 207393)
+++ ipa-prop.c  (working copy)
@@ -2359,10 +2359,13 @@ update_jump_functions_after_inlining (st
                  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: testsuite/g++.dg/ipa/devirt-21.C
===================================================================
--- testsuite/g++.dg/ipa/devirt-21.C    (revision 0)
+++ testsuite/g++.dg/ipa/devirt-21.C    (revision 0)
@@ -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" } } */

Reply via email to