[clang-tools-extra] [clang-tidy] Add check performance-lost-std-move (PR #139525)

2025-05-12 Thread Vasiliy Kulikov via cfe-commits

https://github.com/segoon updated 
https://github.com/llvm/llvm-project/pull/139525

>From 3abbce9f817f6d09f9a5b7549a8122c80821eaf8 Mon Sep 17 00:00:00 2001
From: Vasily Kulikov 
Date: Mon, 12 May 2025 13:05:43 +0300
Subject: [PATCH 1/6] [clang-tidy] Add check performance-lost-std-move

---
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/LostStdMoveCheck.cpp  |  96 
 .../clang-tidy/performance/LostStdMoveCheck.h |  37 ++
 .../performance/PerformanceTidyModule.cpp |   2 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   5 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/performance/lost-std-move.rst  |  14 +++
 .../checkers/performance/lost-std-move.cpp| 108 ++
 8 files changed, 264 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/lost-std-move.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/lost-std-move.cpp

diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021..333abd10a583a 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -12,6 +12,7 @@ add_clang_library(clangTidyPerformanceModule
   InefficientAlgorithmCheck.cpp
   InefficientStringConcatenationCheck.cpp
   InefficientVectorOperationCheck.cpp
+  LostStdMoveCheck.cpp
   MoveConstArgCheck.cpp
   MoveConstructorInitCheck.cpp
   NoAutomaticMoveCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
new file mode 100644
index 0..26148e1d26de9
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
@@ -0,0 +1,96 @@
+//===--- LostStdMoveCheck.cpp - clang-tidy 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "LostStdMoveCheck.h"
+#include "../utils/DeclRefExprUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::performance {
+
+using utils::decl_ref_expr::allDeclRefExprs;
+
+AST_MATCHER(CXXRecordDecl, hasTrivialMoveConstructor) {
+  return Node.hasDefinition() && Node.hasTrivialMoveConstructor();
+}
+
+void LostStdMoveCheck::registerMatchers(MatchFinder *Finder) {
+  auto returnParent =
+  hasParent(expr(hasParent(cxxConstructExpr(hasParent(returnStmt());
+
+  Finder->addMatcher(
+  declRefExpr(
+  // not "return x;"
+  unless(returnParent),
+
+  unless(hasType(namedDecl(hasName("::std::string_view",
+
+  // non-trivial type
+  hasType(hasCanonicalType(hasDeclaration(cxxRecordDecl(,
+
+  // non-trivial X(X&&)
+  unless(hasType(hasCanonicalType(
+  hasDeclaration(cxxRecordDecl(hasTrivialMoveConstructor()),
+
+  // Not in a cycle
+  unless(hasAncestor(forStmt())), unless(hasAncestor(doStmt())),
+  unless(hasAncestor(whileStmt())),
+
+  // only non-X&
+  unless(hasDeclaration(
+  varDecl(hasType(qualType(lValueReferenceType()),
+
+  hasDeclaration(
+  varDecl(hasAncestor(functionDecl().bind("func"))).bind("decl")),
+
+  hasParent(expr(hasParent(cxxConstructExpr())).bind("use_parent")))
+  .bind("use"),
+  this);
+}
+
+const Expr *LostStdMoveCheck::getLastVarUsage(const VarDecl &Var,
+  const Decl &Func,
+  ASTContext &Context) {
+  auto Exprs = allDeclRefExprs(Var, Func, Context);
+
+  const Expr *LastExpr = nullptr;
+  for (const auto &Expr : Exprs) {
+if (!LastExpr)
+  LastExpr = Expr;
+
+if (LastExpr->getBeginLoc() < Expr->getBeginLoc())
+  LastExpr = Expr;
+  }
+
+  return LastExpr;
+}
+
+void LostStdMoveCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl = Result.Nodes.getNodeAs("decl");
+  const auto *MatchedFunc = Result.Nodes.getNodeAs("func");
+  const auto *MatchedUse = Result.Nodes.getNodeAs("use");
+  const auto *MatchedUseCall = Result.Nodes.getNodeAs("use_parent");
+
+  if (MatchedUseCall)
+return;
+
+  const auto *LastUsage =
+  getLastVarUsage(*MatchedDecl, *MatchedFunc, *Result.Context);
+  if (LastUsage == nullptr)
+return;
+
+  if (LastUsage->getBeginLoc() > MatchedUse->getBeginLoc()) {
+// "use" is not the last refere

[clang-tools-extra] [clang-tidy] Add check performance-lost-std-move (PR #139525)

2025-05-12 Thread Vasiliy Kulikov via cfe-commits

https://github.com/segoon updated 
https://github.com/llvm/llvm-project/pull/139525

>From 3abbce9f817f6d09f9a5b7549a8122c80821eaf8 Mon Sep 17 00:00:00 2001
From: Vasily Kulikov 
Date: Mon, 12 May 2025 13:05:43 +0300
Subject: [PATCH 1/2] [clang-tidy] Add check performance-lost-std-move

---
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/LostStdMoveCheck.cpp  |  96 
 .../clang-tidy/performance/LostStdMoveCheck.h |  37 ++
 .../performance/PerformanceTidyModule.cpp |   2 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   5 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/performance/lost-std-move.rst  |  14 +++
 .../checkers/performance/lost-std-move.cpp| 108 ++
 8 files changed, 264 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/lost-std-move.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/lost-std-move.cpp

diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021..333abd10a583a 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -12,6 +12,7 @@ add_clang_library(clangTidyPerformanceModule
   InefficientAlgorithmCheck.cpp
   InefficientStringConcatenationCheck.cpp
   InefficientVectorOperationCheck.cpp
+  LostStdMoveCheck.cpp
   MoveConstArgCheck.cpp
   MoveConstructorInitCheck.cpp
   NoAutomaticMoveCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
new file mode 100644
index 0..26148e1d26de9
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
@@ -0,0 +1,96 @@
+//===--- LostStdMoveCheck.cpp - clang-tidy 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "LostStdMoveCheck.h"
+#include "../utils/DeclRefExprUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::performance {
+
+using utils::decl_ref_expr::allDeclRefExprs;
+
+AST_MATCHER(CXXRecordDecl, hasTrivialMoveConstructor) {
+  return Node.hasDefinition() && Node.hasTrivialMoveConstructor();
+}
+
+void LostStdMoveCheck::registerMatchers(MatchFinder *Finder) {
+  auto returnParent =
+  hasParent(expr(hasParent(cxxConstructExpr(hasParent(returnStmt());
+
+  Finder->addMatcher(
+  declRefExpr(
+  // not "return x;"
+  unless(returnParent),
+
+  unless(hasType(namedDecl(hasName("::std::string_view",
+
+  // non-trivial type
+  hasType(hasCanonicalType(hasDeclaration(cxxRecordDecl(,
+
+  // non-trivial X(X&&)
+  unless(hasType(hasCanonicalType(
+  hasDeclaration(cxxRecordDecl(hasTrivialMoveConstructor()),
+
+  // Not in a cycle
+  unless(hasAncestor(forStmt())), unless(hasAncestor(doStmt())),
+  unless(hasAncestor(whileStmt())),
+
+  // only non-X&
+  unless(hasDeclaration(
+  varDecl(hasType(qualType(lValueReferenceType()),
+
+  hasDeclaration(
+  varDecl(hasAncestor(functionDecl().bind("func"))).bind("decl")),
+
+  hasParent(expr(hasParent(cxxConstructExpr())).bind("use_parent")))
+  .bind("use"),
+  this);
+}
+
+const Expr *LostStdMoveCheck::getLastVarUsage(const VarDecl &Var,
+  const Decl &Func,
+  ASTContext &Context) {
+  auto Exprs = allDeclRefExprs(Var, Func, Context);
+
+  const Expr *LastExpr = nullptr;
+  for (const auto &Expr : Exprs) {
+if (!LastExpr)
+  LastExpr = Expr;
+
+if (LastExpr->getBeginLoc() < Expr->getBeginLoc())
+  LastExpr = Expr;
+  }
+
+  return LastExpr;
+}
+
+void LostStdMoveCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl = Result.Nodes.getNodeAs("decl");
+  const auto *MatchedFunc = Result.Nodes.getNodeAs("func");
+  const auto *MatchedUse = Result.Nodes.getNodeAs("use");
+  const auto *MatchedUseCall = Result.Nodes.getNodeAs("use_parent");
+
+  if (MatchedUseCall)
+return;
+
+  const auto *LastUsage =
+  getLastVarUsage(*MatchedDecl, *MatchedFunc, *Result.Context);
+  if (LastUsage == nullptr)
+return;
+
+  if (LastUsage->getBeginLoc() > MatchedUse->getBeginLoc()) {
+// "use" is not the last refere

[clang-tools-extra] [clang-tidy] Add check performance-lost-std-move (PR #139525)

2025-05-12 Thread Vasiliy Kulikov via cfe-commits

https://github.com/segoon updated 
https://github.com/llvm/llvm-project/pull/139525



  



Rate limit · GitHub


  body {
background-color: #f6f8fa;
color: #24292e;
font-family: -apple-system,BlinkMacSystemFont,Segoe 
UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 14px;
line-height: 1.5;
margin: 0;
  }

  .container { margin: 50px auto; max-width: 600px; text-align: center; 
padding: 0 24px; }

  a { color: #0366d6; text-decoration: none; }
  a:hover { text-decoration: underline; }

  h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; 
text-shadow: 0 1px 0 #fff; }
  p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; }

  ul { list-style: none; margin: 25px 0; padding: 0; }
  li { display: table-cell; font-weight: bold; width: 1%; }

  .logo { display: inline-block; margin-top: 35px; }
  .logo-img-2x { display: none; }
  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  only screen and ( -o-min-device-pixel-ratio: 2/1),
  only screen and (min-device-pixel-ratio: 2),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
  }

  #suggestions {
margin-top: 35px;
color: #ccc;
  }
  #suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
  }


  
  



  Whoa there!
  You have exceeded a secondary rate limit.
Please wait a few minutes before you try again;
in some cases this may take up to an hour.
  
  
https://support.github.com/contact";>Contact Support —
https://githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
  

  

  

  

  

  


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


[clang-tools-extra] [clang-tidy] Add check performance-lost-std-move (PR #139525)

2025-05-12 Thread Vasiliy Kulikov via cfe-commits

https://github.com/segoon created 
https://github.com/llvm/llvm-project/pull/139525

None

>From 3abbce9f817f6d09f9a5b7549a8122c80821eaf8 Mon Sep 17 00:00:00 2001
From: Vasily Kulikov 
Date: Mon, 12 May 2025 13:05:43 +0300
Subject: [PATCH] [clang-tidy] Add check performance-lost-std-move

---
 .../clang-tidy/performance/CMakeLists.txt |   1 +
 .../performance/LostStdMoveCheck.cpp  |  96 
 .../clang-tidy/performance/LostStdMoveCheck.h |  37 ++
 .../performance/PerformanceTidyModule.cpp |   2 +
 clang-tools-extra/docs/ReleaseNotes.rst   |   5 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../checks/performance/lost-std-move.rst  |  14 +++
 .../checkers/performance/lost-std-move.cpp| 108 ++
 8 files changed, 264 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/performance/lost-std-move.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/performance/lost-std-move.cpp

diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
index 81128ff086021..333abd10a583a 100644
--- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt
@@ -12,6 +12,7 @@ add_clang_library(clangTidyPerformanceModule
   InefficientAlgorithmCheck.cpp
   InefficientStringConcatenationCheck.cpp
   InefficientVectorOperationCheck.cpp
+  LostStdMoveCheck.cpp
   MoveConstArgCheck.cpp
   MoveConstructorInitCheck.cpp
   NoAutomaticMoveCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
new file mode 100644
index 0..26148e1d26de9
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/performance/LostStdMoveCheck.cpp
@@ -0,0 +1,96 @@
+//===--- LostStdMoveCheck.cpp - clang-tidy 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "LostStdMoveCheck.h"
+#include "../utils/DeclRefExprUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::performance {
+
+using utils::decl_ref_expr::allDeclRefExprs;
+
+AST_MATCHER(CXXRecordDecl, hasTrivialMoveConstructor) {
+  return Node.hasDefinition() && Node.hasTrivialMoveConstructor();
+}
+
+void LostStdMoveCheck::registerMatchers(MatchFinder *Finder) {
+  auto returnParent =
+  hasParent(expr(hasParent(cxxConstructExpr(hasParent(returnStmt());
+
+  Finder->addMatcher(
+  declRefExpr(
+  // not "return x;"
+  unless(returnParent),
+
+  unless(hasType(namedDecl(hasName("::std::string_view",
+
+  // non-trivial type
+  hasType(hasCanonicalType(hasDeclaration(cxxRecordDecl(,
+
+  // non-trivial X(X&&)
+  unless(hasType(hasCanonicalType(
+  hasDeclaration(cxxRecordDecl(hasTrivialMoveConstructor()),
+
+  // Not in a cycle
+  unless(hasAncestor(forStmt())), unless(hasAncestor(doStmt())),
+  unless(hasAncestor(whileStmt())),
+
+  // only non-X&
+  unless(hasDeclaration(
+  varDecl(hasType(qualType(lValueReferenceType()),
+
+  hasDeclaration(
+  varDecl(hasAncestor(functionDecl().bind("func"))).bind("decl")),
+
+  hasParent(expr(hasParent(cxxConstructExpr())).bind("use_parent")))
+  .bind("use"),
+  this);
+}
+
+const Expr *LostStdMoveCheck::getLastVarUsage(const VarDecl &Var,
+  const Decl &Func,
+  ASTContext &Context) {
+  auto Exprs = allDeclRefExprs(Var, Func, Context);
+
+  const Expr *LastExpr = nullptr;
+  for (const auto &Expr : Exprs) {
+if (!LastExpr)
+  LastExpr = Expr;
+
+if (LastExpr->getBeginLoc() < Expr->getBeginLoc())
+  LastExpr = Expr;
+  }
+
+  return LastExpr;
+}
+
+void LostStdMoveCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl = Result.Nodes.getNodeAs("decl");
+  const auto *MatchedFunc = Result.Nodes.getNodeAs("func");
+  const auto *MatchedUse = Result.Nodes.getNodeAs("use");
+  const auto *MatchedUseCall = Result.Nodes.getNodeAs("use_parent");
+
+  if (MatchedUseCall)
+return;
+
+  const auto *LastUsage =
+  getLastVarUsage(*MatchedDecl, *MatchedFunc, *Result.Context);
+  if (LastUsage == nullptr)
+return;
+
+  if (LastUsage->getBeginLoc() > MatchedUse->getBeginLoc()) {
+// "use" is not the last refe

[clang-tools-extra] [clang-tidy] Add check performance-lost-std-move (PR #139525)

2025-05-12 Thread Vasiliy Kulikov via cfe-commits

https://github.com/segoon updated 
https://github.com/llvm/llvm-project/pull/139525



  



Rate limit · GitHub


  body {
background-color: #f6f8fa;
color: #24292e;
font-family: -apple-system,BlinkMacSystemFont,Segoe 
UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
font-size: 14px;
line-height: 1.5;
margin: 0;
  }

  .container { margin: 50px auto; max-width: 600px; text-align: center; 
padding: 0 24px; }

  a { color: #0366d6; text-decoration: none; }
  a:hover { text-decoration: underline; }

  h1 { line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; 
text-shadow: 0 1px 0 #fff; }
  p { color: rgba(0, 0, 0, 0.5); margin: 20px 0 40px; }

  ul { list-style: none; margin: 25px 0; padding: 0; }
  li { display: table-cell; font-weight: bold; width: 1%; }

  .logo { display: inline-block; margin-top: 35px; }
  .logo-img-2x { display: none; }
  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  only screen and ( -o-min-device-pixel-ratio: 2/1),
  only screen and (min-device-pixel-ratio: 2),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
  }

  #suggestions {
margin-top: 35px;
color: #ccc;
  }
  #suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
  }


  
  



  Whoa there!
  You have exceeded a secondary rate limit.
Please wait a few minutes before you try again;
in some cases this may take up to an hour.
  
  
https://support.github.com/contact";>Contact Support —
https://githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
  

  

  

  

  

  


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