clang-tools 10.0.0

PosixReturnCheck.cpp
Go to the documentation of this file.
1 //===--- PosixReturnCheck.cpp - clang-tidy---------------------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "PosixReturnCheck.h"
10 #include "../utils/Matchers.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13
14 using namespace clang::ast_matchers;
15
16 namespace clang {
17 namespace tidy {
18 namespace bugprone {
19
20 static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result,
21 const char *BindingStr) {
22 const CallExpr *MatchedCall = cast<CallExpr>(
23 (Result.Nodes.getNodeAs<BinaryOperator>(BindingStr))->getLHS());
24 const SourceManager &SM = *Result.SourceManager;
25 return Lexer::getSourceText(CharSourceRange::getTokenRange(
26 MatchedCall->getCallee()->getSourceRange()),
27 SM, Result.Context->getLangOpts());
28 }
29
30 void PosixReturnCheck::registerMatchers(MatchFinder *Finder) {
31 Finder->addMatcher(
32 binaryOperator(
33 hasOperatorName("<"),
34 hasLHS(callExpr(callee(functionDecl(
35 anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
36 unless(hasName("::posix_openpt")))))),
37 hasRHS(integerLiteral(equals(0))))
38 .bind("ltzop"),
39 this);
40 Finder->addMatcher(
41 binaryOperator(
42 hasOperatorName(">="),
43 hasLHS(callExpr(callee(functionDecl(
44 anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
45 unless(hasName("::posix_openpt")))))),
46 hasRHS(integerLiteral(equals(0))))
47 .bind("atop"),
48 this);
49 Finder->addMatcher(
50 binaryOperator(
51 anyOf(hasOperatorName("=="), hasOperatorName("!="),
52 hasOperatorName("<="), hasOperatorName("<")),
53 hasLHS(callExpr(callee(functionDecl(
54 anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
55 unless(hasName("::posix_openpt")))))),
56 hasRHS(unaryOperator(hasOperatorName("-"),
57 hasUnaryOperand(integerLiteral()))))
58 .bind("binop"),
59 this);
60 }
61
62 void PosixReturnCheck::check(const MatchFinder::MatchResult &Result) {
63 if (const auto *LessThanZeroOp =
64 Result.Nodes.getNodeAs<BinaryOperator>("ltzop")) {
65 SourceLocation OperatorLoc = LessThanZeroOp->getOperatorLoc();
66 diag(OperatorLoc, "the comparison always evaluates to false because %0 "
67 "always returns non-negative values")
68 << getFunctionSpelling(Result, "ltzop")
69 << FixItHint::CreateReplacement(OperatorLoc, Twine(">").str());
70 return;
71 }
72 if (const auto *AlwaysTrueOp =
73 Result.Nodes.getNodeAs<BinaryOperator>("atop")) {
74 diag(AlwaysTrueOp->getOperatorLoc(),
75 "the comparison always evaluates to true because %0 always returns "
76 "non-negative values")
77 << getFunctionSpelling(Result, "atop");
78 return;
79 }
80 const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binop");
81 diag(BinOp->getOperatorLoc(), "%0 only returns non-negative values")
82 << getFunctionSpelling(Result, "binop");
83 }
84
85 } // namespace bugprone
86 } // namespace tidy
87 } // namespace clang
clang::ast_matchers
Definition: AbseilMatcher.h:14
clang::clangd::getTokenRange
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
Definition: SourceCode.cpp:227
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
PosixReturnCheck.h
clang::tidy::bugprone::getFunctionSpelling
static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result, const char *BindingStr)
Definition: PosixReturnCheck.cpp:20