[clang] 6026822 - bugfix in InfiniteLoopCheck to not print warnings for unevaluated loops
usama hameed via cfe-commits
cfe-commits at lists.llvm.org
Mon May 23 20:20:09 PDT 2022
Author: usama hameed
Date: 2022-05-23T20:18:48-07:00
New Revision: 602682225ad6c9135e84bbca3b91d5738712c64f
URL: https://github.com/llvm/llvm-project/commit/602682225ad6c9135e84bbca3b91d5738712c64f
DIFF: https://github.com/llvm/llvm-project/commit/602682225ad6c9135e84bbca3b91d5738712c64f.diff
LOG: bugfix in InfiniteLoopCheck to not print warnings for unevaluated loops
Differential Revision: https://reviews.llvm.org/D126034
Added:
Modified:
clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
clang/lib/Analysis/ExprMutationAnalyzer.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index 3359a7f8932ed..cb9bd7bb43f50 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -81,6 +81,22 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, const Stmt *LoopStmt,
return false;
}
+bool isUnevaluated(const Decl *Func, const Stmt *LoopStmt, const Stmt *Cond,
+ ASTContext *Context) {
+ if (const auto *Exp = dyn_cast<Expr>(Cond)) {
+ if (const auto *ForLoop = dyn_cast<ForStmt>(LoopStmt)) {
+ return (ForLoop->getInc() && ExprMutationAnalyzer::isUnevaluated(
+ Exp, *ForLoop->getInc(), *Context)) ||
+ (ForLoop->getBody() && ExprMutationAnalyzer::isUnevaluated(
+ Exp, *ForLoop->getBody(), *Context)) ||
+ (ForLoop->getCond() && ExprMutationAnalyzer::isUnevaluated(
+ Exp, *ForLoop->getCond(), *Context));
+ }
+ return ExprMutationAnalyzer::isUnevaluated(Exp, *LoopStmt, *Context);
+ }
+ return true;
+}
+
/// Return whether at least one variable of `Cond` changed in `LoopStmt`.
static bool isAtLeastOneCondVarChanged(const Decl *Func, const Stmt *LoopStmt,
const Stmt *Cond, ASTContext *Context) {
@@ -177,6 +193,9 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
}
}
+ if (isUnevaluated(Func, LoopStmt, Cond, Result.Context))
+ return;
+
if (isAtLeastOneCondVarChanged(Func, LoopStmt, Cond, Result.Context))
return;
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 0074266ce4b87..a22f1bf06a534 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
@@ -650,3 +650,38 @@ void test_dependent_condition() {
do {
} while (1, (false) && val4 == 1);
}
+
+void test_typeof() {
+ __typeof__({
+ for (int i = 0; i < 10; ++i) {
+ }
+ 0;
+ }) x;
+}
+
+void test_typeof_infinite() {
+ __typeof__({
+ for (int i = 0; i < 10;) {
+ }
+ 0;
+ }) x;
+}
+
+void test_typeof_while_infinite() {
+ __typeof__({
+ int i = 0;
+ while (i < 10) {
+ }
+ 0;
+ }) x;
+}
+
+void test_typeof_dowhile_infinite() {
+ __typeof__({
+ int i = 0;
+ do {
+
+ } while (i < 10);
+ 0;
+ }) x;
+}
diff --git a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
index 9397c5df78abe..1b2b7ffcfb67a 100644
--- a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -38,6 +38,8 @@ class ExprMutationAnalyzer {
}
const Stmt *findPointeeMutation(const Expr *Exp);
const Stmt *findPointeeMutation(const Decl *Dec);
+ static bool isUnevaluated(const Expr *Exp, const Stmt &Stm,
+ ASTContext &Context);
private:
using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index e9ff5e5e87658..4d7decc1137c2 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -194,7 +194,8 @@ const Stmt *ExprMutationAnalyzer::tryEachDeclRef(const Decl *Dec,
return nullptr;
}
-bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {
+bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp, const Stmt &Stm,
+ ASTContext &Context) {
return selectFirst<Expr>(
NodeID<Expr>::value,
match(
@@ -225,6 +226,10 @@ bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {
Stm, Context)) != nullptr;
}
+bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {
+ return isUnevaluated(Exp, Stm, Context);
+}
+
const Stmt *
ExprMutationAnalyzer::findExprMutation(ArrayRef<BoundNodes> Matches) {
return tryEachMatch<Expr>(Matches, this, &ExprMutationAnalyzer::findMutation);
More information about the cfe-commits
mailing list