diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -40,7 +40,8 @@ AllowedTypes( utils::options::parseStringList(Options.get("AllowedTypes", ""))) {} -void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { +void UnnecessaryCopyInitialization::registerMatchers( + internal::MatchFinder *Finder) { auto ConstReference = referenceType(pointee(qualType(isConstQualified()))); // Match method call expressions where the `this` argument is only used as @@ -57,17 +58,20 @@ unless(callee(cxxMethodDecl()))) .bind("initFunctionCall"); - auto localVarCopiedFrom = [this](const internal::Matcher &CopyCtorArg) { + auto localVarCopiedFrom = [this](const Matcher &CopyCtorArg) { return compoundStmt( forEachDescendant( declStmt( has(varDecl(hasLocalStorage(), hasType(qualType( - hasCanonicalType( - matchers::isExpensiveToCopy()), + hasCanonicalType(allOf( + matchers::isExpensiveToCopy(), + unless(hasDeclaration(namedDecl( + hasName("::std::function")))))), unless(hasDeclaration(namedDecl( - matchers::matchesAnyListedName( - AllowedTypes)))))), + anyOf(matchers::matchesAnyListedName( + AllowedTypes), + isStdFunction())))))), unless(isImplicit()), hasInitializer(traverse( ast_type_traits::TK_AsIs, 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 @@ -405,3 +405,41 @@ ExpensiveToCopyType Orig; const ExpensiveToCopyType Copy = freeFunctionWithDefaultArg(&Orig); } + +namespace std { +inline namespace __1 { + +template +class function; +template +class function { +public: + function(); + function(const function &other); + R operator()(Args &&...args) const; +}; + +} // namespace __1 +} // namespace std + +void negativeStdFunction() { + std::function Orig; + std::function Copy = Orig; + int i = Orig(); +} + +using Functor = std::function; + +void negativeAliasedStdFunction() { + Functor Orig; + Functor Copy = Orig; + int i = Orig(); +} + +typedef std::function TypedefFunc; + +void negativeTypedefedStdFunction() { + TypedefFunc Orig; + TypedefFunc Copy = Orig; + int i = Orig(); +}