summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/misc/MoveConstantArgumentCheck.cpp
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2015-11-25 15:56:11 +0000
committerAlexander Kornienko <alexfh@google.com>2015-11-25 15:56:11 +0000
commite4ac60d7bc115089fe78e29c304aa2fe4cb13f02 (patch)
treebbe0ed105951fa6b34858406f20a67a70dd02487 /clang-tools-extra/clang-tidy/misc/MoveConstantArgumentCheck.cpp
parent25150784ae5013c34a6bc0eb7d180e08835cf297 (diff)
downloadbcm5719-llvm-e4ac60d7bc115089fe78e29c304aa2fe4cb13f02.tar.gz
bcm5719-llvm-e4ac60d7bc115089fe78e29c304aa2fe4cb13f02.zip
[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 llvm-svn: 254070
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/MoveConstantArgumentCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/misc/MoveConstantArgumentCheck.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/MoveConstantArgumentCheck.cpp b/clang-tools-extra/clang-tidy/misc/MoveConstantArgumentCheck.cpp
new file mode 100644
index 00000000000..172dc4ff24f
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/MoveConstantArgumentCheck.cpp
@@ -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
OpenPOWER on IntegriCloud