Skip to content

[NFC] [analyzer] Add ArrayBound tests to document casting bug #127062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion clang/test/Analysis/out-of-bounds.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,security.ArrayBound -verify %s
// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,security.ArrayBound,debug.ExprInspection -verify %s

void clang_analyzer_value(int);

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

int table[256], small_table[128];
int test_cast_to_unsigned(signed char x) {
unsigned char y = x;
if (x >= 0)
return x;
// FIXME: Here the analyzer ignores the signed -> unsigned cast, and manages to
// load a negative value from an unsigned variable. This causes an underflow
// report, which is an ugly false positive.
// The underlying issue is tracked by Github ticket #39492.
clang_analyzer_value(y); // expected-warning {{8s:{ [-128, -1] } }}
return table[y]; // expected-warning {{Out of bound access to memory preceding}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also dump the value range of this y sym?
That would probably highlight the "wrong assumption"

Maybe in the rest of the examples too. Wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that seems to be useful, I added the value dumps to the two testcases where they are relevant. (The third testcase is not buggy, I just created it to highlight potential drawbacks of naive solutions for silencing the bug.)

}

int test_cast_to_unsigned_overflow(signed char x) {
unsigned char y = x;
if (x >= 0)
return x;
// A variant of 'test_cast_to_unsigned' where the correct behavior would be
// an overflow report (because the negative values are cast to `unsigned
// char` values that are too large).
// FIXME: See comment in 'test_cast_to_unsigned'.
clang_analyzer_value(y); // expected-warning {{8s:{ [-128, -1] } }}
return small_table[y]; // expected-warning {{Out of bound access to memory preceding}}
}

int test_negative_offset_with_unsigned_idx(void) {
// An example where the subscript operator uses an unsigned index, but the
// underflow report is still justified. (We should try to keep this if we
// silence false positives like the one in 'test_cast_to_unsigned'.)
int *p = table - 10;
unsigned idx = 2u;
return p[idx]; // expected-warning {{Out of bound access to memory preceding}}
}