[PATCH] D80025: [ASTMatcher] Correct memoization bug ignoring direction (descendants or ancestors)
Loïc Joly via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon May 18 14:06:06 PDT 2020
loic-joly-sonarsource updated this revision to Diff 264709.
loic-joly-sonarsource added a comment.
Take into account transitive/non transitive request
Clarify unit tests
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D80025/new/
https://reviews.llvm.org/D80025
Files:
clang/lib/ASTMatchers/ASTMatchFinder.cpp
clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -2689,6 +2689,34 @@
compoundStmt(hasParent(ifStmt()))));
}
+TEST(MatcherMemoize, HasParentDiffersFromHas) {
+ // Test introduced after detecting a bug in memoization
+ constexpr auto code = "void f() { throw 1; }";
+ EXPECT_TRUE(notMatches(
+ code,
+ cxxThrowExpr(hasParent(expr()))));
+ EXPECT_TRUE(matches(
+ code,
+ cxxThrowExpr(has(expr()))));
+ EXPECT_TRUE(matches(
+ code,
+ cxxThrowExpr(anyOf(hasParent(expr()), has(expr())))));
+}
+
+TEST(MatcherMemoize, HasDiffersFromHasDescendant) {
+ // Test introduced after detecting a bug in memoization
+ constexpr auto code = "void f() { throw 1+1; }";
+ EXPECT_TRUE(notMatches(
+ code,
+ cxxThrowExpr(has(integerLiteral()))));
+ EXPECT_TRUE(matches(
+ code,
+ cxxThrowExpr(hasDescendant(integerLiteral()))));
+ EXPECT_TRUE(notMatches(code,
+ cxxThrowExpr(allOf(
+ hasDescendant(integerLiteral()),
+ has(integerLiteral())))));
+}
TEST(HasAncestor, MatchesAllAncestors) {
EXPECT_TRUE(matches(
"template <typename T> struct C { static void f() { 42; } };"
Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp
===================================================================
--- clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -43,6 +43,13 @@
// optimize this on.
static const unsigned MaxMemoizationEntries = 10000;
+enum class MatchType {
+ Ancestors,
+ Descendants,
+ Parent,
+ Child
+};
+
// We use memoization to avoid running the same matcher on the same
// AST node twice. This struct is the key for looking up match
// result. It consists of an ID of the MatcherInterface (for
@@ -60,10 +67,11 @@
DynTypedNode Node;
BoundNodesTreeBuilder BoundNodes;
TraversalKind Traversal = TK_AsIs;
+ MatchType Type;
bool operator<(const MatchKey &Other) const {
- return std::tie(Traversal, MatcherID, Node, BoundNodes) <
- std::tie(Other.Traversal, Other.MatcherID, Other.Node,
+ return std::tie(Traversal, Type, MatcherID, Node, BoundNodes) <
+ std::tie(Other.Traversal, Other.Type, Other.MatcherID, Other.Node,
Other.BoundNodes);
}
};
@@ -456,7 +464,7 @@
// Note that we key on the bindings *before* the match.
Key.BoundNodes = *Builder;
Key.Traversal = Ctx.getParentMapContext().getTraversalKind();
-
+ Key.Type = MaxDepth == 1 ? MatchType::Child : MatchType::Descendants;
MemoizationMap::iterator I = ResultCache.find(Key);
if (I != ResultCache.end()) {
*Builder = I->second.Nodes;
@@ -702,6 +710,8 @@
Key.Node = Node;
Key.BoundNodes = *Builder;
Key.Traversal = Ctx.getParentMapContext().getTraversalKind();
+ Key.Type = MatchMode == AncestorMatchMode::AMM_ParentOnly ?
+ MatchType::Parent : MatchType::Ancestors;
// Note that we cannot use insert and reuse the iterator, as recursive
// calls to match might invalidate the result cache iterators.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80025.264709.patch
Type: text/x-patch
Size: 3212 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200518/42974e75/attachment.bin>
More information about the cfe-commits
mailing list