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); }