[clang] 63ecb7d - 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:11 PDT 2022


Author: usama hameed
Date: 2022-05-23T20:18:49-07:00
New Revision: 63ecb7dcc80d17770461c8bf01bddeb2b795625b

URL: https://github.com/llvm/llvm-project/commit/63ecb7dcc80d17770461c8bf01bddeb2b795625b
DIFF: https://github.com/llvm/llvm-project/commit/63ecb7dcc80d17770461c8bf01bddeb2b795625b.diff

LOG: bugfix in InfiniteLoopCheck to not print warnings for unevaluated loops

Added a separate check for unevaluated statements. Updated InfiniteLoopCheck to use new check

Differential Revision: https://reviews.llvm.org/D126246

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.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 cb9bd7bb43f50..8815de220882e 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -81,22 +81,6 @@ 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) {
@@ -193,7 +177,7 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
     }
   }
 
-  if (isUnevaluated(Func, LoopStmt, Cond, Result.Context))
+  if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *LoopStmt, *Result.Context))
     return;
 
   if (isAtLeastOneCondVarChanged(Func, LoopStmt, Cond, Result.Context))

diff  --git a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
index 1b2b7ffcfb67a..a48b9735dfee5 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 Stmt *Smt, const Stmt &Stm,
+                            ASTContext &Context);
   static bool isUnevaluated(const Expr *Exp, const Stmt &Stm,
                             ASTContext &Context);
 

diff  --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index 4d7decc1137c2..135327a3cfe54 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -194,36 +194,44 @@ const Stmt *ExprMutationAnalyzer::tryEachDeclRef(const Decl *Dec,
   return nullptr;
 }
 
+auto isUnevaluatedMatcher(const Stmt *Exp) {
+  return anyOf(
+      // `Exp` is part of the underlying expression of
+      // decltype/typeof if it has an ancestor of
+      // typeLoc.
+      hasAncestor(typeLoc(unless(hasAncestor(unaryExprOrTypeTraitExpr())))),
+      hasAncestor(expr(anyOf(
+          // `UnaryExprOrTypeTraitExpr` is unevaluated
+          // unless it's sizeof on VLA.
+          unaryExprOrTypeTraitExpr(
+              unless(sizeOfExpr(hasArgumentOfType(variableArrayType())))),
+          // `CXXTypeidExpr` is unevaluated unless it's
+          // applied to an expression of glvalue of
+          // polymorphic class type.
+          cxxTypeidExpr(unless(isPotentiallyEvaluated())),
+          // The controlling expression of
+          // `GenericSelectionExpr` is unevaluated.
+          genericSelectionExpr(
+              hasControllingExpr(hasDescendant(equalsNode(Exp)))),
+          cxxNoexceptExpr()))));
+}
+
 bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp, const Stmt &Stm,
                                          ASTContext &Context) {
-  return selectFirst<Expr>(
+  return selectFirst<Expr>(NodeID<Expr>::value,
+                           match(findAll(expr(canResolveToExpr(equalsNode(Exp)),
+                                              isUnevaluatedMatcher(Exp))
+                                             .bind(NodeID<Expr>::value)),
+                                 Stm, Context)) != nullptr;
+}
+
+bool ExprMutationAnalyzer::isUnevaluated(const Stmt *Exp, const Stmt &Stm,
+                                         ASTContext &Context) {
+  return selectFirst<Stmt>(
              NodeID<Expr>::value,
-             match(
-                 findAll(
-                     expr(canResolveToExpr(equalsNode(Exp)),
-                          anyOf(
-                              // `Exp` is part of the underlying expression of
-                              // decltype/typeof if it has an ancestor of
-                              // typeLoc.
-                              hasAncestor(typeLoc(unless(
-                                  hasAncestor(unaryExprOrTypeTraitExpr())))),
-                              hasAncestor(expr(anyOf(
-                                  // `UnaryExprOrTypeTraitExpr` is unevaluated
-                                  // unless it's sizeof on VLA.
-                                  unaryExprOrTypeTraitExpr(unless(sizeOfExpr(
-                                      hasArgumentOfType(variableArrayType())))),
-                                  // `CXXTypeidExpr` is unevaluated unless it's
-                                  // applied to an expression of glvalue of
-                                  // polymorphic class type.
-                                  cxxTypeidExpr(
-                                      unless(isPotentiallyEvaluated())),
-                                  // The controlling expression of
-                                  // `GenericSelectionExpr` is unevaluated.
-                                  genericSelectionExpr(hasControllingExpr(
-                                      hasDescendant(equalsNode(Exp)))),
-                                  cxxNoexceptExpr())))))
-                         .bind(NodeID<Expr>::value)),
-                 Stm, Context)) != nullptr;
+             match(findAll(stmt(equalsNode(Exp), isUnevaluatedMatcher(Exp))
+                               .bind(NodeID<Expr>::value)),
+                   Stm, Context)) != nullptr;
 }
 
 bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) {


        


More information about the cfe-commits mailing list