[llvm-branch-commits] [clang] Backport "[analyzer] Fix crash on using `bitcast(<type>, <array>)` as array subscript" (PR #101684)
Balazs Benics via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Aug 2 08:10:59 PDT 2024
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/101684
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
(cherry picked from commit d96569ecc2807a13dab6495d8cc4e82775b00af1)
>From a9ef1edf0778a1702b2c8bb4027675238e032d79 Mon Sep 17 00:00:00 2001
From: Pavel Skripkin <paskripkin at gmail.com>
Date: Fri, 2 Aug 2024 18:04:57 +0300
Subject: [PATCH] [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
(cherry picked from commit d96569ecc2807a13dab6495d8cc4e82775b00af1)
---
clang/docs/ReleaseNotes.rst | 3 +++
clang/lib/StaticAnalyzer/Core/Store.cpp | 12 +++++++++++-
clang/test/Analysis/exercise-ps.c | 20 ++++++++++++++++++--
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c42cb9932f3f7..5cd398c22c946 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -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)
diff --git a/clang/lib/StaticAnalyzer/Core/Store.cpp b/clang/lib/StaticAnalyzer/Core/Store.cpp
index 67ca61bb56ba2..b436dd746d21f 100644
--- a/clang/lib/StaticAnalyzer/Core/Store.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Store.cpp
@@ -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.
diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c
index d1e1771afddb5..50643d5b04687 100644
--- a/clang/test/Analysis/exercise-ps.c
+++ b/clang/test/Analysis/exercise-ps.c
@@ -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++;
@@ -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
+}
More information about the llvm-branch-commits
mailing list