-
Notifications
You must be signed in to change notification settings - Fork 12.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][ASTImporter] Fix crash when import VarTemplateDecl
in record
#67522
[clang][ASTImporter] Fix crash when import VarTemplateDecl
in record
#67522
Conversation
@llvm/pr-subscribers-clang Changes[clang][ASTImporter] fix clash when import Full diff: https://github.com/llvm/llvm-project/pull/67522.diff 2 Files Affected:
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"(
|
23c1002
to
f9ff9c8
Compare
VarTemplateDecl
in recordVarTemplateDecl
in record
✅ With the latest revision this PR passed the C/C++ code formatter. |
f9ff9c8
to
bbde18a
Compare
VarTemplateDecl
in recordVarTemplateDecl
in record
bbde18a
to
9dc31bf
Compare
9dc31bf
to
4a14372
Compare
[clang][ASTImporter] Fix crash when import
VarTemplateDecl
in recordstatic VarTemplateDecl in record isn't a definition, when imported before, it will crash in
ASTContext::setTemplateOrSpecializationInfo
due to setting specialization while it already exists. This patch skip this specific case.