@@ -1163,6 +1163,8 @@ class WarningGadget : public Gadget {
11631163 virtual void handleUnsafeOperation (UnsafeBufferUsageHandler &Handler,
11641164 bool IsRelatedToDecl,
11651165 ASTContext &Ctx) const = 0;
1166+
1167+ virtual SmallVector<const Expr *, 1 > getUnsafePtrs () const = 0;
11661168};
11671169
11681170// / Fixable gadgets correspond to code patterns that aren't always unsafe but
@@ -1245,6 +1247,10 @@ class IncrementGadget : public WarningGadget {
12451247
12461248 return std::move (Uses);
12471249 }
1250+
1251+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1252+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
1253+ }
12481254};
12491255
12501256// / A decrement of a pointer-type value is unsafe as it may run the pointer
@@ -1288,6 +1294,10 @@ class DecrementGadget : public WarningGadget {
12881294
12891295 return {};
12901296 }
1297+
1298+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1299+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
1300+ }
12911301};
12921302
12931303// / Array subscript expressions on raw pointers as if they're arrays. Unsafe as
@@ -1337,6 +1347,10 @@ class ArraySubscriptGadget : public WarningGadget {
13371347
13381348 return {};
13391349 }
1350+
1351+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1352+ return {ASE->getBase ()->IgnoreParenImpCasts ()};
1353+ }
13401354};
13411355
13421356// / A pointer arithmetic expression of one of the forms:
@@ -1400,6 +1414,11 @@ class PointerArithmeticGadget : public WarningGadget {
14001414
14011415 return {};
14021416 }
1417+
1418+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1419+ return {Ptr->IgnoreParenImpCasts ()};
1420+ }
1421+
14031422 // FIXME: pointer adding zero should be fine
14041423 // FIXME: this gadge will need a fix-it
14051424};
@@ -1457,6 +1476,8 @@ class SpanTwoParamConstructorGadget : public WarningGadget {
14571476 }
14581477 return {};
14591478 }
1479+
1480+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
14601481};
14611482
14621483// / A pointer initialization expression of the form:
@@ -1689,6 +1710,8 @@ class UnsafeBufferUsageAttrGadget : public WarningGadget {
16891710 SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
16901711
16911712 DeclUseList getClaimedVarUseSites () const override { return {}; }
1713+
1714+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
16921715};
16931716
16941717// / A call of a constructor that performs unchecked buffer operations
@@ -1727,6 +1750,8 @@ class UnsafeBufferUsageCtorAttrGadget : public WarningGadget {
17271750 SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
17281751
17291752 DeclUseList getClaimedVarUseSites () const override { return {}; }
1753+
1754+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
17301755};
17311756
17321757// Warning gadget for unsafe invocation of span::data method.
@@ -1793,6 +1818,8 @@ class DataInvocationGadget : public WarningGadget {
17931818 return true ;
17941819 return false ;
17951820 }
1821+
1822+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
17961823};
17971824
17981825class UnsafeLibcFunctionCallGadget : public WarningGadget {
@@ -1896,6 +1923,8 @@ class UnsafeLibcFunctionCallGadget : public WarningGadget {
18961923 }
18971924
18981925 DeclUseList getClaimedVarUseSites () const override { return {}; }
1926+
1927+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
18991928};
19001929
19011930// Represents expressions of the form `DRE[*]` in the Unspecified Lvalue
@@ -2467,6 +2496,52 @@ template <typename NodeTy> struct CompareNode {
24672496 }
24682497};
24692498
2499+ std::set<const Expr *> clang::findUnsafePointers (const FunctionDecl *FD) {
2500+ class MockReporter : public UnsafeBufferUsageHandler {
2501+ public:
2502+ MockReporter () {}
2503+ void handleUnsafeOperation (const Stmt *, bool , ASTContext &) override {}
2504+ void handleUnsafeLibcCall (const CallExpr *, unsigned , ASTContext &,
2505+ const Expr *UnsafeArg = nullptr ) override {}
2506+ void handleUnsafeOperationInContainer (const Stmt *, bool ,
2507+ ASTContext &) override {}
2508+ void handleUnsafeVariableGroup (const VarDecl *,
2509+ const VariableGroupsManager &, FixItList &&,
2510+ const Decl *,
2511+ const FixitStrategy &) override {}
2512+ bool isSafeBufferOptOut (const SourceLocation &) const override {
2513+ return false ;
2514+ }
2515+ bool ignoreUnsafeBufferInContainer (const SourceLocation &) const override {
2516+ return false ;
2517+ }
2518+ bool ignoreUnsafeBufferInLibcCall (const SourceLocation &) const override {
2519+ return false ;
2520+ }
2521+ std::string getUnsafeBufferUsageAttributeTextAt (
2522+ SourceLocation, StringRef WSSuffix = " " ) const override {
2523+ return " " ;
2524+ }
2525+ };
2526+
2527+ FixableGadgetList FixableGadgets;
2528+ WarningGadgetList WarningGadgets;
2529+ DeclUseTracker Tracker;
2530+ MockReporter IgnoreHandler;
2531+
2532+ findGadgets (FD->getBody (), FD->getASTContext (), IgnoreHandler, false ,
2533+ FixableGadgets, WarningGadgets, Tracker);
2534+
2535+ std::set<const Expr *> Result;
2536+ for (auto &G : WarningGadgets) {
2537+ for (const Expr *E : G->getUnsafePtrs ()) {
2538+ Result.insert (E);
2539+ }
2540+ }
2541+
2542+ return Result;
2543+ }
2544+
24702545struct WarningGadgetSets {
24712546 std::map<const VarDecl *, std::set<const WarningGadget *>,
24722547 // To keep keys sorted by their locations in the map so that the
0 commit comments