This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ubsan PATCH to fix compile-time hog with operator overloading (PR sanitizer/78208)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]