[clang] [clang][ASTImporter] fix clash when import `VarTemplateDecl` in record (PR #67522)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 27 00:40:31 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
<details>
<summary>Changes</summary>
[clang][ASTImporter] fix clash when import `VarTemplateDecl` in record
VarTemplateDecl in Record isn't a definition, when imported, it will crash in `ASTContext::setTemplateOrSpecializationInfo` due to setting specialization while it already exists. This patch skip this specific case.
---
Full diff: https://github.com/llvm/llvm-project/pull/67522.diff
2 Files Affected:
- (modified) clang/lib/AST/ASTImporter.cpp (+4-2)
- (modified) clang/unittests/AST/ASTImporterTest.cpp (+44-52)
``````````diff
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index c7c2aecc8b179a4..b207c39cdf90154 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -6236,10 +6236,12 @@ 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) ||
+ FoundTemplate->getDeclContext()->isRecord())
// FIXME Check for ODR error if the two definitions have
// different initializers?
- return Importer.MapImported(D, FoundDef);
+ 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"(
``````````
</details>
https://github.com/llvm/llvm-project/pull/67522
More information about the cfe-commits
mailing list