@@ -1163,6 +1163,8 @@ class WarningGadget : public Gadget {
1163
1163
virtual void handleUnsafeOperation (UnsafeBufferUsageHandler &Handler,
1164
1164
bool IsRelatedToDecl,
1165
1165
ASTContext &Ctx) const = 0;
1166
+
1167
+ virtual SmallVector<const Expr *, 1 > getUnsafePtrs () const = 0;
1166
1168
};
1167
1169
1168
1170
// / Fixable gadgets correspond to code patterns that aren't always unsafe but
@@ -1245,6 +1247,10 @@ class IncrementGadget : public WarningGadget {
1245
1247
1246
1248
return std::move (Uses);
1247
1249
}
1250
+
1251
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1252
+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
1253
+ }
1248
1254
};
1249
1255
1250
1256
// / A decrement of a pointer-type value is unsafe as it may run the pointer
@@ -1288,6 +1294,10 @@ class DecrementGadget : public WarningGadget {
1288
1294
1289
1295
return {};
1290
1296
}
1297
+
1298
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1299
+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
1300
+ }
1291
1301
};
1292
1302
1293
1303
// / Array subscript expressions on raw pointers as if they're arrays. Unsafe as
@@ -1337,6 +1347,10 @@ class ArraySubscriptGadget : public WarningGadget {
1337
1347
1338
1348
return {};
1339
1349
}
1350
+
1351
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1352
+ return {ASE->getBase ()->IgnoreParenImpCasts ()};
1353
+ }
1340
1354
};
1341
1355
1342
1356
// / A pointer arithmetic expression of one of the forms:
@@ -1400,6 +1414,11 @@ class PointerArithmeticGadget : public WarningGadget {
1400
1414
1401
1415
return {};
1402
1416
}
1417
+
1418
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
1419
+ return {Ptr->IgnoreParenImpCasts ()};
1420
+ }
1421
+
1403
1422
// FIXME: pointer adding zero should be fine
1404
1423
// FIXME: this gadge will need a fix-it
1405
1424
};
@@ -1457,6 +1476,8 @@ class SpanTwoParamConstructorGadget : public WarningGadget {
1457
1476
}
1458
1477
return {};
1459
1478
}
1479
+
1480
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
1460
1481
};
1461
1482
1462
1483
// / A pointer initialization expression of the form:
@@ -1689,6 +1710,8 @@ class UnsafeBufferUsageAttrGadget : public WarningGadget {
1689
1710
SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
1690
1711
1691
1712
DeclUseList getClaimedVarUseSites () const override { return {}; }
1713
+
1714
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
1692
1715
};
1693
1716
1694
1717
// / A call of a constructor that performs unchecked buffer operations
@@ -1727,6 +1750,8 @@ class UnsafeBufferUsageCtorAttrGadget : public WarningGadget {
1727
1750
SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
1728
1751
1729
1752
DeclUseList getClaimedVarUseSites () const override { return {}; }
1753
+
1754
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
1730
1755
};
1731
1756
1732
1757
// Warning gadget for unsafe invocation of span::data method.
@@ -1793,6 +1818,8 @@ class DataInvocationGadget : public WarningGadget {
1793
1818
return true ;
1794
1819
return false ;
1795
1820
}
1821
+
1822
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
1796
1823
};
1797
1824
1798
1825
class UnsafeLibcFunctionCallGadget : public WarningGadget {
@@ -1896,6 +1923,8 @@ class UnsafeLibcFunctionCallGadget : public WarningGadget {
1896
1923
}
1897
1924
1898
1925
DeclUseList getClaimedVarUseSites () const override { return {}; }
1926
+
1927
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
1899
1928
};
1900
1929
1901
1930
// Represents expressions of the form `DRE[*]` in the Unspecified Lvalue
@@ -2467,6 +2496,52 @@ template <typename NodeTy> struct CompareNode {
2467
2496
}
2468
2497
};
2469
2498
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
+
2470
2545
struct WarningGadgetSets {
2471
2546
std::map<const VarDecl *, std::set<const WarningGadget *>,
2472
2547
// To keep keys sorted by their locations in the map so that the
0 commit comments