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
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++;
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++;
// 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);