[clang] [analyzer] use `invalidateRegions()` in `VisitGCCAsmStmt` (PR #109838)

Pavel Skripkin via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 24 12:15:53 PDT 2024


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 <paskripkin at gmail.com>
Date: Tue, 24 Sep 2024 20:18:30 +0300
Subject: [PATCH 1/2] 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 at -1{{TRUE}}
+  clang_analyzer_eval(ref == 1);    // expected-warning{{FALSE}}
+                                    // expected-warning at -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 <paskripkin at gmail.com>
Date: Tue, 24 Sep 2024 21:53:11 +0300
Subject: [PATCH 2/2] 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>}}}
 }



More information about the cfe-commits mailing list