[PATCH] D49223: [AST] Check described template at structural equivalence check.

Balázs Kéri via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 12 02:02:03 PDT 2018


balazske created this revision.
Herald added a subscriber: cfe-commits.

When checking a class or function the described class or function template
is checked too.
Improved test with symmetric check, added new tests.


Repository:
  rC Clang

https://reviews.llvm.org/D49223

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


Index: unittests/AST/StructuralEquivalenceTest.cpp
===================================================================
--- unittests/AST/StructuralEquivalenceTest.cpp
+++ unittests/AST/StructuralEquivalenceTest.cpp
@@ -63,10 +63,18 @@
   }
 
   bool testStructuralMatch(NamedDecl *D0, NamedDecl *D1) {
-    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
-    StructuralEquivalenceContext Ctx(D0->getASTContext(), D1->getASTContext(),
-                                     NonEquivalentDecls, false, false);
-    return Ctx.IsStructurallyEquivalent(D0, D1);
+    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
+    llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
+    StructuralEquivalenceContext Ctx01(
+        D0->getASTContext(), D1->getASTContext(),
+        NonEquivalentDecls01, false, false);
+    StructuralEquivalenceContext Ctx10(
+        D1->getASTContext(), D0->getASTContext(),
+        NonEquivalentDecls10, false, false);
+    bool Eq01 = Ctx01.IsStructurallyEquivalent(D0, D1);
+    bool Eq10 = Ctx10.IsStructurallyEquivalent(D1, D0);
+    EXPECT_EQ(Eq01, Eq10);
+    return Eq01;
   }
 
   bool testStructuralMatch(std::tuple<NamedDecl *, NamedDecl *> t) {
@@ -199,6 +207,14 @@
 struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
 };
 
+TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
+  auto t = makeNamedDecls(
+      "void foo();",
+      "template<class T> void foo();",
+      Lang_CXX);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
   auto t = makeNamedDecls("void foo(int&);",
                           "void foo(const int&);", Lang_CXX);
@@ -534,6 +550,15 @@
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
+  auto t = makeDecls<CXXRecordDecl>(
+      "struct A { };",
+      "template<class T> struct A { };",
+      Lang_CXX,
+      cxxRecordDecl(hasName("A")));
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
   auto t = makeNamedDecls(
       "struct A{ }; struct B{ }; void foo(A a, A b);",
Index: lib/AST/ASTStructuralEquivalence.cpp
===================================================================
--- lib/AST/ASTStructuralEquivalence.cpp
+++ lib/AST/ASTStructuralEquivalence.cpp
@@ -955,13 +955,21 @@
   if (!D1 || !D2)
     return true;
 
+  if (D1->isTemplated() != D2->isTemplated())
+    return false;
+
   if (auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
     if (auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
       if (D1CXX->hasExternalLexicalStorage() &&
           !D1CXX->isCompleteDefinition()) {
         D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
       }
 
+      if (auto *T1 = D1CXX->getDescribedClassTemplate())
+        if (auto *T2 = D2CXX->getDescribedClassTemplate())
+          if (!IsStructurallyEquivalent(Context, T1, T2))
+            return false;
+
       if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
         if (Context.Complain) {
           Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
@@ -1309,6 +1317,14 @@
   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
     return false;
 
+  if (D1->isTemplated() != D2->isTemplated())
+    return false;
+
+  if (auto T1 = D1->getDescribedFunctionTemplate())
+    if (auto T2 = D2->getDescribedFunctionTemplate())
+      if (!IsStructurallyEquivalent(Context, T1, T2))
+        return false;
+
   return true;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49223.155131.patch
Type: text/x-patch
Size: 3585 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180712/84c07a04/attachment.bin>


More information about the cfe-commits mailing list