aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-02-20 19:44:50 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2024-02-20 19:44:50 -0500
commit79d4c7ddc83e000adc8174b179dff44a88d5a41b (patch)
tree205b088f6a7d92d2d1031e675236e0c8c7e131fb
parentb4c88cc717e5ccedca34cabe62e1e8903cad9d5f (diff)
downloadgcc-79d4c7ddc83e000adc8174b179dff44a88d5a41b.zip
gcc-79d4c7ddc83e000adc8174b179dff44a88d5a41b.tar.gz
gcc-79d4c7ddc83e000adc8174b179dff44a88d5a41b.tar.bz2
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 <dmalcolm@redhat.com>
-rw-r--r--gcc/analyzer/ranges.cc18
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/overlapping-buffers-pr113998.c21
2 files changed, 39 insertions, 0 deletions
diff --git a/gcc/analyzer/ranges.cc b/gcc/analyzer/ranges.cc
index f46b041..ffdd0d4 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 0000000..5c6352e
--- /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" } */
+}