From 3e8c29525e949f2706046aa446fcfc6c0ae7b9d2 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Tue, 25 Mar 2014 14:39:26 +0000 Subject: [PATCH] Fixes a bug in DynTypedNode. Two DynTypedNodes can be equal if they do not have the same node type, because DynTypedNodes for the same underlying object might have been created from different types (for example, Decl vs VarDecl). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204722 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTTypeTraits.h | 4 +-- unittests/ASTMatchers/ASTMatchersTest.cpp | 33 ++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h index b920767a10..abc88571eb 100644 --- a/include/clang/AST/ASTTypeTraits.h +++ b/include/clang/AST/ASTTypeTraits.h @@ -212,8 +212,8 @@ public: return getMemoizationData() < Other.getMemoizationData(); } bool operator==(const DynTypedNode &Other) const { - // Nodes with different types cannot be equal. - if (!NodeKind.isSame(Other.NodeKind)) + if (!NodeKind.isBaseOf(Other.NodeKind) && + !Other.NodeKind.isBaseOf(NodeKind)) return false; // FIXME: Implement for other types. diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index f1b792139d..787f81992d 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -4260,7 +4260,6 @@ TEST(EqualsBoundNodeMatcher, Type) { } TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) { - EXPECT_TRUE(matchAndVerifyResultTrue( "int f() {" " if (1) {" @@ -4294,5 +4293,37 @@ TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) { new VerifyIdIsBoundTo("d", 5))); } +TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) { + EXPECT_TRUE(matchAndVerifyResultTrue( + "struct StringRef { int size() const; const char* data() const; };" + "void f(StringRef v) {" + " v.data();" + "}", + memberCallExpr( + callee(methodDecl(hasName("data"))), + on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef")))) + .bind("var")))), + unless(hasAncestor(stmt(hasDescendant(memberCallExpr( + callee(methodDecl(anyOf(hasName("size"), hasName("length")))), + on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) + .bind("data"), + new VerifyIdIsBoundTo("data", 1))); + + EXPECT_FALSE(matches( + "struct StringRef { int size() const; const char* data() const; };" + "void f(StringRef v) {" + " v.data();" + " v.size();" + "}", + memberCallExpr( + callee(methodDecl(hasName("data"))), + on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef")))) + .bind("var")))), + unless(hasAncestor(stmt(hasDescendant(memberCallExpr( + callee(methodDecl(anyOf(hasName("size"), hasName("length")))), + on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) + .bind("data"))); +} + } // end namespace ast_matchers } // end namespace clang -- 2.40.0