[clang] [clang][ASTImporter] fix clash when import `VarTemplateDecl` in record (PR #67522)

Qizhi Hu via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 27 00:42:30 PDT 2023


https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/67522

>From 77224ec6297a4fb9a86f2634f4a0278b49e81625 Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at feysh.com>
Date: Wed, 27 Sep 2023 15:32:10 +0800
Subject: [PATCH] [clang][ASTImporter] fix clash when import `VarTemplateDecl`
 in record

---
 clang/lib/AST/ASTImporter.cpp           |  5 +-
 clang/unittests/AST/ASTImporterTest.cpp | 96 ++++++++++++-------------
 2 files changed, 48 insertions(+), 53 deletions(-)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index c7c2aecc8b179a4..441c61c16917bea 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -6236,10 +6236,13 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
         // The Decl in the "From" context has a definition, but in the
         // "To" context we already have a definition.
         VarTemplateDecl *FoundDef = getTemplateDefinition(FoundTemplate);
-        if (D->isThisDeclarationADefinition() && FoundDef)
+
+        if ((D->isThisDeclarationADefinition() && FoundDef))
           // FIXME Check for ODR error if the two definitions have
           // different initializers?
           return Importer.MapImported(D, FoundDef);
+        if (FoundTemplate->getDeclContext()->isRecord())
+          return Importer.MapImported(D, FoundTemplate);
 
         FoundByLookup = FoundTemplate;
         break;
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index c90b5aaeb624306..f2fafaf4329b740 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -4355,58 +4355,6 @@ TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) {
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
-TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
-  Decl *ToTU = getToTuDecl(
-      R"(
-      template <class T, T U>
-      class A;
-
-      template <class T, T U>
-      class A {
-      public:
-        template <class P, P Q>
-        friend class A;
-
-        A(T x)  :x(x) {}
-
-      private:
-        T x;
-      };
-      )",
-      Lang_CXX11);
-
-  auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
-      ToTU,
-      classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
-  Decl *FromTU = getTuDecl(
-      R"(
-      template <class T, T U>
-      class A;
-
-      template <class T, T U>
-      class A {
-      public:
-        template <class P, P Q>
-        friend class A;
-
-        A(T x) : x(x) {}
-
-      private:
-        T x;
-      };
-
-      A<int,3> a1(0);
-      )",
-      Lang_CXX11, "input1.cc");
-  auto *FromA = FirstDeclMatcher<ClassTemplateDecl>().match(
-      FromTU,
-      classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
-  auto *ToA = Import(FromA, Lang_CXX11);
-  EXPECT_TRUE(ToA);
-  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
-            ToA->getTemplatedDecl()->getTypeForDecl());
-}
-
 TEST_P(ImportFriendClasses,
        ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
@@ -4988,6 +4936,50 @@ TEST_P(ASTImporterOptionSpecificTestBase,
   }
 }
 
+TEST_P(ImportFriendClasses, RecordVarTemplateDecl) {
+  Decl *ToTU = getToTuDecl(
+      R"(
+      template <class T>
+      class A {
+      public:
+        template <class U>
+        struct B {
+          static U Value;
+        };
+
+        template <class W>
+        static constexpr bool X = !B<W>::Value;
+      };
+      )",
+      Lang_CXX14);
+
+  auto *Fwd = FirstDeclMatcher<VarTemplateDecl>().match(
+      ToTU, varTemplateDecl(hasName("X")));
+  Decl *FromTU = getTuDecl(
+      R"(
+      template <class T>
+      class A {
+      public:
+        template <class U>
+        struct B {
+          static U Value;
+        };
+
+        template <class W>
+        static constexpr bool X = !B<W>::Value;
+      };
+      )",
+      Lang_CXX14, "input1.cc");
+  auto *FromA = FirstDeclMatcher<VarTemplateDecl>().match(
+      FromTU, varTemplateDecl(hasName("X")));
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  EXPECT_EQ(Fwd->getTemplatedDecl(),
+            ToA->getTemplatedDecl());
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getDefinition(),
+            ToA->getTemplatedDecl()->getDefinition());
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) {
   constexpr auto Code =
       R"(



More information about the cfe-commits mailing list