[PATCH] D116593: Fix `performance-unnecessary-value-param` for template specialization
gehry via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 4 04:29:46 PST 2022
Sockke created this revision.
Sockke added reviewers: aaron.ballman, flx, njames93.
Herald added a subscriber: carlosgalvezp.
Sockke requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.
The checker missed a check for parameter type of primary template of specialization template and this could cause build breakages.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D116593
Files:
clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-value-param.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-value-param.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-value-param.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/performance-unnecessary-value-param.cpp
@@ -381,3 +381,24 @@
// CHECK-FIXES: void templateFunction<ExpensiveToCopyType>(ExpensiveToCopyType E) {
E.constReference();
}
+
+template <class T>
+T templateSpecializationFunction(ExpensiveToCopyType E) {
+ // CHECK-MESSAGES: [[@LINE-1]]:54: warning: the parameter 'E' is copied
+ // CHECK-FIXES: T templateSpecializationFunction(const ExpensiveToCopyType& E) {
+ return T();
+}
+
+template <>
+bool templateSpecializationFunction(ExpensiveToCopyType E) {
+ // CHECK-MESSAGES: [[@LINE-1]]:57: warning: the parameter 'E' is copied
+ // CHECK-FIXES: bool templateSpecializationFunction(const ExpensiveToCopyType& E) {
+ return true;
+}
+
+template <>
+int templateSpecializationFunction(ExpensiveToCopyType E) {
+ // CHECK-MESSAGES: [[@LINE-1]]:56: warning: the parameter 'E' is copied
+ // CHECK-FIXES: int templateSpecializationFunction(const ExpensiveToCopyType& E) {
+ return 0;
+}
Index: clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
+++ clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
@@ -51,6 +51,21 @@
return Matches.empty();
}
+bool isTemplateTypeParmOfPrimaryTemplate(const FunctionDecl &Function,
+ int Index) {
+ // Check the specific parameter type of primary template whether is template
+ // type.
+ if (const auto *PrimaryTemplateInfo = Function.getPrimaryTemplate()) {
+ if (const auto *PrimaryTemplateFunction =
+ PrimaryTemplateInfo->getTemplatedDecl()) {
+ const auto *ParamInfo = PrimaryTemplateFunction->getParamDecl(Index);
+ if (ParamInfo && ParamInfo->getOriginalType()->isTemplateTypeParmType())
+ return true;
+ }
+ }
+ return false;
+}
+
bool isExplicitTemplateSpecialization(const FunctionDecl &Function) {
if (const auto *SpecializationInfo = Function.getTemplateSpecializationInfo())
if (SpecializationInfo->getTemplateSpecializationKind() ==
@@ -146,15 +161,21 @@
// 2. the function is virtual as it might break overrides
// 3. the function is referenced outside of a call expression within the
// compilation unit as the signature change could introduce build errors.
- // 4. the function is an explicit template specialization.
+ // 4. the function is an explicit template specialization and the specific
+ // parameter of primary template is template type.
const auto *Method = llvm::dyn_cast<CXXMethodDecl>(Function);
+ bool IsExplicitTemplateSpecialization =
+ isExplicitTemplateSpecialization(*Function);
if (Param->getBeginLoc().isMacroID() || (Method && Method->isVirtual()) ||
isReferencedOutsideOfCallExpr(*Function, *Result.Context) ||
- isExplicitTemplateSpecialization(*Function))
+ (IsExplicitTemplateSpecialization &&
+ isTemplateTypeParmOfPrimaryTemplate(*Function, Index)))
return;
for (const auto *FunctionDecl = Function; FunctionDecl != nullptr;
FunctionDecl = FunctionDecl->getPreviousDecl()) {
const auto &CurrentParam = *FunctionDecl->getParamDecl(Index);
+ if (IsExplicitTemplateSpecialization && Function != FunctionDecl)
+ continue;
Diag << utils::fixit::changeVarDeclToReference(CurrentParam,
*Result.Context);
// The parameter of each declaration needs to be checked individually as to
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D116593.397259.patch
Type: text/x-patch
Size: 3827 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220104/5ad5729f/attachment-0001.bin>
More information about the cfe-commits
mailing list