forked from OSchip/llvm-project
Ensure that we don't leave behind "InstantiatingSpecialization" entries
after destroying an InstantiatingTemplate object. This previously caused us to (silently!) bail out of class template instantiation, thinking we'd produced an error, in some corner cases.
This commit is contained in:
parent
f23fae29eb
commit
a3fe12dc58
|
@ -390,6 +390,9 @@ void Sema::Initialize() {
|
|||
}
|
||||
|
||||
Sema::~Sema() {
|
||||
assert(InstantiatingSpecializations.empty() &&
|
||||
"failed to clean up an InstantiatingTemplate?");
|
||||
|
||||
if (VisContext) FreeVisContext();
|
||||
|
||||
// Kill all the active scopes.
|
||||
|
|
|
@ -261,7 +261,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|||
|
||||
AlreadyInstantiating = !Inst.Entity ? false :
|
||||
!SemaRef.InstantiatingSpecializations
|
||||
.insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
|
||||
.insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
|
||||
.second;
|
||||
atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
|
||||
}
|
||||
|
@ -480,7 +480,7 @@ void Sema::InstantiatingTemplate::Clear() {
|
|||
auto &Active = SemaRef.CodeSynthesisContexts.back();
|
||||
if (Active.Entity)
|
||||
SemaRef.InstantiatingSpecializations.erase(
|
||||
std::make_pair(Active.Entity, Active.Kind));
|
||||
{Active.Entity->getCanonicalDecl(), Active.Kind});
|
||||
}
|
||||
|
||||
atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
|
||||
|
@ -3037,14 +3037,16 @@ bool Sema::usesPartialOrExplicitSpecialization(
|
|||
/// Get the instantiation pattern to use to instantiate the definition of a
|
||||
/// given ClassTemplateSpecializationDecl (either the pattern of the primary
|
||||
/// template or of a partial specialization).
|
||||
static CXXRecordDecl *
|
||||
static ActionResult<CXXRecordDecl *>
|
||||
getPatternForClassTemplateSpecialization(
|
||||
Sema &S, SourceLocation PointOfInstantiation,
|
||||
ClassTemplateSpecializationDecl *ClassTemplateSpec,
|
||||
TemplateSpecializationKind TSK, bool Complain) {
|
||||
TemplateSpecializationKind TSK) {
|
||||
Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec);
|
||||
if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
|
||||
return nullptr;
|
||||
if (Inst.isInvalid())
|
||||
return {/*Invalid=*/true};
|
||||
if (Inst.isAlreadyInstantiating())
|
||||
return {/*Invalid=*/false};
|
||||
|
||||
llvm::PointerUnion<ClassTemplateDecl *,
|
||||
ClassTemplatePartialSpecializationDecl *>
|
||||
|
@ -3141,7 +3143,7 @@ getPatternForClassTemplateSpecialization(
|
|||
<< S.getTemplateArgumentBindingsText(
|
||||
P->Partial->getTemplateParameters(), *P->Args);
|
||||
|
||||
return nullptr;
|
||||
return {/*Invalid=*/true};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3192,14 +3194,15 @@ bool Sema::InstantiateClassTemplateSpecialization(
|
|||
if (ClassTemplateSpec->isInvalidDecl())
|
||||
return true;
|
||||
|
||||
CXXRecordDecl *Pattern = getPatternForClassTemplateSpecialization(
|
||||
*this, PointOfInstantiation, ClassTemplateSpec, TSK, Complain);
|
||||
if (!Pattern)
|
||||
return true;
|
||||
ActionResult<CXXRecordDecl *> Pattern =
|
||||
getPatternForClassTemplateSpecialization(*this, PointOfInstantiation,
|
||||
ClassTemplateSpec, TSK);
|
||||
if (!Pattern.isUsable())
|
||||
return Pattern.isInvalid();
|
||||
|
||||
return InstantiateClass(PointOfInstantiation, ClassTemplateSpec, Pattern,
|
||||
getTemplateInstantiationArgs(ClassTemplateSpec), TSK,
|
||||
Complain);
|
||||
return InstantiateClass(
|
||||
PointOfInstantiation, ClassTemplateSpec, Pattern.get(),
|
||||
getTemplateInstantiationArgs(ClassTemplateSpec), TSK, Complain);
|
||||
}
|
||||
|
||||
/// Instantiates the definitions of all of the member
|
||||
|
|
|
@ -4521,6 +4521,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
|
|||
// into a template instantiation for this specific function template
|
||||
// specialization, which is not a SFINAE context, so that we diagnose any
|
||||
// further errors in the declaration itself.
|
||||
//
|
||||
// FIXME: This is a hack.
|
||||
typedef Sema::CodeSynthesisContext ActiveInstType;
|
||||
ActiveInstType &ActiveInst = SemaRef.CodeSynthesisContexts.back();
|
||||
if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||
|
||||
|
@ -4530,6 +4532,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
|
|||
assert(FunTmpl->getTemplatedDecl() == Tmpl &&
|
||||
"Deduction from the wrong function template?");
|
||||
(void) FunTmpl;
|
||||
SemaRef.InstantiatingSpecializations.erase(
|
||||
{ActiveInst.Entity->getCanonicalDecl(), ActiveInst.Kind});
|
||||
atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst);
|
||||
ActiveInst.Kind = ActiveInstType::TemplateInstantiation;
|
||||
ActiveInst.Entity = New;
|
||||
|
|
Loading…
Reference in New Issue