[clang] db6051d - [analyzer] fix crash on binding to symbolic region with `void *` type (#107572)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 9 09:12:42 PDT 2024


Author: Pavel Skripkin
Date: 2024-09-09T18:12:38+02:00
New Revision: db6051dae085c35020c1273ae8d38508c9958bc7

URL: https://github.com/llvm/llvm-project/commit/db6051dae085c35020c1273ae8d38508c9958bc7
DIFF: https://github.com/llvm/llvm-project/commit/db6051dae085c35020c1273ae8d38508c9958bc7.diff

LOG: [analyzer] fix crash on binding to symbolic region with `void *` type (#107572)

As reported in
https://github.com/llvm/llvm-project/pull/103714#issuecomment-2295769193.
CSA crashes on trying to bind value to symbolic region with `void *`.
This happens when such region gets passed as inline asm input and engine
tries to bind `UnknownVal` to that region.

Fix it by changing type from void to char before calling
`GetElementZeroRegion`

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Core/RegionStore.cpp
    clang/test/Analysis/asm.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index ba29c123139016..c257a87dff385b 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2380,8 +2380,12 @@ RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
 
   // Binding directly to a symbolic region should be treated as binding
   // to element 0.
-  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
-    R = GetElementZeroRegion(SR, SR->getPointeeStaticType());
+  if (const auto *SymReg = dyn_cast<SymbolicRegion>(R)) {
+    QualType Ty = SymReg->getPointeeStaticType();
+    if (Ty->isVoidType())
+      Ty = StateMgr.getContext().CharTy;
+    R = GetElementZeroRegion(SymReg, Ty);
+  }
 
   assert((!isa<CXXThisRegion>(R) || !B.lookup(R)) &&
          "'this' pointer is not an l-value and is not assignable");

diff  --git a/clang/test/Analysis/asm.cpp b/clang/test/Analysis/asm.cpp
index b17ab04994d249..e0691dc4d794f5 100644
--- a/clang/test/Analysis/asm.cpp
+++ b/clang/test/Analysis/asm.cpp
@@ -2,6 +2,8 @@
 // RUN:      -analyzer-checker debug.ExprInspection,core -Wno-error=invalid-gnu-asm-cast -w %s -verify
 
 int clang_analyzer_eval(int);
+void clang_analyzer_dump(int);
+void clang_analyzer_dump_ptr(void *);
 
 int global;
 void testRValueOutput() {
@@ -40,3 +42,13 @@ void testInlineAsmMemcpyUninit(void)
     MyMemcpy(&a[1], &b[1], sizeof(b) - sizeof(b[1]));
     c = a[0]; // expected-warning{{Assigned value is garbage or undefined}}
 }
+
+void testAsmWithVoidPtrArgument()
+{
+  extern void *globalVoidPtr;
+  clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning-re {{reg_${{[0-9]+}}<int Element{SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>},0 S64b,int}>}}
+  clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
+  asm ("" : : "a"(globalVoidPtr)); // no crash
+  clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning {{Unknown}}
+  clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
+}


        


More information about the cfe-commits mailing list