[clang-tools-extra] [clang-tidy][bugprone-posix-return] support integer literals as LHS (PR #109302)
Congcong Cai via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 19 08:47:06 PDT 2024
https://github.com/HerrCai0907 created https://github.com/llvm/llvm-project/pull/109302
Refactor matches to give more generic checker.
>From cc2c798193722b3a537c76e74981ff767d064efa Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Thu, 19 Sep 2024 23:46:16 +0800
Subject: [PATCH] [clang-tidy][bugprone-posix-return] support integer literals
as LHS
Refactor matches to give more generic checker.
---
.../clang-tidy/bugprone/PosixReturnCheck.cpp | 61 +++++++++++--------
clang-tools-extra/docs/ReleaseNotes.rst | 4 ++
.../checkers/bugprone/posix-return.cpp | 25 +++++++-
3 files changed, 62 insertions(+), 28 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp
index 378427a1eab000..9d70039080d332 100644
--- a/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp
@@ -7,19 +7,17 @@
//===----------------------------------------------------------------------===//
#include "PosixReturnCheck.h"
-#include "../utils/Matchers.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers;
namespace clang::tidy::bugprone {
-static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result,
- const char *BindingStr) {
- const CallExpr *MatchedCall = cast<CallExpr>(
- (Result.Nodes.getNodeAs<BinaryOperator>(BindingStr))->getLHS());
+static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result) {
+ const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>("call");
const SourceManager &SM = *Result.SourceManager;
return Lexer::getSourceText(CharSourceRange::getTokenRange(
MatchedCall->getCallee()->getSourceRange()),
@@ -27,32 +25,40 @@ static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result,
}
void PosixReturnCheck::registerMatchers(MatchFinder *Finder) {
+ const auto PosixCall =
+ callExpr(callee(functionDecl(
+ anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
+ unless(hasName("::posix_openpt")))))
+ .bind("call");
+ const auto ZeroIntegerLiteral = integerLiteral(equals(0));
+ const auto NegIntegerLiteral =
+ unaryOperator(hasOperatorName("-"), hasUnaryOperand(integerLiteral()));
+
Finder->addMatcher(
binaryOperator(
- hasOperatorName("<"),
- hasLHS(callExpr(callee(functionDecl(
- anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
- unless(hasName("::posix_openpt")))))),
- hasRHS(integerLiteral(equals(0))))
+ anyOf(allOf(hasOperatorName("<"), hasLHS(PosixCall),
+ hasRHS(ZeroIntegerLiteral)),
+ allOf(hasOperatorName(">"), hasLHS(ZeroIntegerLiteral),
+ hasRHS(PosixCall))))
.bind("ltzop"),
this);
Finder->addMatcher(
binaryOperator(
- hasOperatorName(">="),
- hasLHS(callExpr(callee(functionDecl(
- anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
- unless(hasName("::posix_openpt")))))),
- hasRHS(integerLiteral(equals(0))))
+ anyOf(allOf(hasOperatorName(">="), hasLHS(PosixCall),
+ hasRHS(ZeroIntegerLiteral)),
+ allOf(hasOperatorName("<="), hasLHS(ZeroIntegerLiteral),
+ hasRHS(PosixCall))))
.bind("atop"),
this);
+ Finder->addMatcher(binaryOperator(hasAnyOperatorName("==", "!="),
+ hasOperands(PosixCall, NegIntegerLiteral))
+ .bind("binop"),
+ this);
Finder->addMatcher(
- binaryOperator(
- hasAnyOperatorName("==", "!=", "<=", "<"),
- hasLHS(callExpr(callee(functionDecl(
- anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
- unless(hasName("::posix_openpt")))))),
- hasRHS(unaryOperator(hasOperatorName("-"),
- hasUnaryOperand(integerLiteral()))))
+ binaryOperator(anyOf(allOf(hasAnyOperatorName("<=", "<"),
+ hasLHS(PosixCall), hasRHS(NegIntegerLiteral)),
+ allOf(hasAnyOperatorName(">", ">="),
+ hasLHS(NegIntegerLiteral), hasRHS(PosixCall))))
.bind("binop"),
this);
}
@@ -61,10 +67,13 @@ void PosixReturnCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *LessThanZeroOp =
Result.Nodes.getNodeAs<BinaryOperator>("ltzop")) {
SourceLocation OperatorLoc = LessThanZeroOp->getOperatorLoc();
+ char NewBinOp = LessThanZeroOp->getOpcode() == BinaryOperator::Opcode::BO_LT
+ ? '>'
+ : '<';
diag(OperatorLoc, "the comparison always evaluates to false because %0 "
"always returns non-negative values")
- << getFunctionSpelling(Result, "ltzop")
- << FixItHint::CreateReplacement(OperatorLoc, Twine(">").str());
+ << getFunctionSpelling(Result)
+ << FixItHint::CreateReplacement(OperatorLoc, Twine(NewBinOp).str());
return;
}
if (const auto *AlwaysTrueOp =
@@ -72,12 +81,12 @@ void PosixReturnCheck::check(const MatchFinder::MatchResult &Result) {
diag(AlwaysTrueOp->getOperatorLoc(),
"the comparison always evaluates to true because %0 always returns "
"non-negative values")
- << getFunctionSpelling(Result, "atop");
+ << getFunctionSpelling(Result);
return;
}
const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binop");
diag(BinOp->getOperatorLoc(), "%0 only returns non-negative values")
- << getFunctionSpelling(Result, "binop");
+ << getFunctionSpelling(Result);
}
} // namespace clang::tidy::bugprone
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index d032cef6b76164..3729a479abeff2 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -126,6 +126,10 @@ Changes in existing checks
usages of ``sizeof()``, ``alignof()``, and ``offsetof()`` when adding or
subtracting from a pointer.
+- Improved :doc:`bugprone-posix-return
+ <clang-tidy/checks/bugprone/posix-return>` check to support integer literals
+ as LHS and posix call as RHS of comparison.
+
- Improved :doc:`cert-flp30-c <clang-tidy/checks/cert/flp30-c>` check to
fix false positive that floating point variable is only used in increment
expression.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp
index 271893c7070695..76d447a71d68b3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp
@@ -74,6 +74,9 @@ void warningLessThanZero() {
if (pthread_yield() < 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning:
// CHECK-FIXES: pthread_yield() > 0
+ if (0 > pthread_yield() ) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning:
+ // CHECK-FIXES: 0 < pthread_yield()
}
@@ -90,7 +93,8 @@ void warningAlwaysTrue() {
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning:
if (pthread_yield() >= 0) {}
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning:
-
+ if (0 <= pthread_yield()) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning:
}
void warningEqualsNegative() {
@@ -120,7 +124,14 @@ void warningEqualsNegative() {
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
if (pthread_create(NULL, NULL, NULL, NULL) < -1) {}
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
-
+ if (-1 == pthread_create(NULL, NULL, NULL, NULL)) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
+ if (-1 != pthread_create(NULL, NULL, NULL, NULL)) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
+ if (-1 >= pthread_create(NULL, NULL, NULL, NULL)) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
+ if (-1 > pthread_create(NULL, NULL, NULL, NULL)) {}
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
}
void WarningWithMacro() {
@@ -162,6 +173,16 @@ void noWarning() {
if (posix_openpt(0) < -1) {}
if (posix_fadvise(0, 0, 0, 0) <= 0) {}
if (posix_fadvise(0, 0, 0, 0) == 1) {}
+ if (0 > posix_openpt(0)) {}
+ if (0 >= posix_openpt(0)) {}
+ if (-1 == posix_openpt(0)) {}
+ if (-1 != posix_openpt(0)) {}
+ if (-1 >= posix_openpt(0)) {}
+ if (-1 > posix_openpt(0)) {}
+ if (posix_fadvise(0, 0, 0, 0) <= 0) {}
+ if (posix_fadvise(0, 0, 0, 0) == 1) {}
+ if (0 >= posix_fadvise(0, 0, 0, 0)) {}
+ if (1 == posix_fadvise(0, 0, 0, 0)) {}
}
namespace i {
More information about the cfe-commits
mailing list