9 #include "../utils/Matchers.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/Lexer.h"
22 AST_MATCHER(BinaryOperator, isRHSATempFailureRetryArg) {
23 if (!Node.getBeginLoc().isMacroID())
26 const SourceManager &SM = Finder->getASTContext().getSourceManager();
27 if (!SM.isMacroArgExpansion(Node.getRHS()->IgnoreParenCasts()->getBeginLoc()))
30 const LangOptions &Opts = Finder->getASTContext().getLangOpts();
31 SourceLocation LocStart = Node.getBeginLoc();
32 while (LocStart.isMacroID()) {
33 SourceLocation Invocation = SM.getImmediateMacroCallerLoc(LocStart);
35 if (!Lexer::getRawToken(SM.getSpellingLoc(Invocation), Tok, SM, Opts,
37 if (Tok.getKind() == tok::raw_identifier &&
38 Tok.getRawIdentifier() ==
"TEMP_FAILURE_RETRY")
42 LocStart = Invocation;
48 void ComparisonInTempFailureRetryCheck::registerMatchers(MatchFinder *Finder) {
64 binaryOperator(hasOperatorName(
"="),
65 hasRHS(ignoringParenCasts(
66 binaryOperator(isComparisonOperator()).bind(
"binop"))),
67 isRHSATempFailureRetryArg()),
71 void ComparisonInTempFailureRetryCheck::check(
72 const MatchFinder::MatchResult &Result) {
73 const auto &BinOp = *Result.Nodes.getNodeAs<BinaryOperator>(
"binop");
74 diag(BinOp.getOperatorLoc(),
"top-level comparison in TEMP_FAILURE_RETRY");