From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2209) id 027EF3858D20; Wed, 21 Feb 2024 00:46:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 027EF3858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1708476397; bh=3eDn66Z9w9LDd4xeSLfZXtCCBwEAJNMf4b8n7KDf7ro=; h=From:To:Subject:Date:From; b=WbRF4YrOzc035w63nkqnVlXKm2RNkK39P431U0Nofh8DSbwPtyXop3BXanHF/ENiz Tc95UjVX6IGt0OzqAEkiWTK9O3rjspx7YQuxRdM09WY+allHk7DBH49SSI4qHEqZBZ ZbhkN5FqTj9benav40I8WQgl3+IV3rS0k6XvCqj0= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: David Malcolm To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-9090] analyzer: handle empty ranges in symbolic_byte_range::intersection [PR113998] X-Act-Checkin: gcc X-Git-Author: David Malcolm X-Git-Refname: refs/heads/master X-Git-Oldrev: b4c88cc717e5ccedca34cabe62e1e8903cad9d5f X-Git-Newrev: 79d4c7ddc83e000adc8174b179dff44a88d5a41b Message-Id: <20240221004637.027EF3858D20@sourceware.org> Date: Wed, 21 Feb 2024 00:46:36 +0000 (GMT) List-Id: https://gcc.gnu.org/g:79d4c7ddc83e000adc8174b179dff44a88d5a41b commit r14-9090-g79d4c7ddc83e000adc8174b179dff44a88d5a41b Author: David Malcolm Date: Tue Feb 20 19:44:50 2024 -0500 analyzer: handle empty ranges in symbolic_byte_range::intersection [PR113998] gcc/analyzer/ChangeLog: PR analyzer/113998 * ranges.cc (symbolic_byte_range::intersection): Handle empty ranges. (selftest::test_intersects): Add test coverage for empty ranges. gcc/testsuite/ChangeLog: PR analyzer/113998 * c-c++-common/analyzer/overlapping-buffers-pr113998.c: New test. Signed-off-by: David Malcolm Diff: --- gcc/analyzer/ranges.cc | 18 ++++++++++++++++++ .../analyzer/overlapping-buffers-pr113998.c | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/gcc/analyzer/ranges.cc b/gcc/analyzer/ranges.cc index f46b04121d3f..ffdd0d4c5722 100644 --- a/gcc/analyzer/ranges.cc +++ b/gcc/analyzer/ranges.cc @@ -193,6 +193,12 @@ tristate symbolic_byte_range::intersection (const symbolic_byte_range &other, const region_model &model) const { + /* If either is empty, then there is no intersection. */ + if (empty_p ()) + return tristate::TS_FALSE; + if (other.empty_p ()) + return tristate::TS_FALSE; + /* For brevity, consider THIS to be "range A", and OTHER to be "range B". */ region_model_manager *mgr = model.get_manager (); @@ -262,12 +268,17 @@ static void test_intersects (void) ASSERT_EQ (r0_9.get_next_byte_offset (mgr), ten); ASSERT_EQ (r0_9.get_last_byte_offset (mgr), nine); + symbolic_byte_range concrete_empty (zero, zero); + ASSERT_TRUE (concrete_empty.empty_p ()); + ASSERT_EQ (r0_9.intersection (r0, m), tristate::TS_TRUE); ASSERT_EQ (r0.intersection (r0_9, m), tristate::TS_TRUE); ASSERT_EQ (r0_9.intersection (r9, m), tristate::TS_TRUE); ASSERT_EQ (r9.intersection (r0_9, m), tristate::TS_TRUE); ASSERT_EQ (r0_9.intersection (r10, m), tristate::TS_FALSE); ASSERT_EQ (r10.intersection (r0_9, m), tristate::TS_FALSE); + ASSERT_EQ (concrete_empty.intersection (r0_9, m), tristate::TS_FALSE); + ASSERT_EQ (r0_9.intersection (concrete_empty, m), tristate::TS_FALSE); ASSERT_EQ (r5_9.intersection (r0, m), tristate::TS_FALSE); ASSERT_EQ (r0.intersection (r5_9, m), tristate::TS_FALSE); @@ -286,6 +297,9 @@ static void test_intersects (void) symbolic_byte_range ry (y_init_sval, one); symbolic_byte_range rx_x_plus_y_minus_1 (x_init_sval, y_init_sval); + symbolic_byte_range symbolic_empty (x_init_sval, zero); + ASSERT_TRUE (symbolic_empty.empty_p ()); + ASSERT_EQ (rx_x_plus_y_minus_1.get_start_byte_offset (), x_init_sval); ASSERT_EQ (rx_x_plus_y_minus_1.get_size_in_bytes (), y_init_sval); ASSERT_EQ @@ -296,6 +310,10 @@ static void test_intersects (void) SK_BINOP); ASSERT_EQ (rx.intersection (ry, m), tristate::TS_UNKNOWN); + ASSERT_EQ (rx.intersection (concrete_empty, m), tristate::TS_FALSE); + ASSERT_EQ (concrete_empty.intersection (rx, m), tristate::TS_FALSE); + ASSERT_EQ (rx.intersection (symbolic_empty, m), tristate::TS_FALSE); + ASSERT_EQ (symbolic_empty.intersection (rx, m), tristate::TS_FALSE); ASSERT_EQ (r0_x_minus_1.intersection (r0, m), tristate::TS_TRUE); #if 0 ASSERT_EQ (r0_x_minus_1.intersection (rx, m), tristate::TS_FALSE); diff --git a/gcc/testsuite/c-c++-common/analyzer/overlapping-buffers-pr113998.c b/gcc/testsuite/c-c++-common/analyzer/overlapping-buffers-pr113998.c new file mode 100644 index 000000000000..5c6352eb42f4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/overlapping-buffers-pr113998.c @@ -0,0 +1,21 @@ +/* Verify we don't ICE on -Wanalyzer-overlapping-buffers on + execution paths where the size is constant zero, but the + optimizer didn't see that. */ + +typedef __SIZE_TYPE__ size_t; + +extern char a[]; +size_t n; + +size_t __attribute__((noinline)) +get_hidden_zero () +{ + return 0; +} + +void +test_pr113998 () +{ + size_t n = get_hidden_zero (); + __builtin_strncpy (a, a, n); /* { dg-warning "overlapping buffers passed as arguments to" } */ +}