[clang-tools-extra] [clang-tidy] Don't suggest const on `std::moved` locals in templates … (PR #226577)

Zeyi Xu via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 24 08:06:43 PDT 2026


https://github.com/zeyi2 updated https://github.com/llvm/llvm-project/pull/226577

>From b391ee1e57f7e83232cb86030a8b85321180a4c4 Mon Sep 17 00:00:00 2001
From: Daniel Petrovic <daniel-dev at hotmail.de>
Date: Wed, 23 Sep 2026 22:09:58 +0200
Subject: [PATCH 1/2] [clang-tidy] Don't suggest const on `std::moved` locals
 in templates (#225395)

Skip diagnostics in template instantiations for locals that are used
as arguments of std::move. Reason: for some instantiations the move
may be converted to copy so the variable may look unmutated and flagged,
whereas for other template instantiations the real move semantics may
apply.

Fixes: #225395
---
 .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 30 +++++++++++++++++--
 clang-tools-extra/docs/ReleaseNotes.md        | 11 +++++--
 .../misc/const-correctness-templates.cpp      | 20 +++++++++++++
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
index 90919555d447e8..4532a27962af29 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
@@ -199,6 +199,25 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
   }
 }
 
+static bool isStdMoveOperandInTemplate(const VarDecl *Variable,
+                                       const FunctionDecl *Func,
+                                       ASTContext &Context) {
+  if (Func->isTemplateInstantiation())
+    if (const Stmt *Body = Func->getBody()) {
+      // Match on the instantiated body where `std::move` is resolved to a
+      // concrete function and the argument references the instantiated
+      // variable.
+      const auto Moves =
+          match(stmt(forEachDescendant(
+                    callExpr(callee(functionDecl(hasName("std::move"))),
+                             hasArgument(0, ignoringParenImpCasts(declRefExpr(
+                                                to(equalsNode(Variable)))))))),
+                *Body, Context);
+      return !Moves.empty();
+    }
+  return false;
+}
+
 static void addConstFixits(const DiagnosticBuilder &Diag,
                            const VarDecl *Variable,
                            const FunctionDecl *Function,
@@ -255,9 +274,6 @@ void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
   /// dependent. Variables like 'int x = 42;' in a template that can become
   /// const emit multiple warnings otherwise.
   bool IsNormalVariableInTemplate = Function->isTemplateInstantiation();
-  if (IsNormalVariableInTemplate &&
-      TemplateDiagnosticsCache.contains(Variable->getBeginLoc()))
-    return;
 
   VariableCategory VC = VariableCategory::Value;
   const QualType VT = Variable->getType();
@@ -269,6 +285,14 @@ void ConstCorrectnessCheck::check(const MatchFinder::MatchResult &Result) {
            ArrayT && ArrayT->getElementType()->isPointerType())
     VC = VariableCategory::Pointer;
 
+  if (IsNormalVariableInTemplate && VC != VariableCategory::Pointer &&
+      isStdMoveOperandInTemplate(Variable, Function, *Result.Context))
+    return;
+
+  if (IsNormalVariableInTemplate &&
+      TemplateDiagnosticsCache.contains(Variable->getBeginLoc()))
+    return;
+
   const auto CheckValue = [&]() {
     // Offload const-analysis to utility function.
     if (isMutated(Variable, LocalScope, Function, Result.Context))
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 57ed93042aff2c..11812c2089ab3a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -10,8 +10,8 @@ myst:
 % ReleaseNotes.md and ReleaseNotesTemplate.txt.
 
 {#extra-clang-tools-release-releasenotestitle}
-# Extra Clang Tools {{env.config.release}} {{ (('(In-Progress) ' if env.app.tags.has('PreRelease') else '') ~ 'Release Notes') }}
 
+# Extra Clang Tools {{env.config.release}} {{ (('(In-Progress) ' if env.app.tags.has('PreRelease') else '') ~ 'Release Notes') }}
 
 Written by the [LLVM Team](https://llvm.org/)
 
@@ -42,6 +42,7 @@ the current one. To see the release notes for a specific release, please
 see the [releases page](https://llvm.org/releases/).
 
 {#what-s-new-in-extra-clang-tools-release}
+
 ## What's New in Extra Clang Tools {{env.config.release}}?
 
 Some of the major new features and improvements to Extra Clang Tools are listed
@@ -261,10 +262,14 @@ infrastructure are described first, followed by tool-specific sections.
 
   - No longer diagnoses variables declared with `decltype(auto)`, where the
     suggested `const` does not compile.
-    
+
   - No longer diagnoses parameters of `main`, whose signature is fixed by the
     standard.
 
+  - No longer diagnoses variables used as operands of `std::move` in template
+    instantiations, where the suggested `const` would break the move for
+    instantiations with real move semantics.
+
 - Fixed an infinite loop in {doc}`misc-multiple-inheritance
   <clang-tidy/checks/misc/multiple-inheritance>` when checking a class that
   inherits from itself or has a circular inheritance graph.
@@ -429,7 +434,7 @@ infrastructure are described first, followed by tool-specific sections.
   - Ignored preprocessor directives such as `#endif` that appear immediately
     before an enum's closing brace, which previously produced a false positive
     and a fix-it that inserted a comma after the directive.
-    
+
   - Fixed a false positive on empty brace initializers of types with default
     member initializers.
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
index 98bf27033c3b5f..624159210698c5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
@@ -6,6 +6,9 @@
 // RUN:   misc-const-correctness.TransformPointersAsValues: false} \
 // RUN:   }" -- -fno-delayed-template-parsing
 
+#include <string>
+#include <utility>
+
 template <typename T>
 void type_dependent_variables() {
   T value = 42;
@@ -27,6 +30,23 @@ void instantiate_template_cases() {
   type_dependent_variables<float>();
 }
 
+namespace gh225395 {
+
+template <typename T> void my_swap(T &t1, T &t2) {
+  auto tmp = std::move(t1);
+  t1 = std::move(t2);
+  t2 = std::move(tmp);
+}
+void instantiate() {
+  std::string a;
+  std::string b;
+  my_swap(a, b);
+  int x = 0;
+  int y = 0;
+  my_swap(x, y);
+}
+} // namespace gh225395
+
 namespace gh57297{
 // The expression to check may not be the dependent operand in a dependent
 // operator.

>From 593c8dd2cbddb3f0dc7567cd66514daa838a07b1 Mon Sep 17 00:00:00 2001
From: Zeyi Xu <zeyi2 at nekoarch.cc>
Date: Sat, 24 Oct 2026 23:06:35 +0800
Subject: [PATCH 2/2] Apply batched suggestions from code review

Co-authored-by: Zeyi Xu <zeyi2 at nekoarch.cc>
---
 clang-tools-extra/docs/ReleaseNotes.md | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 11812c2089ab3a..903c636b978c42 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -10,7 +10,6 @@ myst:
 % ReleaseNotes.md and ReleaseNotesTemplate.txt.
 
 {#extra-clang-tools-release-releasenotestitle}
-
 # Extra Clang Tools {{env.config.release}} {{ (('(In-Progress) ' if env.app.tags.has('PreRelease') else '') ~ 'Release Notes') }}
 
 Written by the [LLVM Team](https://llvm.org/)
@@ -42,7 +41,6 @@ the current one. To see the release notes for a specific release, please
 see the [releases page](https://llvm.org/releases/).
 
 {#what-s-new-in-extra-clang-tools-release}
-
 ## What's New in Extra Clang Tools {{env.config.release}}?
 
 Some of the major new features and improvements to Extra Clang Tools are listed



More information about the cfe-commits mailing list