https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113599
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The problem is in that typeck2.cc change: - datum = fold_build_pointer_plus (fold_convert (ptype, datum), component); + datum = cp_convert (ptype, datum, complain); + if (!processing_template_decl) + datum = build2 (POINTER_PLUS_EXPR, ptype, + datum, convert_to_ptrofftype (component)); datum is &d and ptype is A * from the #c1 testcase. So, previously, we would correctly build (and fold) a POINTER_PLUS_EXPR of (A *) &d and (sizetype) e (where e is 16, offsetof C::c in C). But, because C has A base, cp_convert of &d to A * doesn't create (A *) &d, but returns &d.D.2800 where D.2800 is the A base in C, which is at offset 8 in the structure. If we add to that 16, we get something at offset 24 rather than the offset 16. I understand the desire to get some error checking on the pointer to pointer conversion, but cp_convert in this case calls cp_convert_pointer which does the base lookups and build_base_path etc. If no checking is needed, then it could be just datum = build_nop (ptype, datum); if we don't want folding.