@@ -171,12 +171,6 @@ class MatchDescendantVisitor
171171 return VisitorBase::TraverseCXXTypeidExpr (Node);
172172 }
173173
174- bool TraverseCXXDefaultInitExpr (CXXDefaultInitExpr *Node) {
175- if (!TraverseStmt (Node->getExpr ()))
176- return false ;
177- return VisitorBase::TraverseCXXDefaultInitExpr (Node);
178- }
179-
180174 bool TraverseStmt (Stmt *Node, DataRecursionQueue *Queue = nullptr ) {
181175 if (!Node)
182176 return true ;
@@ -1998,18 +1992,14 @@ class DerefSimplePtrArithFixableGadget : public FixableGadget {
19981992};
19991993
20001994// / Scan the function and return a list of gadgets found with provided kits.
2001- static void findGadgets (const Stmt *S, ASTContext &Ctx,
2002- const UnsafeBufferUsageHandler &Handler,
2003- bool EmitSuggestions, FixableGadgetList &FixableGadgets,
2004- WarningGadgetList &WarningGadgets,
2005- DeclUseTracker &Tracker) {
1995+ static std::tuple<FixableGadgetList, WarningGadgetList, DeclUseTracker>
1996+ findGadgets (const Decl *D, const UnsafeBufferUsageHandler &Handler,
1997+ bool EmitSuggestions) {
20061998
20071999 struct GadgetFinderCallback : MatchFinder::MatchCallback {
2008- GadgetFinderCallback (FixableGadgetList &FixableGadgets,
2009- WarningGadgetList &WarningGadgets,
2010- DeclUseTracker &Tracker)
2011- : FixableGadgets(FixableGadgets), WarningGadgets(WarningGadgets),
2012- Tracker (Tracker) {}
2000+ FixableGadgetList FixableGadgets;
2001+ WarningGadgetList WarningGadgets;
2002+ DeclUseTracker Tracker;
20132003
20142004 void run (const MatchFinder::MatchResult &Result) override {
20152005 // In debug mode, assert that we've found exactly one gadget.
@@ -2050,14 +2040,10 @@ static void findGadgets(const Stmt *S, ASTContext &Ctx,
20502040 assert (numFound >= 1 && " Gadgets not found in match result!" );
20512041 assert (numFound <= 1 && " Conflicting bind tags in gadgets!" );
20522042 }
2053-
2054- FixableGadgetList &FixableGadgets;
2055- WarningGadgetList &WarningGadgets;
2056- DeclUseTracker &Tracker;
20572043 };
20582044
20592045 MatchFinder M;
2060- GadgetFinderCallback CB{FixableGadgets, WarningGadgets, Tracker} ;
2046+ GadgetFinderCallback CB;
20612047
20622048 // clang-format off
20632049 M.addMatcher (
@@ -2102,7 +2088,9 @@ static void findGadgets(const Stmt *S, ASTContext &Ctx,
21022088 // clang-format on
21032089 }
21042090
2105- M.match(*S, Ctx);
2091+ M.match (*D->getBody (), D->getASTContext ());
2092+ return {std::move (CB.FixableGadgets ), std::move (CB.WarningGadgets ),
2093+ std::move (CB.Tracker )};
21062094}
21072095
21082096// Compares AST nodes by source locations.
@@ -3646,9 +3634,39 @@ class VariableGroupsManagerImpl : public VariableGroupsManager {
36463634 }
36473635};
36483636
3649- void applyGadgets (const Decl *D, FixableGadgetList FixableGadgets,
3650- WarningGadgetList WarningGadgets, DeclUseTracker Tracker,
3651- UnsafeBufferUsageHandler &Handler, bool EmitSuggestions) {
3637+ void clang::checkUnsafeBufferUsage (const Decl *D,
3638+ UnsafeBufferUsageHandler &Handler,
3639+ bool EmitSuggestions) {
3640+ #ifndef NDEBUG
3641+ Handler.clearDebugNotes ();
3642+ #endif
3643+
3644+ assert (D && D->getBody ());
3645+ // We do not want to visit a Lambda expression defined inside a method
3646+ // independently. Instead, it should be visited along with the outer method.
3647+ // FIXME: do we want to do the same thing for `BlockDecl`s?
3648+ if (const auto *fd = dyn_cast<CXXMethodDecl>(D)) {
3649+ if (fd->getParent ()->isLambda () && fd->getParent ()->isLocalClass ())
3650+ return ;
3651+ }
3652+
3653+ // Do not emit fixit suggestions for functions declared in an
3654+ // extern "C" block.
3655+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3656+ for (FunctionDecl *FReDecl : FD->redecls ()) {
3657+ if (FReDecl->isExternC ()) {
3658+ EmitSuggestions = false ;
3659+ break ;
3660+ }
3661+ }
3662+ }
3663+
3664+ WarningGadgetSets UnsafeOps;
3665+ FixableGadgetSets FixablesForAllVars;
3666+
3667+ auto [FixableGadgets, WarningGadgets, Tracker] =
3668+ findGadgets (D, Handler, EmitSuggestions);
3669+
36523670 if (!EmitSuggestions) {
36533671 // Our job is very easy without suggestions. Just warn about
36543672 // every problematic operation and consider it done. No need to deal
@@ -3692,10 +3710,8 @@ void applyGadgets(const Decl *D, FixableGadgetList FixableGadgets,
36923710 if (WarningGadgets.empty ())
36933711 return ;
36943712
3695- WarningGadgetSets UnsafeOps =
3696- groupWarningGadgetsByVar (std::move (WarningGadgets));
3697- FixableGadgetSets FixablesForAllVars =
3698- groupFixablesByVar (std::move (FixableGadgets));
3713+ UnsafeOps = groupWarningGadgetsByVar (std::move (WarningGadgets));
3714+ FixablesForAllVars = groupFixablesByVar (std::move (FixableGadgets));
36993715
37003716 std::map<const VarDecl *, FixItList> FixItsForVariableGroup;
37013717
@@ -3916,56 +3932,3 @@ void applyGadgets(const Decl *D, FixableGadgetList FixableGadgets,
39163932 }
39173933 }
39183934}
3919-
3920- void clang::checkUnsafeBufferUsage (const Decl *D,
3921- UnsafeBufferUsageHandler &Handler,
3922- bool EmitSuggestions) {
3923- #ifndef NDEBUG
3924- Handler.clearDebugNotes ();
3925- #endif
3926-
3927- assert (D);
3928-
3929- SmallVector<Stmt *> Stmts;
3930-
3931- if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3932- // We do not want to visit a Lambda expression defined inside a method
3933- // independently. Instead, it should be visited along with the outer method.
3934- // FIXME: do we want to do the same thing for `BlockDecl`s?
3935- if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3936- if (MD->getParent ()->isLambda () && MD->getParent ()->isLocalClass ())
3937- return ;
3938- }
3939-
3940- for (FunctionDecl *FReDecl : FD->redecls ()) {
3941- if (FReDecl->isExternC ()) {
3942- // Do not emit fixit suggestions for functions declared in an
3943- // extern "C" block.
3944- EmitSuggestions = false ;
3945- break ;
3946- }
3947- }
3948-
3949- Stmts.push_back (FD->getBody ());
3950-
3951- if (const auto *ID = dyn_cast<CXXConstructorDecl>(D)) {
3952- for (const CXXCtorInitializer *CI : ID->inits ()) {
3953- Stmts.push_back (CI->getInit ());
3954- }
3955- }
3956- } else if (isa<BlockDecl>(D) || isa<ObjCMethodDecl>(D)) {
3957- Stmts.push_back (D->getBody ());
3958- }
3959-
3960- assert (!Stmts.empty ());
3961-
3962- FixableGadgetList FixableGadgets;
3963- WarningGadgetList WarningGadgets;
3964- DeclUseTracker Tracker;
3965- for (Stmt *S : Stmts) {
3966- findGadgets (S, D->getASTContext (), Handler, EmitSuggestions, FixableGadgets,
3967- WarningGadgets, Tracker);
3968- }
3969- applyGadgets (D, std::move (FixableGadgets), std::move (WarningGadgets),
3970- std::move (Tracker), Handler, EmitSuggestions);
3971- }
0 commit comments