[PATCH] D136848: [clang][AST] Compare UnresolvedLookupExpr in structural equivalence.
This revision was automatically updated to reflect the committed changes. Closed by commit rG13417808474c: [clang][AST] Compare UnresolvedLookupExpr in structural equivalence. (authored by balazske). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136848/new/ https://reviews.llvm.org/D136848 Files: clang/lib/AST/ASTStructuralEquivalence.cpp clang/unittests/AST/StructuralEquivalenceTest.cpp Index: clang/unittests/AST/StructuralEquivalenceTest.cpp === --- clang/unittests/AST/StructuralEquivalenceTest.cpp +++ clang/unittests/AST/StructuralEquivalenceTest.cpp @@ -2125,5 +2125,128 @@ EXPECT_FALSE(testStructuralMatch(t)); } +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) { + auto t = makeStmts( + R"( + void f1(int); + template + void f(T t) { +f1(t); + } + void g() { f(1); } + )", + R"( + void f2(int); + template + void f(T t) { +f2(t); + } + void g() { f(1); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) { + auto t = makeStmts( + R"( + struct X { +static void g(int); +static void g(char); + }; + + template + void f(T t) { +X::g(t); + } + + void g() { f(1); } + )", + R"( + struct Y { +static void g(int); +static void g(char); + }; + + template + void f(T t) { +Y::g(t); + } + + void g() { f(1); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, + UnresolvedLookupDifferentTemplateArgument) { + auto t = makeStmts( + R"( + struct A {}; + template + void g() {} + + template + void f() { +g(); + } + + void h() { f(); } + )", + R"( + struct B {}; + template + void g() {} + + template + void f() { +g(); + } + + void h() { f(); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) { + auto t = makeStmts( + R"( + struct A {}; + struct B { +template +static void g(int) {}; +template +static void g(char) {}; + }; + + template + void f(T2 x) { +B::g(x); + } + + void g() { f(1); } + )", + R"( + struct A {}; + struct B { +template +static void g(int) {}; +template +static void g(char) {}; + }; + + template + void f(T2 x) { +B::g(x); + } + + void g() { f(1); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_TRUE(testStructuralMatch(t)); +} + } // end namespace ast_matchers } // end namespace clang Index: clang/lib/AST/ASTStructuralEquivalence.cpp === --- clang/lib/AST/ASTStructuralEquivalence.cpp +++ clang/lib/AST/ASTStructuralEquivalence.cpp @@ -102,6 +102,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, const TemplateArgument &Arg1, const TemplateArgument &Arg2); +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const TemplateArgumentLoc &Arg1, + const TemplateArgumentLoc &Arg2); static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, NestedNameSpecifier *NNS1, NestedNameSpecifier *NNS2); @@ -340,6 +343,30 @@ return true; } + bool IsStmtEquivalent(const OverloadExpr *E1, const OverloadExpr *E2) { +if (!IsStructurallyEquivalent(Context, E1->getName(), E2->getName())) + return false; + +if (static_cast(E1->getQualifier()) != +static_cast(E2->getQualifier())) + return false; +if (E1->getQualifier() && +!IsStructurallyEquivalent(Context, E1->getQualifier(), + E2->getQualifier())) + return false; + +if (E1->getNumTemplateArgs() != E2->getNumTemplateArgs()) + return false; +const TemplateArgumentLoc *Args1 = E1->getTemplateArgs(); +const TemplateArgumentLoc *Args2 = E2->getTemplateArgs(); +for (unsigned int ArgI = 0, ArgN = E1->getNumTemplateArgs(); ArgI < ArgN; + ++ArgI) + if (!IsStructurallyEquivalent(Context, Args1[ArgI], Args2[ArgI])) +return false; + +return true; + } + /// End point of the traversal chain. bool TraverseStmt(const Stmt *S1, const Stmt *S2) { retur
[PATCH] D136848: [clang][AST] Compare UnresolvedLookupExpr in structural equivalence.
gamesh411 accepted this revision. gamesh411 added a comment. This revision is now accepted and ready to land. I have verified this patch on open-source projects. Bitcoin had quite a few crashes without this; those are gone. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136848/new/ https://reviews.llvm.org/D136848 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D136848: [clang][AST] Compare UnresolvedLookupExpr in structural equivalence.
balazske added a comment. ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136848/new/ https://reviews.llvm.org/D136848 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D136848: [clang][AST] Compare UnresolvedLookupExpr in structural equivalence.
balazske updated this revision to Diff 472971. balazske added a comment. Try to fix test failures on Windows pre-merge check. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136848/new/ https://reviews.llvm.org/D136848 Files: clang/lib/AST/ASTStructuralEquivalence.cpp clang/unittests/AST/StructuralEquivalenceTest.cpp Index: clang/unittests/AST/StructuralEquivalenceTest.cpp === --- clang/unittests/AST/StructuralEquivalenceTest.cpp +++ clang/unittests/AST/StructuralEquivalenceTest.cpp @@ -2125,5 +2125,128 @@ EXPECT_FALSE(testStructuralMatch(t)); } +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) { + auto t = makeStmts( + R"( + void f1(int); + template + void f(T t) { +f1(t); + } + void g() { f(1); } + )", + R"( + void f2(int); + template + void f(T t) { +f2(t); + } + void g() { f(1); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) { + auto t = makeStmts( + R"( + struct X { +static void g(int); +static void g(char); + }; + + template + void f(T t) { +X::g(t); + } + + void g() { f(1); } + )", + R"( + struct Y { +static void g(int); +static void g(char); + }; + + template + void f(T t) { +Y::g(t); + } + + void g() { f(1); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, + UnresolvedLookupDifferentTemplateArgument) { + auto t = makeStmts( + R"( + struct A {}; + template + void g() {} + + template + void f() { +g(); + } + + void h() { f(); } + )", + R"( + struct B {}; + template + void g() {} + + template + void f() { +g(); + } + + void h() { f(); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) { + auto t = makeStmts( + R"( + struct A {}; + struct B { +template +static void g(int) {}; +template +static void g(char) {}; + }; + + template + void f(T2 x) { +B::g(x); + } + + void g() { f(1); } + )", + R"( + struct A {}; + struct B { +template +static void g(int) {}; +template +static void g(char) {}; + }; + + template + void f(T2 x) { +B::g(x); + } + + void g() { f(1); } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_TRUE(testStructuralMatch(t)); +} + } // end namespace ast_matchers } // end namespace clang Index: clang/lib/AST/ASTStructuralEquivalence.cpp === --- clang/lib/AST/ASTStructuralEquivalence.cpp +++ clang/lib/AST/ASTStructuralEquivalence.cpp @@ -102,6 +102,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, const TemplateArgument &Arg1, const TemplateArgument &Arg2); +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const TemplateArgumentLoc &Arg1, + const TemplateArgumentLoc &Arg2); static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, NestedNameSpecifier *NNS1, NestedNameSpecifier *NNS2); @@ -340,6 +343,30 @@ return true; } + bool IsStmtEquivalent(const OverloadExpr *E1, const OverloadExpr *E2) { +if (!IsStructurallyEquivalent(Context, E1->getName(), E2->getName())) + return false; + +if (static_cast(E1->getQualifier()) != +static_cast(E2->getQualifier())) + return false; +if (E1->getQualifier() && +!IsStructurallyEquivalent(Context, E1->getQualifier(), + E2->getQualifier())) + return false; + +if (E1->getNumTemplateArgs() != E2->getNumTemplateArgs()) + return false; +const TemplateArgumentLoc *Args1 = E1->getTemplateArgs(); +const TemplateArgumentLoc *Args2 = E2->getTemplateArgs(); +for (unsigned int ArgI = 0, ArgN = E1->getNumTemplateArgs(); ArgI < ArgN; + ++ArgI) + if (!IsStructurallyEquivalent(Context, Args1[ArgI], Args2[ArgI])) +return false; + +return true; + } + /// End point of the traversal chain. bool TraverseStmt(const Stmt *S1, const Stmt *S2) { return true; } @@ -599,6 +626,14 @@ return true; } +/// Determine whet
[PATCH] D136848: [clang][AST] Compare UnresolvedLookupExpr in structural equivalence.
balazske created this revision. Herald added subscribers: steakhal, martong, gamesh411, Szelethus, dkrupp. Herald added a project: All. balazske requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136848 Files: clang/lib/AST/ASTStructuralEquivalence.cpp clang/unittests/AST/StructuralEquivalenceTest.cpp Index: clang/unittests/AST/StructuralEquivalenceTest.cpp === --- clang/unittests/AST/StructuralEquivalenceTest.cpp +++ clang/unittests/AST/StructuralEquivalenceTest.cpp @@ -2125,5 +2125,112 @@ EXPECT_FALSE(testStructuralMatch(t)); } +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) { + auto t = makeStmts( + R"( + template + void f(T t) { +f1(t); + } + )", + R"( + template + void f(T t) { +f2(t); + } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentQualifier) { + auto t = makeStmts( + R"( + struct X { +static void g(int); +static void g(char); + }; + + template + void f(T t) { +X::g(t); + } + )", + R"( + struct Y { +static void g(int); +static void g(char); + }; + + template + void f(T t) { +Y::g(t); + } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, + UnresolvedLookupDifferentTemplateArgument) { + auto t = makeStmts( + R"( + struct A {}; + template + void g() {} + + template + void f() { +g(); + } + )", + R"( + struct B {}; + template + void g() {} + + template + void f() { +g(); + } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) { + auto t = makeStmts( + R"( + struct A {}; + struct B { +template +static void g(int) {}; +template +static void g(char) {}; + }; + + template + void f(T2 x) { +B::g(x); + } + )", + R"( + struct A {}; + struct B { +template +static void g(int) {}; +template +static void g(char) {}; + }; + + template + void f(T2 x) { +B::g(x); + } + )", + Lang_CXX03, unresolvedLookupExpr()); + EXPECT_TRUE(testStructuralMatch(t)); +} + } // end namespace ast_matchers } // end namespace clang Index: clang/lib/AST/ASTStructuralEquivalence.cpp === --- clang/lib/AST/ASTStructuralEquivalence.cpp +++ clang/lib/AST/ASTStructuralEquivalence.cpp @@ -102,6 +102,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, const TemplateArgument &Arg1, const TemplateArgument &Arg2); +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const TemplateArgumentLoc &Arg1, + const TemplateArgumentLoc &Arg2); static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, NestedNameSpecifier *NNS1, NestedNameSpecifier *NNS2); @@ -340,6 +343,30 @@ return true; } + bool IsStmtEquivalent(const OverloadExpr *E1, const OverloadExpr *E2) { +if (!IsStructurallyEquivalent(Context, E1->getName(), E2->getName())) + return false; + +if (static_cast(E1->getQualifier()) != +static_cast(E2->getQualifier())) + return false; +if (E1->getQualifier() && +!IsStructurallyEquivalent(Context, E1->getQualifier(), + E2->getQualifier())) + return false; + +if (E1->getNumTemplateArgs() != E2->getNumTemplateArgs()) + return false; +const TemplateArgumentLoc *Args1 = E1->getTemplateArgs(); +const TemplateArgumentLoc *Args2 = E2->getTemplateArgs(); +for (unsigned int ArgI = 0, ArgN = E1->getNumTemplateArgs(); ArgI < ArgN; + ++ArgI) + if (!IsStructurallyEquivalent(Context, Args1[ArgI], Args2[ArgI])) +return false; + +return true; + } + /// End point of the traversal chain. bool TraverseStmt(const Stmt *S1, const Stmt *S2) { return true; } @@ -599,6 +626,14 @@ return true; } +/// Determine whether two template argument locations are equivalent. +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const TemplateArgumentLoc &Arg1, +