From 9dc65372aa6101bd72be80ca0901cb8dd780d01f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= Date: Wed, 4 Mar 2026 19:02:26 +0100 Subject: [PATCH] [clang-tidy] Don't report unnamed params for misc-const-correctness (#184388) Previously misc-const-correctness warned about non-const unnamed parameters; but this commit excludes them because these warnings are not actually useful. An unnamed parameter cannot be referenced at all, so marking them as 'const' doesn't add additional information. Also the diagnostic messages look awkward without a name. Fixes #184330 --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 8 ++++- .../checks/misc/const-correctness.rst | 6 ++-- .../misc/const-correctness-parameters.cpp | 31 +++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 7e388201bf79..f07b49444f3e 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -23,6 +23,12 @@ namespace { // FIXME: This matcher exists in some other code-review as well. // It should probably move to ASTMatchers. AST_MATCHER(VarDecl, isLocal) { return Node.isLocalVarDecl(); } +// FIXME: The matcher 'hasName(Name)' asserts that its argument 'Name' is +// nonempty. Perhaps remove that assertion and replace 'isUnnamed()' with +// 'hasName("")'. +AST_MATCHER(VarDecl, isUnnamed) { + return Node.getDeclName().isIdentifier() && Node.getName().empty(); +} AST_MATCHER_P(DeclStmt, containsAnyDeclaration, ast_matchers::internal::Matcher, InnerMatcher) { return ast_matchers::internal::matchesFirstInPointerRange( @@ -148,7 +154,7 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { if (AnalyzeParameters) { const auto ParamMatcher = - parmVarDecl(unless(CommonExcludeTypes), + parmVarDecl(unless(CommonExcludeTypes), unless(isUnnamed()), anyOf(hasType(referenceType()), hasType(pointerType()))) .bind("value"); diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst index 0365df2aa450..7a0c73e09949 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst @@ -110,15 +110,15 @@ Options Enable or disable the analysis of function parameters, like ``void foo(int* ptr)``. Only reference and pointer parameters are analyzed. - Currently, member functions (including constructors) and lambdas are excluded - from the analysis. Default is `true`. + Unnamed parameters, member functions (including constructors) and lambdas are + excluded from the analysis. Default is `true`. .. code-block:: c++ // Warning void function(int& param) {} // No warning - void function(const int& param) {} + void function(const int& param, int&) {} .. option:: WarnPointersAsValues diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp index 96d54b844170..8ff099eadb5a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp @@ -509,3 +509,34 @@ void struct_ptr_param_modified(Bar** bp) { // CHECK-FIXES: void struct_ptr_param_modified(Bar** const bp) { (*bp)->mutating_method(); } + +void unnamed_parameters(int&, char*, Bar, Bar&, int[5]) { + // Unnamed parameters are never reported. +} + +void unnamed_and_named_irrelevant_params(const int& X, char*, Bar Z, Bar&, int[5]) { + // No report, all parameters are excluded for various reasons. +} + +void unnamed_and_named_params(int& X, int&) { + // But a named parameter is reported even if it is next to an unnamed one. + // CHECK-MESSAGES: [[@LINE-2]]:31: warning: variable 'X' of type 'int &' can be declared 'const' + // CHECK-FIXES: void unnamed_and_named_params(int const& X, int&) { +} + +// If the parameter is named in the definition, its type will be updated in all +// declarations, inclunding ones where it is unnamed. +void unnamed_in_decl_named_in_def(int&); +// CHECK-FIXES: void unnamed_in_decl_named_in_def(int const&); + +void unnamed_in_decl_named_in_def(int& X) { + // CHECK-MESSAGES: [[@LINE-1]]:35: warning: variable 'X' of type 'int &' can be declared 'const' + // CHECK-FIXES: void unnamed_in_decl_named_in_def(int const& X) { +} + +void named_in_decl_unnamed_in_def(int& X); + +void named_in_decl_unnamed_in_def(int&) { + // If the parameter is unnamed in the definition, it will not be reported, even + // if it is named in some declaration. +}