Sockke updated this revision to Diff 366815.
Sockke added a comment.

update! Fixed some diagnostic descriptions.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107450/new/

https://reviews.llvm.org/D107450

Files:
  clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
  clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h
  clang-tools-extra/test/clang-tidy/checkers/performance-move-const-arg.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/performance-move-const-arg.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/performance-move-const-arg.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/performance-move-const-arg.cpp
@@ -246,3 +246,27 @@
   };
   f(MoveSemantics());
 }
+
+void showInt(int &&) {}
+void testInt() {
+  int a = 10;
+  showInt(std::move(a));
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: std::move of the variable 'a' of the trivially-copyable type 'int' has no effect; consider changing showInt's parameter from 'int &&' to 'int'
+}
+template <class T>
+void forwardToShowInt(T &&t) {
+  showInt(static_cast<T &&>(t));
+}
+void testTemplate() {
+  int a = 10;
+  forwardToShowInt(std::move(a));
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: std::move of the variable 'a' of the trivially-copyable type 'int' has no effect
+}
+
+struct Tmp {};
+void showTmp(Tmp &&) {}
+void testTmp() {
+  Tmp t;
+  showTmp(std::move(t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: std::move of the variable 't' of the trivially-copyable type 'Tmp' has no effect
+}
Index: clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h
+++ clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.h
@@ -10,6 +10,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MOVECONSTANTARGUMENTCHECK_H
 
 #include "../ClangTidyCheck.h"
+#include "llvm/ADT/DenseSet.h"
 
 namespace clang {
 namespace tidy {
@@ -36,6 +37,7 @@
 
 private:
   const bool CheckTriviallyCopyableMove;
+  llvm::DenseSet<const CallExpr *> HasCheckedMoveSet;
 };
 
 } // namespace performance
Index: clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
+++ clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
@@ -50,7 +50,9 @@
   Finder->addMatcher(
       invocation(forEachArgumentWithParam(
                      MoveCallMatcher,
-                     parmVarDecl(hasType(references(isConstQualified())))))
+                     parmVarDecl(anyOf(hasType(references(isConstQualified())),
+                                       hasType(rValueReferenceType())))
+                         .bind("invocation-parm")))
           .bind("receiving-expr"),
       this);
 }
@@ -58,6 +60,15 @@
 void MoveConstArgCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move");
   const auto *ReceivingExpr = Result.Nodes.getNodeAs<Expr>("receiving-expr");
+  const auto *InvocationParm =
+      Result.Nodes.getNodeAs<ParmVarDecl>("invocation-parm");
+
+  if (!ReceivingExpr && HasCheckedMoveSet.contains(CallMove))
+    return;
+
+  if (ReceivingExpr)
+    HasCheckedMoveSet.insert(CallMove);
+
   const Expr *Arg = CallMove->getArg(0);
   SourceManager &SM = Result.Context->getSourceManager();
 
@@ -90,20 +101,52 @@
       return;
 
     bool IsVariable = isa<DeclRefExpr>(Arg);
+    bool IsRValueReferenceArg = false;
+    bool IsTemplateInstantiation = false;
+    StringRef FuncName;
+    QualType ParmType;
     const auto *Var =
         IsVariable ? dyn_cast<DeclRefExpr>(Arg)->getDecl() : nullptr;
-    auto Diag = diag(FileMoveRange.getBegin(),
-                     "std::move of the %select{|const }0"
-                     "%select{expression|variable %4}1 "
-                     "%select{|of the trivially-copyable type %5 }2"
-                     "has no effect; remove std::move()"
-                     "%select{| or make the variable non-const}3")
-                << IsConstArg << IsVariable << IsTriviallyCopyable
-                << (IsConstArg && IsVariable && !IsTriviallyCopyable) << Var
-                << Arg->getType();
+
+    if (ReceivingExpr &&
+        InvocationParm->getOriginalType()->isRValueReferenceType() &&
+        !ReceivingExpr->getType()->isRecordType() && Arg->isLValue()) {
+      IsRValueReferenceArg = true;
+      if (Arg->getType()->isBuiltinType()) {
+        const auto *ReceivingCallExpr = dyn_cast<CallExpr>(ReceivingExpr);
+        if (!ReceivingCallExpr)
+          return;
+        IsTemplateInstantiation =
+            ReceivingCallExpr->getDirectCallee()->isTemplateInstantiation();
+        FuncName = ReceivingCallExpr->getDirectCallee()->getName();
+        ParmType = InvocationParm->getOriginalType();
+      }
+    }
+
+    auto Diag =
+        diag(FileMoveRange.getBegin(),
+             "std::move of the %select{|const }0"
+             "%select{expression|variable %6}1 "
+             "%select{|of the trivially-copyable type %7 }2"
+             "has no effect%select{; remove std::move()|}3"
+             "%select{| or make the variable non-const}4"
+             "%select{|; consider changing %8's parameter from %9 to %7}5")
+        << IsConstArg << IsVariable << IsTriviallyCopyable
+        << IsRValueReferenceArg
+        << (IsConstArg && IsVariable && !IsTriviallyCopyable &&
+            !IsRValueReferenceArg)
+        << (IsRValueReferenceArg && Arg->getType()->isBuiltinType() &&
+            !IsTemplateInstantiation)
+        << Var << Arg->getType() << FuncName << ParmType;
+
+    if (IsRValueReferenceArg)
+      return;
 
     replaceCallWithArg(CallMove, Diag, SM, getLangOpts());
   } else if (ReceivingExpr) {
+    if (InvocationParm->getOriginalType()->isRValueReferenceType())
+      return;
+
     auto Diag = diag(FileMoveRange.getBegin(),
                      "passing result of std::move() as a const reference "
                      "argument; no move will actually happen");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to