diff --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp @@ -174,6 +174,10 @@ const auto *Function = Result.Nodes.getNodeAs("function"); if (!Function->hasWrittenPrototype() || Function->isTemplateInstantiation()) return; + if (Function->hasAttrs()) + for (const clang::Attr *A : Function->getAttrs()) + if (A->getParsedKind() == Attr::AT_Naked) + return; if (const auto *Method = dyn_cast(Function)) if (Method->isLambdaStaticInvoker()) return; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14632,8 +14632,17 @@ 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()) + bool FDHasNakedAttr{false}; + if (FD->hasAttrs()) + for (const clang::Attr *A : FD->getAttrs()) + if (A->getParsedKind() == Attr::AT_Naked) { + FDHasNakedAttr = true; + break; + } + // Don't diagnose unused parameters of defaulted, deleted or naked + // functions. + if (!FD->isDeleted() && !FD->isDefaulted() && !FD->hasSkippedBody() && + !FDHasNakedAttr) DiagnoseUnusedParameters(FD->parameters()); DiagnoseSizeOfParametersAndReturnValue(FD->parameters(), FD->getReturnType(), FD);