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]

[PATCH] Don't expand string/memory builtins if ASan is enabled.


Hi,

this patch disables string/memory builtin functions inlining if ASan is enabled. As described in my previous post (https://gcc.gnu.org/ml/gcc/2014-09/msg00020.html), this allow us to be sure that some dangerous builtins (strcpy, stpcpy, etc) will be handled correctly. Also, some redundant checks will be removed for builtin functions, that are instrumented but later not inlined for some reason.

Patch also changes logic in asan_mem_ref_hash updating. I eliminated memory ref access size from hash computing, so all accesses for same memory reference have the same hash. Updating of asan_mem_ref_hash occurs only if new access size is greater then saved one.

I've provided some performance testing (spec2006 v1.1) on x86_64-unknown-linux-gnu and attached results in test.res (sorry for this, I couldn't make my Thunderbird make a pretty table).

Regtested / bootstrapped on x86_64-unknown-linux-gnu.

Does this patch look sane?

-Maxim

Attachment: test.res
Description: Text document

gcc/ChangeLog:

2014-10-17  Max Ostapenko  <m.ostapenko@partner.samsung.com>

	* asan.c (asan_mem_ref_hasher::hash): Remove MEM_REF access size from
	hash value construction. Call iterative_hash_expr instead of explicit
	hash building.
	(asan_mem_ref_hasher::equal): Change condition.
	(has_mem_ref_been_instrumented): Likewise.
	(update_mem_ref_hash_table): Likewise.
	(maybe_update_mem_ref_hash_table): New function.
	(instrument_strlen_call): Removed.
	(instrument_mem_region_access): Likewise.
	(instrument_builtin_call): Call maybe_update_mem_ref_hash_table instead
	of instrument_mem_region_access.
	* builtins.c (is_memory_builtin): New function.
	(expand_builtin): Don't expand string/memory builtin functions if ASan
	is enabled.
	* builtins.def: Add comment.

gcc/testsuite/ChangeLog:

2014-10-17  Max Ostapenko  <m.ostapenko@partner.samsung.com>

	* c-c++-common/asan/no-redundant-instrumentation-1.c: Updated test.
	* c-c++-common/asan/no-redundant-instrumentation-4.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-5.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-6.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-7.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-8.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-2.c: Removed.
	* c-c++-common/asan/no-redundant-instrumentation-9.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-10.c: New test.
	* c-c++-common/asan/no-redundant-instrumentation-11.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index 2a61a82..391f693 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -352,10 +352,7 @@ struct asan_mem_ref_hasher
 inline hashval_t
 asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
 {
-  inchash::hash hstate;
-  inchash::add_expr (mem_ref->start, hstate);
-  hstate.add_wide_int (mem_ref->access_size);
-  return hstate.end ();
+  return iterative_hash_expr (mem_ref->start, 0);
 }
 
 /* Compare two memory references.  We accept the length of either
@@ -365,8 +362,7 @@ inline bool
 asan_mem_ref_hasher::equal (const asan_mem_ref *m1,
 			    const asan_mem_ref *m2)
 {
-  return (m1->access_size == m2->access_size
-	  && operand_equal_p (m1->start, m2->start, 0));
+  return operand_equal_p (m1->start, m2->start, 0);
 }
 
 static hash_table<asan_mem_ref_hasher> *asan_mem_ref_ht;
@@ -417,7 +413,8 @@ has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
   asan_mem_ref r;
   asan_mem_ref_init (&r, ref, access_size);
 
-  return (get_mem_ref_hash_table ()->find (&r) != NULL);
+  asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r);
+  return saved_ref && (saved_ref->access_size >= access_size);
 }
 
 /* Return true iff the memory reference REF has been instrumented.  */
@@ -434,19 +431,11 @@ has_mem_ref_been_instrumented (const asan_mem_ref *ref)
 static bool
 has_mem_ref_been_instrumented (const asan_mem_ref *ref, tree len)
 {
-  /* First let's see if the address of the beginning of REF has been
-     instrumented.  */
-  if (!has_mem_ref_been_instrumented (ref))
-    return false;
-
-  if (len != 0)
-    {
-      /* Let's see if the end of the region has been instrumented.  */
-      if (!has_mem_ref_been_instrumented (asan_mem_ref_get_end (ref, len),
-					  ref->access_size))
-	return false;
-    }
-  return true;
+  HOST_WIDE_INT size_in_bytes
+    = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
+  if (size_in_bytes != -1)
+    return has_mem_ref_been_instrumented (ref->start, size_in_bytes);
+  return false;
 }
 
 /* Set REF to the memory reference present in a gimple assignment
@@ -870,7 +859,7 @@ update_mem_ref_hash_table (tree ref, HOST_WIDE_INT access_size)
   asan_mem_ref_init (&r, ref, access_size);
 
   asan_mem_ref **slot = ht->find_slot (&r, INSERT);
-  if (*slot == NULL)
+  if ((*slot == NULL) || ((*slot)->access_size < access_size))
     *slot = asan_mem_ref_new (ref, access_size);
 }
 
@@ -1784,113 +1773,21 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
 
 }
 
-/* Instrument an access to a contiguous memory region that starts at
-   the address pointed to by BASE, over a length of LEN (expressed in
-   the sizeof (*BASE) bytes).  ITER points to the instruction before
-   which the instrumentation instructions must be inserted.  LOCATION
-   is the source location that the instrumentation instructions must
-   have.  If IS_STORE is true, then the memory access is a store;
-   otherwise, it's a load.  */
+/*  Insert a memory reference into the hash table if access length
+    can be determined in compile time.  */
 
 static void
-instrument_mem_region_access (tree base, tree len,
-			      gimple_stmt_iterator *iter,
-			      location_t location, bool is_store)
+maybe_update_mem_ref_hash_table (tree base, tree len)
 {
   if (!POINTER_TYPE_P (TREE_TYPE (base))
-      || !INTEGRAL_TYPE_P (TREE_TYPE (len))
-      || integer_zerop (len))
+      || !INTEGRAL_TYPE_P (TREE_TYPE (len)))
     return;
 
-  /* If the beginning of the memory region has already been
-     instrumented, do not instrument it.  */
-  bool start_instrumented = has_mem_ref_been_instrumented (base, 1);
-
-  /* If the end of the memory region has already been instrumented, do
-     not instrument it.  */
-  tree end = asan_mem_ref_get_end (base, len);
-  bool end_instrumented = has_mem_ref_been_instrumented (end, 1);
-
   HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
 
-  build_check_stmt (location, base, len, size_in_bytes, iter,
-		    /*is_non_zero_len*/size_in_bytes > 0, /*before_p*/true,
-		    is_store, /*is_scalar_access*/false, /*align*/0,
-		    start_instrumented, end_instrumented);
-
-  update_mem_ref_hash_table (base, 1);
-  if (size_in_bytes != -1)
-    update_mem_ref_hash_table (end, 1);
-
-  *iter = gsi_for_stmt (gsi_stmt (*iter));
-}
-
-/* Instrument the call (to the builtin strlen function) pointed to by
-   ITER.
-
-   This function instruments the access to the first byte of the
-   argument, right before the call.  After the call it instruments the
-   access to the last byte of the argument; it uses the result of the
-   call to deduce the offset of that last byte.
-
-   Upon completion, iff the call has actually been instrumented, this
-   function returns TRUE and *ITER points to the statement logically
-   following the built-in strlen function call *ITER was initially
-   pointing to.  Otherwise, the function returns FALSE and *ITER
-   remains unchanged.  */
-
-static bool
-instrument_strlen_call (gimple_stmt_iterator *iter)
-{
-  gimple g;
-  gimple call = gsi_stmt (*iter);
-  gcc_assert (is_gimple_call (call));
-
-  tree callee = gimple_call_fndecl (call);
-  gcc_assert (is_builtin_fn (callee)
-	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
-	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_STRLEN);
-
-  location_t loc = gimple_location (call);
-
-  tree len = gimple_call_lhs (call);
-  if (len == NULL)
-    /* Some passes might clear the return value of the strlen call;
-       bail out in that case.  Return FALSE as we are not advancing
-       *ITER.  */
-    return false;
-  gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (len)));
-
-  len = maybe_cast_to_ptrmode (loc, len, iter, /*before_p*/false);
-
-  tree str_arg = gimple_call_arg (call, 0);
-  bool start_instrumented = has_mem_ref_been_instrumented (str_arg, 1);
-
-  tree cptr_type = build_pointer_type (char_type_node);
-  g = gimple_build_assign_with_ops (NOP_EXPR,
-				    make_ssa_name (cptr_type, NULL),
-				    str_arg, NULL);
-  gimple_set_location (g, loc);
-  gsi_insert_before (iter, g, GSI_SAME_STMT);
-  str_arg = gimple_assign_lhs (g);
-
-  build_check_stmt (loc, str_arg, NULL_TREE, 1, iter,
-		    /*is_non_zero_len*/true, /*before_p=*/true,
-		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0,
-		    start_instrumented, start_instrumented);
-
-  g = gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
-				    make_ssa_name (cptr_type, NULL),
-				    str_arg,
-				    len);
-  gimple_set_location (g, loc);
-  gsi_insert_after (iter, g, GSI_NEW_STMT);
-
-  build_check_stmt (loc, gimple_assign_lhs (g), NULL_TREE, 1, iter,
-		    /*is_non_zero_len*/true, /*before_p=*/false,
-		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0);
-
-  return true;
+  if ((size_in_bytes != -1)
+      && !has_mem_ref_been_instrumented (base, size_in_bytes))
+    update_mem_ref_hash_table (base, size_in_bytes);
 }
 
 /* Instrument the call to a built-in memory access function that is
@@ -1910,50 +1807,41 @@ instrument_builtin_call (gimple_stmt_iterator *iter)
 
   gcc_checking_assert (gimple_call_builtin_p (call, BUILT_IN_NORMAL));
 
-  tree callee = gimple_call_fndecl (call);
   location_t loc = gimple_location (call);
 
-  if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STRLEN)
-    iter_advanced_p = instrument_strlen_call (iter);
-  else
-    {
-      asan_mem_ref src0, src1, dest;
-      asan_mem_ref_init (&src0, NULL, 1);
-      asan_mem_ref_init (&src1, NULL, 1);
-      asan_mem_ref_init (&dest, NULL, 1);
+  asan_mem_ref src0, src1, dest;
+  asan_mem_ref_init (&src0, NULL, 1);
+  asan_mem_ref_init (&src1, NULL, 1);
+  asan_mem_ref_init (&dest, NULL, 1);
 
-      tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
-      bool src0_is_store = false, src1_is_store = false,
-	dest_is_store = false, dest_is_deref = false;
+  tree src0_len = NULL_TREE, src1_len = NULL_TREE, dest_len = NULL_TREE;
+  bool src0_is_store = false, src1_is_store = false, dest_is_store = false;
+  bool dest_is_deref = false;
 
-      if (get_mem_refs_of_builtin_call (call,
-					&src0, &src0_len, &src0_is_store,
-					&src1, &src1_len, &src1_is_store,
-					&dest, &dest_len, &dest_is_store,
-					&dest_is_deref))
+  if (get_mem_refs_of_builtin_call (call,
+				    &src0, &src0_len, &src0_is_store,
+				    &src1, &src1_len, &src1_is_store,
+				    &dest, &dest_len, &dest_is_store,
+				    &dest_is_deref))
+    {
+      if (dest_is_deref)
 	{
-	  if (dest_is_deref)
-	    {
-	      instrument_derefs (iter, dest.start, loc, dest_is_store);
-	      gsi_next (iter);
-	      iter_advanced_p = true;
-	    }
-	  else if (src0_len || src1_len || dest_len)
-	    {
-	      if (src0.start != NULL_TREE)
-		instrument_mem_region_access (src0.start, src0_len,
-					      iter, loc, /*is_store=*/false);
-	      if (src1.start != NULL_TREE)
-		instrument_mem_region_access (src1.start, src1_len,
-					      iter, loc, /*is_store=*/false);
-	      if (dest.start != NULL_TREE)
-		instrument_mem_region_access (dest.start, dest_len,
-					      iter, loc, /*is_store=*/true);
-	      *iter = gsi_for_stmt (call);
-	      gsi_next (iter);
-	      iter_advanced_p = true;
-	    }
+	  instrument_derefs (iter, dest.start, loc, dest_is_store);
+	  gsi_next (iter);
+	  iter_advanced_p = true;
 	}
+       else
+	 {
+	   gsi_next (iter);
+	   iter_advanced_p = true;
+
+	   if (src0.start != NULL_TREE)
+	     maybe_update_mem_ref_hash_table (src0.start, src0_len);
+	   if (src1.start != NULL_TREE)
+	     maybe_update_mem_ref_hash_table (src1.start, src1_len);
+	   if (dest.start != NULL_TREE)
+	     maybe_update_mem_ref_hash_table (dest.start, dest_len);
+	 }
     }
   return iter_advanced_p;
 }
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 975f696..f32057b3 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5747,6 +5747,15 @@ expand_stack_save (void)
   return ret;
 }
 
+/* Returns TRUE if given FCODE corresponds to string or memory builtin function.
+ */
+
+static inline bool
+is_memory_builtin (enum built_in_function fcode)
+{
+  return fcode <= BUILT_IN_STRSTR && fcode >= BUILT_IN_BCMP;
+}
+
 /* Expand an expression EXP that calls a built-in function,
    with result going to TARGET if that's convenient
    (and in mode MODE if that's convenient).
@@ -5762,6 +5771,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
   int flags;
 
+  if ((flag_sanitize & SANITIZE_ADDRESS)
+       && is_memory_builtin (fcode))
+    return expand_call (exp, target, ignore);
+
   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
 
diff --git a/gcc/builtins.def b/gcc/builtins.def
index cd823a3..a76c937 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -569,7 +569,11 @@ DEF_C99_COMPL_BUILTIN        (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_
 
 /* Category: string/memory builtins.  */
 /* bcmp, bcopy and bzero have traditionally accepted NULL pointers
-   when the length parameter is zero, so don't apply attribute "nonnull".  */
+   when the length parameter is zero, so don't apply attribute "nonnull".
+   Do not reorder the BUILT_IN_* builtins, e.g. builtins.c relies on this
+   order.  If you want to add a new string/memory builtin, please insert
+   it after BUILT_IN_BCMP and before BUILT_IN_STRSTR.  */
+
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
index 028f8d7..baacb1e 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
@@ -6,7 +6,7 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
-extern char tab[4];
+extern char tab[6];
 
 static int
 test0 ()
@@ -35,17 +35,10 @@ test1 (int i)
     the initialization.  */
   foo[i] = 1;
 
-  /*__builtin___asan_report_store_n called once here to instrument
-    the store to the memory region of tab.  */
+  /* Instrument tab memory region.  */
   __builtin_memset (tab, 3, sizeof (tab));
 
-  /* There is no instrumentation for the two memset calls below.  */
-  __builtin_memset (tab, 4, sizeof (tab));
-  __builtin_memset (tab, 5, sizeof (tab));
-
-  /* There is a call to __builtin___asan_report_store_n and a call
-     to __builtin___asan_report_load_n to instrument the store to
-     (subset of) the memory region of tab.  */
+  /* Instrument tab[1] with access size 3.  */
   __builtin_memcpy (&tab[1], foo + i, 3);
 
   /* This should not generate a __builtin___asan_report_load1 because
@@ -63,6 +56,5 @@ main ()
 }
 
 /* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "sanopt" }  } */
+/* { dg-final { scan-tree-dump-not "__builtin___asan_report_load1" "sanopt" } } */
 /* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-10.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-10.c
new file mode 100644
index 0000000..24dfcfe
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-10.c
@@ -0,0 +1,18 @@
+/* { dg-options "-fdump-tree-sanopt" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+extern __UINT32_TYPE__ a;
+
+void
+foo ()
+{
+  /* Instrument a with access size 3.  */
+  int d = __builtin_memcmp (&a, "123", 3);
+  /* This should  generate a __builtin___asan_report_store4, because
+     the reference to a has been instrumented above with access size 3.  */
+  a = 1;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store4" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-11.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-11.c
new file mode 100644
index 0000000..4082f32
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-11.c
@@ -0,0 +1,20 @@
+/* { dg-options "-fdump-tree-sanopt" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+extern __UINT32_TYPE__ a;
+
+void
+foo ()
+{
+  /* Instrument a with access size 5.  */
+  int d = __builtin_memcmp (&a, "12345", 4);
+  /* This should not generate a __builtin___asan_report_store4 because
+     the reference to a has been already instrumented above with access
+     size 5.  */
+  a = 1;
+}
+
+/* { dg-final { scan-tree-dump-not "& 7" "sanopt" } } */
+/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
deleted file mode 100644
index a58411c..0000000
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This tests that when faced with two references to the same memory
-   location in the same basic block, the second reference should not
-   be instrumented by the Address Sanitizer.  But in case of access to
-   overlapping regions we must be precise.  */
-
-/* { dg-options "-fdump-tree-sanopt" } */
-/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
-
-int
-main ()
-{
-  char tab[5];
-
-  /* Here, we instrument the access at offset 0 and access at offset
-     4.  */
-  __builtin_memset (tab, 1, sizeof (tab));
-  /* We instrumented access at offset 0 above already, so only access
-     at offset 3 is instrumented.  */
-  __builtin_memset (tab, 1, 3);
-}
-
-/* { dg-final { scan-tree-dump-times "& 7" 3 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "sanopt" }  } */
-/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
index c3632aa..a613b92 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
@@ -5,13 +5,13 @@
 void
 foo  (int *a, char *b, char *c)
 {
-  /* One check for c[0], one check for a[], one check for c, two checks for b.  */
+  /* One check for c[0], one check for a[].  */
   __builtin_memmove (c, b, a[c[0]]);
-  /* For a total of 5 checks.  */
+  /* For a total of 2 checks.  */
+  int d = c[0] == 1;
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 2 "sanopt" } } */
 /* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "sanopt" } } */
 /* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
index 077ea34..f4ca603 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
@@ -5,14 +5,12 @@
 void
 foo  (int *a, char *b, char *c)
 {
-  /* One check for b[0], one check for a[], 2 checks for c and one checks for b.  */
-  __builtin_memmove (c, b, a[b[0]]);
-  /* For a total of 5 checks.  */
+  /* One check for a[].  */
+  __builtin_memmove (c, b, a[0]);
+  /* For a total of 1 checks.  */
+  int d = a[0] == 0;
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 1 "sanopt" } } */
 /* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
 /* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
index 6d87104..757f0ee 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
@@ -5,16 +5,15 @@
 void
 foo  (int *a, char *b, char *c)
 {
-  /* One check for c[0], one check for a[], one check for c and 2 checks for b.  */
+  /* One check for c[0], one check for a[].  */
   __builtin_memmove (c, b, a[c[0]]);
-  /* One check for a[], one check for c and one check for b.  */
+  /* One check for b[0], one check for a[].  */
   __builtin_memmove (c, b, a[b[0]]);
-  /* For a total of 8 checks.  */
+  /* For a total of 4 checks.  */
+  int d = c[0] == b[0];
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 8 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 4 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 2 "sanopt" } } */
 /* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
 /* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
index 5baa10d..0c50145 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
@@ -2,26 +2,22 @@
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
-char e[200];
+char e[5];
 
-struct S
+extern struct S
 {
-  char a[100];
-  char b[100];
+  int a;
+  char b;
 } s;
 
 int
 foo  (int *a, char *b, char *c)
 {
-  /* 2 checks for s.a, 2 checks for e.  */
-  int d = __builtin_memcmp (s.a, e, 100);
-  /* One check for s.a and one check for e.  */
-  d += __builtin_memcmp (s.a, e, 200);
-  /* For a total of 6 checks.  */
-  return d;
+  int d = __builtin_memcmp (&s.a, e, 4);
+  /* No check because s.a was instrumented above with access size 4.  */
+  return s.a;
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 6 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "sanopt" } } */
-/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "sanopt" } } */
+/* { dg-final { scan-tree-dump-not "& 7" "sanopt" } } */
+/* { dg-final { scan-tree-dump-not "__builtin___asan_report_load4" "sanopt" } } */
 /* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
index 2a4c081..4eeedce 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
@@ -5,16 +5,16 @@
 char
 foo  (int *a, char *b, char *c)
 {
-  /* One check for b[0], one check for a[], two checks for c and one check for b.  */
+  /* One check for b[0], one check for a[].  */
   __builtin_memmove (c, b, a[b[0]]);
+  /* One check for c[0], one check for a[].  */
+  __builtin_memmove (b, c, a[c[0]]);
   /* No checks here.  */
   return c[0] + b[0];
-  /* For a total of 5 checks.  */
+  /* For a total of 4 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 4 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "sanopt" } } */
 /* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
deleted file mode 100644
index 9449de5..0000000
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* { dg-options "-fdump-tree-sanopt" } */
-/* { dg-do compile } */
-/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
-
-__SIZE_TYPE__
-f (char *a)
-{
-  a[0] = '1';
-  return  __builtin_strlen (a);
-}
-
-/* { dg-final { scan-tree-dump-times "__asan_report_load1" 1 "sanopt" } } */
-/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
index f58f554..0f49286 100644
--- a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
+++ b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
@@ -9,14 +9,8 @@ char a[2] = "0";
 #ifdef __cplusplus
 extern "C"
 #endif
-
-__attribute__((no_sanitize_address, noinline)) __SIZE_TYPE__
-strlen (const char *p) {
-
-  __SIZE_TYPE__ n = 0;
-  for (; *p; ++n, ++p);
-  return n;
-}
+__SIZE_TYPE__
+strlen (const char *p);
 
 int main () {
   char *p = &a[0];
@@ -25,6 +19,6 @@ int main () {
   return __builtin_strlen (a);
 }
 
-/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
-/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strlen-overflow-1.c:25|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 1 bytes inside of global variable" } */
+/* { dg-output "READ of size 2 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strlen-overflow-1.c:19|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */


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