-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang-tidy][bugprone-posix-return] support integer literals as LHS #109302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Refactor matches to give more generic checker.
@llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang-tools-extra Author: Congcong Cai (HerrCai0907) ChangesRefactor matches to give more generic checker. Full diff: https://github.com/llvm/llvm-project/pull/109302.diff 3 Files Affected:
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 {
|
Co-authored-by: EugeneZelenko <[email protected]>
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…lvm#109302) Refactor matches to give more generic checker. --------- Co-authored-by: EugeneZelenko <[email protected]>
Refactor matches to give more generic checker.