Skip to content

Commit 8d661fd

Browse files
authored
[analyzer] use invalidateRegions() in VisitGCCAsmStmt (#109838)
1 parent a3cc4b6 commit 8d661fd

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3811,15 +3811,19 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
38113811
assert(!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef.
38123812

38133813
if (std::optional<Loc> LV = X.getAs<Loc>())
3814-
state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
3814+
state = state->invalidateRegions(*LV, A, currBldrCtx->blockCount(),
3815+
Pred->getLocationContext(),
3816+
/*CausedByPointerEscape=*/true);
38153817
}
38163818

38173819
// Do not reason about locations passed inside inline assembly.
38183820
for (const Expr *I : A->inputs()) {
38193821
SVal X = state->getSVal(I, Pred->getLocationContext());
38203822

38213823
if (std::optional<Loc> LV = X.getAs<Loc>())
3822-
state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
3824+
state = state->invalidateRegions(*LV, A, currBldrCtx->blockCount(),
3825+
Pred->getLocationContext(),
3826+
/*CausedByPointerEscape=*/true);
38233827
}
38243828

38253829
Bldr.generateNode(A, Pred, state);

clang/test/Analysis/asm.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ void clang_analyzer_dump_ptr(void *);
77

88
int global;
99
void testRValueOutput() {
10-
int &ref = global;
11-
ref = 1;
10+
int origVal = global;
1211
__asm__("" : "=r"(((int)(global)))); // don't crash on rvalue output operand
13-
clang_analyzer_eval(global == 1); // expected-warning{{UNKNOWN}}
14-
clang_analyzer_eval(ref == 1); // expected-warning{{UNKNOWN}}
12+
int newVal = global; // Value "after" the invalidation.
13+
clang_analyzer_eval(origVal == newVal); // expected-warning{{TRUE}} expected-warning{{FALSE}}
1514
}
1615

1716
void *MyMemcpy(void *d, const void *s, const int n) {
@@ -40,7 +39,20 @@ void testInlineAsmMemcpyUninit(void)
4039
{
4140
int a[10], b[10] = {}, c;
4241
MyMemcpy(&a[1], &b[1], sizeof(b) - sizeof(b[1]));
43-
c = a[0]; // expected-warning{{Assigned value is garbage or undefined}}
42+
c = a[0]; // FIXME: should be warning about uninitialized value, but invalidateRegions() also
43+
// invalidates super region.
44+
}
45+
46+
void testInlineAsmMemcpyUninitLoop(const void *src, unsigned long len)
47+
{
48+
int a[10], c;
49+
unsigned long toCopy = sizeof(a) < len ? sizeof(a) : len;
50+
51+
MyMemcpy(a, src, toCopy);
52+
53+
// Use index 1, since before use of invalidateRegions in VisitGCCAsmStmt, engine bound unknown SVal only to
54+
// first element.
55+
c = a[1]; // no-warning
4456
}
4557

4658
void testAsmWithVoidPtrArgument()
@@ -49,6 +61,6 @@ void testAsmWithVoidPtrArgument()
4961
clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning-re {{reg_${{[0-9]+}}<int Element{SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>},0 S64b,int}>}}
5062
clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
5163
asm ("" : : "a"(globalVoidPtr)); // no crash
52-
clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning {{Unknown}}
64+
clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning {{derived_}}
5365
clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
5466
}

0 commit comments

Comments
 (0)