From: Bill Wendling Date: Thu, 28 Nov 2013 00:34:28 +0000 (+0000) Subject: Merging r195887: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=65173e04eacb68ff89a58fbff14979eb318896c9;p=clang Merging r195887: ------------------------------------------------------------------------ r195887 | majnemer | 2013-11-27 14:57:44 -0800 (Wed, 27 Nov 2013) | 9 lines Sema: Instantiation of variable definitions weren't local enough We wouldn't properly save and restore the pending local instantiations we had built up prior to instantiation of a variable definition. This would lead to us instantiating too much causing crashes and other general badness. This fixes PR14374. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_34@195901 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ed285832c6..618e8d0496 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -6406,6 +6406,24 @@ public: /// types, static variables, enumerators, etc. std::deque PendingLocalImplicitInstantiations; + class SavePendingLocalImplicitInstantiationsRAII { + public: + SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) { + SavedPendingLocalImplicitInstantiations.swap( + S.PendingLocalImplicitInstantiations); + } + + ~SavePendingLocalImplicitInstantiationsRAII() { + SavedPendingLocalImplicitInstantiations.swap( + S.PendingLocalImplicitInstantiations); + } + + private: + Sema &S; + std::deque + SavedPendingLocalImplicitInstantiations; + }; + void PerformPendingInstantiations(bool LocalOnly = false); TypeSourceInfo *SubstType(TypeSourceInfo *T, diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 32f304338c..574659cd26 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3224,10 +3224,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, // while we're still within our own instantiation context. SmallVector SavedVTableUses; std::deque SavedPendingInstantiations; - std::deque - SavedPendingLocalImplicitInstantiations; - SavedPendingLocalImplicitInstantiations.swap( - PendingLocalImplicitInstantiations); + SavePendingLocalImplicitInstantiationsRAII + SavedPendingLocalImplicitInstantiations(*this); if (Recursive) { VTableUses.swap(SavedVTableUses); PendingInstantiations.swap(SavedPendingInstantiations); @@ -3308,8 +3306,6 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, "PendingInstantiations should be empty before it is discarded."); PendingInstantiations.swap(SavedPendingInstantiations); } - SavedPendingLocalImplicitInstantiations.swap( - PendingLocalImplicitInstantiations); } VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation( @@ -3727,6 +3723,8 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, // while we're still within our own instantiation context. SmallVector SavedVTableUses; std::deque SavedPendingInstantiations; + SavePendingLocalImplicitInstantiationsRAII + SavedPendingLocalImplicitInstantiations(*this); if (Recursive) { VTableUses.swap(SavedVTableUses); PendingInstantiations.swap(SavedPendingInstantiations); diff --git a/test/SemaTemplate/instantiate-local-class.cpp b/test/SemaTemplate/instantiate-local-class.cpp index 2b5db0fda3..bdc5ea0d4a 100644 --- a/test/SemaTemplate/instantiate-local-class.cpp +++ b/test/SemaTemplate/instantiate-local-class.cpp @@ -160,3 +160,23 @@ void call() { C::func([]() {}); } } + +namespace PR14373 { + struct function { + template function(_Functor __f) { __f(); } + }; + template function exec_func(Func f) { + struct functor { + functor(Func f) : func(f) {} + void operator()() const { func(); } + Func func; + }; + return functor(f); + } + struct Type { + void operator()() const {} + }; + int call() { + exec_func(Type()); + } +}