From a307b9d3d811ee979653936eebad3e86df84055a Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Mon, 26 Mar 2018 18:22:47 +0000 Subject: [MS] Fix late-parsed template infinite loop in eager instantiation Summary: This fixes PR33561 and PR34185. Don't store pending template instantiations for late-parsed templates in the normal PendingInstantiations queue. Instead, use a separate list that will only be parsed and instantiated at end of TU when late template parsing actually works and doesn't infinite loop. Reviewers: rsmith, thakis, hans Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D44846 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328567 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'lib/Sema/Sema.cpp') diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 171b3ec5f8..5c0026cd37 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -850,6 +850,20 @@ void Sema::ActOnEndOfTranslationUnit() { if (PP.isCodeCompletionEnabled()) return; + // Transfer late parsed template instantiations over to the pending template + // instantiation list. During normal compliation, the late template parser + // will be installed and instantiating these templates will succeed. + // + // If we are building a TU prefix for serialization, it is also safe to + // transfer these over, even though they are not parsed. The end of the TU + // should be outside of any eager template instantiation scope, so when this + // AST is deserialized, these templates will not be parsed until the end of + // the combined TU. + PendingInstantiations.insert(PendingInstantiations.end(), + LateParsedInstantiations.begin(), + LateParsedInstantiations.end()); + LateParsedInstantiations.clear(); + // Complete translation units and modules define vtables and perform implicit // instantiations. PCH files do not. if (TUKind != TU_Prefix) { @@ -879,8 +893,13 @@ void Sema::ActOnEndOfTranslationUnit() { PendingInstantiations.insert(PendingInstantiations.begin(), Pending.begin(), Pending.end()); } + PerformPendingInstantiations(); + assert(LateParsedInstantiations.empty() && + "end of TU template instantiation should not create more " + "late-parsed templates"); + if (LateTemplateParserCleanup) LateTemplateParserCleanup(OpaqueParser); -- cgit v1.2.1