[clang] [clang][ASTImporter] Fix crash when template class static member imported to other translation unit. (PR #68774)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 31 19:53:23 PDT 2023


https://github.com/mzyKi updated https://github.com/llvm/llvm-project/pull/68774

>From fa32c05f7af8ee64d0cf3b427755e87b6ed07547 Mon Sep 17 00:00:00 2001
From: miaozhiyuan <miaozhiyuan at feysh.com>
Date: Wed, 11 Oct 2023 15:45:36 +0800
Subject: [PATCH] [clang][ASTImporter] Fix crash when template class static
 member imported to other translation unit. Fixes: #68769

---
 clang/lib/AST/ASTImporter.cpp           | 11 ++++++++
 clang/unittests/AST/ASTImporterTest.cpp | 34 +++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 650ff201e66b72e..c4e931e220f69b5 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -4476,6 +4476,17 @@ ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
     auto ToVTOrErr = import(D->getDescribedVarTemplate());
     if (!ToVTOrErr)
       return ToVTOrErr.takeError();
+  } else if (MemberSpecializationInfo *MSI = D->getMemberSpecializationInfo()) {
+    TemplateSpecializationKind SK = MSI->getTemplateSpecializationKind();
+    VarDecl *FromInst = D->getInstantiatedFromStaticDataMember();
+    if (Expected<VarDecl *> ToInstOrErr = import(FromInst))
+      ToVar->setInstantiationOfStaticDataMember(*ToInstOrErr, SK);
+    else
+      return ToInstOrErr.takeError();
+    if (ExpectedSLoc POIOrErr = import(MSI->getPointOfInstantiation()))
+      ToVar->getMemberSpecializationInfo()->setPointOfInstantiation(*POIOrErr);
+    else
+      return POIOrErr.takeError();
   }
 
   if (Error Err = ImportInitializer(D, ToVar))
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 87e6cd1e160c4cc..119ee58e55310b4 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -1370,6 +1370,40 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) {
   ASSERT_EQ(ToTemplated1, ToTemplated);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase,
+       ImportTemplateSpecializationStaticMember) {
+  auto FromCode = 
+        R"(
+        template <typename H> class Test{
+        public:
+	        static const unsigned int length;
+        };
+
+        template<> const unsigned int Test<int>::length;
+        template<> const unsigned int Test<int>::length = 0;
+        )";
+  auto ToCode = 
+        R"(
+        template <typename H> class Test {
+        public:
+          static const unsigned int length;
+        };
+        
+        template <> const unsigned int Test<int>::length;
+
+        void foo() { int i = 1 / Test<int>::length; }
+        )";
+  Decl *FromTU = getTuDecl(FromCode, Lang_CXX14);
+  auto FromDecl = FirstDeclMatcher<VarDecl>().match(
+      FromTU, varDecl(hasName("length"), isDefinition()));
+  Decl *ToTu = getToTuDecl(ToCode, Lang_CXX14);
+  auto ToX = Import(FromDecl, Lang_CXX03);
+  auto ToDecl = FirstDeclMatcher<VarDecl>().match(
+      ToTu, varDecl(hasName("length"), isDefinition()));
+  EXPECT_TRUE(ToX);
+  EXPECT_EQ(ToX, ToDecl);
+}
+
 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) {
   // This tests the import of isConditionTrue directly to make sure the importer
   // gets it right.



More information about the cfe-commits mailing list