Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,9 @@ Crash and bug fixes
- Fixed a crash when storing through an address that refers to the address of
a label. (#GH89185)

- Fixed a crash when using ``__builtin_bitcast(type, array)`` as an array
subscript. (#GH94496)

- Z3 crosschecking (aka. Z3 refutation) is now bounded, and can't consume
more total time than the eymbolic execution itself. (#GH97298)

Expand Down
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
}