@@ -1386,14 +1386,18 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
13861386};
13871387
13881388// / Scan the function and return a list of gadgets found with provided kits.
1389- static std::tuple<FixableGadgetList, WarningGadgetList, DeclUseTracker>
1390- findGadgets (const Stmt *S, ASTContext &Ctx,
1391- const UnsafeBufferUsageHandler &Handler, bool EmitSuggestions) {
1389+ static void findGadgets (const Stmt *S, ASTContext &Ctx,
1390+ const UnsafeBufferUsageHandler &Handler,
1391+ bool EmitSuggestions, FixableGadgetList &FixableGadgets,
1392+ WarningGadgetList &WarningGadgets,
1393+ DeclUseTracker &Tracker) {
13921394
13931395 struct GadgetFinderCallback : MatchFinder::MatchCallback {
1394- FixableGadgetList FixableGadgets;
1395- WarningGadgetList WarningGadgets;
1396- DeclUseTracker Tracker;
1396+ GadgetFinderCallback (FixableGadgetList &FixableGadgets,
1397+ WarningGadgetList &WarningGadgets,
1398+ DeclUseTracker &Tracker)
1399+ : FixableGadgets(FixableGadgets), WarningGadgets(WarningGadgets),
1400+ Tracker (Tracker) {}
13971401
13981402 void run (const MatchFinder::MatchResult &Result) override {
13991403 // In debug mode, assert that we've found exactly one gadget.
@@ -1434,10 +1438,14 @@ findGadgets(const Stmt *S, ASTContext &Ctx,
14341438 assert (numFound >= 1 && " Gadgets not found in match result!" );
14351439 assert (numFound <= 1 && " Conflicting bind tags in gadgets!" );
14361440 }
1441+
1442+ FixableGadgetList &FixableGadgets;
1443+ WarningGadgetList &WarningGadgets;
1444+ DeclUseTracker &Tracker;
14371445 };
14381446
14391447 MatchFinder M;
1440- GadgetFinderCallback CB;
1448+ GadgetFinderCallback CB{FixableGadgets, WarningGadgets, Tracker} ;
14411449
14421450 // clang-format off
14431451 M.addMatcher(
@@ -1484,8 +1492,6 @@ findGadgets(const Stmt *S, ASTContext &Ctx,
14841492 }
14851493
14861494 M.match(*S, Ctx);
1487- return {std::move (CB.FixableGadgets ), std::move (CB.WarningGadgets ),
1488- std::move (CB.Tracker )};
14891495}
14901496
14911497// Compares AST nodes by source locations.
@@ -3312,19 +3318,19 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
33123318
33133319 SmallVector<Stmt *> Stmts;
33143320
3315- // We do not want to visit a Lambda expression defined inside a method
3316- // independently. Instead, it should be visited along with the outer method.
3317- // FIXME: do we want to do the same thing for `BlockDecl`s?
3318- if (const auto *fd = dyn_cast<CXXMethodDecl>(D)) {
3319- if (fd->getParent ()->isLambda () && fd->getParent ()->isLocalClass ())
3320- return ;
3321- }
3322-
3323- // Do not emit fixit suggestions for functions declared in an
3324- // extern "C" block.
33253321 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3322+ // We do not want to visit a Lambda expression defined inside a method
3323+ // independently. Instead, it should be visited along with the outer method.
3324+ // FIXME: do we want to do the same thing for `BlockDecl`s?
3325+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3326+ if (MD->getParent ()->isLambda () && MD->getParent ()->isLocalClass ())
3327+ return ;
3328+ }
3329+
33263330 for (FunctionDecl *FReDecl : FD->redecls ()) {
33273331 if (FReDecl->isExternC ()) {
3332+ // Do not emit fixit suggestions for functions declared in an
3333+ // extern "C" block.
33283334 EmitSuggestions = false ;
33293335 break ;
33303336 }
@@ -3337,26 +3343,29 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
33373343 Stmts.push_back (CI->getInit ());
33383344 }
33393345 }
3340- }
3341-
3342- if (const auto *FD = dyn_cast<FieldDecl>(D)) {
3346+ } else if (const auto *FlD = dyn_cast<FieldDecl>(D)) {
33433347 // Visit in-class initializers for fields.
3344- if (!FD ->hasInClassInitializer ())
3348+ if (!FlD ->hasInClassInitializer ())
33453349 return ;
3346-
3347- Stmts.push_back (FD->getInClassInitializer ());
3348- }
3349-
3350- if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) {
3350+ Stmts.push_back (FlD->getInClassInitializer ());
3351+ // In a FieldDecl there is no function body, there is only a single
3352+ // statement, and the suggestions machinery is not set up to handle that
3353+ // kind of structure yet and would give poor suggestions or likely even hit
3354+ // asserts.
3355+ EmitSuggestions = false ;
3356+ } else if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) {
33513357 Stmts.push_back (D->getBody ());
33523358 }
33533359
33543360 assert (!Stmts.empty ());
33553361
3362+ FixableGadgetList FixableGadgets;
3363+ WarningGadgetList WarningGadgets;
3364+ DeclUseTracker Tracker;
33563365 for (Stmt *S : Stmts) {
3357- auto [FixableGadgets, WarningGadgets, Tracker] =
3358- findGadgets (S, D->getASTContext (), Handler, EmitSuggestions);
3359- applyGadgets (D, std::move (FixableGadgets), std::move (WarningGadgets),
3360- std::move (Tracker), Handler, EmitSuggestions);
3366+ findGadgets (S, D->getASTContext (), Handler, EmitSuggestions, FixableGadgets,
3367+ WarningGadgets, Tracker);
33613368 }
3369+ applyGadgets (D, std::move (FixableGadgets), std::move (WarningGadgets),
3370+ std::move (Tracker), Handler, EmitSuggestions);
33623371}
0 commit comments