Author: Karasev Nikita Date: 2020-02-28T09:17:16-05:00 New Revision: 365c99fd7d5461be902a5cec54d773cb82b56101
URL: https://github.com/llvm/llvm-project/commit/365c99fd7d5461be902a5cec54d773cb82b56101 DIFF: https://github.com/llvm/llvm-project/commit/365c99fd7d5461be902a5cec54d773cb82b56101.diff LOG: Skip TemplateSpecializedType in modernize-pass-by-value. Existing 'modernize-pass-by-value' check works only with non template values in initializers. Fixes PR37210. Added: Modified: clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp index e3c7d1d83e63..a6efdc4ab0e0 100644 --- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp @@ -46,8 +46,9 @@ AST_MATCHER(CXXRecordDecl, isMoveConstructible) { } } // namespace -static TypeMatcher constRefType() { - return lValueReferenceType(pointee(isConstQualified())); +static TypeMatcher notTemplateSpecConstRefType() { + return lValueReferenceType( + pointee(unless(templateSpecializationType()), isConstQualified())); } static TypeMatcher nonConstValueType() { @@ -145,16 +146,18 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) { // ParenListExpr is generated instead of a CXXConstructExpr, // filtering out templates automatically for us. withInitializer(cxxConstructExpr( - has(ignoringParenImpCasts(declRefExpr(to( - parmVarDecl( - hasType(qualType( - // Match only const-ref or a non-const value - // parameters. Rvalues and const-values - // shouldn't be modified. - ValuesOnly ? nonConstValueType() - : anyOf(constRefType(), - nonConstValueType())))) - .bind("Param"))))), + has(ignoringParenImpCasts(declRefExpr( + to(parmVarDecl( + hasType(qualType( + // Match only const-ref or a non-const + // value parameters. Rvalues, + // TemplateSpecializationValues and + // const-values shouldn't be modified. + ValuesOnly + ? nonConstValueType() + : anyOf(notTemplateSpecConstRefType(), + nonConstValueType())))) + .bind("Param"))))), hasDeclaration(cxxConstructorDecl( isCopyConstructor(), unless(isDeleted()), hasDeclContext( diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value.cpp index 6bf68ca0b6ab..45f51a902cc3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-pass-by-value.cpp @@ -118,6 +118,26 @@ template <typename T> struct J { J<Movable> j1(Movable()); J<NotMovable> j2(NotMovable()); +template<class T> +struct MovableTemplateT +{ + MovableTemplateT() {} + MovableTemplateT(const MovableTemplateT& o) { } + MovableTemplateT(MovableTemplateT&& o) { } +}; + +template <class T> +struct J2 { + J2(const MovableTemplateT<T>& A); + // CHECK-FIXES: J2(const MovableTemplateT<T>& A); + MovableTemplateT<T> M; +}; + +template <class T> +J2<T>::J2(const MovableTemplateT<T>& A) : M(A) {} +// CHECK-FIXES: J2<T>::J2(const MovableTemplateT<T>& A) : M(A) {} +J2<int> j3(MovableTemplateT<int>{}); + struct K_Movable { K_Movable() = default; K_Movable(const K_Movable &) = default; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits