danix800 updated this revision to Diff 542824.
danix800 added a comment.

Apply git-clang-format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155321/new/

https://reviews.llvm.org/D155321

Files:
  
clang-tools-extra/test/clang-tidy/checkers/readability/use-anyofallof-nocrash.cpp
  clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
  clang/lib/Analysis/ExprMutationAnalyzer.cpp
  clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Index: clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
===================================================================
--- clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -1309,6 +1309,30 @@
   EXPECT_FALSE(isMutated(Results, AST.get()));
 }
 
+TEST(ExprMutationAnalyzerTest, RangeForNonArrayByConstRefNoCrash) {
+  const auto AST = buildASTFromCode(R"(
+    struct V {
+      V* begin() const;
+      V* end() const;
+    };
+    void f(V &elem) {
+      auto rec = [](const auto& e, auto&& self) -> bool {
+        for (auto& child : e) {
+          if (!self(child, self)) {
+            return false;
+          }
+        }
+        return true;
+      };
+
+      rec(elem, rec);
+    }
+  )");
+  const auto Results =
+      match(withEnclosingCompound(declRefTo("elem")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
+}
+
 // section: unevaluated expressions
 
 TEST(ExprMutationAnalyzerTest, UnevaluatedExpressions) {
Index: clang/lib/Analysis/ExprMutationAnalyzer.cpp
===================================================================
--- clang/lib/Analysis/ExprMutationAnalyzer.cpp
+++ clang/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -568,6 +568,11 @@
     if (!Func->getBody() || !Func->getPrimaryTemplate())
       return Exp;
 
+    if (DeclAnalyzed->contains(Func)) {
+      return nullptr;
+    }
+    DeclAnalyzed->insert(Func);
+
     const auto *Parm = Nodes.getNodeAs<ParmVarDecl>("parm");
     const ArrayRef<ParmVarDecl *> AllParams =
         Func->getPrimaryTemplate()->getTemplatedDecl()->parameters();
@@ -586,7 +591,8 @@
         std::unique_ptr<FunctionParmMutationAnalyzer> &Analyzer =
             FuncParmAnalyzer[Func];
         if (!Analyzer)
-          Analyzer.reset(new FunctionParmMutationAnalyzer(*Func, Context));
+          Analyzer.reset(
+              new FunctionParmMutationAnalyzer(*Func, Context, DeclAnalyzed));
         if (Analyzer->findMutation(Parm))
           return Exp;
         continue;
@@ -599,8 +605,8 @@
 }
 
 FunctionParmMutationAnalyzer::FunctionParmMutationAnalyzer(
-    const FunctionDecl &Func, ASTContext &Context)
-    : BodyAnalyzer(*Func.getBody(), Context) {
+    const FunctionDecl &Func, ASTContext &Context, DeclSet *DeclAnalyzed)
+    : BodyAnalyzer(*Func.getBody(), Context, DeclAnalyzed) {
   if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(&Func)) {
     // CXXCtorInitializer might also mutate Param but they're not part of
     // function body, check them eagerly here since they're typically trivial.
Index: clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
===================================================================
--- clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -18,12 +18,20 @@
 
 class FunctionParmMutationAnalyzer;
 
+using DeclSet = llvm::DenseSet<const Decl *>;
+
 /// Analyzes whether any mutative operations are applied to an expression within
 /// a given statement.
 class ExprMutationAnalyzer {
 public:
-  ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
-      : Stm(Stm), Context(Context) {}
+  ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context,
+                       DeclSet *DeclAnalyzed = nullptr)
+      : Stm(Stm), Context(Context), DeclAnalyzed(DeclAnalyzed) {
+    if (nullptr == DeclAnalyzed) {
+      OwningDeclAnalyzed = std::make_unique<DeclSet>();
+      this->DeclAnalyzed = OwningDeclAnalyzed.get();
+    }
+  }
 
   bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
   bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
@@ -74,13 +82,16 @@
       FuncParmAnalyzer;
   ResultMap Results;
   ResultMap PointeeResults;
+  DeclSet *DeclAnalyzed;
+  std::unique_ptr<DeclSet> OwningDeclAnalyzed;
 };
 
 // A convenient wrapper around ExprMutationAnalyzer for analyzing function
 // params.
 class FunctionParmMutationAnalyzer {
 public:
-  FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context);
+  FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context,
+                               DeclSet *DeclAnalyzed = nullptr);
 
   bool isMutated(const ParmVarDecl *Parm) {
     return findMutation(Parm) != nullptr;
Index: clang-tools-extra/test/clang-tidy/checkers/readability/use-anyofallof-nocrash.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/use-anyofallof-nocrash.cpp
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy -std=c++14,c++17 %s readability-use-anyofallof %t --
+
+struct V {
+  V* begin() const;
+  V* end() const;
+};
+
+void bad_all_of(V &elem) {
+  auto rec = [](const auto& e, auto&& self) -> bool {
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: replace loop by 'std::all_of()' [readability-use-anyofallof]
+    for (auto& child : e) {
+      if (!self(child, self)) {
+        return false;
+      }
+    }
+    return true;
+  };
+
+  rec(elem, rec);
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to