Hi,
this patch fixes two bugs I introducedinto get_binfo_at_offset in the previous 
changes.
First BINFO_OFFSET is pointer to INTEGER_CST and not integer as the code 
assumes.
Second the code gets confused by presence of empty classes (such as in 
testcase) that
may interpose with non-empty.
I fixed it by looking only into basses with virtual table.

Bootstrapped/regtested x86_64-linux, comitted.

Honza

        PR ipa/59882
        * tree.c (get_binfo_at_offset): Do not get confused by empty classes;
        * g++.dg/torture/pr59882.C: New testcase
Index: tree.c
===================================================================
--- tree.c      (revision 207438)
+++ tree.c      (working copy)
@@ -12005,10 +12005,15 @@ get_binfo_at_offset (tree binfo, HOST_WI
                    break;
                  }
                else
-                 if (BINFO_OFFSET (base_binfo) - BINFO_OFFSET (binfo) < pos
+                 if ((tree_to_shwi (BINFO_OFFSET (base_binfo)) 
+                      - tree_to_shwi (BINFO_OFFSET (binfo)))
+                     * BITS_PER_UNIT < pos
+                     /* Rule out types with no virtual methods or we can get 
confused
+                        here by zero sized bases.  */
+                     && BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (base_binfo)))
                      && (!containing_binfo
-                         || (BINFO_OFFSET (containing_binfo)
-                             < BINFO_OFFSET (base_binfo))))
+                         || (tree_to_shwi (BINFO_OFFSET (containing_binfo))
+                             < tree_to_shwi (BINFO_OFFSET (base_binfo)))))
                    containing_binfo = base_binfo;
              if (found_binfo)
                {
Index: testsuite/g++.dg/torture/pr59882.C
===================================================================
--- testsuite/g++.dg/torture/pr59882.C  (revision 0)
+++ testsuite/g++.dg/torture/pr59882.C  (revision 0)
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+class A;
+class B {};
+struct C {
+  virtual void dispatch();
+  int traversal_map_;
+};
+template <typename> class F : public virtual C {};
+
+struct I : F<A>, F<int> {};
+struct J : B, I {};
+class D {};
+struct L {
+  L(D &, int &p2) : map_(p2) {}
+  virtual void traverse(int &p1) {
+    int &s = p1;
+    names<L>(s, names_);
+  }
+  int &map_;
+  J names_;
+  template <typename> void names(int &, C &p2) { p2.dispatch(); }
+};
+
+struct G : D {
+  G(D &, int &p2) : map_(p2) { L(*this, map_); }
+  int &map_;
+};
+
+int a;
+void fn1(D &p1) { G(p1, a); }

Reply via email to