diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp --- a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp @@ -59,9 +59,13 @@ extractNodesByIdTo(Matches, "declRef", DeclRefs); auto ConstReferenceOrValue = qualType(anyOf(referenceType(pointee(qualType(isConstQualified()))), - unless(anyOf(referenceType(), pointerType())))); + unless(anyOf(referenceType(), pointerType(), + substTemplateTypeParmType())))); + auto ConstReferenceOrValueOrReplaced = qualType(anyOf( + ConstReferenceOrValue, + substTemplateTypeParmType(hasReplacementType(ConstReferenceOrValue)))); auto UsedAsConstRefOrValueArg = forEachArgumentWithParam( - DeclRefToVar, parmVarDecl(hasType(ConstReferenceOrValue))); + DeclRefToVar, parmVarDecl(hasType(ConstReferenceOrValueOrReplaced))); Matches = match(findAll(callExpr(UsedAsConstRefOrValueArg)), Stmt, Context); extractNodesByIdTo(Matches, "declRef", DeclRefs); Matches = diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s performance-unnecessary-copy-initialization %t +// RUN: %check_clang_tidy -std=c++17 %s performance-unnecessary-copy-initialization %t struct ExpensiveToCopyType { ExpensiveToCopyType(); @@ -411,12 +411,12 @@ template class function; -template -class function { +template +class function { public: function(); - function(const function &other); - R operator()(Args &&...args) const; + function(const function &Other); + R operator()(ArgTypes &&...Args) const; }; } // namespace __1 @@ -460,3 +460,19 @@ } } // namespace fake + +void positiveInvokedOnStdFunction( + std::function Update, + const ExpensiveToCopyType Orig) { + auto Copy = Orig.reference(); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'Copy' is copy-constructed from a const reference + // CHECK-FIXES: const auto& Copy = Orig.reference(); + Update(Copy); +} + +void negativeInvokedOnStdFunction( + std::function Update, + const ExpensiveToCopyType Orig) { + auto Copy = Orig.reference(); + Update(Copy); +}