diff --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp @@ -64,8 +64,9 @@ : nullptr)); } +template static FixItHint removeArgument(const MatchFinder::MatchResult &Result, - const CallExpr *Call, unsigned Index) { + const CallExprT *Call, unsigned Index) { return FixItHint::CreateRemoval(removeNode( Result, Index > 0 ? Call->getArg(Index - 1) : nullptr, Call->getArg(Index), @@ -75,13 +76,20 @@ class UnusedParametersCheck::IndexerVisitor : public RecursiveASTVisitor { public: - IndexerVisitor(ASTContext &Ctx) { TraverseAST(Ctx); } + IndexerVisitor(ASTContext &Ctx) : mgr(Ctx.getSourceManager()) { + TraverseAST(Ctx); + } const std::unordered_set & getFnCalls(const FunctionDecl *Fn) { return Index[Fn->getCanonicalDecl()].Calls; } + const std::unordered_set & + getCtorCalls(const FunctionDecl *Fn) { + return Index[Fn->getCanonicalDecl()].CtorRefs; + } + const std::unordered_set & getOtherRefs(const FunctionDecl *Fn) { return Index[Fn->getCanonicalDecl()].OtherRefs; @@ -97,6 +105,15 @@ return true; } + bool WalkUpFromCXXConstructExpr(CXXConstructExpr *Call) { + if (const auto *Ctor = + dyn_cast_or_null(Call->getConstructor())) { + Ctor = Ctor->getCanonicalDecl(); + Index[Ctor].CtorRefs.insert(Call); + } + return true; + } + bool WalkUpFromCallExpr(CallExpr *Call) { if (const auto *Fn = dyn_cast_or_null(Call->getCalleeDecl())) { @@ -114,8 +131,9 @@ struct IndexEntry { std::unordered_set Calls; std::unordered_set OtherRefs; + std::unordered_set CtorRefs; }; - + SourceManager &mgr; std::unordered_map Index; }; @@ -165,9 +183,14 @@ MyDiag << removeParameter(Result, FD, ParamIndex); // Fix all call sites. - for (const CallExpr *Call : Indexer->getFnCalls(Function)) + for (const CallExpr *Call : Indexer->getFnCalls(Function)) { + if (ParamIndex < Call->getNumArgs()) // See PR38055 for example. + MyDiag << removeArgument(Result, Call, ParamIndex); + } + for (const CXXConstructExpr *Call : Indexer->getCtorCalls(Function)) { if (ParamIndex < Call->getNumArgs()) // See PR38055 for example. MyDiag << removeArgument(Result, Call, ParamIndex); + } } void UnusedParametersCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp @@ -186,6 +186,7 @@ void someMoreCallSites() { C c(42); +// CHECK-FIXES: C c(); c.f(1); // CHECK-FIXES: c.f(); c.g(1);