[clang] [analyzer] Add hack in ArrayBound to cover up missing casts (PR #127117)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 13 11:55:38 PST 2025
================
@@ -188,29 +189,50 @@ int test_cast_to_unsigned(signed char 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.
+ // load a negative value from an unsigned variable.
// 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}}
+ // However, a hack in the ArrayBound checker suppresses the false positive
+ // underflow report that would be generated here.
+ return table[y]; // no-warning
}
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'.
+ // FIXME: As in 'test_cast_to_unsigned', the analyzer thinks that this
+ // unsigned variable contains a negative value.
clang_analyzer_value(y); // expected-warning {{8s:{ [-128, -1] } }}
- return small_table[y]; // expected-warning {{Out of bound access to memory preceding}}
+ // FIXME: The following subscript expression should produce an overflow
+ // report (because negative signed char corresponds to unsigned char >= 128);
+ // but the hack in ArrayBound just silences reports and cannot "restore" the
+ // real execution paths.
+ return small_table[y]; // no-warning
+}
+
+int test_cast_to_unsigned_with_ptr_arith(signed char x) {
+ unsigned char y = x;
+ int *p = table - 10;
+
+ if (x >= 0)
+ return x;
+ // FIXME: As in 'test_cast_to_unsigned', the analyzer thinks that this
+ // unsigned variable contains a negative value.
+ clang_analyzer_value(y); // expected-warning {{8s:{ [-128, -1] } }}
+ // In this case, the hack in ArrayBound cannot suppress the false positive
+ // underflow report because 'p' is not the beginning of a memory region, so
+ // it cannot clearly say that an unsigned index guarantees no overflow.
+ // However, we still don't get an underflow report because (for some unclear
+ // reason) the analyzer fails to evaluate this more complex expression.
----------------
NagyDonat wrote:
I expected that this test case would demonstrate a shortcoming of my hacky report suppression -- but I was surprised to see that this case does not produce a false positive underflow report.
I verified with some manual debugging that my `isOffsetObviouslyNonnegative()` branch does not trigger in this testcase. The disappearance of the report is caused by something else -- perhaps the increased complexity of the expression?
https://github.com/llvm/llvm-project/pull/127117
More information about the cfe-commits
mailing list