Skip to content

Commit

Permalink
[analysis] assume expr is not mutated after analysis to avoid recursive
Browse files Browse the repository at this point in the history
Fixes: llvm#89376.
  • Loading branch information
HerrCai0907 committed Apr 30, 2024
1 parent eb148ae commit f0d640d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
6 changes: 4 additions & 2 deletions clang/lib/Analysis/ExprMutationAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
26 changes: 24 additions & 2 deletions clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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>"
Expand Down

0 comments on commit f0d640d

Please sign in to comment.