Author: Congcong Cai Date: 2024-05-02T00:11:32+08:00 New Revision: 6e31714d249f857f15262518327b0f0c9509db72
URL: https://github.com/llvm/llvm-project/commit/6e31714d249f857f15262518327b0f0c9509db72 DIFF: https://github.com/llvm/llvm-project/commit/6e31714d249f857f15262518327b0f0c9509db72.diff LOG: [analysis] assume expr is not mutated after analysis to avoid recursive (#90581) Fixes: #89376. Added: Modified: clang-tools-extra/docs/ReleaseNotes.rst clang/lib/Analysis/ExprMutationAnalyzer.cpp clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 3038d2b125f20d..5956ccb925485c 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -261,7 +261,8 @@ Changes in existing checks - Improved :doc:`misc-const-correctness <clang-tidy/checks/misc/const-correctness>` check by avoiding infinite recursion - for recursive forwarding reference. + for recursive functions with forwarding reference parameters and reference + variables which refer to themselves. - Improved :doc:`misc-definitions-in-headers <clang-tidy/checks/misc/definitions-in-headers>` check by replacing the local diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index 941322be8f870b..3b3782fa1db9a0 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -235,15 +235,17 @@ const Stmt *ExprMutationAnalyzer::Analyzer::findMutationMemoized( if (Memoized != MemoizedResults.end()) return Memoized->second; + // Assume Exp is not mutated before analyzing Exp. + MemoizedResults[Exp] = nullptr; if (isUnevaluated(Exp)) - return MemoizedResults[Exp] = nullptr; + return nullptr; for (const auto &Finder : Finders) { if (const Stmt *S = (this->*Finder)(Exp)) return MemoizedResults[Exp] = S; } - return MemoizedResults[Exp] = nullptr; + return nullptr; } const Stmt * diff --git a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp index e94bc0d6039791..9c4ec07e139a12 100644 --- a/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp +++ b/clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp @@ -10,8 +10,8 @@ #include "clang/AST/TypeLoc.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Frontend/ASTUnit.h" #include "clang/Tooling/Tooling.h" -#include "llvm/ADT/SmallString.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include <cctype> @@ -43,7 +43,7 @@ std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code) { } ExprMatcher declRefTo(StringRef Name) { - return declRefExpr(to(namedDecl(hasName(Name)))); + return declRefExpr(to(namedDecl(hasName(Name)).bind("decl"))); } StmtMatcher withEnclosingCompound(ExprMatcher Matcher) { @@ -57,6 +57,13 @@ bool isMutated(const SmallVectorImpl<BoundNodes> &Results, ASTUnit *AST) { return ExprMutationAnalyzer(*S, AST->getASTContext()).isMutated(E); } +bool isDeclMutated(const SmallVectorImpl<BoundNodes> &Results, ASTUnit *AST) { + const auto *const S = selectFirst<Stmt>("stmt", Results); + const auto *const D = selectFirst<Decl>("decl", Results); + TraversalKindScope RAII(AST->getASTContext(), TK_AsIs); + return ExprMutationAnalyzer(*S, AST->getASTContext()).isMutated(D); +} + SmallVector<std::string, 1> mutatedBy(const SmallVectorImpl<BoundNodes> &Results, ASTUnit *AST) { const auto *const S = selectFirst<Stmt>("stmt", Results); @@ -1552,6 +1559,21 @@ TEST(ExprMutationAnalyzerTest, UniquePtr) { // section: complex problems detected on real code +TEST(ExprMutationAnalyzerTest, SelfRef) { + std::unique_ptr<ASTUnit> AST{}; + SmallVector<BoundNodes, 1> Results{}; + + AST = buildASTFromCodeWithArgs("void f() { int &x = x; }", + {"-Wno-unused-value", "-Wno-uninitialized"}); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_FALSE(isDeclMutated(Results, AST.get())); + + AST = buildASTFromCodeWithArgs("void f() { int &x = x; x = 1; }", + {"-Wno-unused-value", "-Wno-uninitialized"}); + Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext()); + EXPECT_TRUE(isDeclMutated(Results, AST.get())); +} + TEST(ExprMutationAnalyzerTest, UnevaluatedContext) { const std::string Example = "template <typename T>" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits