From b46ca217bb7057b32cbfcbab071f4db34c5a90fc Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 19 Oct 2025 00:42:41 +0300 Subject: [PATCH 1/2] [clang-tidy] Fix param-pack fix-its for 'performance-unnecessary-value-param' check --- .../clang-tidy/utils/FixItHintUtils.cpp | 5 ++++ clang-tools-extra/docs/ReleaseNotes.rst | 3 ++- .../unnecessary-value-param-templates.cpp | 24 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp index 086c7f3a15d45..b30c83e3aeb35 100644 --- a/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp @@ -21,6 +21,11 @@ FixItHint changeVarDeclToReference(const VarDecl &Var, ASTContext &Context) { SourceLocation AmpLocation = Var.getLocation(); auto Token = utils::lexer::getPreviousToken( AmpLocation, Context.getSourceManager(), Context.getLangOpts()); + + // For parameter packs the '&' must go before the '...' token + if (Token.is(tok::ellipsis)) + return FixItHint::CreateInsertion(Token.getLocation(), "&"); + if (!Token.is(tok::unknown)) AmpLocation = Lexer::getLocForEndOfToken(Token.getLocation(), 0, Context.getSourceManager(), diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a94dd9737468c..2a4511b1c92d5 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -384,7 +384,8 @@ Changes in existing checks - Improved :doc:`performance-unnecessary-value-param ` by printing - the type of the diagnosed variable. + the type of the diagnosed variable and correctly generating fix-it hints for + parameter-pack arguments. - Improved :doc:`portability-template-virtual-member-function ` check to diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp index 688c79bbaa9ac..43a7df4da75fd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp @@ -96,3 +96,27 @@ void lambdaNonConstAutoValue() { }; fn(ExpensiveToCopyType()); } + +template +void ParameterPack(Args... args) { + // CHECK-MESSAGES: [[@LINE-1]]:28: warning: the parameter 'args' of type 'ExpensiveToCopyType' + // CHECK-FIXES: void ParameterPack(const Args&... args) { +} + +template +void ParameterPackWithParams(const ExpensiveToCopyType E1, ExpensiveToCopyType E2, Args... args) { + // CHECK-MESSAGES: [[@LINE-1]]:56: warning: the const qualified parameter 'E1' + // CHECK-MESSAGES: [[@LINE-2]]:80: warning: the parameter 'E2' + // CHECK-MESSAGES: [[@LINE-3]]:92: warning: the parameter 'args' + // CHECK-FIXES: void ParameterPackWithParams(const ExpensiveToCopyType& E1, const ExpensiveToCopyType& E2, const Args&... args) { +} + +template +void PackWithNonExpensive(int x, Args... args) {} + +void instantiatedParameterPack() { + ExpensiveToCopyType E; + ParameterPack(E); + ParameterPackWithParams(E, E, E); + PackWithNonExpensive(5, 5); +} From 165bce49e9a84b6e4bc29f4bb19a21755b9e7d91 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 19 Oct 2025 00:53:49 +0300 Subject: [PATCH 2/2] add test with different const placement --- .../performance/unnecessary-value-param-templates.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp index 43a7df4da75fd..61758c5dac071 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-templates.cpp @@ -103,6 +103,12 @@ void ParameterPack(Args... args) { // CHECK-FIXES: void ParameterPack(const Args&... args) { } +template +void ParameterPackConst(Args const... args) { + // CHECK-MESSAGES: [[@LINE-1]]:39: warning: the const qualified parameter 'args' of type 'const ExpensiveToCopyType' + // CHECK-FIXES: void ParameterPackConst(Args const&... args) { +} + template void ParameterPackWithParams(const ExpensiveToCopyType E1, ExpensiveToCopyType E2, Args... args) { // CHECK-MESSAGES: [[@LINE-1]]:56: warning: the const qualified parameter 'E1' @@ -117,6 +123,7 @@ void PackWithNonExpensive(int x, Args... args) {} void instantiatedParameterPack() { ExpensiveToCopyType E; ParameterPack(E); + ParameterPackConst(E); ParameterPackWithParams(E, E, E); PackWithNonExpensive(5, 5); }