From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 0C68A385842E for ; Thu, 1 Dec 2022 02:42:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0C68A385842E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1669862527; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bdT6X24X6JPqR57KyA1y7O3kjDZf66sTtMy3J2Uxeu0=; b=ARoDEGkieegFVY2S7A6DuKllXxyPG2X1hN7gqs6E6fYGaTRLabDwR+BzG/7QX0zdL4glb2 W3vw1qUz8IE03lsb5bksSDpb88sNt89jUER/YCZ4WbCo+5WvCXkUzVyBmNsgFhdEVtiLh5 I8sK9+Vif7vWYzmIfE8MnNF/ebiau2Q= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-194-iegmrZF7MgedTp0R4eHZew-1; Wed, 30 Nov 2022 21:42:06 -0500 X-MC-Unique: iegmrZF7MgedTp0R4eHZew-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DE313811E81 for ; Thu, 1 Dec 2022 02:42:05 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.2.16.65]) by smtp.corp.redhat.com (Postfix) with ESMTP id B3FDA2024CBE; Thu, 1 Dec 2022 02:42:05 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [committed 4/7] analyzer: more bounds-checking wording tweaks [PR106626] Date: Wed, 30 Nov 2022 21:41:57 -0500 Message-Id: <20221201024200.3722982-4-dmalcolm@redhat.com> In-Reply-To: <20221201024200.3722982-1-dmalcolm@redhat.com> References: <20221201024200.3722982-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This patch tweaks the wording of -Wanalyzer-out-of-bounds: * use the spellings/terminology of CWE: * replace "underread" with "under-read", as per: https://cwe.mitre.org/data/definitions/127.html * replace "overread" with "over-read" as per: https://cwe.mitre.org/data/definitions/126.html * replace "underflow" with "underwrite" as per: https://cwe.mitre.org/data/definitions/124.html * wherever known, specify the memory region of the bad access, so that it says e.g. "heap-based buffer over-read" or "stack-based buffer over-read" Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r13-4428-gdf460cf51b2586. gcc/analyzer/ChangeLog: PR analyzer/106626 * bounds-checking.cc (out_of_bounds::get_memory_space): New. (buffer_overflow::emit): Use it. (class buffer_overread): Rename to... (class buffer_over_read): ...this. (buffer_over_read::emit): Specify which memory space the read is from, where known. Change "overread" to "over-read". (class buffer_underflow): Rename to... (class buffer_underwrite): ...this. (buffer_underwrite::emit): Specify which memory space the write is to, where known. Change "underflow" to "underwrite". (class buffer_underread): Rename to... (class buffer_under_read): Rename to... (buffer_under_read::emit): Specify which memory space the read is from, where known. Change "underread" to "under-read". (symbolic_past_the_end::get_memory_space): New. (symbolic_buffer_overflow::emit): Use it. (class symbolic_buffer_overread): Rename to... (class symbolic_buffer_over_read): ...this. (symbolic_buffer_over_read::emit): Specify which memory space the read is from, where known. Change "overread" to "over-read". (region_model::check_symbolic_bounds): Update for class renaming. (region_model::check_region_bounds): Likewise. gcc/testsuite/ChangeLog: PR analyzer/106626 * gcc.dg/analyzer/call-summaries-2.c: Update expected results. * gcc.dg/analyzer/out-of-bounds-1.c: Likewise. * gcc.dg/analyzer/out-of-bounds-2.c: Likewise. * gcc.dg/analyzer/out-of-bounds-3.c: Likewise. * gcc.dg/analyzer/out-of-bounds-4.c: Likewise. * gcc.dg/analyzer/out-of-bounds-5.c: Likewise. * gcc.dg/analyzer/out-of-bounds-container_of.c: Likewise. * gcc.dg/analyzer/out-of-bounds-read-char-arr.c: Likewise. Rename functions from "int_arr_" to "char_arr_". * gcc.dg/analyzer/out-of-bounds-read-int-arr.c: Update expected results. * gcc.dg/analyzer/out-of-bounds-read-struct-arr.c: New test. * gcc.dg/analyzer/out-of-bounds-write-char-arr.c: Update expected results. Rename functions from "int_arr_" to "char_arr_". * gcc.dg/analyzer/out-of-bounds-write-int-arr.c: Update expected results. * gcc.dg/analyzer/out-of-bounds-write-struct-arr.c: New test. * gcc.dg/analyzer/pr101962.c: Update expected results. * gcc.dg/analyzer/realloc-5.c: Update expected results. * gcc.dg/analyzer/zlib-3.c: Update expected results. Signed-off-by: David Malcolm --- gcc/analyzer/bounds-checking.cc | 133 +++++++++++++----- .../gcc.dg/analyzer/call-summaries-2.c | 2 +- .../gcc.dg/analyzer/out-of-bounds-1.c | 4 +- .../gcc.dg/analyzer/out-of-bounds-2.c | 15 +- .../gcc.dg/analyzer/out-of-bounds-3.c | 27 ++-- .../gcc.dg/analyzer/out-of-bounds-4.c | 15 +- .../gcc.dg/analyzer/out-of-bounds-5.c | 20 +-- .../analyzer/out-of-bounds-container_of.c | 4 +- .../analyzer/out-of-bounds-read-char-arr.c | 34 +++-- .../analyzer/out-of-bounds-read-int-arr.c | 18 ++- .../analyzer/out-of-bounds-read-struct-arr.c | 65 +++++++++ .../analyzer/out-of-bounds-write-char-arr.c | 22 +-- .../analyzer/out-of-bounds-write-int-arr.c | 6 +- .../analyzer/out-of-bounds-write-struct-arr.c | 65 +++++++++ gcc/testsuite/gcc.dg/analyzer/pr101962.c | 2 +- gcc/testsuite/gcc.dg/analyzer/realloc-5.c | 2 +- gcc/testsuite/gcc.dg/analyzer/zlib-3.c | 2 +- 17 files changed, 327 insertions(+), 109 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c diff --git a/gcc/analyzer/bounds-checking.cc b/gcc/analyzer/bounds-checking.cc index b02bc79a926..bc7d2dd17ae 100644 --- a/gcc/analyzer/bounds-checking.cc +++ b/gcc/analyzer/bounds-checking.cc @@ -71,6 +71,11 @@ public: } protected: + enum memory_space get_memory_space () const + { + return m_reg->get_memory_space (); + } + /* Potentially add a note about valid ways to index this array, such as (given "int arr[10];"): note: valid subscripts for 'arr' are '[0]' to '[9]' @@ -150,7 +155,7 @@ public: { diagnostic_metadata m; bool warned; - switch (m_reg->get_memory_space ()) + switch (get_memory_space ()) { default: m.add_cwe (787); @@ -234,22 +239,36 @@ public: } }; -/* Concrete subclass to complain about buffer overreads. */ +/* Concrete subclass to complain about buffer over-reads. */ -class buffer_overread : public past_the_end +class buffer_over_read : public past_the_end { public: - buffer_overread (const region *reg, tree diag_arg, - byte_range range, tree byte_bound) + buffer_over_read (const region *reg, tree diag_arg, + byte_range range, tree byte_bound) : past_the_end (reg, diag_arg, range, byte_bound) {} bool emit (rich_location *rich_loc) final override { diagnostic_metadata m; + bool warned; m.add_cwe (126); - bool warned = warning_meta (rich_loc, m, get_controlling_option (), - "buffer overread"); + switch (get_memory_space ()) + { + default: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "buffer over-read"); + break; + case MEMSPACE_STACK: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "stack-based buffer over-read"); + break; + case MEMSPACE_HEAP: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "heap-based buffer over-read"); + break; + } if (warned) { @@ -316,21 +335,35 @@ public: } }; -/* Concrete subclass to complain about buffer underflows. */ +/* Concrete subclass to complain about buffer underwrites. */ -class buffer_underflow : public out_of_bounds +class buffer_underwrite : public out_of_bounds { public: - buffer_underflow (const region *reg, tree diag_arg, byte_range range) + buffer_underwrite (const region *reg, tree diag_arg, byte_range range) : out_of_bounds (reg, diag_arg, range) {} bool emit (rich_location *rich_loc) final override { diagnostic_metadata m; + bool warned; m.add_cwe (124); - bool warned = warning_meta (rich_loc, m, get_controlling_option (), - "buffer underflow"); + switch (get_memory_space ()) + { + default: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "buffer underwrite"); + break; + case MEMSPACE_STACK: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "stack-based buffer underwrite"); + break; + case MEMSPACE_HEAP: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "heap-based buffer underwrite"); + break; + } if (warned) maybe_describe_array_bounds (rich_loc->get_loc ()); return warned; @@ -368,21 +401,35 @@ public: } }; -/* Concrete subclass to complain about buffer underreads. */ +/* Concrete subclass to complain about buffer under-reads. */ -class buffer_underread : public out_of_bounds +class buffer_under_read : public out_of_bounds { public: - buffer_underread (const region *reg, tree diag_arg, byte_range range) + buffer_under_read (const region *reg, tree diag_arg, byte_range range) : out_of_bounds (reg, diag_arg, range) {} bool emit (rich_location *rich_loc) final override { diagnostic_metadata m; + bool warned; m.add_cwe (127); - bool warned = warning_meta (rich_loc, m, get_controlling_option (), - "buffer underread"); + switch (get_memory_space ()) + { + default: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "buffer under-read"); + break; + case MEMSPACE_STACK: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "stack-based buffer under-read"); + break; + case MEMSPACE_HEAP: + warned = warning_meta (rich_loc, m, get_controlling_option (), + "heap-based buffer under-read"); + break; + } if (warned) maybe_describe_array_bounds (rich_loc->get_loc ()); return warned; @@ -519,6 +566,11 @@ public: } protected: + enum memory_space get_memory_space () const + { + return m_reg->get_memory_space (); + } + const region *m_reg; tree m_diag_arg; tree m_offset; @@ -542,7 +594,7 @@ public: bool emit (rich_location *rich_loc) final override { diagnostic_metadata m; - switch (m_reg->get_memory_space ()) + switch (get_memory_space ()) { default: m.add_cwe (787); @@ -560,13 +612,13 @@ public: } }; -/* Concrete subclass to complain about overreads with symbolic values. */ +/* Concrete subclass to complain about over-reads with symbolic values. */ -class symbolic_buffer_overread : public symbolic_past_the_end +class symbolic_buffer_over_read : public symbolic_past_the_end { public: - symbolic_buffer_overread (const region *reg, tree diag_arg, tree offset, - tree num_bytes, tree capacity) + symbolic_buffer_over_read (const region *reg, tree diag_arg, tree offset, + tree num_bytes, tree capacity) : symbolic_past_the_end (reg, diag_arg, offset, num_bytes, capacity) { m_dir_str = "read"; @@ -576,8 +628,21 @@ public: { diagnostic_metadata m; m.add_cwe (126); - return warning_meta (rich_loc, m, get_controlling_option (), - "buffer overread"); + switch (get_memory_space ()) + { + default: + m.add_cwe (787); + return warning_meta (rich_loc, m, get_controlling_option (), + "buffer over-read"); + case MEMSPACE_STACK: + m.add_cwe (121); + return warning_meta (rich_loc, m, get_controlling_option (), + "stack-based buffer over-read"); + case MEMSPACE_HEAP: + m.add_cwe (122); + return warning_meta (rich_loc, m, get_controlling_option (), + "heap-based buffer over-read"); + } } }; @@ -609,11 +674,11 @@ region_model::check_symbolic_bounds (const region *base_reg, gcc_unreachable (); break; case DIR_READ: - ctxt->warn (make_unique (base_reg, - diag_arg, - offset_tree, - num_bytes_tree, - capacity_tree)); + ctxt->warn (make_unique (base_reg, + diag_arg, + offset_tree, + num_bytes_tree, + capacity_tree)); break; case DIR_WRITE: ctxt->warn (make_unique (base_reg, @@ -701,7 +766,7 @@ region_model::check_region_bounds (const region *reg, /* NUM_BYTES_TREE should always be interpreted as unsigned. */ byte_offset_t num_bytes_unsigned = wi::to_offset (num_bytes_tree); byte_range read_bytes (offset, num_bytes_unsigned); - /* If read_bytes has a subset < 0, we do have an underflow. */ + /* If read_bytes has a subset < 0, we do have an underwrite. */ if (read_bytes.falls_short_of_p (0, &out)) { tree diag_arg = get_representative_tree (base_reg); @@ -711,10 +776,10 @@ region_model::check_region_bounds (const region *reg, gcc_unreachable (); break; case DIR_READ: - ctxt->warn (make_unique (reg, diag_arg, out)); + ctxt->warn (make_unique (reg, diag_arg, out)); break; case DIR_WRITE: - ctxt->warn (make_unique (reg, diag_arg, out)); + ctxt->warn (make_unique (reg, diag_arg, out)); break; } } @@ -739,8 +804,8 @@ region_model::check_region_bounds (const region *reg, gcc_unreachable (); break; case DIR_READ: - ctxt->warn (make_unique (reg, diag_arg, - out, byte_bound)); + ctxt->warn (make_unique (reg, diag_arg, + out, byte_bound)); break; case DIR_WRITE: ctxt->warn (make_unique (reg, diag_arg, diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c index a7a17dbd358..22ca475b2ed 100644 --- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c @@ -329,7 +329,7 @@ int test_returns_element_ptr (int j) __analyzer_eval (*returns_element_ptr (0) == 7); /* { dg-warning "TRUE" } */ __analyzer_eval (*returns_element_ptr (1) == 8); /* { dg-warning "TRUE" } */ __analyzer_eval (*returns_element_ptr (2) == 9); /* { dg-warning "TRUE" } */ - return *returns_element_ptr (3); /* { dg-warning "buffer overread" } */ + return *returns_element_ptr (3); /* { dg-warning "buffer over-read" } */ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } .-1 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c index dc4de9b28a6..977476ed2fb 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-1.c @@ -93,7 +93,7 @@ void test6 (void) /* { dg-warning "buffer overflow" "warning" { target *-*-* } test6b } */ /* { dg-message "" "note" { target *-*-* } test6b } */ - /* { dg-warning "buffer overread" "warning" { target *-*-* } test6c } */ + /* { dg-warning "buffer over-read" "warning" { target *-*-* } test6c } */ /* { dg-message "" "note" { target *-*-* } test6c } */ } @@ -116,7 +116,7 @@ void test7 (void) fn (destBuf, srcBuf, returnChunkSize (destBuf)); /* { dg-line test7 } */ // TODO: Should we handle widening_svalues as a follow-up? - /* { dg-warning "overread" "warning" { xfail *-*-* } test7 } */ + /* { dg-warning "over-read" "warning" { xfail *-*-* } test7 } */ /* { dg-warning "overflow" "warning" { xfail *-*-* } test7 } */ /* { dg-message "" "note" { xfail *-*-* } test7 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c index 0df9364c5c1..1330090f348 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-2.c @@ -3,7 +3,7 @@ #include #include -/* Wanalyzer-out-of-bounds tests for buffer overreads. */ +/* Wanalyzer-out-of-bounds tests for buffer over-reads. */ /* Avoid folding of memcpy. */ typedef void * (*memcpy_t) (void *dst, const void *src, size_t n); @@ -21,8 +21,9 @@ void test1 (void) memset (id_sequence, 0, 3 * sizeof(int)); printf ("%i", id_sequence[3]); /* { dg-line test1 } */ - /* { dg-warning "overread" "warning" { target *-*-* } test1 } */ - /* { dg-message "" "note" { target *-*-* } test1 } */ + /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test1 } */ + /* { dg-message "read of 4 bytes from after the end of 'id_sequence'" "num bad bytes note" { target *-*-* } test1 } */ + /* { dg-message "valid subscripts for 'id_sequence' are '\\\[0\\\]' to '\\\[2\\\]'" "valid subscript note" { target *-*-* } test1 } */ } void test2 (void) @@ -46,7 +47,7 @@ void test3 (void) for (int i = n; i > 0; i--) sum += arr[i]; /* { dg-line test3 } */ - /* { dg-warning "overread" "warning" { target *-*-* } test3 } */ + /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test3 } */ /* { dg-message "" "note" { target *-*-* } test3 } */ } @@ -78,6 +79,8 @@ void test5 (void) sum += *(arr + i); /* { dg-line test5 } */ free (arr); - /* { dg-warning "overread" "warning" { target *-*-* } test5 } */ - /* { dg-message "" "note" { target *-*-* } test5 } */ + /* { dg-warning "heap-based buffer over-read" "bounds warning" { target *-*-* } test5 } */ + /* { dg-message "read of 4 bytes from after the end of the region" "num bad bytes note" { target *-*-* } test5 } */ + + /* { dg-warning "use of uninitialized value" "uninit warning" { target *-*-* } test5 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c index 7446b182e48..5fd9cc3c6b1 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-3.c @@ -2,7 +2,7 @@ #include #include -/* Wanalyzer-out-of-bounds tests for buffer underreads and writes. */ +/* Wanalyzer-out-of-bounds tests for buffer under-reads and underwrites. */ /* Avoid folding of memcpy. */ typedef void * (*memcpy_t) (void *dst, const void *src, size_t n); @@ -19,8 +19,9 @@ void test1 (void) int *e = buf - 1; *e = 42; /* { dg-line test1 } */ - /* { dg-warning "underflow" "warning" { target *-*-* } test1 } */ - /* { dg-message "" "note" { target *-*-* } test1 } */ + /* { dg-warning "stack-based buffer underwrite" "warning" { target *-*-* } test1 } */ + /* { dg-message "out-of-bounds write from byte -4 till byte -1 but 'buf' starts at byte 0" "final event" { target *-*-* } test1 } */ + /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test1 } */ } void test2 (void) @@ -38,8 +39,9 @@ void test3 (void) *e = 123; *(e - 2) = 321; /* { dg-line test3 } */ - /* { dg-warning "underflow" "warning" { target *-*-* } test3 } */ - /* { dg-message "" "note" { target *-*-* } test3 } */ + /* { dg-warning "stack-based buffer underwrite" "warning" { target *-*-* } test3 } */ + /* { dg-message "out-of-bounds write from byte -4 till byte -1 but 'buf' starts at byte 0" "final event" { target *-*-* } test3 } */ + /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test3 } */ } void test4 (void) @@ -50,8 +52,9 @@ void test4 (void) int n = -4; fn (&(buf[n]), buf, sizeof (int)); /* { dg-line test4 } */ - /* { dg-warning "underflow" "warning" { target *-*-* } test4 } */ - /* { dg-message "" "note" { target *-*-* } test4 } */ + /* { dg-warning "stack-based buffer underwrite" "warning" { target *-*-* } test4 } */ + /* { dg-message "out-of-bounds write from byte -16 till byte -13 but 'buf' starts at byte 0" "final event" { target *-*-* } test4 } */ + /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test4 } */ } void test5 (void) @@ -63,8 +66,9 @@ void test5 (void) for (int i = 4; i >= 0; i++) sum += *(buf - i); /* { dg-line test5 } */ - /* { dg-warning "underread" "warning" { target *-*-* } test5 } */ - /* { dg-message "" "note" { target *-*-* } test5 } */ + /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } test5 } */ + /* { dg-message "out-of-bounds read from byte -16 till byte -13 but 'buf' starts at byte 0" "final event" { target *-*-* } test5 } */ + /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test5 } */ } void test6 (void) @@ -86,6 +90,7 @@ void test8 (void) int n = -4; fn (buf, &(buf[n]), sizeof (int)); /* { dg-line test8 } */ - /* { dg-warning "underread" "warning" { target *-*-* } test8 } */ - /* { dg-message "" "note" { target *-*-* } test8 } */ + /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } test8 } */ + /* { dg-message "out-of-bounds read from byte -16 till byte -13 but 'buf' starts at byte 0" "note" { target *-*-* } test8 } */ + /* { dg-message "valid subscripts for 'buf' are '\\\[0\\\]' to '\\\[3\\\]'" "valid subscript note" { target *-*-* } test8 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c index 46f600de658..9cd8bda76c3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-4.c @@ -11,8 +11,9 @@ void test1 (void) char dst[5]; strcpy (dst, "Hello"); /* { dg-line test1 } */ - /* { dg-warning "overflow" "warning" { target *-*-* } test1 } */ - /* { dg-message "dst" "note" { target *-*-* } test1 } */ + /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test1 } */ + /* { dg-message "write of 1 byte to beyond the end of 'dst'" "num bad bytes note" { target *-*-* } test1 } */ + /* { dg-message "valid subscripts for 'dst' are '\\\[0\\\]' to '\\\[4\\\]'" "valid subscript note" { target *-*-* } test1 } */ } void test2 (void) @@ -27,8 +28,9 @@ void test3 (void) char dst[5]; strcpy (dst, src); /* { dg-line test3 } */ - /* { dg-warning "overflow" "warning" { target *-*-* } test3 } */ - /* { dg-message "dst" "note" { target *-*-* } test3 } */ + /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test3 } */ + /* { dg-message "write of 1 byte to beyond the end of 'dst'" "num bad bytes note" { target *-*-* } test3 } */ + /* { dg-message "valid subscripts for 'dst' are '\\\[0\\\]' to '\\\[4\\\]'" "valid subscript note" { target *-*-* } test3 } */ } void test4 (void) @@ -51,8 +53,9 @@ void test5 (void) char dst[5]; strcpy (dst, str); /* { dg-line test5 } */ - /* { dg-warning "overflow" "warning" { target *-*-* } test5 } */ - /* { dg-message "dst" "note" { target *-*-* } test5 } */ + /* { dg-warning "stack-based buffer overflow" "warning" { target *-*-* } test5 } */ + /* { dg-message "write of 1 byte to beyond the end of 'dst'" "num bad bytes note" { target *-*-* } test5 } */ + /* { dg-message "valid subscripts for 'dst' are '\\\[0\\\]' to '\\\[4\\\]'" "valid subscript note" { target *-*-* } test5 } */ } void test6 (void) diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c index 7dc0bc5bf18..52fea79152e 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-5.c @@ -13,7 +13,7 @@ void test1 (size_t size) char *buf = __builtin_malloc (size); if (!buf) return; - buf[size] = '\0'; /* { dg-warning "overflow" } */ + buf[size] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ free (buf); } @@ -22,7 +22,7 @@ void test2 (size_t size) char *buf = __builtin_malloc (size); if (!buf) return; - buf[size + 1] = '\0'; /* { dg-warning "overflow" } */ + buf[size + 1] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ free (buf); } @@ -31,33 +31,33 @@ void test3 (size_t size, size_t op) char *buf = __builtin_malloc (size); if (!buf) return; - buf[size + op] = '\0'; /* { dg-warning "overflow" } */ + buf[size + op] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ free (buf); } void test4 (size_t size, unsigned short s) { char *buf = __builtin_alloca (size); - buf[size + s] = '\0'; /* { dg-warning "overflow" } */ + buf[size + s] = '\0'; /* { dg-warning "stack-based buffer overflow" } */ } void test5 (size_t size) { int32_t *buf = __builtin_alloca (4 * size); - buf[size] = 42; /* { dg-warning "overflow" } */ + buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */ } void test6 (size_t size) { int32_t *buf = __builtin_alloca (4 * size); memset (buf, 0, 4 * size); - int32_t last = *(buf + 4 * size); /* { dg-warning "overread" } */ + int32_t last = *(buf + 4 * size); /* { dg-warning "stack-based buffer over-read" } */ } void test7 (size_t size) { int32_t *buf = __builtin_alloca (4 * size + 3); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ - buf[size] = 42; /* { dg-warning "overflow" } */ + buf[size] = 42; /* { dg-warning "stack-based buffer overflow" } */ } /* Test where the offset itself is not out-of-bounds @@ -68,7 +68,7 @@ void test8 (size_t size, size_t offset) char src[size]; char dst[size]; memcpy (dst, src, size + offset); /* { dg-line test8 } */ - /* { dg-warning "overread" "warning" { target *-*-* } test8 } */ + /* { dg-warning "over-read" "warning" { target *-*-* } test8 } */ /* { dg-warning "overflow" "warning" { target *-*-* } test8 } */ } @@ -77,7 +77,7 @@ void test9 (size_t size, size_t offset) int32_t src[size]; int32_t dst[size]; memcpy (dst, src, 4 * size + 1); /* { dg-line test9 } */ - /* { dg-warning "overread" "warning" { target *-*-* } test9 } */ + /* { dg-warning "over-read" "warning" { target *-*-* } test9 } */ /* { dg-warning "overflow" "warning" { target *-*-* } test9 } */ } @@ -151,6 +151,6 @@ char *test99 (const char *x, const char *y) __builtin_memcpy (result, x, len_x); __builtin_memcpy (result + len_x, y, len_y); /* BUG (symptom): off-by-one out-of-bounds write to heap. */ - result[len_x + len_y] = '\0'; /* { dg-warning "overflow" } */ + result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ return result; } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c index 172ec474c42..ef460f4e772 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-container_of.c @@ -44,8 +44,8 @@ int test (struct outer *outer_p, struct inner *inner_p) sum += o->i; /* { dg-line testB } */ return sum; - /* { dg-warning "underread" "warning" { target *-*-* } testA } */ + /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } testA } */ /* { dg-message "" "note" { target *-*-* } testA } */ - /* { dg-warning "underread" "warning" { target *-*-* } testB } */ + /* { dg-warning "stack-based buffer under-read" "warning" { target *-*-* } testB } */ /* { dg-message "" "note" { target *-*-* } testB } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c index 2b43000f833..f6d0dda9fb9 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-char-arr.c @@ -1,50 +1,56 @@ char arr[10]; /* { dg-message "capacity is 10 bytes" } */ -char int_arr_read_element_before_start_far(void) +char char_arr_read_element_before_start_far(void) { - return arr[-100]; /* { dg-warning "buffer underread" "warning" } */ + return arr[-100]; /* { dg-warning "buffer under-read" "warning" } */ /* { dg-message "out-of-bounds read at byte -100 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } -char int_arr_read_element_before_start_near(void) +char char_arr_read_element_before_start_near(void) { - return arr[-2]; /* { dg-warning "buffer underread" "warning" } */ + return arr[-2]; /* { dg-warning "buffer under-read" "warning" } */ /* { dg-message "out-of-bounds read at byte -2 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } -char int_arr_read_element_before_start_off_by_one(void) +char char_arr_read_element_before_start_off_by_one(void) { - return arr[-1]; /* { dg-warning "buffer underread" "warning" } */ + return arr[-1]; /* { dg-warning "buffer under-read" "warning" } */ /* { dg-message "out-of-bounds read at byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } -char int_arr_read_element_at_start(void) +char char_arr_read_element_at_start(void) { return arr[0]; } -char int_arr_read_element_at_end(void) +char char_arr_read_element_at_end(void) { return arr[9]; } -char int_arr_read_element_after_end_off_by_one(void) +char char_arr_read_element_after_end_off_by_one(void) { - return arr[10]; /* { dg-warning "buffer overread" "warning" } */ + return arr[10]; /* { dg-warning "buffer over-read" "warning" } */ /* { dg-message "out-of-bounds read at byte 10 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */ /* { dg-message "read of 1 byte from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } -char int_arr_read_element_after_end_near(void) +char char_arr_read_element_after_end_near(void) { - return arr[11]; /* { dg-warning "buffer overread" "warning" } */ + return arr[11]; /* { dg-warning "buffer over-read" "warning" } */ /* { dg-message "out-of-bounds read at byte 11 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */ /* { dg-message "read of 1 byte from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } -char int_arr_read_element_after_end_far(void) +char char_arr_read_element_after_end_far(void) { - return arr[100]; /* { dg-warning "buffer overread" "warning" } */ + return arr[100]; /* { dg-warning "buffer over-read" "warning" } */ /* { dg-message "out-of-bounds read at byte 100 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */ /* { dg-message "read of 1 byte from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c index 0dc95563620..f1b6e119777 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-int-arr.c @@ -4,20 +4,23 @@ int32_t arr[10]; /* { dg-message "capacity is 40 bytes" } */ int32_t int_arr_read_element_before_start_far(void) { - return arr[-100]; /* { dg-warning "buffer underread" "warning" } */ + return arr[-100]; /* { dg-warning "buffer under-read" "warning" } */ /* { dg-message "out-of-bounds read from byte -400 till byte -397 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } int32_t int_arr_read_element_before_start_near(void) { - return arr[-2]; /* { dg-warning "buffer underread" "warning" } */ + return arr[-2]; /* { dg-warning "buffer under-read" "warning" } */ /* { dg-message "out-of-bounds read from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } int32_t int_arr_read_element_before_start_off_by_one(void) { - return arr[-1]; /* { dg-warning "buffer underread" "warning" } */ + return arr[-1]; /* { dg-warning "buffer under-read" "warning" } */ /* { dg-message "out-of-bounds read from byte -4 till byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } int32_t int_arr_read_element_at_start(void) @@ -32,21 +35,24 @@ int32_t int_arr_read_element_at_end(void) int32_t int_arr_read_element_after_end_off_by_one(void) { - return arr[10]; /* { dg-warning "buffer overread" "warning" } */ + return arr[10]; /* { dg-warning "buffer over-read" "warning" } */ /* { dg-message "out-of-bounds read from byte 40 till byte 43 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } int32_t int_arr_read_element_after_end_near(void) { - return arr[11]; /* { dg-warning "buffer overread" "warning" } */ + return arr[11]; /* { dg-warning "buffer over-read" "warning" } */ /* { dg-message "out-of-bounds read from byte 44 till byte 47 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } int32_t int_arr_read_element_after_end_far(void) { - return arr[100]; /* { dg-warning "buffer overread" "warning" } */ + return arr[100]; /* { dg-warning "buffer over-read" "warning" } */ /* { dg-message "out-of-bounds read from byte 400 till byte 403 but 'arr' ends at byte 40" "final event" { target *-*-* } .-1 } */ /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c new file mode 100644 index 00000000000..0f50bb92290 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-read-struct-arr.c @@ -0,0 +1,65 @@ +#include + +struct st +{ + char buf[16]; + int32_t x; + int32_t y; +}; + +struct st arr[10]; + +int32_t struct_arr_read_x_element_before_start_far(void) +{ + return arr[-100].x; /* { dg-warning "buffer under-read" "warning" } */ + /* { dg-message "out-of-bounds read from byte -2384 till byte -2381 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ +} + +int32_t struct_arr_read_x_element_before_start_near(void) +{ + return arr[-2].x; /* { dg-warning "buffer under-read" "warning" } */ + /* { dg-message "out-of-bounds read from byte -32 till byte -29 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ +} + +int32_t struct_arr_read_x_element_before_start_off_by_one(void) +{ + return arr[-1].x; /* { dg-warning "buffer under-read" "warning" } */ + /* { dg-message "out-of-bounds read from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ +} + +int32_t struct_arr_read_x_element_at_start(void) +{ + return arr[0].x; +} + +int32_t struct_arr_read_x_element_at_end(void) +{ + return arr[9].x; +} + +int32_t struct_arr_read_x_element_after_end_off_by_one(void) +{ + return arr[10].x; /* { dg-warning "buffer over-read" "warning" } */ + /* { dg-message "out-of-bounds read from byte 256 till byte 259 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */ + /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ +} + +int32_t struct_arr_read_x_element_after_end_near(void) +{ + return arr[11].x; /* { dg-warning "buffer over-read" "warning" } */ + /* { dg-message "out-of-bounds read from byte 280 till byte 283 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */ + /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ +} + +int32_t struct_arr_read_x_element_after_end_far(void) +{ + return arr[100].x; /* { dg-warning "buffer over-read" "warning" } */ + /* { dg-message "out-of-bounds read from byte 2416 till byte 2419 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */ + /* { dg-message "read of 4 bytes from after the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c index 739ebb11590..2f3bbfa2dc2 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-char-arr.c @@ -1,37 +1,37 @@ char arr[10]; /* { dg-message "capacity is 10 bytes" } */ -void int_arr_write_element_before_start_far(char x) +void char_arr_write_element_before_start_far(char x) { - arr[-100] = x; /* { dg-warning "buffer underflow" "warning" } */ + arr[-100] = x; /* { dg-warning "buffer underwrite" "warning" } */ /* { dg-message "out-of-bounds write at byte -100 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } -void int_arr_write_element_before_start_near(char x) +void char_arr_write_element_before_start_near(char x) { - arr[-2] = x; /* { dg-warning "buffer underflow" "warning" } */ + arr[-2] = x; /* { dg-warning "buffer underwrite" "warning" } */ /* { dg-message "out-of-bounds write at byte -2 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } -void int_arr_write_element_before_start_off_by_one(char x) +void char_arr_write_element_before_start_off_by_one(char x) { - arr[-1] = x; /* { dg-warning "buffer underflow" "warning" } */ + arr[-1] = x; /* { dg-warning "buffer underwrite" "warning" } */ /* { dg-message "out-of-bounds write at byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } -void int_arr_write_element_at_start(char x) +void char_arr_write_element_at_start(char x) { arr[0] = x; } -void int_arr_write_element_at_end(char x) +void char_arr_write_element_at_end(char x) { arr[9] = x; } -void int_arr_write_element_after_end_off_by_one(char x) +void char_arr_write_element_after_end_off_by_one(char x) { arr[10] = x; /* { dg-warning "buffer overflow" "warning" } */ /* { dg-message "out-of-bounds write at byte 10 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */ @@ -39,7 +39,7 @@ void int_arr_write_element_after_end_off_by_one(char x) /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } -void int_arr_write_element_after_end_near(char x) +void char_arr_write_element_after_end_near(char x) { arr[11] = x; /* { dg-warning "buffer overflow" "warning" } */ /* { dg-message "out-of-bounds write at byte 11 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */ @@ -47,7 +47,7 @@ void int_arr_write_element_after_end_near(char x) /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ } -void int_arr_write_element_after_end_far(char x) +void char_arr_write_element_after_end_far(char x) { arr[100] = x; /* { dg-warning "buffer overflow" "warning" } */ /* { dg-message "out-of-bounds write at byte 100 but 'arr' ends at byte 10" "final event" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c index b2b37b92e01..0adb7899641 100644 --- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-int-arr.c @@ -4,21 +4,21 @@ int32_t arr[10]; /* { dg-message "capacity is 40 bytes" } */ void int_arr_write_element_before_start_far(int32_t x) { - arr[-100] = x; /* { dg-warning "buffer underflow" "warning" } */ + arr[-100] = x; /* { dg-warning "buffer underwrite" "warning" } */ /* { dg-message "out-of-bounds write from byte -400 till byte -397 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } void int_arr_write_element_before_start_near(int32_t x) { - arr[-2] = x; /* { dg-warning "buffer underflow" "warning" } */ + arr[-2] = x; /* { dg-warning "buffer underwrite" "warning" } */ /* { dg-message "out-of-bounds write from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } void int_arr_write_element_before_start_off_by_one(int32_t x) { - arr[-1] = x; /* { dg-warning "buffer underflow" "warning" } */ + arr[-1] = x; /* { dg-warning "buffer underwrite" "warning" } */ /* { dg-message "out-of-bounds write from byte -4 till byte -1 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c new file mode 100644 index 00000000000..cf6b458f44b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-write-struct-arr.c @@ -0,0 +1,65 @@ +#include + +struct st +{ + char buf[16]; + int32_t x; + int32_t y; +}; + +struct st arr[10]; + +void struct_arr_write_x_element_before_start_far(int32_t x) +{ + arr[-100].x = x; /* { dg-warning "buffer underwrite" "warning" } */ + /* { dg-message "out-of-bounds write from byte -2384 till byte -2381 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ +} + +void struct_arr_write_x_element_before_start_near(int32_t x) +{ + arr[-2].x = x; /* { dg-warning "buffer underwrite" "warning" } */ + /* { dg-message "out-of-bounds write from byte -32 till byte -29 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ +} + +void struct_arr_write_x_element_before_start_off_by_one(int32_t x) +{ + arr[-1].x = x; /* { dg-warning "buffer underwrite" "warning" } */ + /* { dg-message "out-of-bounds write from byte -8 till byte -5 but 'arr' starts at byte 0" "final event" { target *-*-* } .-1 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-2 } */ +} + +void struct_arr_write_x_element_at_start(int32_t x) +{ + arr[0].x = x; +} + +void struct_arr_write_x_element_at_end(int32_t x) +{ + arr[9].x = x; +} + +void struct_arr_write_x_element_after_end_off_by_one(int32_t x) +{ + arr[10].x = x; /* { dg-warning "buffer overflow" "warning" } */ + /* { dg-message "out-of-bounds write from byte 256 till byte 259 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */ + /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ +} + +void struct_arr_write_x_element_after_end_near(int32_t x) +{ + arr[11].x = x; /* { dg-warning "buffer overflow" "warning" } */ + /* { dg-message "out-of-bounds write from byte 280 till byte 283 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */ + /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ +} + +void struct_arr_write_x_element_after_end_far(int32_t x) +{ + arr[100].x = x; /* { dg-warning "buffer overflow" "warning" } */ + /* { dg-message "out-of-bounds write from byte 2416 till byte 2419 but 'arr' ends at byte 240" "final event" { target *-*-* } .-1 } */ + /* { dg-message "write of 4 bytes to beyond the end of 'arr'" "num bad bytes note" { target *-*-* } .-2 } */ + /* { dg-message "valid subscripts for 'arr' are '\\\[0\\\]' to '\\\[9\\\]'" "valid subscript note" { target *-*-* } .-3 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c b/gcc/testsuite/gcc.dg/analyzer/pr101962.c index cf0041b2fcd..08c0aba5cbf 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr101962.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr101962.c @@ -25,7 +25,7 @@ test_1 (void) return *a; /* { dg-line test_1 } */ /* { dg-warning "use of uninitialized value '\\*a'" "warning" { target *-*-* } test_1 } */ - /* { dg-warning "overread" "warning" { target *-*-* } test_1 } */ + /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test_1 } */ } static const char * __attribute__((noinline)) diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c index 2efe3371e12..75f0b70a996 100644 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c @@ -37,7 +37,7 @@ void test_1 () __analyzer_eval (q[8] == 1); /* { dg-line eval } */ /* { dg-warning "UNKNOWN" "warning" { target *-*-* } eval } */ - /* { dg-warning "overread" "warning" { target *-*-* } eval } */ + /* { dg-warning "heap-based buffer over-read" "warning" { target *-*-* } eval } */ /* { dg-warning "use of uninitialized value" "warning" { target *-*-* } eval } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c index b05b8629a7f..def83006a71 100644 --- a/gcc/testsuite/gcc.dg/analyzer/zlib-3.c +++ b/gcc/testsuite/gcc.dg/analyzer/zlib-3.c @@ -184,7 +184,7 @@ static int huft_build(uInt *b, uInt n, uInt s, const uInt *d, const uInt *e, mask = (1 << w) - 1; /* The analyzer thinks that h can be -1 here. This is probably a false positive. */ - while ((i & mask) != x[h]) { /* { dg-bogus "underread" "" { xfail *-*-* } } */ + while ((i & mask) != x[h]) { /* { dg-bogus "under-read" "" { xfail *-*-* } } */ h--; w -= l; mask = (1 << w) - 1; -- 2.26.3