================
@@ -1986,112 +2360,119 @@ class DerefSimplePtrArithFixableGadget : public 
FixableGadget {
   }
 };
 
-/// Scan the function and return a list of gadgets found with provided kits.
-static void findGadgets(const Stmt *S, ASTContext &Ctx,
-                        const UnsafeBufferUsageHandler &Handler,
-                        bool EmitSuggestions, FixableGadgetList 
&FixableGadgets,
-                        WarningGadgetList &WarningGadgets,
-                        DeclUseTracker &Tracker) {
+class EvaluatedStmtMatcher : public FastMatcher {
 
-  struct GadgetFinderCallback : MatchFinder::MatchCallback {
-    GadgetFinderCallback(FixableGadgetList &FixableGadgets,
-                         WarningGadgetList &WarningGadgets,
-                         DeclUseTracker &Tracker)
-        : FixableGadgets(FixableGadgets), WarningGadgets(WarningGadgets),
-          Tracker(Tracker) {}
-
-    void run(const MatchFinder::MatchResult &Result) override {
-      // In debug mode, assert that we've found exactly one gadget.
-      // This helps us avoid conflicts in .bind() tags.
-#if NDEBUG
-#define NEXT return
-#else
-      [[maybe_unused]] int numFound = 0;
-#define NEXT ++numFound
-#endif
-
-      if (const auto *DRE = Result.Nodes.getNodeAs<DeclRefExpr>("any_dre")) {
-        Tracker.discoverUse(DRE);
-        NEXT;
-      }
+public:
+  EvaluatedStmtMatcher(WarningGadgetList &WarningGadgets)
+      : WarningGadgets(WarningGadgets) {}
 
-      if (const auto *DS = Result.Nodes.getNodeAs<DeclStmt>("any_ds")) {
-        Tracker.discoverDecl(DS);
-        NEXT;
-      }
+  bool matches(const DynTypedNode &DynNode, ASTContext &Ctx,
+               const UnsafeBufferUsageHandler &Handler) override {
+    const Stmt *S = DynNode.get<Stmt>();
+    if (!S)
+      return false;
 
-      // Figure out which matcher we've found, and call the appropriate
-      // subclass constructor.
-      // FIXME: Can we do this more logarithmically?
-#define FIXABLE_GADGET(name)                                                   
\
-  if (Result.Nodes.getNodeAs<Stmt>(#name)) {                                   
\
-    FixableGadgets.push_back(std::make_unique<name##Gadget>(Result));          
\
-    NEXT;                                                                      
\
-  }
-#include "clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def"
+    MatchResult Result;
 #define WARNING_GADGET(name)                                                   
\
-  if (Result.Nodes.getNodeAs<Stmt>(#name)) {                                   
\
+  if (name##Gadget::matches(S, Ctx, Result) &&                                 
\
+      notInSafeBufferOptOut(*S, &Handler)) {                                   
\
+    WarningGadgets.push_back(std::make_unique<name##Gadget>(Result));          
\
+    return true;                                                               
\
+  }
+#define WARNING_OPTIONAL_GADGET(name)                                          
\
+  if (name##Gadget::matches(S, Ctx, &Handler, Result) &&                       
\
+      notInSafeBufferOptOut(*S, &Handler)) {                                   
\
     WarningGadgets.push_back(std::make_unique<name##Gadget>(Result));          
\
-    NEXT;                                                                      
\
+    return true;                                                               
\
   }
 #include "clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def"
+    return false;
+  }
 
-      assert(numFound >= 1 && "Gadgets not found in match result!");
-      assert(numFound <= 1 && "Conflicting bind tags in gadgets!");
-    }
+private:
+  WarningGadgetList &WarningGadgets;
+};
 
-    FixableGadgetList &FixableGadgets;
-    WarningGadgetList &WarningGadgets;
-    DeclUseTracker &Tracker;
-  };
+class StmtMatcher : public FastMatcher {
 
-  MatchFinder M;
-  GadgetFinderCallback CB{FixableGadgets, WarningGadgets, Tracker};
-
-  // clang-format off
-  M.addMatcher(
-      stmt(
-        forEachDescendantEvaluatedStmt(stmt(anyOf(
-          // Add Gadget::matcher() for every gadget in the registry.
-#define WARNING_GADGET(x)                                                      
\
-          allOf(x ## Gadget::matcher().bind(#x),                               
\
-                notInSafeBufferOptOut(&Handler)),
-#define WARNING_OPTIONAL_GADGET(x)                                            \
-          allOf(x ## Gadget::matcher(&Handler).bind(#x),                      \
-                notInSafeBufferOptOut(&Handler)),
-#include "clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def"
-            // Avoid a hanging comma.
-            unless(stmt())
-        )))
-    ),
-    &CB
-  );
-  // clang-format on
+public:
+  StmtMatcher(FixableGadgetList &FixableGadgets, DeclUseTracker &Tracker)
+      : FixableGadgets(FixableGadgets), Tracker(Tracker) {}
+
+  // Match all DeclRefExprs so that to find out
+  // whether there are any uncovered by gadgets.
+  bool matchDeclRefExprs(const Stmt *S, MatchResult &Result) {
----------------
ilya-biryukov wrote:

NIT: make this private, move to the end of the class (it's an implementation 
detail after all, it's better to start with the "meat"

https://github.com/llvm/llvm-project/pull/125492
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to