Skip to content

Commit

Permalink
[analyzer] use invalidateRegions() in VisitGCCAsmStmt (#109838)
Browse files Browse the repository at this point in the history
  • Loading branch information
pskrgag authored Oct 4, 2024
1 parent a3cc4b6 commit 8d661fd
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
8 changes: 6 additions & 2 deletions clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3811,15 +3811,19 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
assert(!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef.

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

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

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

Bldr.generateNode(A, Pred, state);
Expand Down
24 changes: 18 additions & 6 deletions clang/test/Analysis/asm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ void clang_analyzer_dump_ptr(void *);

int global;
void testRValueOutput() {
int &ref = global;
ref = 1;
int origVal = global;
__asm__("" : "=r"(((int)(global)))); // don't crash on rvalue output operand
clang_analyzer_eval(global == 1); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(ref == 1); // expected-warning{{UNKNOWN}}
int newVal = global; // Value "after" the invalidation.
clang_analyzer_eval(origVal == newVal); // expected-warning{{TRUE}} expected-warning{{FALSE}}
}

void *MyMemcpy(void *d, const void *s, const int n) {
Expand Down Expand Up @@ -40,7 +39,20 @@ void testInlineAsmMemcpyUninit(void)
{
int a[10], b[10] = {}, c;
MyMemcpy(&a[1], &b[1], sizeof(b) - sizeof(b[1]));
c = a[0]; // expected-warning{{Assigned value is garbage or undefined}}
c = a[0]; // FIXME: should be warning about uninitialized value, but invalidateRegions() also
// invalidates super region.
}

void testInlineAsmMemcpyUninitLoop(const void *src, unsigned long len)
{
int a[10], c;
unsigned long toCopy = sizeof(a) < len ? sizeof(a) : len;

MyMemcpy(a, src, toCopy);

// Use index 1, since before use of invalidateRegions in VisitGCCAsmStmt, engine bound unknown SVal only to
// first element.
c = a[1]; // no-warning
}

void testAsmWithVoidPtrArgument()
Expand All @@ -49,6 +61,6 @@ void testAsmWithVoidPtrArgument()
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(*(int *)globalVoidPtr); // expected-warning {{derived_}}
clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}}
}

0 comments on commit 8d661fd

Please sign in to comment.