Skip to content

Commit 5e35594

Browse files
authored
[clang][ASTImporter] Fix import of variable template redeclarations. (#72841)
In some cases variable templates (specially if static member of record) were not correctly imported and an assertion "Missing call to MapImported?" could happen.
1 parent 4c7e4e1 commit 5e35594

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

clang/lib/AST/ASTImporter.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6280,17 +6280,21 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
62806280
D->getTemplatedDecl()))
62816281
continue;
62826282
if (IsStructuralMatch(D, FoundTemplate)) {
6283-
// The Decl in the "From" context has a definition, but in the
6284-
// "To" context we already have a definition.
6283+
// FIXME Check for ODR error if the two definitions have
6284+
// different initializers?
62856285
VarTemplateDecl *FoundDef = getTemplateDefinition(FoundTemplate);
6286-
if (D->isThisDeclarationADefinition() && FoundDef)
6287-
// FIXME Check for ODR error if the two definitions have
6288-
// different initializers?
6289-
return Importer.MapImported(D, FoundDef);
6290-
if (FoundTemplate->getDeclContext()->isRecord() &&
6291-
D->getDeclContext()->isRecord())
6292-
return Importer.MapImported(D, FoundTemplate);
6293-
6286+
if (D->getDeclContext()->isRecord()) {
6287+
assert(FoundTemplate->getDeclContext()->isRecord() &&
6288+
"Member variable template imported as non-member, "
6289+
"inconsistent imported AST?");
6290+
if (FoundDef)
6291+
return Importer.MapImported(D, FoundDef);
6292+
if (!D->isThisDeclarationADefinition())
6293+
return Importer.MapImported(D, FoundTemplate);
6294+
} else {
6295+
if (FoundDef && D->isThisDeclarationADefinition())
6296+
return Importer.MapImported(D, FoundDef);
6297+
}
62946298
FoundByLookup = FoundTemplate;
62956299
break;
62966300
}

clang/unittests/AST/ASTImporterTest.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5219,6 +5219,59 @@ TEST_P(ImportFriendClasses, RecordVarTemplateDecl) {
52195219
EXPECT_EQ(ToTUX, ToX);
52205220
}
52215221

5222+
TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclConflict) {
5223+
getToTuDecl(
5224+
R"(
5225+
template <class U>
5226+
constexpr int X = 1;
5227+
)",
5228+
Lang_CXX14);
5229+
5230+
Decl *FromTU = getTuDecl(
5231+
R"(
5232+
template <class U>
5233+
constexpr int X = 2;
5234+
)",
5235+
Lang_CXX14, "input1.cc");
5236+
auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match(
5237+
FromTU, varTemplateDecl(hasName("X")));
5238+
auto *ToX = Import(FromX, Lang_CXX11);
5239+
// FIXME: This import should fail.
5240+
EXPECT_TRUE(ToX);
5241+
}
5242+
5243+
TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateStaticDefinition) {
5244+
Decl *ToTU = getToTuDecl(
5245+
R"(
5246+
struct A {
5247+
template <class U>
5248+
static int X;
5249+
};
5250+
)",
5251+
Lang_CXX14);
5252+
auto *ToX = FirstDeclMatcher<VarTemplateDecl>().match(
5253+
ToTU, varTemplateDecl(hasName("X")));
5254+
ASSERT_FALSE(ToX->isThisDeclarationADefinition());
5255+
5256+
Decl *FromTU = getTuDecl(
5257+
R"(
5258+
struct A {
5259+
template <class U>
5260+
static int X;
5261+
};
5262+
template <class U>
5263+
int A::X = 2;
5264+
)",
5265+
Lang_CXX14, "input1.cc");
5266+
auto *FromXDef = LastDeclMatcher<VarTemplateDecl>().match(
5267+
FromTU, varTemplateDecl(hasName("X")));
5268+
ASSERT_TRUE(FromXDef->isThisDeclarationADefinition());
5269+
auto *ToXDef = Import(FromXDef, Lang_CXX14);
5270+
EXPECT_TRUE(ToXDef);
5271+
EXPECT_TRUE(ToXDef->isThisDeclarationADefinition());
5272+
EXPECT_EQ(ToXDef->getPreviousDecl(), ToX);
5273+
}
5274+
52225275
TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) {
52235276
constexpr auto Code =
52245277
R"(

0 commit comments

Comments
 (0)