1 //===--- BadSignalToKillThreadCheck.cpp - clang-tidy ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "BadSignalToKillThreadCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/Lex/Preprocessor.h"
15 using namespace clang::ast_matchers
;
17 namespace clang::tidy::bugprone
{
19 void BadSignalToKillThreadCheck::registerMatchers(MatchFinder
*Finder
) {
21 callExpr(callee(functionDecl(hasName("::pthread_kill"))),
23 hasArgument(1, integerLiteral().bind("integer-literal")))
28 static Preprocessor
*PP
;
30 void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult
&Result
) {
31 const auto IsSigterm
= [](const auto &KeyValue
) -> bool {
32 return KeyValue
.first
->getName() == "SIGTERM" &&
33 KeyValue
.first
->hasMacroDefinition();
35 const auto TryExpandAsInteger
=
36 [](Preprocessor::macro_iterator It
) -> std::optional
<unsigned> {
37 if (It
== PP
->macro_end())
39 const MacroInfo
*MI
= PP
->getMacroInfo(It
->first
);
40 const Token
&T
= MI
->tokens().back();
41 if (!T
.isLiteral() || !T
.getLiteralData())
43 StringRef ValueStr
= StringRef(T
.getLiteralData(), T
.getLength());
46 constexpr unsigned AutoSenseRadix
= 0;
47 if (ValueStr
.getAsInteger(AutoSenseRadix
, IntValue
))
49 return IntValue
.getZExtValue();
52 const auto SigtermMacro
= llvm::find_if(PP
->macros(), IsSigterm
);
54 if (!SigtermValue
&& !(SigtermValue
= TryExpandAsInteger(SigtermMacro
)))
57 const auto *MatchedExpr
= Result
.Nodes
.getNodeAs
<Expr
>("thread-kill");
58 const auto *MatchedIntLiteral
=
59 Result
.Nodes
.getNodeAs
<IntegerLiteral
>("integer-literal");
60 if (MatchedIntLiteral
->getValue() == *SigtermValue
) {
61 diag(MatchedExpr
->getBeginLoc(),
62 "thread should not be terminated by raising the 'SIGTERM' signal");
66 void BadSignalToKillThreadCheck::registerPPCallbacks(
67 const SourceManager
&SM
, Preprocessor
*Pp
, Preprocessor
*ModuleExpanderPP
) {
71 } // namespace clang::tidy::bugprone