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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits