[clang-tools-extra] r319111 - Add an option to misc-move-const-arg to not diagnose on trivially copyable types.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 27 14:59:34 PST 2017


Author: aaronballman
Date: Mon Nov 27 14:59:33 2017
New Revision: 319111

URL: http://llvm.org/viewvc/llvm-project?rev=319111&view=rev
Log:
Add an option to misc-move-const-arg to not diagnose on trivially copyable types.

Patch by Oleg Smolsky

Added:
    clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg-trivially-copyable.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp
    clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/misc-move-const-arg.rst
    clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp?rev=319111&r1=319110&r2=319111&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp Mon Nov 27 14:59:33 2017
@@ -36,6 +36,11 @@ static void ReplaceCallWithArg(const Cal
   }
 }
 
+void MoveConstantArgumentCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "CheckTriviallyCopyableMove", CheckTriviallyCopyableMove);
+}
+
 void MoveConstantArgumentCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus)
     return;
@@ -85,6 +90,10 @@ void MoveConstantArgumentCheck::check(co
           return;
       }
     }
+
+    if (!IsConstArg && IsTriviallyCopyable && !CheckTriviallyCopyableMove)
+      return;
+
     bool IsVariable = isa<DeclRefExpr>(Arg);
     const auto *Var =
         IsVariable ? dyn_cast<DeclRefExpr>(Arg)->getDecl() : nullptr;

Modified: clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h?rev=319111&r1=319110&r2=319111&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h Mon Nov 27 14:59:33 2017
@@ -16,12 +16,24 @@ namespace clang {
 namespace tidy {
 namespace misc {
 
+/// Find casts of calculation results to bigger type. Typically from int to
+///
+/// There is one option:
+///
+///   - `CheckTriviallyCopyableMove`: Whether to check for trivially-copyable
+//      types as their objects are not moved but copied. Enabled by default.
 class MoveConstantArgumentCheck : public ClangTidyCheck {
 public:
   MoveConstantArgumentCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
+      : ClangTidyCheck(Name, Context),
+        CheckTriviallyCopyableMove(
+            Options.get("CheckTriviallyCopyableMove", true)) {}
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  const bool CheckTriviallyCopyableMove;
 };
 
 } // namespace misc

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/misc-move-const-arg.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/misc-move-const-arg.rst?rev=319111&r1=319110&r2=319111&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/misc-move-const-arg.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/misc-move-const-arg.rst Mon Nov 27 14:59:33 2017
@@ -27,3 +27,11 @@ Here are examples of each of the three c
   void f(const string &s);
   string s;
   f(std::move(s));  // Warning: passing result of std::move as a const reference argument; no move will actually happen
+
+Options
+-------
+
+.. option:: CheckTriviallyCopyableMove
+
+   If non-zero, enables detection of trivially copyable types that do not
+   have a move constructor. Default is non-zero.

Added: clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg-trivially-copyable.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg-trivially-copyable.cpp?rev=319111&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg-trivially-copyable.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg-trivially-copyable.cpp Mon Nov 27 14:59:33 2017
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s misc-move-const-arg %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: misc-move-const-arg.CheckTriviallyCopyableMove, value: 0}]}' \
+// RUN: -- -std=c++14
+
+namespace std {
+
+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 typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) {
+  return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);
+}
+
+template <typename _Tp>
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept {
+  return static_cast<_Tp &&>(__t);
+}
+
+} // namespace std
+
+class NoMoveSemantics {
+ public:
+  NoMoveSemantics();
+  NoMoveSemantics(const NoMoveSemantics &);
+
+  NoMoveSemantics &operator=(const NoMoveSemantics &);
+};
+
+void callByConstRef(const NoMoveSemantics &);
+void callByConstRef(int i, const NoMoveSemantics &);
+
+void moveToConstReferencePositives() {
+  NoMoveSemantics obj;
+
+  // Basic case. It is here just to have a single "detected and fixed" case.
+  callByConstRef(std::move(obj));
+  // CHECK-MESSAGES: :[[@LINE-1]]:18:  warning: passing result of std::move() as a const reference argument; no move will actually happen [misc-move-const-arg]
+  // CHECK-FIXES: callByConstRef(obj);
+}
+
+struct TriviallyCopyable {
+  int i;
+};
+
+void f(TriviallyCopyable) {}
+
+void g() {
+  TriviallyCopyable obj;
+  f(std::move(obj));
+}
+
+class MoveSemantics {
+ public:
+  MoveSemantics();
+  MoveSemantics(MoveSemantics &&);
+
+  MoveSemantics &operator=(MoveSemantics &&);
+};
+
+void fmovable(MoveSemantics);
+
+void lambda1() {
+  auto f = [](MoveSemantics m) {
+    fmovable(std::move(m));
+  };
+  f(MoveSemantics());
+}
+
+template<class T> struct function {};
+
+template<typename Result, typename... Args>
+class function<Result(Args...)> {
+public:
+  function() = default;
+  void operator()(Args... args) const {
+    fmovable(std::forward<Args>(args)...);
+  }
+};
+
+void functionInvocation() {
+  function<void(MoveSemantics)> callback;
+  MoveSemantics m;
+  callback(std::move(m));
+}
+
+void lambda2() {
+  function<void(MoveSemantics)> callback;
+
+  auto f = [callback = std::move(callback)](MoveSemantics m) mutable {
+    callback(std::move(m));
+  };
+  f(MoveSemantics());
+}

Modified: clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg.cpp?rev=319111&r1=319110&r2=319111&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-move-const-arg.cpp Mon Nov 27 14:59:33 2017
@@ -14,6 +14,12 @@ constexpr typename std::remove_reference
   return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);
 }
 
+template <typename _Tp>
+constexpr _Tp &&
+forward(typename remove_reference<_Tp>::type &__t) noexcept {
+  return static_cast<_Tp &&>(__t);
+}
+
 } // namespace std
 
 class A {
@@ -23,6 +29,19 @@ public:
   A(A &&rhs) {}
 };
 
+struct TriviallyCopyable {
+  int i;
+};
+
+void f(TriviallyCopyable) {}
+
+void g() {
+  TriviallyCopyable obj;
+  f(std::move(obj));
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: std::move of the variable 'obj' of the trivially-copyable type 'TriviallyCopyable' has no effect; remove std::move() [misc-move-const-arg]
+  // CHECK-FIXES: f(obj);
+}
+
 int f1() {
   return std::move(42);
   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of the trivially-copyable type 'int' has no effect; remove std::move() [misc-move-const-arg]
@@ -176,3 +195,40 @@ void Q(T);
 void moveOnlyNegatives(MoveOnly val) {
   Q(std::move(val));
 }
+
+void fmovable(MoveSemantics);
+
+void lambda1() {
+  auto f = [](MoveSemantics m) {
+    fmovable(std::move(m));
+  };
+  f(MoveSemantics());
+}
+
+template<class T> struct function {};
+
+template<typename Result, typename... Args>
+class function<Result(Args...)> {
+public:
+  function() = default;
+  void operator()(Args... args) const {
+    fmovable(std::forward<Args>(args)...);
+  }
+};
+
+void functionInvocation() {
+  function<void(MoveSemantics)> callback;
+  MoveSemantics m;
+  callback(std::move(m));
+}
+
+void lambda2() {
+  function<void(MoveSemantics)> callback;
+
+  auto f = [callback = std::move(callback)](MoveSemantics m) mutable {
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: std::move of the variable 'callback' of the trivially-copyable type 'function<void (MoveSemantics)>' has no effect; remove std::move()
+    // CHECK-FIXES: auto f = [callback = callback](MoveSemantics m) mutable {
+    callback(std::move(m));
+  };
+  f(MoveSemantics());
+}




More information about the cfe-commits mailing list