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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits