flx updated this revision to Diff 301388. flx added a comment. Add instantiated template method.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D90042/new/ https://reviews.llvm.org/D90042 Files: clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp Index: clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp +++ clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp @@ -411,14 +411,37 @@ template <class> class function; -template <class R, class... Args> -class function<R(Args...)> { +template <class R, class... ArgTypes> +class function<R(ArgTypes...)> { public: function(); - function(const function &other); - R operator()(Args &&...args) const; + function(const function &Other); + R operator()(ArgTypes &&...Args) const; +}; + +template <typename> +struct remove_reference; + +template <typename _Tp> +struct remove_reference { + typedef _Tp type; +}; + +template <typename _Tp> +struct remove_reference<_Tp &> { + typedef _Tp type; +}; + +template <typename _Tp> +struct remove_reference<_Tp &&> { + typedef _Tp type; }; +template <typename _Tp> +constexpr _Tp &&forward(typename remove_reference<_Tp>::type &__t) noexcept { + return static_cast<_Tp &&>(__t); +} + } // namespace __1 } // namespace std @@ -460,3 +483,24 @@ } } // namespace fake + +void positiveInvokedOnStdFunction( + std::function<void(const ExpensiveToCopyType &)> 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); +} + +template <class Type> +void foo(Type &&T) { + std::forward<Type>(T).nonConstMethod(); +} + +void negativeInvokedOnStdFunction( + std::function<void(ExpensiveToCopyType &)> Update, + const ExpensiveToCopyType Orig) { + auto Copy = Orig.reference(); + foo(Copy); +} Index: clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp =================================================================== --- clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp +++ clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp @@ -59,7 +59,11 @@ 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))); Matches = match(findAll(callExpr(UsedAsConstRefOrValueArg)), Stmt, Context);
Index: clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp +++ clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-copy-initialization.cpp @@ -411,14 +411,37 @@ template <class> class function; -template <class R, class... Args> -class function<R(Args...)> { +template <class R, class... ArgTypes> +class function<R(ArgTypes...)> { public: function(); - function(const function &other); - R operator()(Args &&...args) const; + function(const function &Other); + R operator()(ArgTypes &&...Args) const; +}; + +template <typename> +struct remove_reference; + +template <typename _Tp> +struct remove_reference { + typedef _Tp type; +}; + +template <typename _Tp> +struct remove_reference<_Tp &> { + typedef _Tp type; +}; + +template <typename _Tp> +struct remove_reference<_Tp &&> { + typedef _Tp type; }; +template <typename _Tp> +constexpr _Tp &&forward(typename remove_reference<_Tp>::type &__t) noexcept { + return static_cast<_Tp &&>(__t); +} + } // namespace __1 } // namespace std @@ -460,3 +483,24 @@ } } // namespace fake + +void positiveInvokedOnStdFunction( + std::function<void(const ExpensiveToCopyType &)> 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); +} + +template <class Type> +void foo(Type &&T) { + std::forward<Type>(T).nonConstMethod(); +} + +void negativeInvokedOnStdFunction( + std::function<void(ExpensiveToCopyType &)> Update, + const ExpensiveToCopyType Orig) { + auto Copy = Orig.reference(); + foo(Copy); +} Index: clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp =================================================================== --- clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp +++ clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp @@ -59,7 +59,11 @@ 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))); Matches = match(findAll(callExpr(UsedAsConstRefOrValueArg)), Stmt, Context);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits