Don't trigger unused-parameter warnings on naked functions

This commit checks if a function is marked with the naked attribute
and, if it is, will silence the emission of any unused-parameter
warning.

Inside a naked function only the usage of basic ASM instructions is
expected. In this context the parameters can actually be used by
fetching them according to the underlying ABI. Since parameters might
be used through ASM instructions, the linter and the compiler will have
a hard time understanding if one of those is unused or not, therefore
no unused-parameter warning should ever be triggered whenever a
function is marked naked.
This commit is contained in:
MuAlphaOmegaEpsilon 2022-01-27 11:39:05 -05:00 committed by Aaron Ballman
parent 8f972cb0fd
commit ccce1a03c9
7 changed files with 28 additions and 8 deletions

View File

@ -31,10 +31,11 @@ bool isOverrideMethod(const FunctionDecl *Function) {
} // namespace
void UnusedParametersCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
functionDecl(isDefinition(), hasBody(stmt()), hasAnyParameter(decl()))
.bind("function"),
this);
Finder->addMatcher(functionDecl(isDefinition(), hasBody(stmt()),
hasAnyParameter(decl()),
unless(hasAttr(attr::Kind::Naked)))
.bind("function"),
this);
}
template <typename T>

View File

@ -22,4 +22,8 @@ public:
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
// CHECK-FIXES: {{^}} F(int /*j*/) : i() {}{{$}}
};
// Do not warn on naked functions.
[[gnu::naked]] int nakedFunction(int a, float b, const char *c) { ; }
__attribute__((naked)) void nakedFunction(int a, int b) { ; }
}

View File

@ -15,3 +15,5 @@ static void b(int i) {;}
// ===============
void h(i, c, d) int i; char *c, *d; {} // Don't mess with K&R style
// Do not warn on naked functions.
__attribute__((naked)) void nakedFunction(int a, int b) { ; }

View File

@ -286,3 +286,7 @@ void test() {
f([](int I) { return; });
}
} // namespace lambda
// Do not warn on naked functions.
[[gnu::naked]] int nakedFunction(int a, float b, const char *c) { ; }
__attribute__((naked)) void nakedFunction(int a, int b) { ; }

View File

@ -14694,8 +14694,10 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
Diag(FD->getLocation(), diag::ext_pure_function_definition);
if (!FD->isInvalidDecl()) {
// Don't diagnose unused parameters of defaulted or deleted functions.
if (!FD->isDeleted() && !FD->isDefaulted() && !FD->hasSkippedBody())
// Don't diagnose unused parameters of defaulted, deleted or naked
// functions.
if (!FD->isDeleted() && !FD->isDefaulted() && !FD->hasSkippedBody() &&
!FD->hasAttr<NakedAttr>())
DiagnoseUnusedParameters(FD->parameters());
DiagnoseSizeOfParametersAndReturnValue(FD->parameters(),
FD->getReturnType(), FD);

View File

@ -17,14 +17,17 @@ void f1(void) {
// warnings for the above cases.
static void achor() {};
// Do not warn on naked functions.
__attribute__((naked)) static void nakedFunction(int a, int b) { }
// CHECK: 5:12: warning: unused parameter 'y'
// CHECK: 12:15: warning: unused parameter 'y'
// CHECK-unused: 1 warning generated
// CHECK-unused: 2 warnings generated
// RUN: %clang_cc1 -fblocks -fsyntax-only -Weverything %s 2>&1 | FileCheck -check-prefix=CHECK-everything %s
// RUN: not %clang_cc1 -fblocks -fsyntax-only -Weverything -Werror %s 2>&1 | FileCheck -check-prefix=CHECK-everything-error %s
// RUN: %clang_cc1 -fblocks -fsyntax-only -Weverything -Wno-unused %s 2>&1 | FileCheck -check-prefix=CHECK-everything-no-unused %s
// CHECK-everything: 6 warnings generated
// CHECK-everything: 7 warnings generated
// CHECK-everything-error: 5 errors generated
// CHECK-everything-no-unused: 5 warnings generated

View File

@ -32,3 +32,7 @@ static int test_pack(T... t, T... s)
auto l = [&t...]() { return sizeof...(s); };
return l();
}
// Do not warn on naked functions.
[[gnu::naked]] int nakedFunction(int a, float b, const char* c) { ; }
__attribute__((naked)) void nakedFunction(int a, int b) { ; }