This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ubsan PATCH to fix compile-time hog with operator overloading (PR sanitizer/78208)
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>, Jason Merrill <jason at redhat dot com>
- Date: Fri, 4 Nov 2016 17:05:51 +0100
- Subject: ubsan PATCH to fix compile-time hog with operator overloading (PR sanitizer/78208)
- Authentication-results: sourceware.org; auth=none
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 <polacek@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