diff options
Diffstat (limited to 'clang-tools-extra')
3 files changed, 31 insertions, 3 deletions
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp index 15d3d095946..dfa8b67aeb2 100644 --- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp +++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp @@ -10,6 +10,7 @@ #include "TypeTraits.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" namespace clang { namespace tidy { @@ -17,19 +18,34 @@ namespace utils { namespace type_traits { namespace { + bool classHasTrivialCopyAndDestroy(QualType Type) { auto *Record = Type->getAsCXXRecordDecl(); return Record && Record->hasDefinition() && !Record->hasNonTrivialCopyConstructor() && !Record->hasNonTrivialDestructor(); } + +bool hasDeletedCopyConstructor(QualType Type) { + auto *Record = Type->getAsCXXRecordDecl(); + if (!Record || !Record->hasDefinition()) + return false; + for (const auto *Constructor : Record->ctors()) { + if (Constructor->isCopyConstructor() && Constructor->isDeleted()) + return true; + } + return false; +} + } // namespace -llvm::Optional<bool> isExpensiveToCopy(QualType Type, ASTContext &Context) { +llvm::Optional<bool> isExpensiveToCopy(QualType Type, + const ASTContext &Context) { if (Type->isDependentType()) return llvm::None; return !Type.isTriviallyCopyableType(Context) && - !classHasTrivialCopyAndDestroy(Type); + !classHasTrivialCopyAndDestroy(Type) && + !hasDeletedCopyConstructor(Type); } bool recordIsTriviallyDefaultConstructible(const RecordDecl &RecordDecl, diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.h b/clang-tools-extra/clang-tidy/utils/TypeTraits.h index 4cf3ab25f86..8fde9d1a761 100644 --- a/clang-tools-extra/clang-tidy/utils/TypeTraits.h +++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.h @@ -19,7 +19,8 @@ namespace utils { namespace type_traits { // \brief Returns true If \c Type is expensive to copy. -llvm::Optional<bool> isExpensiveToCopy(QualType Type, ASTContext &Context); +llvm::Optional<bool> isExpensiveToCopy(QualType Type, + const ASTContext &Context); // \brief Returns true If \c Type is trivially default constructible. bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context); diff --git a/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param.cpp b/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param.cpp index 4c88b907c87..032f71f0108 100644 --- a/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param.cpp +++ b/clang-tools-extra/test/clang-tidy/performance-unnecessary-value-param.cpp @@ -23,6 +23,13 @@ class SomewhatTrivial { SomewhatTrivial& operator=(const SomewhatTrivial&); }; +struct MoveOnlyType { + MoveOnlyType(const MoveOnlyType &) = delete; + MoveOnlyType(MoveOnlyType &&) = default; + ~MoveOnlyType(); + void constMethod() const; +}; + void positiveExpensiveConstValue(const ExpensiveToCopyType Obj); // CHECK-FIXES: void positiveExpensiveConstValue(const ExpensiveToCopyType& Obj); void positiveExpensiveConstValue(const ExpensiveToCopyType Obj) { @@ -169,3 +176,7 @@ struct NegativeDeletedMethod { NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete; }; + +void NegativeMoveOnlyTypePassedByValue(MoveOnlyType M) { + M.constMethod(); +} |

