Skip to content

Commit 79d4c7d

Browse files
committed
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 <[email protected]>
1 parent b4c88cc commit 79d4c7d

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

gcc/analyzer/ranges.cc

+18
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ tristate
193193
symbolic_byte_range::intersection (const symbolic_byte_range &other,
194194
const region_model &model) const
195195
{
196+
/* If either is empty, then there is no intersection. */
197+
if (empty_p ())
198+
return tristate::TS_FALSE;
199+
if (other.empty_p ())
200+
return tristate::TS_FALSE;
201+
196202
/* For brevity, consider THIS to be "range A", and OTHER to be "range B". */
197203

198204
region_model_manager *mgr = model.get_manager ();
@@ -262,12 +268,17 @@ static void test_intersects (void)
262268
ASSERT_EQ (r0_9.get_next_byte_offset (mgr), ten);
263269
ASSERT_EQ (r0_9.get_last_byte_offset (mgr), nine);
264270

271+
symbolic_byte_range concrete_empty (zero, zero);
272+
ASSERT_TRUE (concrete_empty.empty_p ());
273+
265274
ASSERT_EQ (r0_9.intersection (r0, m), tristate::TS_TRUE);
266275
ASSERT_EQ (r0.intersection (r0_9, m), tristate::TS_TRUE);
267276
ASSERT_EQ (r0_9.intersection (r9, m), tristate::TS_TRUE);
268277
ASSERT_EQ (r9.intersection (r0_9, m), tristate::TS_TRUE);
269278
ASSERT_EQ (r0_9.intersection (r10, m), tristate::TS_FALSE);
270279
ASSERT_EQ (r10.intersection (r0_9, m), tristate::TS_FALSE);
280+
ASSERT_EQ (concrete_empty.intersection (r0_9, m), tristate::TS_FALSE);
281+
ASSERT_EQ (r0_9.intersection (concrete_empty, m), tristate::TS_FALSE);
271282

272283
ASSERT_EQ (r5_9.intersection (r0, m), tristate::TS_FALSE);
273284
ASSERT_EQ (r0.intersection (r5_9, m), tristate::TS_FALSE);
@@ -286,6 +297,9 @@ static void test_intersects (void)
286297
symbolic_byte_range ry (y_init_sval, one);
287298
symbolic_byte_range rx_x_plus_y_minus_1 (x_init_sval, y_init_sval);
288299

300+
symbolic_byte_range symbolic_empty (x_init_sval, zero);
301+
ASSERT_TRUE (symbolic_empty.empty_p ());
302+
289303
ASSERT_EQ (rx_x_plus_y_minus_1.get_start_byte_offset (), x_init_sval);
290304
ASSERT_EQ (rx_x_plus_y_minus_1.get_size_in_bytes (), y_init_sval);
291305
ASSERT_EQ
@@ -296,6 +310,10 @@ static void test_intersects (void)
296310
SK_BINOP);
297311

298312
ASSERT_EQ (rx.intersection (ry, m), tristate::TS_UNKNOWN);
313+
ASSERT_EQ (rx.intersection (concrete_empty, m), tristate::TS_FALSE);
314+
ASSERT_EQ (concrete_empty.intersection (rx, m), tristate::TS_FALSE);
315+
ASSERT_EQ (rx.intersection (symbolic_empty, m), tristate::TS_FALSE);
316+
ASSERT_EQ (symbolic_empty.intersection (rx, m), tristate::TS_FALSE);
299317
ASSERT_EQ (r0_x_minus_1.intersection (r0, m), tristate::TS_TRUE);
300318
#if 0
301319
ASSERT_EQ (r0_x_minus_1.intersection (rx, m), tristate::TS_FALSE);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* Verify we don't ICE on -Wanalyzer-overlapping-buffers on
2+
execution paths where the size is constant zero, but the
3+
optimizer didn't see that. */
4+
5+
typedef __SIZE_TYPE__ size_t;
6+
7+
extern char a[];
8+
size_t n;
9+
10+
size_t __attribute__((noinline))
11+
get_hidden_zero ()
12+
{
13+
return 0;
14+
}
15+
16+
void
17+
test_pr113998 ()
18+
{
19+
size_t n = get_hidden_zero ();
20+
__builtin_strncpy (a, a, n); /* { dg-warning "overlapping buffers passed as arguments to" } */
21+
}

0 commit comments

Comments
 (0)