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? Bootstrapped/regtested on x86_64-linux, ok for trunk? 2016-11-04 Marek Polacek <pola...@redhat.com> PR sanitizer/78208 * cp-gimplify.c (cp_genericize_r): Don't instrument CALL_EXPR_OPERATOR_SYNTAX. * g++.dg/ubsan/null-8.C: New. diff --git gcc/cp/cp-gimplify.c gcc/cp/cp-gimplify.c index 9b9b511..f39e9d5 100644 --- gcc/cp/cp-gimplify.c +++ gcc/cp/cp-gimplify.c @@ -1495,7 +1495,8 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) = TREE_CODE (fn) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)); - if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) + if (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT) + && !CALL_EXPR_OPERATOR_SYNTAX (stmt)) ubsan_maybe_instrument_member_call (stmt, is_ctor); if ((flag_sanitize & SANITIZE_VPTR) && !is_ctor) cp_ubsan_maybe_instrument_member_call (stmt); diff --git gcc/testsuite/g++.dg/ubsan/null-8.C gcc/testsuite/g++.dg/ubsan/null-8.C index e69de29..0600b93 100644 --- gcc/testsuite/g++.dg/ubsan/null-8.C +++ gcc/testsuite/g++.dg/ubsan/null-8.C @@ -0,0 +1,22 @@ +// PR sanitizer/78208 +// { dg-do compile } +// { dg-options "-fsanitize=null" } + +class S +{ + virtual void foo () = 0; +}; + +struct T { + T &operator << (const char *s); +}; + +T t; + +void +S::foo () +{ + t << "a" << "b" << "c" << "d" << "e" << "f" << "g" << "h" << "i" + << "j" << "k" << "l" << "m" << "n" << "o" << "p" << "q" << "r" + << "s" << "t" << "u" << "v" << "w" << "z"; +} Marek