brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · 3e1188d Raw
72 lines · cpp
1//===----------------------------------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "BadSignalToKillThreadCheck.h"10#include "clang/AST/ASTContext.h"11#include "clang/ASTMatchers/ASTMatchFinder.h"12#include "clang/Lex/Preprocessor.h"13#include <optional>14 15using namespace clang::ast_matchers;16 17namespace clang::tidy::bugprone {18 19void BadSignalToKillThreadCheck::registerMatchers(MatchFinder *Finder) {20  Finder->addMatcher(21      callExpr(callee(functionDecl(hasName("::pthread_kill"))),22               argumentCountIs(2),23               hasArgument(1, integerLiteral().bind("integer-literal")))24          .bind("thread-kill"),25      this);26}27 28static Preprocessor *PP;29 30void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) {31  const auto IsSigterm = [](const auto &KeyValue) -> bool {32    return KeyValue.first->getName() == "SIGTERM" &&33           KeyValue.first->hasMacroDefinition();34  };35  const auto TryExpandAsInteger =36      [](Preprocessor::macro_iterator It) -> std::optional<unsigned> {37    if (It == PP->macro_end())38      return std::nullopt;39    const MacroInfo *MI = PP->getMacroInfo(It->first);40    const Token &T = MI->tokens().back();41    if (!T.isLiteral() || !T.getLiteralData())42      return std::nullopt;43    const StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength());44 45    llvm::APInt IntValue;46    constexpr unsigned AutoSenseRadix = 0;47    if (ValueStr.getAsInteger(AutoSenseRadix, IntValue))48      return std::nullopt;49    return IntValue.getZExtValue();50  };51 52  const auto SigtermMacro = llvm::find_if(PP->macros(), IsSigterm);53 54  if (!SigtermValue && !(SigtermValue = TryExpandAsInteger(SigtermMacro)))55    return;56 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");63  }64}65 66void BadSignalToKillThreadCheck::registerPPCallbacks(67    const SourceManager &SM, Preprocessor *Pp, Preprocessor *ModuleExpanderPP) {68  PP = Pp;69}70 71} // namespace clang::tidy::bugprone72