Author: Balázs Kéri Date: 2021-01-07T11:28:11+01:00 New Revision: 0877b963ef2d3c384b47f7a6161c9d9ab106a7f2
URL: https://github.com/llvm/llvm-project/commit/0877b963ef2d3c384b47f7a6161c9d9ab106a7f2 DIFF: https://github.com/llvm/llvm-project/commit/0877b963ef2d3c384b47f7a6161c9d9ab106a7f2.diff LOG: [clang][ASTImporter] Fix a possible assertion failure `NeedsInjectedClassNameType(Decl)'. The assertion can happen if ASTImporter imports a CXXRecordDecl in a template and then imports another redeclaration of this declaration, while the first import is in progress. The process of first import did not set the "described template" yet and the second import finds the first declaration at setting the injected types. Setting the injected type requires in the assertion that the described template is set. The exact assertion was: clang/lib/AST/ASTContext.cpp:4411: clang::QualType clang::ASTContext::getInjectedClassNameType(clang::CXXRecordDecl*, clang::QualType) const: Assertion `NeedsInjectedClassNameType(Decl)' failed. Reviewed By: shafik Differential Revision: https://reviews.llvm.org/D94067 Added: Modified: clang/lib/AST/ASTImporter.cpp clang/unittests/AST/ASTImporterTest.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 54816b721a4a..5c6aa5d3c015 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5393,16 +5393,16 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { CXXRecordDecl *FromTemplated = D->getTemplatedDecl(); + auto TemplateParamsOrErr = import(D->getTemplateParameters()); + if (!TemplateParamsOrErr) + return TemplateParamsOrErr.takeError(); + // Create the declaration that is being templated. CXXRecordDecl *ToTemplated; if (Error Err = importInto(ToTemplated, FromTemplated)) return std::move(Err); // Create the class template declaration itself. - auto TemplateParamsOrErr = import(D->getTemplateParameters()); - if (!TemplateParamsOrErr) - return TemplateParamsOrErr.takeError(); - ClassTemplateDecl *D2; if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, Loc, Name, *TemplateParamsOrErr, ToTemplated)) diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 2472fa265589..8a07a5b8e0df 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -6141,6 +6141,41 @@ TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) { EXPECT_EQ(ToAttr->getAnnotation(), "A"); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) { + Decl *FromTU = getTuDecl( + R"( + + namespace std { + template<typename T> + class basic_stringbuf; + } + namespace std { + class char_traits; + template<typename T = char_traits> + class basic_stringbuf; + } + namespace std { + template<typename T> + class basic_stringbuf {}; + } + + )", + Lang_CXX11); + + auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11)); + EXPECT_TRUE(To1); + + auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match( + FromTU, + classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit()))); + auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11)); + EXPECT_TRUE(To2); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits