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:
parent
e3d6bcf5e0
commit
fd6c685f2e
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue