https://github.com/jkorous-apple created 
https://github.com/llvm/llvm-project/pull/135421

None

>From 9354e44180338d53bfe811fb9f566f3c959c9d7b Mon Sep 17 00:00:00 2001
From: Jan Korous <jkor...@apple.com>
Date: Fri, 11 Apr 2025 11:09:33 -0700
Subject: [PATCH] [-Wunsafe-buffer-usage] Add findUnsafePointers

---
 .../Analysis/Analyses/UnsafeBufferUsage.h     |  3 +
 clang/lib/Analysis/UnsafeBufferUsage.cpp      | 75 +++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h 
b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
index 267cde64f8f23..9b53f1dc1d759 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
@@ -19,6 +19,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/Support/Debug.h"
+#include <set>
 
 namespace clang {
 
@@ -186,6 +187,8 @@ namespace internal {
 bool anyConflict(const llvm::SmallVectorImpl<FixItHint> &FixIts,
                  const SourceManager &SM);
 } // namespace internal
+
+std::set<const Expr *> findUnsafePointers(const FunctionDecl *FD);
 } // end namespace clang
 
 #endif /* LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H */
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp 
b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 0dbb683729427..4eaf8ba61eaec 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -1163,6 +1163,8 @@ class WarningGadget : public Gadget {
   virtual void handleUnsafeOperation(UnsafeBufferUsageHandler &Handler,
                                      bool IsRelatedToDecl,
                                      ASTContext &Ctx) const = 0;
+
+  virtual SmallVector<const Expr *, 1> getUnsafePtrs() const = 0;
 };
 
 /// Fixable gadgets correspond to code patterns that aren't always unsafe but
@@ -1245,6 +1247,10 @@ class IncrementGadget : public WarningGadget {
 
     return std::move(Uses);
   }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override {
+    return {Op->getSubExpr()->IgnoreParenImpCasts()};
+  }
 };
 
 /// A decrement of a pointer-type value is unsafe as it may run the pointer
@@ -1288,6 +1294,10 @@ class DecrementGadget : public WarningGadget {
 
     return {};
   }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override {
+    return {Op->getSubExpr()->IgnoreParenImpCasts()};
+  }
 };
 
 /// Array subscript expressions on raw pointers as if they're arrays. Unsafe as
@@ -1337,6 +1347,10 @@ class ArraySubscriptGadget : public WarningGadget {
 
     return {};
   }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override {
+    return {ASE->getBase()->IgnoreParenImpCasts()};
+  }
 };
 
 /// A pointer arithmetic expression of one of the forms:
@@ -1400,6 +1414,11 @@ class PointerArithmeticGadget : public WarningGadget {
 
     return {};
   }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override {
+    return {Ptr->IgnoreParenImpCasts()};
+  }
+
   // FIXME: pointer adding zero should be fine
   // FIXME: this gadge will need a fix-it
 };
@@ -1457,6 +1476,8 @@ class SpanTwoParamConstructorGadget : public 
WarningGadget {
     }
     return {};
   }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
 };
 
 /// A pointer initialization expression of the form:
@@ -1689,6 +1710,8 @@ class UnsafeBufferUsageAttrGadget : public WarningGadget {
   SourceLocation getSourceLoc() const override { return Op->getBeginLoc(); }
 
   DeclUseList getClaimedVarUseSites() const override { return {}; }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
 };
 
 /// A call of a constructor that performs unchecked buffer operations
@@ -1727,6 +1750,8 @@ class UnsafeBufferUsageCtorAttrGadget : public 
WarningGadget {
   SourceLocation getSourceLoc() const override { return Op->getBeginLoc(); }
 
   DeclUseList getClaimedVarUseSites() const override { return {}; }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
 };
 
 // Warning gadget for unsafe invocation of span::data method.
@@ -1793,6 +1818,8 @@ class DataInvocationGadget : public WarningGadget {
       return true;
     return false;
   }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
 };
 
 class UnsafeLibcFunctionCallGadget : public WarningGadget {
@@ -1896,6 +1923,8 @@ class UnsafeLibcFunctionCallGadget : public WarningGadget 
{
   }
 
   DeclUseList getClaimedVarUseSites() const override { return {}; }
+
+  SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
 };
 
 // Represents expressions of the form `DRE[*]` in the Unspecified Lvalue
@@ -2467,6 +2496,52 @@ template <typename NodeTy> struct CompareNode {
   }
 };
 
+std::set<const Expr *> clang::findUnsafePointers(const FunctionDecl *FD) {
+  class MockReporter : public UnsafeBufferUsageHandler {
+  public:
+    MockReporter() {}
+    void handleUnsafeOperation(const Stmt *, bool, ASTContext &) override {}
+    void handleUnsafeLibcCall(const CallExpr *, unsigned, ASTContext &,
+                              const Expr *UnsafeArg = nullptr) override {}
+    void handleUnsafeOperationInContainer(const Stmt *, bool,
+                                          ASTContext &) override {}
+    void handleUnsafeVariableGroup(const VarDecl *,
+                                   const VariableGroupsManager &, FixItList &&,
+                                   const Decl *,
+                                   const FixitStrategy &) override {}
+    bool isSafeBufferOptOut(const SourceLocation &) const override {
+      return false;
+    }
+    bool ignoreUnsafeBufferInContainer(const SourceLocation &) const override {
+      return false;
+    }
+    bool ignoreUnsafeBufferInLibcCall(const SourceLocation &) const override {
+      return false;
+    }
+    std::string getUnsafeBufferUsageAttributeTextAt(
+        SourceLocation, StringRef WSSuffix = "") const override {
+      return "";
+    }
+  };
+
+  FixableGadgetList FixableGadgets;
+  WarningGadgetList WarningGadgets;
+  DeclUseTracker Tracker;
+  MockReporter IgnoreHandler;
+
+  findGadgets(FD->getBody(), FD->getASTContext(), IgnoreHandler, false,
+              FixableGadgets, WarningGadgets, Tracker);
+
+  std::set<const Expr *> Result;
+  for (auto &G : WarningGadgets) {
+    for (const Expr *E : G->getUnsafePtrs()) {
+      Result.insert(E);
+    }
+  }
+
+  return Result;
+}
+
 struct WarningGadgetSets {
   std::map<const VarDecl *, std::set<const WarningGadget *>,
            // To keep keys sorted by their locations in the map so that the

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to