[clang-tools-extra] 127d4f0 - [clang-tidy] Don't suggest const on `std::moved` locals in templates … (#226577)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 24 08:31:54 PDT 2026
Author: Daniel Petrovic
Date: 2026-10-24T15:31:48Z
New Revision: 127d4f032302e315e03b78f40a535fcad13f7a55
URL: https://github.com/llvm/llvm-project/commit/127d4f032302e315e03b78f40a535fcad13f7a55
DIFF: https://github.com/llvm/llvm-project/commit/127d4f032302e315e03b78f40a535fcad13f7a55.diff
LOG: [clang-tidy] Don't suggest const on `std::moved` locals in templates … (#226577)
[clang-tidy] Don't suggest const on std::moved locals in templates
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
Assisted by Gemini for constructing the matcher.
---------
Co-authored-by: Zeyi Xu <zeyi2 at nekoarch.cc>
Added:
Modified:
clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
clang-tools-extra/docs/ReleaseNotes.md
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp
Removed:
################################################################################
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..037df4cd0937c4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -261,10 +261,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 +433,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.
More information about the cfe-commits
mailing list