From: Gabor Marton Date: Fri, 8 Feb 2019 08:55:32 +0000 (+0000) Subject: [AST] Fix structural inequivalence of operators X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=24b6249a6425cb7ab818f1c4ead7f2453219a4ff;p=clang [AST] Fix structural inequivalence of operators Summary: Operators kind was not checked, so we reported e.g. op- to be equal with op+ Reviewers: shafik, a_sidorin, aaron.ballman Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57902 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353504 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp index 9f83c5110f..4a1f6da14e 100644 --- a/lib/AST/ASTStructuralEquivalence.cpp +++ b/lib/AST/ASTStructuralEquivalence.cpp @@ -1650,6 +1650,12 @@ bool StructuralEquivalenceContext::CheckKindSpecificEquivalence( } } else if (FunctionDecl *FD1 = dyn_cast(D1)) { if (FunctionDecl *FD2 = dyn_cast(D2)) { + if (FD1->isOverloadedOperator()) { + if (!FD2->isOverloadedOperator()) + return false; + if (FD1->getOverloadedOperator() != FD2->getOverloadedOperator()) + return false; + } if (!::IsStructurallyEquivalent(FD1->getIdentifier(), FD2->getIdentifier())) return false; diff --git a/unittests/AST/StructuralEquivalenceTest.cpp b/unittests/AST/StructuralEquivalenceTest.cpp index ae62747284..211b9539cf 100644 --- a/unittests/AST/StructuralEquivalenceTest.cpp +++ b/unittests/AST/StructuralEquivalenceTest.cpp @@ -230,6 +230,33 @@ TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) { EXPECT_FALSE(testStructuralMatch(t)); } +TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) { + auto t = makeDecls( + "struct X{}; bool operator<(X, X);", + "struct X{}; bool operator==(X, X);", Lang_CXX, + functionDecl(hasOverloadedOperatorName("<")), + functionDecl(hasOverloadedOperatorName("=="))); + EXPECT_FALSE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceFunctionTest, SameOperators) { + auto t = makeDecls( + "struct X{}; bool operator<(X, X);", + "struct X{}; bool operator<(X, X);", Lang_CXX, + functionDecl(hasOverloadedOperatorName("<")), + functionDecl(hasOverloadedOperatorName("<"))); + EXPECT_TRUE(testStructuralMatch(t)); +} + +TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) { + auto t = makeDecls( + "struct X{ X(); };", + "struct X{ ~X(); };", Lang_CXX, + cxxConstructorDecl(), + cxxDestructorDecl()); + EXPECT_FALSE(testStructuralMatch(t)); +} + TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) { auto t = makeNamedDecls("void foo(int&);", "void foo(const int&);", Lang_CXX);