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.