On Fri, Nov 04, 2016 at 05:16:00PM +0100, Jakub Jelinek wrote:
> On Fri, Nov 04, 2016 at 05:05:51PM +0100, Marek Polacek wrote:
> > This is a similar case to PR sanitizer/70342. Here, we were generating
> > expression
> > in a quadratic fashion because of the initializer--we create SAVE_EXPR <>,
> > then
> > UBSAN_NULL <SAVE_EXPR <>>, and then COMPOUND_EXPR of these two and so on.
> >
> > On this testcase we were instrumention CALL_EXPR that is in fact
> > operator<<. I
> > think those always return a reference, so it cannot be NULL, so there's no
> > point in instrumenting those?
>
> How do you know what is the return type of a user defined overloaded
> operator?
> Even when it returns a reference, I thought the point of -fsanitize=null was
> for all references to verify their addresses are non-null.
>
> I must say I don't understand the issue, if it is the same SAVE_EXPR in both
> lhs of COMPOUND_EXPR and UBSAN_NULL argument, shouldn't cp_genericize_r use
> of hash table to avoid walking the same tree multiple times avoid the
> exponential compile time/memory?
Sorry. So consider the following:
class S
{
virtual void foo () = 0;
};
struct T {
T &operator << (const char *s);
};
T t;
void
S::foo ()
{
t << "a" << "b" << "c";
}
Before
1498 if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1499 ubsan_maybe_instrument_member_call (stmt, is_ctor);
the stmt will be
T::operator<< (T::operator<< (T::operator<< (&t, "a"), "b"), "c")
after ubsan_maybe_instrument_member_call it will be
T::operator<< (UBSAN_NULL (SAVE_EXPR <T::operator<< (T::operator<< (&t, "a"),
"b")>, 4B, 0);, SAVE_EXPR <T::operator<< (T::operator<< (&t, "a"), "b")>;, "c")
and that's what is saved into the hash table. Then another stmt will be the
inner
T::operator<< (T::operator<< (&t, "a"), "b")
which we instrument and put into the hash table, and so on. But those
SAVE_EXPRs aren't the same. So we have a T::operator<< call that has nested
T::operator<< calls and we kind of recursively instrument all of them.
Not sure if I made this any clearer nor if this can be avoided... :(
Marek