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. diff --git gcc/c-family/c-ubsan.c gcc/c-family/c-ubsan.c index 4022bdf..b829c04 100644 --- gcc/c-family/c-ubsan.c +++ gcc/c-family/c-ubsan.c @@ -395,8 +395,11 @@ ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype, int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks; flag_delete_null_pointer_checks = 1; - if (!tree_single_nonzero_warnv_p (op, &strict_overflow_p) - || strict_overflow_p) + if ((!tree_single_nonzero_warnv_p (op, &strict_overflow_p) + || strict_overflow_p) + /* Instrumenting &TARGET_EXPR <...> is a waste and can result + in compile-time hog; see PR70342. */ + && TREE_CODE (TREE_OPERAND (op, 0)) != TARGET_EXPR) instrument = true; flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks; 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