Author: alexfh
Date: Wed Nov 25 09:56:11 2015
New Revision: 254070

URL: http://llvm.org/viewvc/llvm-project?rev=254070&view=rev
Log:
[clang-tidy] Const std::move() argument ClangTidy check

ClangTidy check for finding cases when std::move() is called with const or
trivially copyable arguments, that doesn't lead to any move or argument but it
makes copy. FixIt generates patch for removing call of std::move().

Patch by Vadym Doroshenko! (+ a couple of minor fixes)

Differential Revision: http://reviews.llvm.org/D12031

Added:
    clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp
    clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h
    clang-tools-extra/trunk/test/clang-tidy/move-const-arg.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=254070&r1=254069&r2=254070&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Wed Nov 25 09:56:11 
2015
@@ -10,6 +10,7 @@ add_clang_library(clangTidyMiscModule
   MacroParenthesesCheck.cpp
   MacroRepeatedSideEffectsCheck.cpp
   MiscTidyModule.cpp
+  MoveConstantArgumentCheck.cpp 
   MoveConstructorInitCheck.cpp
   NewDeleteOverloadsCheck.cpp
   NoexceptMoveConstructorCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp?rev=254070&r1=254069&r2=254070&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Wed Nov 25 
09:56:11 2015
@@ -18,6 +18,7 @@
 #include "InefficientAlgorithmCheck.h"
 #include "MacroParenthesesCheck.h"
 #include "MacroRepeatedSideEffectsCheck.h"
+#include "MoveConstantArgumentCheck.h"
 #include "MoveConstructorInitCheck.h"
 #include "NewDeleteOverloadsCheck.h"
 #include "NoexceptMoveConstructorCheck.h"
@@ -54,6 +55,8 @@ public:
         "misc-macro-parentheses");
     CheckFactories.registerCheck<MacroRepeatedSideEffectsCheck>(
         "misc-macro-repeated-side-effects");
+    CheckFactories.registerCheck<MoveConstantArgumentCheck>(
+        "misc-move-const-arg");
     CheckFactories.registerCheck<MoveConstructorInitCheck>(
         "misc-move-constructor-init");
     CheckFactories.registerCheck<NewDeleteOverloadsCheck>(

Added: 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=254070&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp 
(added)
+++ clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.cpp Wed 
Nov 25 09:56:11 2015
@@ -0,0 +1,71 @@
+//===--- MoveConstandArgumentCheck.cpp - clang-tidy 
-----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MoveConstantArgumentCheck.h"
+
+#include <clang/Lex/Lexer.h>
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+using namespace ast_matchers;
+
+void MoveConstantArgumentCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+  Finder->addMatcher(callExpr(unless(isInTemplateInstantiation()),
+                              callee(functionDecl(hasName("::std::move"))))
+                         .bind("call-move"),
+                     this);
+}
+
+void MoveConstantArgumentCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move");
+  if (CallMove->getNumArgs() != 1)
+    return;
+  const Expr *Arg = CallMove->getArg(0);
+  SourceManager &SM = Result.Context->getSourceManager();
+
+  bool IsConstArg = Arg->getType().isConstQualified();
+  bool IsTriviallyCopyable =
+      Arg->getType().isTriviallyCopyableType(*Result.Context);
+
+  if (IsConstArg || IsTriviallyCopyable) {
+    auto MoveRange = CharSourceRange::getCharRange(CallMove->getSourceRange());
+    auto FileMoveRange = Lexer::makeFileCharRange(MoveRange, SM, 
getLangOpts());
+    if (!FileMoveRange.isValid())
+      return;
+    bool IsVariable = isa<DeclRefExpr>(Arg);
+    auto Diag =
+        diag(FileMoveRange.getBegin(), "std::move of the %select{|const }0"
+                                       "%select{expression|variable}1 "
+                                       "%select{|of trivially-copyable type }2"
+                                       "has no effect; remove std::move()")
+        << IsConstArg << IsVariable << IsTriviallyCopyable;
+
+    auto BeforeArgumentsRange = Lexer::makeFileCharRange(
+        CharSourceRange::getCharRange(CallMove->getLocStart(),
+                                      Arg->getLocStart()),
+        SM, getLangOpts());
+    auto AfterArgumentsRange = Lexer::makeFileCharRange(
+        CharSourceRange::getCharRange(
+            CallMove->getLocEnd(), CallMove->getLocEnd().getLocWithOffset(1)),
+        SM, getLangOpts());
+
+    if (BeforeArgumentsRange.isValid() && AfterArgumentsRange.isValid()) {
+      DB << FixItHint::CreateRemoval(BeforeArgumentsRange)
+         << FixItHint::CreateRemoval(AfterArgumentsRange);
+    }
+  }
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang

Added: 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=254070&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/MoveConstantArgumentCheck.h Wed Nov 
25 09:56:11 2015
@@ -0,0 +1,31 @@
+//===--- MoveConstandArgumentCheck.h - clang-tidy 
-------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MOVECONTANTARGUMENTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MOVECONTANTARGUMENTCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+class MoveConstantArgumentCheck : public ClangTidyCheck {
+public:
+  MoveConstantArgumentCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MOVECONTANTARGUMENTCHECK_H

Added: clang-tools-extra/trunk/test/clang-tidy/move-const-arg.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/move-const-arg.cpp?rev=254070&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/move-const-arg.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/move-const-arg.cpp Wed Nov 25 
09:56:11 2015
@@ -0,0 +1,73 @@
+// RUN: %check_clang_tidy %s misc-move-const-arg %t -- -- -std=c++11
+
+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);
+
+} // namespace std
+
+class A {
+public:
+  A() {}
+  A(const A &rhs) {}
+  A(A &&rhs) {}
+};
+
+int f1() {
+  return std::move(42);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the expression of 
trivially-copyable type has no effect; remove std::move() [misc-move-const-arg]
+  // CHECK-FIXES: return 42;
+}
+
+int f2(int x2) {
+  return std::move(x2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable of 
trivially-copyable type
+  // CHECK-FIXES: return x2;
+}
+
+int *f3(int *x3) {
+  return std::move(x3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the variable of 
trivially-copyable type
+  // CHECK-FIXES: return x3;
+}
+
+A f4(A x4) { return std::move(x4); }
+
+A f5(const A x5) {
+  return std::move(x5);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable
+  // CHECK-FIXES: return x5;
+}
+
+template <typename T> T f6(const T x6) { return std::move(x6); }
+
+void f7() { int a = f6(10); }
+
+#define M1(x) x
+void f8() {
+  const A a;
+  M1(A b = std::move(a);)
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: std::move of the const variable
+  // CHECK-FIXES: M1(A b = a;)
+}
+
+#define M2(x) std::move(x)
+int f9() { return M2(1); }
+
+template <typename T> T f10(const int x10) {
+  return std::move(x10);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable
+  // CHECK-FIXES: return x10;
+}
+void f11() {
+  f10<int>(1);
+  f10<double>(1);
+}


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to