[clang] 2f49058 - [-Wunsafe-buffer-usage] Fix debug notes for unclaimed DREs (#80787)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 6 16:19:51 PST 2024


Author: jkorous-apple
Date: 2024-02-06T16:19:46-08:00
New Revision: 2f490583c368627f552c71e340c39f2b55c0526c

URL: https://github.com/llvm/llvm-project/commit/2f490583c368627f552c71e340c39f2b55c0526c
DIFF: https://github.com/llvm/llvm-project/commit/2f490583c368627f552c71e340c39f2b55c0526c.diff

LOG: [-Wunsafe-buffer-usage] Fix debug notes for unclaimed DREs (#80787)

Debug notes for unclaimed DeclRefExpr should report any DRE of an unsafe
variable that is not covered by a Fixable (i. e. fixit for the
particular AST pattern isn't implemented for whatever reason). Currently
not all unclaimed DeclRefExpr-s are reported which is a bug. The debug
notes report only those DREs where the referred VarDecl has at least one
other DeclRefExpr which is claimed (covered by a fixit). If there is an
unsafe VarDecl that has exactly one DRE and the DRE isn't claimed then
the debug note about missing fixit won't be emitted. That is because the
debug note is emitted from within a loop over set of successfully
matched FixableGadgets which by-definition is missing those DRE that are
not matched at all.

The new code simply iterates over all unsafe VarDecls and all of their
unclaimed DREs.

Added: 
    

Modified: 
    clang/lib/Analysis/UnsafeBufferUsage.cpp
    clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 823cd2a7b99691..a6dcf16b928e26 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -2870,19 +2870,6 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
 #endif
         it = FixablesForAllVars.byVar.erase(it);
       } else if (Tracker.hasUnclaimedUses(it->first)) {
-#ifndef NDEBUG
-        auto AllUnclaimed = Tracker.getUnclaimedUses(it->first);
-        for (auto UnclaimedDRE : AllUnclaimed) {
-        std::string UnclaimedUseTrace =
-            getDREAncestorString(UnclaimedDRE, D->getASTContext());
-
-        Handler.addDebugNoteForVar(
-            it->first, UnclaimedDRE->getBeginLoc(),
-            ("failed to produce fixit for '" + it->first->getNameAsString() +
-             "' : has an unclaimed use\nThe unclaimed DRE trace: " +
-             UnclaimedUseTrace));
-        }
-#endif
         it = FixablesForAllVars.byVar.erase(it);
       } else if (it->first->isInitCapture()) {
 #ifndef NDEBUG
@@ -2892,10 +2879,30 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
                                     "' : init capture"));
 #endif
         it = FixablesForAllVars.byVar.erase(it);
-      }else {
-      ++it;
+      } else {
+        ++it;
+      }
+  }
+
+#ifndef NDEBUG
+  for (const auto &it : UnsafeOps.byVar) {
+    const VarDecl *const UnsafeVD = it.first;
+    auto UnclaimedDREs = Tracker.getUnclaimedUses(UnsafeVD);
+    if (UnclaimedDREs.empty())
+      continue;
+    const auto UnfixedVDName = UnsafeVD->getNameAsString();
+    for (const clang::DeclRefExpr *UnclaimedDRE : UnclaimedDREs) {
+      std::string UnclaimedUseTrace =
+          getDREAncestorString(UnclaimedDRE, D->getASTContext());
+
+      Handler.addDebugNoteForVar(
+          UnsafeVD, UnclaimedDRE->getBeginLoc(),
+          ("failed to produce fixit for '" + UnfixedVDName +
+           "' : has an unclaimed use\nThe unclaimed DRE trace: " +
+           UnclaimedUseTrace));
     }
   }
+#endif
 
   // Fixpoint iteration for pointer assignments
   using DepMapTy = DenseMap<const VarDecl *, llvm::SetVector<const VarDecl *>>;

diff  --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp
index e08f70d97e3912..5fff0854d45467 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-debug.cpp
@@ -98,3 +98,10 @@ void test_struct_claim_use() {
   x[6] = 8;  // expected-warning{{unsafe buffer access}}
   x++;  // expected-warning{{unsafe pointer arithmetic}}
 }
+
+void use(int*);
+void array2d(int idx) {
+  int buffer[10][5]; // expected-warning{{'buffer' is an unsafe buffer that does not perform bounds checks}}
+  use(buffer[idx]);  // expected-note{{used in buffer access here}} \
+  // debug-note{{safe buffers debug: failed to produce fixit for 'buffer' : has an unclaimed use}}
+}


        


More information about the cfe-commits mailing list