Skip to content

Commit 1b897f7

Browse files
authored
[clang-tidy] Fix misc-unused-parameters on params with attrs (#122286)
Don't suggest to comment-out the parameter name if the parameter has an attribute that's spelled after the parameter name. This prevents the parameter's attributes from being wrongly applied to the parameter's type. This fixes #122191.
1 parent 876841b commit 1b897f7

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
#include "UnusedParametersCheck.h"
1010
#include "clang/AST/ASTContext.h"
1111
#include "clang/AST/ASTLambda.h"
12+
#include "clang/AST/Attr.h"
13+
#include "clang/AST/Decl.h"
1214
#include "clang/AST/RecursiveASTVisitor.h"
1315
#include "clang/ASTMatchers/ASTMatchFinder.h"
16+
#include "clang/Basic/SourceManager.h"
1417
#include "clang/Lex/Lexer.h"
1518
#include "llvm/ADT/STLExtras.h"
1619
#include <unordered_map>
@@ -26,6 +29,17 @@ bool isOverrideMethod(const FunctionDecl *Function) {
2629
return MD->size_overridden_methods() > 0 || MD->hasAttr<OverrideAttr>();
2730
return false;
2831
}
32+
33+
bool hasAttrAfterParam(const SourceManager *SourceManager,
34+
const ParmVarDecl *Param) {
35+
for (const auto *Attr : Param->attrs()) {
36+
if (SourceManager->isBeforeInTranslationUnit(Param->getLocation(),
37+
Attr->getLocation())) {
38+
return true;
39+
}
40+
}
41+
return false;
42+
}
2943
} // namespace
3044

3145
void UnusedParametersCheck::registerMatchers(MatchFinder *Finder) {
@@ -189,6 +203,11 @@ void UnusedParametersCheck::check(const MatchFinder::MatchResult &Result) {
189203
if (Param->isUsed() || Param->isReferenced() || !Param->getDeclName() ||
190204
Param->hasAttr<UnusedAttr>())
191205
continue;
206+
if (hasAttrAfterParam(Result.SourceManager, Param)) {
207+
// Due to how grammar works, attributes would be wrongly applied to the
208+
// type if we remove the preceding parameter name.
209+
continue;
210+
}
192211

193212
// In non-strict mode ignore function definitions with empty bodies
194213
// (constructor initializer counts for non-empty body).

clang-tools-extra/test/clang-tidy/checkers/misc/unused-parameters.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ void f(void (*fn)()) {;}
3333
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: parameter 'fn' is unused [misc-unused-parameters]
3434
// CHECK-FIXES: {{^}}void f(void (* /*fn*/)()) {;}{{$}}
3535

36+
int *k([[clang::lifetimebound]] int *i) {;}
37+
// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: parameter 'i' is unused [misc-unused-parameters]
38+
// CHECK-FIXES: {{^}}int *k({{\[\[clang::lifetimebound\]\]}} int * /*i*/) {;}{{$}}
39+
40+
#define ATTR_BEFORE(x) [[clang::lifetimebound]] x
41+
int* m(ATTR_BEFORE(const int *i)) { return nullptr; }
42+
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: parameter 'i' is unused [misc-unused-parameters]
43+
// CHECK-FIXES: {{^}}int* m(ATTR_BEFORE(const int * /*i*/)) { return nullptr; }{{$}}
44+
#undef ATTR_BEFORE
45+
3646
// Unchanged cases
3747
// ===============
3848
void f(int i); // Don't remove stuff in declarations
@@ -42,6 +52,12 @@ void s(int i[1]);
4252
void u(void (*fn)());
4353
void w(int i) { (void)i; } // Don't remove used parameters
4454

55+
// Don't reanchor the attribute to the type:
56+
int *x(int *i [[clang::lifetimebound]]) { return nullptr; }
57+
#define ATTR_AFTER(x) x [[clang::lifetimebound]]
58+
int* y(ATTR_AFTER(const int *i)) { return nullptr; }
59+
#undef ATTR_AFTER
60+
4561
bool useLambda(int (*fn)(int));
4662
static bool static_var = useLambda([] (int a) { return a; });
4763

0 commit comments

Comments
 (0)