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.

llvm-svn: 195887
This commit is contained in:
David Majnemer 2013-11-27 22:57:44 +00:00
parent e3d6bcf5e0
commit fd6c685f2e
3 changed files with 42 additions and 6 deletions

View File

@ -6406,6 +6406,24 @@ public:
/// types, static variables, enumerators, etc.
std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
class SavePendingLocalImplicitInstantiationsRAII {
public:
SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) {
SavedPendingLocalImplicitInstantiations.swap(
S.PendingLocalImplicitInstantiations);
}
~SavePendingLocalImplicitInstantiationsRAII() {
SavedPendingLocalImplicitInstantiations.swap(
S.PendingLocalImplicitInstantiations);
}
private:
Sema &S;
std::deque<PendingImplicitInstantiation>
SavedPendingLocalImplicitInstantiations;
};
void PerformPendingInstantiations(bool LocalOnly = false);
TypeSourceInfo *SubstType(TypeSourceInfo *T,

View File

@ -3222,10 +3222,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// while we're still within our own instantiation context.
SmallVector<VTableUse, 16> SavedVTableUses;
std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
std::deque<PendingImplicitInstantiation>
SavedPendingLocalImplicitInstantiations;
SavedPendingLocalImplicitInstantiations.swap(
PendingLocalImplicitInstantiations);
SavePendingLocalImplicitInstantiationsRAII
SavedPendingLocalImplicitInstantiations(*this);
if (Recursive) {
VTableUses.swap(SavedVTableUses);
PendingInstantiations.swap(SavedPendingInstantiations);
@ -3306,8 +3304,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<VTableUse, 16> SavedVTableUses;
std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
SavePendingLocalImplicitInstantiationsRAII
SavedPendingLocalImplicitInstantiations(*this);
if (Recursive) {
VTableUses.swap(SavedVTableUses);
PendingInstantiations.swap(SavedPendingInstantiations);

View File

@ -160,3 +160,23 @@ void call() {
C::func([]() {});
}
}
namespace PR14373 {
struct function {
template <typename _Functor> function(_Functor __f) { __f(); }
};
template <typename Func> 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());
}
}