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 @@ -63,8 +63,10 @@ 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)))))), 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,58 @@ 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(); +} + +namespace fake { +namespace std { +template +struct function { + // Custom copy constructor makes it expensive to copy; + function(const function &); +}; +} // namespace std + +void positiveFakeStdFunction(std::function F) { + auto Copy = F; + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: local copy 'Copy' of the variable 'F' is never modified; + // CHECK-FIXES: const auto& Copy = F; +} + +} // namespace fake