http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59775
--- Comment #9 from Jan Hubicka <hubicka at ucw dot cz> --- This is fix I am testing. It makes get_binfo_at_offset to walk down the non-virtual part of the hiearchy until it hits the proper base. I hope to significantly simplify get_binfo_at_offset by making it to walk bases only and use get_class_context to walk structure fields/array indexes. In that case it would make more sense to implement it same was as record_target_from_binfo (i.e. omit the fields walk completely and only care about bases), but for 4.9 I think this can be resonable fix. Honza Index: tree.c =================================================================== --- tree.c (revision 206542) +++ tree.c (working copy) @@ -11995,16 +11995,35 @@ get_binfo_at_offset (tree binfo, HOST_WI represented in the binfo for the derived class. */ else if (offset != 0) { - tree base_binfo, found_binfo = NULL_TREE; - for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - if (types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld))) - { - found_binfo = base_binfo; - break; - } - if (!found_binfo) - return NULL_TREE; - binfo = found_binfo; + tree base_binfo, binfo2 = binfo; + + /* Find BINFO corresponding to FLD. This is bit harder + by a fact that in virtual inheritance we may need to walk down + the non-virtual inheritance chain. */ + while (true) + { + tree containing_binfo = NULL, found_binfo = NULL; + for (i = 0; BINFO_BASE_ITERATE (binfo2, i, base_binfo); i++) + if (types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld))) + { + found_binfo = base_binfo; + break; + } + else + if (BINFO_OFFSET (base_binfo) - BINFO_OFFSET (binfo) < pos + && (!containing_binfo + || (BINFO_OFFSET (containing_binfo) + < BINFO_OFFSET (base_binfo)))) + containing_binfo = base_binfo; + if (found_binfo) + { + binfo = found_binfo; + break; + } + if (!containing_binfo) + return NULL_TREE; + binfo2 = containing_binfo; + } } type = TREE_TYPE (fld);