@@ -1957,6 +1957,8 @@ class WarningGadget : public Gadget {
19571957 virtual void handleUnsafeOperation (UnsafeBufferUsageHandler &Handler,
19581958 bool IsRelatedToDecl,
19591959 ASTContext &Ctx) const = 0;
1960+
1961+ virtual SmallVector<const Expr *, 1 > getUnsafePtrs () const = 0;
19601962};
19611963
19621964// / Fixable gadgets correspond to code patterns that aren't always unsafe but
@@ -2039,6 +2041,10 @@ class IncrementGadget : public WarningGadget {
20392041
20402042 return std::move (Uses);
20412043 }
2044+
2045+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2046+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
2047+ }
20422048};
20432049
20442050// / A decrement of a pointer-type value is unsafe as it may run the pointer
@@ -2082,6 +2088,10 @@ class DecrementGadget : public WarningGadget {
20822088
20832089 return {};
20842090 }
2091+
2092+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2093+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
2094+ }
20852095};
20862096
20872097// / Array subscript expressions on raw pointers as if they're arrays. Unsafe as
@@ -2131,6 +2141,10 @@ class ArraySubscriptGadget : public WarningGadget {
21312141
21322142 return {};
21332143 }
2144+
2145+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2146+ return {ASE->getBase ()->IgnoreParenImpCasts ()};
2147+ }
21342148};
21352149
21362150// / A pointer arithmetic expression of one of the forms:
@@ -2194,6 +2208,11 @@ class PointerArithmeticGadget : public WarningGadget {
21942208
21952209 return {};
21962210 }
2211+
2212+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2213+ return {Ptr->IgnoreParenImpCasts ()};
2214+ }
2215+
21972216 // FIXME: pointer adding zero should be fine
21982217 // FIXME: this gadge will need a fix-it
21992218};
@@ -2251,6 +2270,8 @@ class SpanTwoParamConstructorGadget : public WarningGadget {
22512270 }
22522271 return {};
22532272 }
2273+
2274+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
22542275};
22552276
22562277// / A pointer initialization expression of the form:
@@ -2483,6 +2504,8 @@ class UnsafeBufferUsageAttrGadget : public WarningGadget {
24832504 SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
24842505
24852506 DeclUseList getClaimedVarUseSites () const override { return {}; }
2507+
2508+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
24862509};
24872510
24882511// / A call of a constructor that performs unchecked buffer operations
@@ -2521,6 +2544,8 @@ class UnsafeBufferUsageCtorAttrGadget : public WarningGadget {
25212544 SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
25222545
25232546 DeclUseList getClaimedVarUseSites () const override { return {}; }
2547+
2548+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
25242549};
25252550
25262551// Warning gadget for unsafe invocation of span::data method.
@@ -2587,6 +2612,8 @@ class DataInvocationGadget : public WarningGadget {
25872612 return true ;
25882613 return false ;
25892614 }
2615+
2616+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
25902617};
25912618
25922619class UnsafeLibcFunctionCallGadget : public WarningGadget {
@@ -2714,6 +2741,8 @@ class UnsafeLibcFunctionCallGadget : public WarningGadget {
27142741 }
27152742
27162743 DeclUseList getClaimedVarUseSites () const override { return {}; }
2744+
2745+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
27172746};
27182747
27192748// Represents expressions of the form `DRE[*]` in the Unspecified Lvalue
@@ -3216,6 +3245,10 @@ class CountAttributedPointerArgumentGadget : public WarningGadget {
32163245 }
32173246 return {};
32183247 }
3248+
3249+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
3250+ return {};
3251+ }
32193252};
32203253
32213254// Represents an argument that is being passed to a __single pointer.
@@ -3266,6 +3299,10 @@ class SinglePointerArgumentGadget : public WarningGadget {
32663299 }
32673300 return {};
32683301 }
3302+
3303+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
3304+ return {};
3305+ }
32693306};
32703307
32713308// / Scan the function and return a list of gadgets found with provided kits.
@@ -3395,6 +3432,52 @@ template <typename NodeTy> struct CompareNode {
33953432 }
33963433};
33973434
3435+ std::set<const Expr *> clang::findUnsafePointers (const FunctionDecl *FD) {
3436+ class MockReporter : public UnsafeBufferUsageHandler {
3437+ public:
3438+ MockReporter () {}
3439+ void handleUnsafeOperation (const Stmt *, bool , ASTContext &) override {}
3440+ void handleUnsafeLibcCall (const CallExpr *, unsigned , ASTContext &,
3441+ const Expr *UnsafeArg = nullptr ) override {}
3442+ void handleUnsafeOperationInContainer (const Stmt *, bool ,
3443+ ASTContext &) override {}
3444+ void handleUnsafeVariableGroup (const VarDecl *,
3445+ const VariableGroupsManager &, FixItList &&,
3446+ const Decl *,
3447+ const FixitStrategy &) override {}
3448+ bool isSafeBufferOptOut (const SourceLocation &) const override {
3449+ return false ;
3450+ }
3451+ bool ignoreUnsafeBufferInContainer (const SourceLocation &) const override {
3452+ return false ;
3453+ }
3454+ bool ignoreUnsafeBufferInLibcCall (const SourceLocation &) const override {
3455+ return false ;
3456+ }
3457+ std::string getUnsafeBufferUsageAttributeTextAt (
3458+ SourceLocation, StringRef WSSuffix = " " ) const override {
3459+ return " " ;
3460+ }
3461+ };
3462+
3463+ FixableGadgetList FixableGadgets;
3464+ WarningGadgetList WarningGadgets;
3465+ DeclUseTracker Tracker;
3466+ MockReporter IgnoreHandler;
3467+
3468+ findGadgets (FD->getBody (), FD->getASTContext (), IgnoreHandler, false ,
3469+ FixableGadgets, WarningGadgets, Tracker);
3470+
3471+ std::set<const Expr *> Result;
3472+ for (auto &G : WarningGadgets) {
3473+ for (const Expr *E : G->getUnsafePtrs ()) {
3474+ Result.insert (E);
3475+ }
3476+ }
3477+
3478+ return Result;
3479+ }
3480+
33983481struct WarningGadgetSets {
33993482 std::map<const VarDecl *, std::set<const WarningGadget *>,
34003483 // To keep keys sorted by their locations in the map so that the
0 commit comments