[clang] [clang][Static analyzer] fix crash on using `bitcast(<type>, <array>)` as array subscript (PR #101647)
Pavel Skripkin via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 2 03:09:44 PDT 2024
https://github.com/pskrgag created https://github.com/llvm/llvm-project/pull/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
>From d94748f76ca793bf40cb57dd904d487c51bdcd40 Mon Sep 17 00:00:00 2001
From: Pavel Skripkin <paskripkin at gmail.com>
Date: Fri, 2 Aug 2024 12:02:11 +0300
Subject: [PATCH 1/2] clang/csa: fix crash on using bitcast(<type>, <array>) 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 67ca61bb56ba2..72587ef31a17c 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<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.
>From 515520dde7eb4d0365b0eed4627b19d4dedde5d7 Mon Sep 17 00:00:00 2001
From: Pavel Skripkin <paskripkin at gmail.com>
Date: Fri, 2 Aug 2024 12:14:11 +0300
Subject: [PATCH 2/2] clang/csa: add test case for array[bitcast(<type>,
<array>)]
---
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 d1e1771afddb5..9bba16c282967 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
+}
More information about the cfe-commits
mailing list