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.

Reply via email to