https://github.com/NagyDonat updated https://github.com/llvm/llvm-project/pull/127062
From c3dc63db8914d759b6c58611b7448d4e83c66752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <donat.n...@ericsson.com> Date: Thu, 13 Feb 2025 11:35:45 +0100 Subject: [PATCH 1/2] [analyzer][NFC] Add ArrayBound tests to document casting bug 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`. --- clang/test/Analysis/out-of-bounds.c | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/clang/test/Analysis/out-of-bounds.c b/clang/test/Analysis/out-of-bounds.c index 923797200d0b4..177c03500a0c3 100644 --- a/clang/test/Analysis/out-of-bounds.c +++ b/clang/test/Analysis/out-of-bounds.c @@ -194,3 +194,34 @@ 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. + 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'. + 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}} +} From 0927d4de066484959b3272fd579390e29ca4ae91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <donat.n...@ericsson.com> Date: Thu, 13 Feb 2025 15:11:35 +0100 Subject: [PATCH 2/2] Dump the value of the signed unsigned char --- clang/test/Analysis/out-of-bounds.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/test/Analysis/out-of-bounds.c b/clang/test/Analysis/out-of-bounds.c index 177c03500a0c3..067ccbd58fff2 100644 --- a/clang/test/Analysis/out-of-bounds.c +++ b/clang/test/Analysis/out-of-bounds.c @@ -1,6 +1,7 @@ // RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,security.ArrayBound,debug.ExprInspection -verify %s void clang_analyzer_eval(int); +void clang_analyzer_value(int); // Tests doing an out-of-bounds access after the end of an array using: // - constant integer index @@ -203,6 +204,7 @@ int test_cast_to_unsigned(signed char x) { // 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}} } @@ -214,6 +216,7 @@ int test_cast_to_unsigned_overflow(signed char x) { // 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}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits