On Thu, Apr 28, 2016 at 11:07:30AM +0200, Jakub Jelinek wrote: > On Wed, Apr 27, 2016 at 07:03:25PM +0200, Marek Polacek wrote: > > This test took forever to compile with -fsanitize=null, because the > > instrumentation was creating incredible amount of duplicated expressions, > > in a > > quadratic fashion. I think the problem is that we instrument &TARGET_EXPR > > <> > > expressions, which doesn't seem to be needed -- we only need to instrument > > the > > initializers in TARGET_EXPRs. With this patch, we avoid creating tons of > > useless > > expressions and the compile time is reduced from ~ infinity to <1s. > > > > Jakub, do you see any problem with this? > > > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > > > 2016-04-27 Marek Polacek <pola...@redhat.com> > > > > PR sanitizer/70342 > > * c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Don't > > null-instrument &TARGET_EXPR <...>. > > > > * g++.dg/ubsan/null-7.C: New test. > > I wonder if this wouldn't be better handled in tree_single_nonzero_warnv_p, > perhaps like: > > case ADDR_EXPR: > { > tree base = TREE_OPERAND (t, 0); > > if (!DECL_P (base)) > base = get_base_address (base); > + > + if (base && TREE_CODE (base) == TARGET_EXPR) > + base = TARGET_EXPR_SLOT (base); > > if (!base) > return false; > > (untested)?
That works too, though it of course affects all users, not just ubsan. Here's the patch with your suggested change. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2016-04-28 Marek Polacek <pola...@redhat.com> Jakub Jelinek <ja...@redhat.com> PR sanitizer/70342 * fold-const.c (tree_single_nonzero_warnv_p): For TARGET_EXPR, use TARGET_EXPR_SLOT as a base. * g++.dg/ubsan/null-7.C: New test. diff --git gcc/fold-const.c gcc/fold-const.c index 96d8484..171ac83 100644 --- gcc/fold-const.c +++ gcc/fold-const.c @@ -13531,6 +13531,9 @@ tree_single_nonzero_warnv_p (tree t, bool *strict_overflow_p) if (!DECL_P (base)) base = get_base_address (base); + if (base && TREE_CODE (base) == TARGET_EXPR) + base = TARGET_EXPR_SLOT (base); + if (!base) return false; diff --git gcc/testsuite/g++.dg/ubsan/null-7.C gcc/testsuite/g++.dg/ubsan/null-7.C index e69de29..8284bc7 100644 --- gcc/testsuite/g++.dg/ubsan/null-7.C +++ gcc/testsuite/g++.dg/ubsan/null-7.C @@ -0,0 +1,24 @@ +// PR sanitizer/70342 +// { dg-do compile } +// { dg-options "-fsanitize=null" } + +class A {}; +class B { +public: + B(A); +}; +class C { +public: + C operator<<(B); +}; +class D { + D(const int &); + C m_blackList; +}; +D::D(const int &) { + m_blackList << A() << A() << A() << A() << A() << A() << A() << A() << A() + << A() << A() << A() << A() << A() << A() << A() << A() << A() + << A() << A() << A() << A() << A() << A() << A() << A() << A() + << A() << A() << A() << A() << A() << A() << A() << A() << A() + << A() << A() << A() << A() << A() << A() << A() << A() << A(); +} Marek