https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68727
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- This changed with r215070. The problem with the move is that build_class_member_access_expr when diagnosing this saw object_type of B, while finish_offsetof sees ((struct A *) (struct B *) 0B + (sizetype) *(long int *) (((struct B *) 0B)->_vptr.B + 18446744073709551592))->i as expr, where object is INDIRECT_REF with type A. But expr is unfortunately a result of folding, so trying to discover the original type used in __builtin_offsetof (such as looking for NOP_EXPR of null_pointer_node and using type from that) might be too unreliable. Consider struct A { int i[2]; }; struct B: virtual A { }; struct C: virtual A { }; __SIZE_TYPE__ a[] = { __builtin_offsetof (B, A::i[(__SIZE_TYPE__)(&((C *)__null)->A::i)]) }; where there is both (B *) 0B and (C *) 0B in the expression. Another option is to pass the original object (i.e. (B *) 0B in this case) to finish_offsetof in addition to expr, but then we need to stick it into OFFSETOF_EXPR as well.