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