Skip to content

Commit d2240cd

Browse files
authored
[NFC] [analyzer] Add ArrayBound tests to document casting bug (#127062)
Add a few security.ArrayBound testcases that document the false positives caused the fact that the analyzer doesn't model a cast from `signed char` to `unsigned char`.
1 parent 62eddf4 commit d2240cd

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

clang/test/Analysis/out-of-bounds.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,security.ArrayBound -verify %s
1+
// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,security.ArrayBound,debug.ExprInspection -verify %s
2+
3+
void clang_analyzer_value(int);
24

35
// Tests doing an out-of-bounds access after the end of an array using:
46
// - constant integer index
@@ -180,3 +182,36 @@ char test_comparison_with_extent_symbol(struct incomplete *p) {
180182
return ((char *)p)[-1]; // no-warning
181183
}
182184

185+
int table[256], small_table[128];
186+
int test_cast_to_unsigned(signed char x) {
187+
unsigned char y = x;
188+
if (x >= 0)
189+
return x;
190+
// FIXME: Here the analyzer ignores the signed -> unsigned cast, and manages to
191+
// load a negative value from an unsigned variable. This causes an underflow
192+
// report, which is an ugly false positive.
193+
// The underlying issue is tracked by Github ticket #39492.
194+
clang_analyzer_value(y); // expected-warning {{8s:{ [-128, -1] } }}
195+
return table[y]; // expected-warning {{Out of bound access to memory preceding}}
196+
}
197+
198+
int test_cast_to_unsigned_overflow(signed char x) {
199+
unsigned char y = x;
200+
if (x >= 0)
201+
return x;
202+
// A variant of 'test_cast_to_unsigned' where the correct behavior would be
203+
// an overflow report (because the negative values are cast to `unsigned
204+
// char` values that are too large).
205+
// FIXME: See comment in 'test_cast_to_unsigned'.
206+
clang_analyzer_value(y); // expected-warning {{8s:{ [-128, -1] } }}
207+
return small_table[y]; // expected-warning {{Out of bound access to memory preceding}}
208+
}
209+
210+
int test_negative_offset_with_unsigned_idx(void) {
211+
// An example where the subscript operator uses an unsigned index, but the
212+
// underflow report is still justified. (We should try to keep this if we
213+
// silence false positives like the one in 'test_cast_to_unsigned'.)
214+
int *p = table - 10;
215+
unsigned idx = 2u;
216+
return p[idx]; // expected-warning {{Out of bound access to memory preceding}}
217+
}

0 commit comments

Comments
 (0)