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