[clang] [clang][Static analyzer] fix crash on using `bitcast(<type>, <array>)` as array subscript (PR #101647)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 2 03:10:13 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Pavel Skripkin (pskrgag)

<details>
<summary>Changes</summary>

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 


---
Full diff: https://github.com/llvm/llvm-project/pull/101647.diff


2 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Core/Store.cpp (+13-1) 
- (modified) clang/test/Analysis/exercise-ps.c (+7) 


``````````diff
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.
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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/101647


More information about the cfe-commits mailing list