Skip to content

Commit

Permalink
[analyzer] Fix crash on using bitcast(<type>, <array>) as array sub…
Browse files Browse the repository at this point in the history
…script (llvm#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 llvm#94496
  • Loading branch information
pskrgag authored Aug 2, 2024
1 parent 12937b1 commit d96569e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
12 changes: 11 additions & 1 deletion clang/lib/StaticAnalyzer/Core/Store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,17 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
const auto *ElemR = dyn_cast<ElementRegion>(BaseRegion);

// Convert the offset to the appropriate size and signedness.
Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>();
auto Off = svalBuilder.convertToArrayIndex(Offset).getAs<NonLoc>();
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.
Expand Down
20 changes: 18 additions & 2 deletions clang/test/Analysis/exercise-ps.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// 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
// (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++;
Expand All @@ -30,3 +33,16 @@ 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};

_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
}

0 comments on commit d96569e

Please sign in to comment.