From patchwork Fri Oct 17 11:45:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: max X-Patchwork-Id: 400506 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 50E2914008C for ; Fri, 17 Oct 2014 22:46:11 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=Y7cAklffXLaS9dQSt V+vngrE2vnrQZAV0mOon5AQEgYT5dYkGPzA29Bqh/5SJYUPBIOgGIE4N9EN/HqLU iyDJdCMH+06WQXcWQTdasBfQ7rL3gfD8faEevJftV7JrEPUvDJMkCgGHNS6H5VSq IYGHRxu3aCWx24k73dCfig3toY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=3BjNIMQs6db+JcINr4CNwq/ WEsw=; b=IyCCvqY4gljmzPCPelcWvlKSb895pTIjNfZngAf6y5tzOx/Vk7aoz+R Fw6sAJwKyI2Ceswo0zH16h6cp3RZbvnT6I5CdbLCZrLVwD2c6lBjrKMMJlvn0Ojv jCDo5Sl2buZdmv81q21eI6SUFP1cO83aBdoUyrxoq5MgSXFI2nSs= Received: (qmail 26952 invoked by alias); 17 Oct 2014 11:46:03 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 26940 invoked by uid 89); 17 Oct 2014 11:46:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mailout2.w1.samsung.com Received: from mailout2.w1.samsung.com (HELO mailout2.w1.samsung.com) (210.118.77.12) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (DES-CBC3-SHA encrypted) ESMTPS; Fri, 17 Oct 2014 11:45:58 +0000 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NDL001TL7H6MB60@mailout2.w1.samsung.com> for gcc-patches@gcc.gnu.org; Fri, 17 Oct 2014 12:48:42 +0100 (BST) Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id B0.35.15956.17101445; Fri, 17 Oct 2014 12:45:53 +0100 (BST) Received: from [106.109.128.119] by eusync4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NDL00GD37CGAP00@eusync4.samsung.com>; Fri, 17 Oct 2014 12:45:53 +0100 (BST) Message-id: <54410170.9030100@partner.samsung.com> Date: Fri, 17 Oct 2014 15:45:52 +0400 From: Maxim Ostapenko User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.0 MIME-version: 1.0 To: GCC Patches Cc: Jakub Jelinek , Yury Gribov , Slava Garbuzov , Maxim Ostapenko Subject: [PATCH] Don't expand string/memory builtins if ASan is enabled. References: <5441008A.2010706@partner.samsung.com> In-reply-to: <5441008A.2010706@partner.samsung.com> X-Forwarded-Message-Id: <5441008A.2010706@partner.samsung.com> Content-type: multipart/mixed; boundary=------------090408080807040604030305 X-IsSubscribed: yes 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 $ ~/install/master-x86_64/bin/gcc -v Using built-in specs. COLLECT_GCC=/home/max/install/master-x86_64/bin/gcc COLLECT_LTO_WRAPPER=/home/max/install/master-x86_64/libexec/gcc/x86_64-unknown-linux-gnu/5.0.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: /home/max/workspace/downloads/gcc/configure --enable-multilib --enable-checking --target=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --build=x86_64-unknown-linux-gnu --prefix=/home/max/install/master-x86_64 --disable-bootstrap --enable-languages=c,c++ Thread model: posix gcc version 5.0.0 20141014 (experimental) (GCC) Compile options: -O3 -fsanitize=address -static-libasan. test master nobuiltin % of slowdown 400.perlbench 1044 1050 0,5747 401.bzip2 682 676 -0,8798 403.gcc 497 495 -0,4024 429.mcf 488 489 0,2049 445.gobmk 723 724 0,1383 456.hmmer 783 750 -4,2146 458.sjeng 887 880 -0,7892 462.libquantum 330 323 -2,1212 464.h264ref 1108 1154 4,1516 471.omnetpp 545 559 2,5688 473.astar 490 480 -2,0408 483.xalancbmk 411 400 -2,6764 433.milc 517 509 -1,5474 444.namd 419 419 0,0000 450.soplex 310 299 -3,5484 453.povray 287 276 -3,8328 470.lbm 299 306 2,3411 482.sphinx3 777 804 3,4749 Geomean: master nobuiltin % of increase 540 538 -0,50 gcc/ChangeLog: 2014-10-17 Max Ostapenko * 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 * 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_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" } */