Index: clang-tidy/utils/TypeTraits.cpp =================================================================== --- clang-tidy/utils/TypeTraits.cpp +++ clang-tidy/utils/TypeTraits.cpp @@ -10,12 +10,15 @@ #include "TypeTraits.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" namespace clang { namespace tidy { namespace utils { namespace type_traits { +using namespace ::clang::ast_matchers; + namespace { bool classHasTrivialCopyAndDestroy(QualType Type) { auto *Record = Type->getAsCXXRecordDecl(); @@ -23,13 +26,26 @@ !Record->hasNonTrivialCopyConstructor() && !Record->hasNonTrivialDestructor(); } + +bool hasDeletedCopyConstructor(QualType Type, ASTContext &Context) { + auto *Record = Type->getAsCXXRecordDecl(); + if (Record == nullptr || !Record->hasDefinition()) + return false; + auto Matches = match(cxxRecordDecl(hasMethod( + cxxConstructorDecl(isCopyConstructor(), isDeleted()) + .bind("constructor"))), + *Record, Context); + return !Matches.empty(); +} + } // namespace llvm::Optional isExpensiveToCopy(QualType Type, ASTContext &Context) { if (Type->isDependentType()) return llvm::None; return !Type.isTriviallyCopyableType(Context) && - !classHasTrivialCopyAndDestroy(Type); + !classHasTrivialCopyAndDestroy(Type) && + !hasDeletedCopyConstructor(Type, Context); } bool recordIsTriviallyDefaultConstructible(const RecordDecl &RecordDecl, Index: test/clang-tidy/performance-unnecessary-value-param.cpp =================================================================== --- test/clang-tidy/performance-unnecessary-value-param.cpp +++ test/clang-tidy/performance-unnecessary-value-param.cpp @@ -23,6 +23,12 @@ SomewhatTrivial& operator=(const SomewhatTrivial&); }; +struct MoveOnlyType { + MoveOnlyType(const MoveOnlyType&) = delete; + ~MoveOnlyType(); + void constMethod() const; +}; + void positiveExpensiveConstValue(const ExpensiveToCopyType Obj); // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj); void positiveExpensiveConstValue(const ExpensiveToCopyType Obj) { @@ -169,3 +175,7 @@ NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; }; + +void NegativeMoveOnlyTypePassedByValue(MoveOnlyType M) { + M.constMethod(); +}