From d94748f76ca793bf40cb57dd904d487c51bdcd40 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Fri, 2 Aug 2024 12:02:11 +0300 Subject: [PATCH 1/4] clang/csa: fix crash on using bitcast(, ) as array subscript --- clang/lib/StaticAnalyzer/Core/Store.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp index 67ca61bb56ba28..72587ef31a17c5 100644 --- a/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/clang/lib/StaticAnalyzer/Core/Store.cpp @@ -472,7 +472,19 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, const auto *ElemR = dyn_cast(BaseRegion); // Convert the offset to the appropriate size and signedness. - Offset = svalBuilder.convertToArrayIndex(Offset).castAs(); + auto Off = svalBuilder.convertToArrayIndex(Offset).getAs(); + if (!Off) { + // Handle cases when LazyCompoundVal is used for an array index. + // Such case is possible if code does: + // + // char b[4]; + // a[__builtin_bitcast(int, b)]; + // + // Return UnknownVal, since we cannot model it. + return UnknownVal(); + } + + Offset = Off.value(); if (!ElemR) { // If the base region is not an ElementRegion, create one. From 515520dde7eb4d0365b0eed4627b19d4dedde5d7 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Fri, 2 Aug 2024 12:14:11 +0300 Subject: [PATCH 2/4] clang/csa: add test case for array[bitcast(, )] --- clang/test/Analysis/exercise-ps.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c index d1e1771afddb5e..9bba16c2829670 100644 --- a/clang/test/Analysis/exercise-ps.c +++ b/clang/test/Analysis/exercise-ps.c @@ -30,3 +30,10 @@ void f3(void *dest) { void *src = __builtin_alloca(5); memcpy(dest, src, 1); // expected-warning{{2nd function call argument is a pointer to uninitialized value}} } + +// Reproduce crash from GH#94496. When array is used as subcript to another array, CSA cannot model it +// and should just assume it's unknown and do not crash. +void f4(char *array) { + char b[4] = {0}; + array[__builtin_bit_cast(int, b)] = 0x10; // no crash +} From 514d89e411285451625a4adad55eedea0e850cdc Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Fri, 2 Aug 2024 13:56:10 +0300 Subject: [PATCH 3/4] clang/csa: pin triple with sizeof(int) == 4 in exercise-ps and fix style --- clang/lib/StaticAnalyzer/Core/Store.cpp | 2 -- clang/test/Analysis/exercise-ps.c | 8 ++++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp index 72587ef31a17c5..b436dd746d21f0 100644 --- a/clang/lib/StaticAnalyzer/Core/Store.cpp +++ b/clang/lib/StaticAnalyzer/Core/Store.cpp @@ -476,10 +476,8 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, if (!Off) { // Handle cases when LazyCompoundVal is used for an array index. // Such case is possible if code does: - // // char b[4]; // a[__builtin_bitcast(int, b)]; - // // Return UnknownVal, since we cannot model it. return UnknownVal(); } diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c index 9bba16c2829670..4b483b1a88a2f3 100644 --- a/clang/test/Analysis/exercise-ps.c +++ b/clang/test/Analysis/exercise-ps.c @@ -1,5 +1,6 @@ -// RUN: %clang_analyze_cc1 %s -verify -Wno-error=implicit-function-declaration \ -// RUN: -analyzer-checker=core,unix.Malloc \ +// RUN: %clang_analyze_cc1 %s -triple=x86_64-unknown-linux \ +// RUN: -verify -Wno-error=implicit-function-declaration \ +// RUN: -analyzer-checker=core,unix.Malloc,debug.ExprInspection \ // RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=true // // Just exercise the analyzer on code that has at one point caused issues @@ -35,5 +36,8 @@ void f3(void *dest) { // and should just assume it's unknown and do not crash. void f4(char *array) { char b[4] = {0}; + + _Static_assert(sizeof(int) == 4, "Wrong triple for the test"); + array[__builtin_bit_cast(int, b)] = 0x10; // no crash } From b928d7b0d2272cd022bddb0ae8b8304b3e3b8d2b Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Fri, 2 Aug 2024 17:02:16 +0300 Subject: [PATCH 4/4] clang/csa: dump SVal of bitcast() and array[bitcast()] --- clang/test/Analysis/exercise-ps.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c index 4b483b1a88a2f3..50643d5b046879 100644 --- a/clang/test/Analysis/exercise-ps.c +++ b/clang/test/Analysis/exercise-ps.c @@ -6,6 +6,8 @@ // Just exercise the analyzer on code that has at one point caused issues // (i.e., no assertions or crashes). +void clang_analyzer_dump_int(int); + static void f1(const char *x, char *y) { while (*x != 0) { *y++ = *x++; @@ -39,5 +41,8 @@ void f4(char *array) { _Static_assert(sizeof(int) == 4, "Wrong triple for the test"); + clang_analyzer_dump_int(__builtin_bit_cast(int, b)); // expected-warning {{lazyCompoundVal}} + clang_analyzer_dump_int(array[__builtin_bit_cast(int, b)]); // expected-warning {{Unknown}} + array[__builtin_bit_cast(int, b)] = 0x10; // no crash }