Skip to content

Commit d96569e

Browse files
authored
[analyzer] Fix crash on using bitcast(<type>, <array>) as array subscript (#101647)
Current CSA logic does not expect `LazyCompoundValKind` as array index. This may happen if array is used as subscript to another, in case of bitcast to integer type. Catch such cases and return `UnknownVal`, since CSA cannot model array -> int casts. Closes #94496
1 parent 12937b1 commit d96569e

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

clang/lib/StaticAnalyzer/Core/Store.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,17 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
472472
const auto *ElemR = dyn_cast<ElementRegion>(BaseRegion);
473473

474474
// Convert the offset to the appropriate size and signedness.
475-
Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>();
475+
auto Off = svalBuilder.convertToArrayIndex(Offset).getAs<NonLoc>();
476+
if (!Off) {
477+
// Handle cases when LazyCompoundVal is used for an array index.
478+
// Such case is possible if code does:
479+
// char b[4];
480+
// a[__builtin_bitcast(int, b)];
481+
// Return UnknownVal, since we cannot model it.
482+
return UnknownVal();
483+
}
484+
485+
Offset = Off.value();
476486

477487
if (!ElemR) {
478488
// If the base region is not an ElementRegion, create one.

clang/test/Analysis/exercise-ps.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
// RUN: %clang_analyze_cc1 %s -verify -Wno-error=implicit-function-declaration \
2-
// RUN: -analyzer-checker=core,unix.Malloc \
1+
// RUN: %clang_analyze_cc1 %s -triple=x86_64-unknown-linux \
2+
// RUN: -verify -Wno-error=implicit-function-declaration \
3+
// RUN: -analyzer-checker=core,unix.Malloc,debug.ExprInspection \
34
// RUN: -analyzer-config core.CallAndMessage:ArgPointeeInitializedness=true
45
//
56
// Just exercise the analyzer on code that has at one point caused issues
67
// (i.e., no assertions or crashes).
78

9+
void clang_analyzer_dump_int(int);
10+
811
static void f1(const char *x, char *y) {
912
while (*x != 0) {
1013
*y++ = *x++;
@@ -30,3 +33,16 @@ void f3(void *dest) {
3033
void *src = __builtin_alloca(5);
3134
memcpy(dest, src, 1); // expected-warning{{2nd function call argument is a pointer to uninitialized value}}
3235
}
36+
37+
// Reproduce crash from GH#94496. When array is used as subcript to another array, CSA cannot model it
38+
// and should just assume it's unknown and do not crash.
39+
void f4(char *array) {
40+
char b[4] = {0};
41+
42+
_Static_assert(sizeof(int) == 4, "Wrong triple for the test");
43+
44+
clang_analyzer_dump_int(__builtin_bit_cast(int, b)); // expected-warning {{lazyCompoundVal}}
45+
clang_analyzer_dump_int(array[__builtin_bit_cast(int, b)]); // expected-warning {{Unknown}}
46+
47+
array[__builtin_bit_cast(int, b)] = 0x10; // no crash
48+
}

0 commit comments

Comments
 (0)