]> granicus.if.org Git - clang/commitdiff
[AST] Fix structural inequivalence of operators
authorGabor Marton <martongabesz@gmail.com>
Fri, 8 Feb 2019 08:55:32 +0000 (08:55 +0000)
committerGabor Marton <martongabesz@gmail.com>
Fri, 8 Feb 2019 08:55:32 +0000 (08:55 +0000)
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

lib/AST/ASTStructuralEquivalence.cpp
unittests/AST/StructuralEquivalenceTest.cpp

index 9f83c5110f629669320ada2d88aebdcb515c2a71..4a1f6da14e3e5b43cc2a982e3d30548cd743d88f 100644 (file)
@@ -1650,6 +1650,12 @@ bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
     }
   } else if (FunctionDecl *FD1 = dyn_cast<FunctionDecl>(D1)) {
     if (FunctionDecl *FD2 = dyn_cast<FunctionDecl>(D2)) {
+      if (FD1->isOverloadedOperator()) {
+        if (!FD2->isOverloadedOperator())
+          return false;
+        if (FD1->getOverloadedOperator() != FD2->getOverloadedOperator())
+          return false;
+      }
       if (!::IsStructurallyEquivalent(FD1->getIdentifier(),
                                       FD2->getIdentifier()))
         return false;
index ae62747284108ddb5116b82e1baad678b4ca8e67..211b9539cf7d45ae6cdfe230fe607408be045b50 100644 (file)
@@ -230,6 +230,33 @@ TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
+  auto t = makeDecls<FunctionDecl>(
+      "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<FunctionDecl>(
+      "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<FunctionDecl>(
+      "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);