https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98206
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Testcase without any headers: template <typename Derived> struct Base1 { char c1; }; template <typename Derived> struct Base2 { char c2; auto &get2 () const { return static_cast<const Derived &> (*this); } }; struct X : public Base1<X>, public Base2<X> { X (const char *d) : data{d} {} const char *data; }; int main () { X x = X{"cheesecake"}; const char *p = x.get2 ().data; } The problem is that ubsan_maybe_instrument_reference is done only during genericization, but we fold: (const struct X &) ((const struct Base2 *) this + 18446744073709551615) to (const struct X &) this + 18446744073709551615 much earlier than that (during parsing even!), and if it wasn't during parsing, it would be during fully folding of the function which is also before genericization. In fold-const.c, it is the: /* Convert (T1)(X p+ Y) into ((T1)X p+ Y), for pointer type, when the new cast (T1)X will fold away. We assume that this happens when X itself is a cast. */ if (POINTER_TYPE_P (type) && TREE_CODE (arg0) == POINTER_PLUS_EXPR && CONVERT_EXPR_P (TREE_OPERAND (arg0, 0))) { tree arg00 = TREE_OPERAND (arg0, 0); tree arg01 = TREE_OPERAND (arg0, 1); return fold_build_pointer_plus_loc (loc, fold_convert_loc (loc, type, arg00), arg01); } optimization that does that. So, one way around this is for !in_gimple_form && sanitize_flags_p (SANITIZE_ALIGNMENT) to avoid the above optimization if type has higher alignment than the p+ first operand's type.