flx updated this revision to Diff 57129.
flx marked 5 inline comments as done.
http://reviews.llvm.org/D20170

Files:
  clang-tidy/utils/TypeTraits.cpp
  test/clang-tidy/performance-unnecessary-value-param.cpp

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,13 @@
   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 @@
   NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
   // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = 
delete;
 };
+
+void NegativeMoveOnlyTypePassedByValue(MoveOnlyType M) {
+  M.constMethod();
+}
Index: clang-tidy/utils/TypeTraits.cpp
===================================================================
--- clang-tidy/utils/TypeTraits.cpp
+++ clang-tidy/utils/TypeTraits.cpp
@@ -10,26 +10,41 @@
 #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 {
 
 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) {
   if (Type->isDependentType())
     return llvm::None;
   return !Type.isTriviallyCopyableType(Context) &&
-         !classHasTrivialCopyAndDestroy(Type);
+         !classHasTrivialCopyAndDestroy(Type) &&
+         !hasDeletedCopyConstructor(Type);
 }
 
 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,13 @@
   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 @@
   NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
   // CHECK-FIXES: NegativeDeletedMethod& operator=(NegativeDeletedMethod N) = delete;
 };
+
+void NegativeMoveOnlyTypePassedByValue(MoveOnlyType M) {
+  M.constMethod();
+}
Index: clang-tidy/utils/TypeTraits.cpp
===================================================================
--- clang-tidy/utils/TypeTraits.cpp
+++ clang-tidy/utils/TypeTraits.cpp
@@ -10,26 +10,41 @@
 #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 {
 
 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) {
   if (Type->isDependentType())
     return llvm::None;
   return !Type.isTriviallyCopyableType(Context) &&
-         !classHasTrivialCopyAndDestroy(Type);
+         !classHasTrivialCopyAndDestroy(Type) &&
+         !hasDeletedCopyConstructor(Type);
 }
 
 bool recordIsTriviallyDefaultConstructible(const RecordDecl &RecordDecl,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to