https://github.com/balazske updated https://github.com/llvm/llvm-project/pull/72841
From 99d6169f62862b7b1147da7fd26a85df20a0aba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <balazs.k...@ericsson.com> Date: Mon, 20 Nov 2023 10:14:52 +0100 Subject: [PATCH 1/3] [clang][ASTImporter] Fix import of variable template redeclarations. In some cases variable templates (specially if static member of record) were not correctly imported and an assertion "Missing call to MapImported?" could happen. --- clang/lib/AST/ASTImporter.cpp | 27 +++--- clang/unittests/AST/ASTImporterTest.cpp | 105 ++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 10 deletions(-) diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index c4e931e220f69..7a5e3d6653285 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -6245,17 +6245,21 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) { D->getTemplatedDecl())) continue; if (IsStructuralMatch(D, FoundTemplate)) { - // The Decl in the "From" context has a definition, but in the - // "To" context we already have a definition. + // FIXME Check for ODR error if the two definitions have + // different initializers? VarTemplateDecl *FoundDef = getTemplateDefinition(FoundTemplate); - 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() && - D->getDeclContext()->isRecord()) - return Importer.MapImported(D, FoundTemplate); - + if (D->getDeclContext()->isRecord()) { + assert(FoundTemplate->getDeclContext()->isRecord() && + "Member variable template imported as non-member, " + "inconsistent imported AST?"); + if (FoundDef) + return Importer.MapImported(D, FoundDef); + if (!D->isThisDeclarationADefinition()) + return Importer.MapImported(D, FoundTemplate); + } else { + if (FoundDef && D->isThisDeclarationADefinition()) + return Importer.MapImported(D, FoundDef); + } FoundByLookup = FoundTemplate; break; } @@ -6374,7 +6378,10 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl( // variable. return Importer.MapImported(D, FoundDef); } + // FIXME HandleNameConflict + return make_error<ASTImportError>(ASTImportError::NameConflict); } + return Importer.MapImported(D, D2); } else { TemplateArgumentListInfo ToTAInfo; if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) { diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 5f4d8d040772c..d439a14b7b998 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -5050,6 +5050,111 @@ TEST_P(ImportFriendClasses, RecordVarTemplateDecl) { EXPECT_EQ(ToTUX, ToX); } +TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclConflict) { + Decl *ToTU = getToTuDecl( + R"( + template <class U> + constexpr int X = 1; + )", + Lang_CXX14); + + Decl *FromTU = getTuDecl( + R"( + template <class U> + constexpr int X = 2; + )", + Lang_CXX14, "input1.cc"); + auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match( + FromTU, varTemplateDecl(hasName("X"))); + auto *ToX = Import(FromX, Lang_CXX11); + // FIXME: This import should fail. + EXPECT_TRUE(ToX); +} + +TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateStaticDefinition) { + Decl *ToTU = getToTuDecl( + R"( + struct A { + template <class U, class V> + static int X; + }; + )", + Lang_CXX14); + auto *ToX = FirstDeclMatcher<VarTemplateDecl>().match( + ToTU, varTemplateDecl(hasName("X"))); + ASSERT_FALSE(ToX->isThisDeclarationADefinition()); + + Decl *FromTU = getTuDecl( + R"( + struct A { + template <class U> + static int X; + }; + template <class U> + int A::X = 2; + )", + Lang_CXX14, "input1.cc"); + auto *FromXDef = LastDeclMatcher<VarTemplateDecl>().match( + FromTU, varTemplateDecl(hasName("X"))); + ASSERT_TRUE(FromXDef->isThisDeclarationADefinition()); + auto *ToXDef = Import(FromXDef, Lang_CXX14); + EXPECT_TRUE(ToXDef); + EXPECT_TRUE(ToXDef->isThisDeclarationADefinition()); + EXPECT_EQ(ToXDef->getPreviousDecl(), ToX); +} + +TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateSpecializationDeclValue) { + Decl *ToTU = getToTuDecl( + R"( + template <class U> + constexpr int X = U::Value; + struct A { static constexpr int Value = 1; }; + constexpr int Y = X<A>; + )", + Lang_CXX14); + + auto *ToTUX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( + ToTU, varTemplateSpecializationDecl(hasName("X"))); + Decl *FromTU = getTuDecl( + R"( + template <class U> + constexpr int X = U::Value; + struct A { static constexpr int Value = 1; }; + constexpr int Y = X<A>; + )", + Lang_CXX14, "input1.cc"); + auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( + FromTU, varTemplateSpecializationDecl(hasName("X"))); + auto *ToX = Import(FromX, Lang_CXX14); + EXPECT_TRUE(ToX); + EXPECT_EQ(ToTUX, ToX); +} + +TEST_P(ASTImporterOptionSpecificTestBase, + VarTemplateSpecializationDeclValueConflict) { + Decl *ToTU = getToTuDecl( + R"( + template <class U> + constexpr int X = U::Value; + struct A { static constexpr int Value = 1; }; + constexpr int Y = X<A>; + )", + Lang_CXX14); + + Decl *FromTU = getTuDecl( + R"( + template <class U> + constexpr int X = U::Value; + struct A { static constexpr int Value = 2; }; + constexpr int Y = X<A>; + )", + Lang_CXX14, "input1.cc"); + auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( + FromTU, varTemplateSpecializationDecl(hasName("X"))); + auto *ToX = Import(FromX, Lang_CXX14); + EXPECT_FALSE(ToX); +} + TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) { constexpr auto Code = R"( From 87b62c7dde30c0a9c652edba81f4234a9999f00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <balazs.k...@ericsson.com> Date: Wed, 22 Nov 2023 17:12:25 +0100 Subject: [PATCH 2/3] removed changes related to VarTemplateSpecializationDecl --- clang/lib/AST/ASTImporter.cpp | 3 -- clang/unittests/AST/ASTImporterTest.cpp | 54 +------------------------ 2 files changed, 1 insertion(+), 56 deletions(-) diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 7a5e3d6653285..e9698915d1940 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -6378,10 +6378,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl( // variable. return Importer.MapImported(D, FoundDef); } - // FIXME HandleNameConflict - return make_error<ASTImportError>(ASTImportError::NameConflict); } - return Importer.MapImported(D, D2); } else { TemplateArgumentListInfo ToTAInfo; if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) { diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index d439a14b7b998..7d1c770108331 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -5051,7 +5051,7 @@ TEST_P(ImportFriendClasses, RecordVarTemplateDecl) { } TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclConflict) { - Decl *ToTU = getToTuDecl( + getToTuDecl( R"( template <class U> constexpr int X = 1; @@ -5103,58 +5103,6 @@ TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateStaticDefinition) { EXPECT_EQ(ToXDef->getPreviousDecl(), ToX); } -TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateSpecializationDeclValue) { - Decl *ToTU = getToTuDecl( - R"( - template <class U> - constexpr int X = U::Value; - struct A { static constexpr int Value = 1; }; - constexpr int Y = X<A>; - )", - Lang_CXX14); - - auto *ToTUX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( - ToTU, varTemplateSpecializationDecl(hasName("X"))); - Decl *FromTU = getTuDecl( - R"( - template <class U> - constexpr int X = U::Value; - struct A { static constexpr int Value = 1; }; - constexpr int Y = X<A>; - )", - Lang_CXX14, "input1.cc"); - auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( - FromTU, varTemplateSpecializationDecl(hasName("X"))); - auto *ToX = Import(FromX, Lang_CXX14); - EXPECT_TRUE(ToX); - EXPECT_EQ(ToTUX, ToX); -} - -TEST_P(ASTImporterOptionSpecificTestBase, - VarTemplateSpecializationDeclValueConflict) { - Decl *ToTU = getToTuDecl( - R"( - template <class U> - constexpr int X = U::Value; - struct A { static constexpr int Value = 1; }; - constexpr int Y = X<A>; - )", - Lang_CXX14); - - Decl *FromTU = getTuDecl( - R"( - template <class U> - constexpr int X = U::Value; - struct A { static constexpr int Value = 2; }; - constexpr int Y = X<A>; - )", - Lang_CXX14, "input1.cc"); - auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match( - FromTU, varTemplateSpecializationDecl(hasName("X"))); - auto *ToX = Import(FromX, Lang_CXX14); - EXPECT_FALSE(ToX); -} - TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) { constexpr auto Code = R"( From 1edb738afb2e3c9d348e825ec4d999d12d074ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= <balazs.k...@ericsson.com> Date: Tue, 5 Dec 2023 16:06:48 +0100 Subject: [PATCH 3/3] fixed wrong test code --- clang/unittests/AST/ASTImporterTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 7d1c770108331..10a8b3be11485 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -5075,7 +5075,7 @@ TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateStaticDefinition) { Decl *ToTU = getToTuDecl( R"( struct A { - template <class U, class V> + template <class U> static int X; }; )", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits