summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Balogh <adam.balogh@ericsson.com>2020-01-23 15:13:30 +0100
committerHans Wennborg <hans@chromium.org>2020-01-29 21:59:00 +0100
commitd275de35f8bdb92e7b5789ebdb96df99fab504ab (patch)
treee928fe4764c15e330738d11adc322698728fc10d
parentd18ccb8b3310867c179f22704b6397e83981fff7 (diff)
downloadbcm5719-llvm-d275de35f8bdb92e7b5789ebdb96df99fab504ab.tar.gz
bcm5719-llvm-d275de35f8bdb92e7b5789ebdb96df99fab504ab.zip
[clan-tidy] Fix false positive in bugprone-infinite-loop
The checker bugprone-infinite-loop does not track changes of variables in the initialization expression of a variable declared inside the condition of the while statement. This leads to false positives, similarly to the one in the bug report https://bugs.llvm.org/show_bug.cgi?id=44618. This patch fixes this issue by enabling tracking of the variables of this expression as well. Differential Revision: https://reviews.llvm.org/D73270 (cherry picked from commit 70f4c6e7b14f225f9628fbdab3620ce037613351)
-rw-r--r--clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp24
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp38
2 files changed, 57 insertions, 5 deletions
diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index 81ae45a0089..c771ba81b25 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -170,17 +170,33 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
const auto *LoopStmt = Result.Nodes.getNodeAs<Stmt>("loop-stmt");
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
+ bool ShouldHaveConditionVariables = true;
+ if (const auto *While = dyn_cast<WhileStmt>(LoopStmt)) {
+ if (const VarDecl *LoopVarDecl = While->getConditionVariable()) {
+ if (const Expr *Init = LoopVarDecl->getInit()) {
+ ShouldHaveConditionVariables = false;
+ Cond = Init;
+ }
+ }
+ }
+
if (isAtLeastOneCondVarChanged(Func, LoopStmt, Cond, Result.Context))
return;
std::string CondVarNames = getCondVarNames(Cond);
- if (CondVarNames.empty())
+ if (ShouldHaveConditionVariables && CondVarNames.empty())
return;
- diag(LoopStmt->getBeginLoc(),
- "this loop is infinite; none of its condition variables (%0)"
- " are updated in the loop body")
+ if (CondVarNames.empty()) {
+ diag(LoopStmt->getBeginLoc(),
+ "this loop is infinite; it does not check any variables in the"
+ " condition");
+ } else {
+ diag(LoopStmt->getBeginLoc(),
+ "this loop is infinite; none of its condition variables (%0)"
+ " are updated in the loop body")
<< CondVarNames;
+ }
}
} // namespace bugprone
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
index 33d94820b0f..d89bdadf021 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
@@ -4,10 +4,20 @@ void simple_infinite_loop1() {
int i = 0;
int j = 0;
while (i < 10) {
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
j++;
}
+ while (int k = 10) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; it does not check any variables in the condition [bugprone-infinite-loop]
+ j--;
+ }
+
+ while (int k = 10) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; it does not check any variables in the condition [bugprone-infinite-loop]
+ k--;
+ }
+
do {
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
j++;
@@ -27,6 +37,16 @@ void simple_infinite_loop2() {
j++;
}
+ while (int k = Limit) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (Limit) are updated in the loop body [bugprone-infinite-loop]
+ j--;
+ }
+
+ while (int k = Limit) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (Limit) are updated in the loop body [bugprone-infinite-loop]
+ k--;
+ }
+
do {
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i, Limit) are updated in the loop body [bugprone-infinite-loop]
j++;
@@ -44,6 +64,22 @@ void simple_not_infinite1() {
// Not an error since 'Limit' is updated.
Limit--;
}
+
+ while (Limit--) {
+ // Not an error since 'Limit' is updated.
+ i++;
+ }
+
+ while (int k = Limit) {
+ // Not an error since 'Limit' is updated.
+ Limit--;
+ }
+
+ while (int k = Limit--) {
+ // Not an error since 'Limit' is updated.
+ i++;
+ }
+
do {
Limit--;
} while (i < Limit);
OpenPOWER on IntegriCloud