https://github.com/loic-joly-sonarsource created https://github.com/llvm/llvm-project/pull/118511
Before the change, getMemoizationData is used as a key to stop visiting the parents, but if a node has no identity, this is nullptr, which means that the visit will stop as soon as a second node with no identity is visited. From ed43bf26057073ba3f1b185838ba95048002980f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Joly?= <loic.j...@sonarsource.com> Date: Tue, 3 Dec 2024 17:20:18 +0100 Subject: [PATCH] Fix a bug with the hasAncestor AST matcher when a node has several parents without pointer identity. Before the change, getMemoizationData is used as a key to stop visiting the parents, but if a node has no identity, this is nullptr, which means that the visit will stop as soon as a second node with no identity is visited. --- clang/lib/ASTMatchers/ASTMatchFinder.cpp | 3 ++- .../ASTMatchers/ASTMatchersTraversalTest.cpp | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp index 3d01a70395a9bb..a7ef5ae6949537 100644 --- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -1237,7 +1237,8 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, // Make sure we do not visit the same node twice. // Otherwise, we'll visit the common ancestors as often as there // are splits on the way down. - if (Visited.insert(Parent.getMemoizationData()).second) + if (Parent.getMemoizationData() == nullptr || + Visited.insert(Parent.getMemoizationData()).second) Queue.push_back(Parent); } Queue.pop_front(); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 1d18869a6b8afc..17b058e4783018 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -5536,6 +5536,24 @@ TEST(HasAncestor, MatchesInImplicitCode) { hasAncestor(recordDecl(hasName("A"))))))))); } +TEST(HasAncestor, MatchesWithMultipleParentsWithoutPointerIdentity) { + EXPECT_TRUE(matches( + R"cpp( +template <int i> class Fact {}; +template <class T> class W {}; +template <class T> struct A +{ + static void f() { + W<Fact<12>> fact12; + } +}; +void f() { + A<int>::f(); + A<double>::f(); +})cpp", + integerLiteral(hasAncestor(functionDecl())))); +} + TEST(HasParent, MatchesOnlyParent) { EXPECT_TRUE(matches( "void f() { if (true) { int x = 42; } }", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits