https://github.com/pskrgag updated https://github.com/llvm/llvm-project/pull/109838
>From dbec0e8368157684f9efc63a556037ba31d5f2ea Mon Sep 17 00:00:00 2001 From: Pavel Skripkin <paskrip...@gmail.com> Date: Tue, 24 Sep 2024 20:18:30 +0300 Subject: [PATCH 1/3] clang/csa: use invalidateRegions() in VisitGCCAsmStmt --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 8 +++++-- clang/test/Analysis/asm.cpp | 22 ++++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index fdabba46992b08..a1a015715b4c8b 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3810,7 +3810,9 @@ 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. @@ -3818,7 +3820,9 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 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); diff --git a/clang/test/Analysis/asm.cpp b/clang/test/Analysis/asm.cpp index e0691dc4d794f5..b77038b2e83db7 100644 --- a/clang/test/Analysis/asm.cpp +++ b/clang/test/Analysis/asm.cpp @@ -10,8 +10,10 @@ void testRValueOutput() { int &ref = global; ref = 1; __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}} + clang_analyzer_eval(global == 1); // expected-warning{{FALSE}} + // expected-warning@-1{{TRUE}} + clang_analyzer_eval(ref == 1); // expected-warning{{FALSE}} + // expected-warning@-1{{TRUE}} } void *MyMemcpy(void *d, const void *s, const int n) { @@ -40,7 +42,19 @@ 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); + + for (unsigned long i = 0; i < toCopy; ++i) + c = a[i]; // no-warning } void testAsmWithVoidPtrArgument() @@ -49,6 +63,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_$3{conj_$2{int, LC1, S2385, #1},Element{SymRegion{reg_$0<void * globalVoidPtr>},0 S64b,int}}}} clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}} } >From cd6167144452e9af7b3a218d51d98504919d9856 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin <paskrip...@gmail.com> Date: Tue, 24 Sep 2024 21:53:11 +0300 Subject: [PATCH 2/3] use regex in test string --- clang/test/Analysis/asm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Analysis/asm.cpp b/clang/test/Analysis/asm.cpp index b77038b2e83db7..1dae83890e6251 100644 --- a/clang/test/Analysis/asm.cpp +++ b/clang/test/Analysis/asm.cpp @@ -51,7 +51,7 @@ 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); + MyMemcpy(a, src, toCopy); for (unsigned long i = 0; i < toCopy; ++i) c = a[i]; // no-warning @@ -63,6 +63,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 {{derived_$3{conj_$2{int, LC1, S2385, #1},Element{SymRegion{reg_$0<void * globalVoidPtr>},0 S64b,int}}}} + clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning-re {{derived_$3{conj_$2{int, LC1, S{{[0-9]+}}, #1},Element{SymRegion{reg_$0<void * globalVoidPtr>},0 S64b,int}}}} clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}} } >From d5a5c47ed5449de9996ccfcbd28e58a9ee50f99d Mon Sep 17 00:00:00 2001 From: Pavel Skripkin <paskrip...@gmail.com> Date: Fri, 4 Oct 2024 10:01:16 +0300 Subject: [PATCH 3/3] address review comments --- clang/test/Analysis/asm.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/clang/test/Analysis/asm.cpp b/clang/test/Analysis/asm.cpp index 1dae83890e6251..a795400ebbcaf7 100644 --- a/clang/test/Analysis/asm.cpp +++ b/clang/test/Analysis/asm.cpp @@ -7,13 +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{{FALSE}} - // expected-warning@-1{{TRUE}} - clang_analyzer_eval(ref == 1); // expected-warning{{FALSE}} - // expected-warning@-1{{TRUE}} + 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) { @@ -53,8 +50,9 @@ void testInlineAsmMemcpyUninitLoop(const void *src, unsigned long len) MyMemcpy(a, src, toCopy); - for (unsigned long i = 0; i < toCopy; ++i) - c = a[i]; // no-warning + // 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() @@ -63,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-re {{derived_$3{conj_$2{int, LC1, S{{[0-9]+}}, #1},Element{SymRegion{reg_$0<void * globalVoidPtr>},0 S64b,int}}}} + clang_analyzer_dump(*(int *)globalVoidPtr); // expected-warning {{derived_}} clang_analyzer_dump_ptr(globalVoidPtr); // expected-warning-re {{&SymRegion{reg_${{[0-9]+}}<void * globalVoidPtr>}}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits