Author: DonĂ¡t Nagy Date: 2025-02-13T16:09:09+01:00 New Revision: d2240cd314102ed99d35b84d43006e324f344163
URL: https://github.com/llvm/llvm-project/commit/d2240cd314102ed99d35b84d43006e324f344163 DIFF: https://github.com/llvm/llvm-project/commit/d2240cd314102ed99d35b84d43006e324f344163.diff LOG: [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`. Added: Modified: clang/test/Analysis/out-of-bounds.c Removed: ################################################################################ diff --git a/clang/test/Analysis/out-of-bounds.c b/clang/test/Analysis/out-of-bounds.c index 9f410e884d763..7a094b8fdc840 100644 --- a/clang/test/Analysis/out-of-bounds.c +++ b/clang/test/Analysis/out-of-bounds.c @@ -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 @@ -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}} +} + +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}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits