Skip to content

Commit db6051d

Browse files
authored
[analyzer] fix crash on binding to symbolic region with void * type (#107572)
As reported in #103714 (comment). 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`
1 parent 3cdb30e commit db6051d

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

clang/lib/StaticAnalyzer/Core/RegionStore.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,8 +2380,12 @@ RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
23802380

23812381
// Binding directly to a symbolic region should be treated as binding
23822382
// to element 0.
2383-
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
2384-
R = GetElementZeroRegion(SR, SR->getPointeeStaticType());
2383+
if (const auto *SymReg = dyn_cast<SymbolicRegion>(R)) {
2384+
QualType Ty = SymReg->getPointeeStaticType();
2385+
if (Ty->isVoidType())
2386+
Ty = StateMgr.getContext().CharTy;
2387+
R = GetElementZeroRegion(SymReg, Ty);
2388+
}
23852389

23862390
assert((!isa<CXXThisRegion>(R) || !B.lookup(R)) &&
23872391
"'this' pointer is not an l-value and is not assignable");

clang/test/Analysis/asm.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// RUN: -analyzer-checker debug.ExprInspection,core -Wno-error=invalid-gnu-asm-cast -w %s -verify
33

44
int clang_analyzer_eval(int);
5+
void clang_analyzer_dump(int);
6+
void clang_analyzer_dump_ptr(void *);
57

68
int global;
79
void testRValueOutput() {
@@ -40,3 +42,13 @@ void testInlineAsmMemcpyUninit(void)
4042
MyMemcpy(&a[1], &b[1], sizeof(b) - sizeof(b[1]));
4143
c = a[0]; // expected-warning{{Assigned value is garbage or undefined}}
4244
}
45+
46+
void testAsmWithVoidPtrArgument()
47+
{
48+
extern void *globalVoidPtr;
49+
clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning-re {{reg_${{[0-9]+}}<int Element{SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>},0 S64b,int}>}}
50+
clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
51+
asm ("" : : "a"(globalVoidPtr)); // no crash
52+
clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning {{Unknown}}
53+
clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
54+
}

0 commit comments

Comments
 (0)