@@ -1972,14 +1972,18 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
19721972};
19731973
19741974// / Scan the function and return a list of gadgets found with provided kits.
1975- static std::tuple<FixableGadgetList, WarningGadgetList, DeclUseTracker>
1976- findGadgets (const Stmt *S, ASTContext &Ctx,
1977- const UnsafeBufferUsageHandler &Handler, bool EmitSuggestions) {
1975+ static void findGadgets (const Stmt *S, ASTContext &Ctx,
1976+ const UnsafeBufferUsageHandler &Handler,
1977+ bool EmitSuggestions, FixableGadgetList &FixableGadgets,
1978+ WarningGadgetList &WarningGadgets,
1979+ DeclUseTracker &Tracker) {
19781980
19791981 struct GadgetFinderCallback : MatchFinder::MatchCallback {
1980- FixableGadgetList FixableGadgets;
1981- WarningGadgetList WarningGadgets;
1982- DeclUseTracker Tracker;
1982+ GadgetFinderCallback (FixableGadgetList &FixableGadgets,
1983+ WarningGadgetList &WarningGadgets,
1984+ DeclUseTracker &Tracker)
1985+ : FixableGadgets(FixableGadgets), WarningGadgets(WarningGadgets),
1986+ Tracker (Tracker) {}
19831987
19841988 void run (const MatchFinder::MatchResult &Result) override {
19851989 // In debug mode, assert that we've found exactly one gadget.
@@ -2020,10 +2024,14 @@ findGadgets(const Stmt *S, ASTContext &Ctx,
20202024 assert (numFound >= 1 && " Gadgets not found in match result!" );
20212025 assert (numFound <= 1 && " Conflicting bind tags in gadgets!" );
20222026 }
2027+
2028+ FixableGadgetList &FixableGadgets;
2029+ WarningGadgetList &WarningGadgets;
2030+ DeclUseTracker &Tracker;
20232031 };
20242032
20252033 MatchFinder M;
2026- GadgetFinderCallback CB;
2034+ GadgetFinderCallback CB{FixableGadgets, WarningGadgets, Tracker} ;
20272035
20282036 // clang-format off
20292037 M.addMatcher(
@@ -2069,8 +2077,6 @@ findGadgets(const Stmt *S, ASTContext &Ctx,
20692077 }
20702078
20712079 M.match(*S, Ctx);
2072- return {std::move (CB.FixableGadgets ), std::move (CB.WarningGadgets ),
2073- std::move (CB.Tracker )};
20742080}
20752081
20762082// Compares AST nodes by source locations.
@@ -3896,19 +3902,19 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
38963902
38973903 SmallVector<Stmt *> Stmts;
38983904
3899- // We do not want to visit a Lambda expression defined inside a method
3900- // independently. Instead, it should be visited along with the outer method.
3901- // FIXME: do we want to do the same thing for `BlockDecl`s?
3902- if (const auto *fd = dyn_cast<CXXMethodDecl>(D)) {
3903- if (fd->getParent ()->isLambda () && fd->getParent ()->isLocalClass ())
3904- return ;
3905- }
3906-
3907- // Do not emit fixit suggestions for functions declared in an
3908- // extern "C" block.
39093905 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3906+ // We do not want to visit a Lambda expression defined inside a method
3907+ // independently. Instead, it should be visited along with the outer method.
3908+ // FIXME: do we want to do the same thing for `BlockDecl`s?
3909+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3910+ if (MD->getParent ()->isLambda () && MD->getParent ()->isLocalClass ())
3911+ return ;
3912+ }
3913+
39103914 for (FunctionDecl *FReDecl : FD->redecls ()) {
39113915 if (FReDecl->isExternC ()) {
3916+ // Do not emit fixit suggestions for functions declared in an
3917+ // extern "C" block.
39123918 EmitSuggestions = false ;
39133919 break ;
39143920 }
@@ -3921,26 +3927,29 @@ void clang::checkUnsafeBufferUsage(const Decl *D,
39213927 Stmts.push_back (CI->getInit ());
39223928 }
39233929 }
3924- }
3925-
3926- if (const auto *FD = dyn_cast<FieldDecl>(D)) {
3930+ } else if (const auto *FlD = dyn_cast<FieldDecl>(D)) {
39273931 // Visit in-class initializers for fields.
3928- if (!FD ->hasInClassInitializer ())
3932+ if (!FlD ->hasInClassInitializer ())
39293933 return ;
3930-
3931- Stmts.push_back (FD->getInClassInitializer ());
3932- }
3933-
3934- if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) {
3934+ Stmts.push_back (FlD->getInClassInitializer ());
3935+ // In a FieldDecl there is no function body, there is only a single
3936+ // statement, and the suggestions machinery is not set up to handle that
3937+ // kind of structure yet and would give poor suggestions or likely even hit
3938+ // asserts.
3939+ EmitSuggestions = false ;
3940+ } else if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) {
39353941 Stmts.push_back (D->getBody ());
39363942 }
39373943
39383944 assert (!Stmts.empty ());
39393945
3946+ FixableGadgetList FixableGadgets;
3947+ WarningGadgetList WarningGadgets;
3948+ DeclUseTracker Tracker;
39403949 for (Stmt *S : Stmts) {
3941- auto [FixableGadgets, WarningGadgets, Tracker] =
3942- findGadgets (S, D->getASTContext (), Handler, EmitSuggestions);
3943- applyGadgets (D, std::move (FixableGadgets), std::move (WarningGadgets),
3944- std::move (Tracker), Handler, EmitSuggestions);
3950+ findGadgets (S, D->getASTContext (), Handler, EmitSuggestions, FixableGadgets,
3951+ WarningGadgets, Tracker);
39453952 }
3953+ applyGadgets (D, std::move (FixableGadgets), std::move (WarningGadgets),
3954+ std::move (Tracker), Handler, EmitSuggestions);
39463955}
0 commit comments