10#include "../utils/Matchers.h"
11#include "clang/AST/ASTContext.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/Lex/Lexer.h"
20 const char *BindingStr) {
21 const CallExpr *MatchedCall = cast<CallExpr>(
22 (Result.Nodes.getNodeAs<BinaryOperator>(BindingStr))->getLHS());
23 const SourceManager &SM = *Result.SourceManager;
24 return Lexer::getSourceText(CharSourceRange::getTokenRange(
25 MatchedCall->getCallee()->getSourceRange()),
26 SM, Result.Context->getLangOpts());
33 hasLHS(callExpr(callee(functionDecl(
34 anyOf(matchesName(
"^::posix_"), matchesName(
"^::pthread_")),
35 unless(hasName(
"::posix_openpt")))))),
36 hasRHS(integerLiteral(equals(0))))
41 hasOperatorName(
">="),
42 hasLHS(callExpr(callee(functionDecl(
43 anyOf(matchesName(
"^::posix_"), matchesName(
"^::pthread_")),
44 unless(hasName(
"::posix_openpt")))))),
45 hasRHS(integerLiteral(equals(0))))
50 hasAnyOperatorName(
"==",
"!=",
"<=",
"<"),
51 hasLHS(callExpr(callee(functionDecl(
52 anyOf(matchesName(
"^::posix_"), matchesName(
"^::pthread_")),
53 unless(hasName(
"::posix_openpt")))))),
54 hasRHS(unaryOperator(hasOperatorName(
"-"),
55 hasUnaryOperand(integerLiteral()))))
61 if (
const auto *LessThanZeroOp =
62 Result.Nodes.getNodeAs<BinaryOperator>(
"ltzop")) {
63 SourceLocation OperatorLoc = LessThanZeroOp->getOperatorLoc();
64 diag(OperatorLoc,
"the comparison always evaluates to false because %0 "
65 "always returns non-negative values")
67 << FixItHint::CreateReplacement(OperatorLoc, Twine(
">").str());
70 if (
const auto *AlwaysTrueOp =
71 Result.Nodes.getNodeAs<BinaryOperator>(
"atop")) {
72 diag(AlwaysTrueOp->getOperatorLoc(),
73 "the comparison always evaluates to true because %0 always returns "
74 "non-negative values")
78 const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>(
"binop");
79 diag(BinOp->getOperatorLoc(),
"%0 only returns non-negative values")
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result, const char *BindingStr)