@@ -1957,6 +1957,8 @@ class WarningGadget : public Gadget {
1957
1957
virtual void handleUnsafeOperation (UnsafeBufferUsageHandler &Handler,
1958
1958
bool IsRelatedToDecl,
1959
1959
ASTContext &Ctx) const = 0;
1960
+
1961
+ virtual SmallVector<const Expr *, 1 > getUnsafePtrs () const = 0;
1960
1962
};
1961
1963
1962
1964
// / Fixable gadgets correspond to code patterns that aren't always unsafe but
@@ -2039,6 +2041,10 @@ class IncrementGadget : public WarningGadget {
2039
2041
2040
2042
return std::move (Uses);
2041
2043
}
2044
+
2045
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2046
+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
2047
+ }
2042
2048
};
2043
2049
2044
2050
// / A decrement of a pointer-type value is unsafe as it may run the pointer
@@ -2082,6 +2088,10 @@ class DecrementGadget : public WarningGadget {
2082
2088
2083
2089
return {};
2084
2090
}
2091
+
2092
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2093
+ return {Op->getSubExpr ()->IgnoreParenImpCasts ()};
2094
+ }
2085
2095
};
2086
2096
2087
2097
// / Array subscript expressions on raw pointers as if they're arrays. Unsafe as
@@ -2131,6 +2141,10 @@ class ArraySubscriptGadget : public WarningGadget {
2131
2141
2132
2142
return {};
2133
2143
}
2144
+
2145
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2146
+ return {ASE->getBase ()->IgnoreParenImpCasts ()};
2147
+ }
2134
2148
};
2135
2149
2136
2150
// / A pointer arithmetic expression of one of the forms:
@@ -2194,6 +2208,11 @@ class PointerArithmeticGadget : public WarningGadget {
2194
2208
2195
2209
return {};
2196
2210
}
2211
+
2212
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
2213
+ return {Ptr->IgnoreParenImpCasts ()};
2214
+ }
2215
+
2197
2216
// FIXME: pointer adding zero should be fine
2198
2217
// FIXME: this gadge will need a fix-it
2199
2218
};
@@ -2251,6 +2270,8 @@ class SpanTwoParamConstructorGadget : public WarningGadget {
2251
2270
}
2252
2271
return {};
2253
2272
}
2273
+
2274
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
2254
2275
};
2255
2276
2256
2277
// / A pointer initialization expression of the form:
@@ -2483,6 +2504,8 @@ class UnsafeBufferUsageAttrGadget : public WarningGadget {
2483
2504
SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
2484
2505
2485
2506
DeclUseList getClaimedVarUseSites () const override { return {}; }
2507
+
2508
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
2486
2509
};
2487
2510
2488
2511
// / A call of a constructor that performs unchecked buffer operations
@@ -2521,6 +2544,8 @@ class UnsafeBufferUsageCtorAttrGadget : public WarningGadget {
2521
2544
SourceLocation getSourceLoc () const override { return Op->getBeginLoc (); }
2522
2545
2523
2546
DeclUseList getClaimedVarUseSites () const override { return {}; }
2547
+
2548
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
2524
2549
};
2525
2550
2526
2551
// Warning gadget for unsafe invocation of span::data method.
@@ -2587,6 +2612,8 @@ class DataInvocationGadget : public WarningGadget {
2587
2612
return true ;
2588
2613
return false ;
2589
2614
}
2615
+
2616
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
2590
2617
};
2591
2618
2592
2619
class UnsafeLibcFunctionCallGadget : public WarningGadget {
@@ -2714,6 +2741,8 @@ class UnsafeLibcFunctionCallGadget : public WarningGadget {
2714
2741
}
2715
2742
2716
2743
DeclUseList getClaimedVarUseSites () const override { return {}; }
2744
+
2745
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override { return {}; }
2717
2746
};
2718
2747
2719
2748
// Represents expressions of the form `DRE[*]` in the Unspecified Lvalue
@@ -3216,6 +3245,10 @@ class CountAttributedPointerArgumentGadget : public WarningGadget {
3216
3245
}
3217
3246
return {};
3218
3247
}
3248
+
3249
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
3250
+ return {};
3251
+ }
3219
3252
};
3220
3253
3221
3254
// Represents an argument that is being passed to a __single pointer.
@@ -3266,6 +3299,10 @@ class SinglePointerArgumentGadget : public WarningGadget {
3266
3299
}
3267
3300
return {};
3268
3301
}
3302
+
3303
+ SmallVector<const Expr *, 1 > getUnsafePtrs () const override {
3304
+ return {};
3305
+ }
3269
3306
};
3270
3307
3271
3308
// / Scan the function and return a list of gadgets found with provided kits.
@@ -3395,6 +3432,52 @@ template <typename NodeTy> struct CompareNode {
3395
3432
}
3396
3433
};
3397
3434
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
+
3398
3481
struct WarningGadgetSets {
3399
3482
std::map<const VarDecl *, std::set<const WarningGadget *>,
3400
3483
// To keep keys sorted by their locations in the map so that the
0 commit comments