[clang] [clang-tools-extra] [clang][analysis] refactor the unevaluated api (PR #117474)

via cfe-commits cfe-commits at lists.llvm.org
Sun Nov 24 02:24:59 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Congcong Cai (HerrCai0907)

<details>
<summary>Changes</summary>

It is unclear for `ExprMutationAnalyzer::isUnevaluated` to accept 2 Stmt.
Redesign the API to accept only 1 Stmt and the API will only check whether stmt is substmt of an unevaluated stmt.


---
Full diff: https://github.com/llvm/llvm-project/pull/117474.diff


3 Files Affected:

- (modified) clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp (+1-1) 
- (modified) clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h (+4-9) 
- (modified) clang/lib/Analysis/ExprMutationAnalyzer.cpp (+24-36) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index e329588290cd4b..2b2d80ea9346bd 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -303,7 +303,7 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
     }
   }
 
-  if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *LoopStmt, *Result.Context))
+  if (ExprMutationAnalyzer::isUnevaluated(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 c7a5b016c949d0..7442f4aad531b7 100644
--- a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -47,8 +47,6 @@ 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);
 
   private:
     using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
@@ -58,8 +56,6 @@ class ExprMutationAnalyzer {
                                      Memoized::ResultMap &MemoizedResults);
     const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
 
-    bool isUnevaluated(const Expr *Exp);
-
     const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
     const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
     const Stmt *
@@ -83,6 +79,10 @@ class ExprMutationAnalyzer {
   ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
       : Memorized(), A(Stm, Context, Memorized) {}
 
+  /// check whether stmt is unevaluated. mutation analyzer will ignore the
+  /// content in unevaluated stmt.
+  static bool isUnevaluated(const Stmt *Stm, ASTContext &Context);
+
   bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
   bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
   const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); }
@@ -101,11 +101,6 @@ class ExprMutationAnalyzer {
     return A.findPointeeMutation(Dec);
   }
 
-  static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
-                            ASTContext &Context) {
-    return Analyzer::isUnevaluated(Smt, Stm, Context);
-  }
-
 private:
   Memoized Memorized;
   Analyzer A;
diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
index a94b22e051d0e1..be0e8aa5743dd9 100644
--- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -236,7 +236,7 @@ const Stmt *ExprMutationAnalyzer::Analyzer::findMutationMemoized(
   if (!Inserted)
     return Memoized->second;
 
-  if (isUnevaluated(Exp))
+  if (ExprMutationAnalyzer::isUnevaluated(Exp, Context))
     return nullptr;
 
   for (const auto &Finder : Finders) {
@@ -268,41 +268,29 @@ ExprMutationAnalyzer::Analyzer::tryEachDeclRef(const Decl *Dec,
   return nullptr;
 }
 
-bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Stmt *Exp,
-                                                   const Stmt &Stm,
-                                                   ASTContext &Context) {
-  return selectFirst<Stmt>(
-             NodeID<Expr>::value,
-             match(
-                 findFirst(
-                     stmt(canResolveToExpr(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;
-}
-
-bool ExprMutationAnalyzer::Analyzer::isUnevaluated(const Expr *Exp) {
-  return isUnevaluated(Exp, Stm, Context);
+bool ExprMutationAnalyzer::isUnevaluated(const Stmt *Stm, ASTContext &Context) {
+  return !match(stmt(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(Stm)))),
+                        cxxNoexceptExpr()))))),
+                *Stm, Context)
+              .empty();
 }
 
 const Stmt *

``````````

</details>


https://github.com/llvm/llvm-project/pull/117474


More information about the cfe-commits mailing list