[clang-tools-extra] [clang-tidy] Add check performance-lost-std-move (PR #139525)
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)
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)
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)
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)
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