forked from OSchip/llvm-project
When we form a new function/class template specialization, we first
search for the specialization (in a folding set) and, if not found form a *Decl that is then inserted into that folding set. In rare cases, the folding set may be reallocated between the search and the insertion, causing a crash. No test case, because triggering rehashing consistently in a small test case is not feasible. Fixes <rdar://problem/11115071>. llvm-svn: 153575
This commit is contained in:
parent
20b32d2da6
commit
ce9978ff1f
|
@ -2255,22 +2255,7 @@ FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C,
|
|||
TemplateArgsAsWritten,
|
||||
PointOfInstantiation);
|
||||
TemplateOrSpecialization = Info;
|
||||
|
||||
// Insert this function template specialization into the set of known
|
||||
// function template specializations.
|
||||
if (InsertPos)
|
||||
Template->addSpecialization(Info, InsertPos);
|
||||
else {
|
||||
// Try to insert the new node. If there is an existing node, leave it, the
|
||||
// set will contain the canonical decls while
|
||||
// FunctionTemplateDecl::findSpecialization will return
|
||||
// the most recent redeclarations.
|
||||
FunctionTemplateSpecializationInfo *Existing
|
||||
= Template->getSpecializations().GetOrInsertNode(Info);
|
||||
(void)Existing;
|
||||
assert((!Existing || Existing->Function->isCanonicalDecl()) &&
|
||||
"Set is supposed to only contain canonical decls");
|
||||
}
|
||||
Template->addSpecialization(Info, InsertPos);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -238,7 +238,10 @@ FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
|
|||
|
||||
void FunctionTemplateDecl::addSpecialization(
|
||||
FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
|
||||
getSpecializations().InsertNode(Info, InsertPos);
|
||||
if (InsertPos)
|
||||
getSpecializations().InsertNode(Info, InsertPos);
|
||||
else
|
||||
getSpecializations().GetOrInsertNode(Info);
|
||||
if (ASTMutationListener *L = getASTMutationListener())
|
||||
L->AddedCXXTemplateSpecialization(this, Info->Function);
|
||||
}
|
||||
|
@ -322,7 +325,14 @@ ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
|
|||
|
||||
void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
|
||||
void *InsertPos) {
|
||||
getSpecializations().InsertNode(D, InsertPos);
|
||||
if (InsertPos)
|
||||
getSpecializations().InsertNode(D, InsertPos);
|
||||
else {
|
||||
ClassTemplateSpecializationDecl *Existing
|
||||
= getSpecializations().GetOrInsertNode(D);
|
||||
(void)Existing;
|
||||
assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
|
||||
}
|
||||
if (ASTMutationListener *L = getASTMutationListener())
|
||||
L->AddedCXXTemplateSpecialization(this, D);
|
||||
}
|
||||
|
@ -338,7 +348,15 @@ ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
|
|||
void ClassTemplateDecl::AddPartialSpecialization(
|
||||
ClassTemplatePartialSpecializationDecl *D,
|
||||
void *InsertPos) {
|
||||
getPartialSpecializations().InsertNode(D, InsertPos);
|
||||
if (InsertPos)
|
||||
getPartialSpecializations().InsertNode(D, InsertPos);
|
||||
else {
|
||||
ClassTemplatePartialSpecializationDecl *Existing
|
||||
= getPartialSpecializations().GetOrInsertNode(D);
|
||||
(void)Existing;
|
||||
assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
|
||||
}
|
||||
|
||||
if (ASTMutationListener *L = getASTMutationListener())
|
||||
L->AddedCXXTemplateSpecialization(this, D);
|
||||
}
|
||||
|
|
|
@ -1014,11 +1014,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
|
|||
// Check whether there is already a function template specialization for
|
||||
// this declaration.
|
||||
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
|
||||
void *InsertPos = 0;
|
||||
if (FunctionTemplate && !TemplateParams) {
|
||||
std::pair<const TemplateArgument *, unsigned> Innermost
|
||||
= TemplateArgs.getInnermost();
|
||||
|
||||
void *InsertPos = 0;
|
||||
FunctionDecl *SpecFunc
|
||||
= FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
|
||||
InsertPos);
|
||||
|
@ -1148,7 +1148,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
|
|||
TemplateArgumentList::CreateCopy(SemaRef.Context,
|
||||
Innermost.first,
|
||||
Innermost.second),
|
||||
InsertPos);
|
||||
/*InsertPos=*/0);
|
||||
} else if (isFriend) {
|
||||
// Note, we need this connection even if the friend doesn't have a body.
|
||||
// Its body may exist but not have been attached yet due to deferred
|
||||
|
@ -1316,7 +1316,6 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
|||
TemplateParameterList *TemplateParams,
|
||||
bool IsClassScopeSpecialization) {
|
||||
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
|
||||
void *InsertPos = 0;
|
||||
if (FunctionTemplate && !TemplateParams) {
|
||||
// We are creating a function template specialization from a function
|
||||
// template. Check whether there is already a function template
|
||||
|
@ -1324,6 +1323,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
|||
std::pair<const TemplateArgument *, unsigned> Innermost
|
||||
= TemplateArgs.getInnermost();
|
||||
|
||||
void *InsertPos = 0;
|
||||
FunctionDecl *SpecFunc
|
||||
= FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
|
||||
InsertPos);
|
||||
|
@ -1476,7 +1476,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
|||
TemplateArgumentList::CreateCopy(SemaRef.Context,
|
||||
Innermost.first,
|
||||
Innermost.second),
|
||||
InsertPos);
|
||||
/*InsertPos=*/0);
|
||||
} else if (!isFriend) {
|
||||
// Record that this is an instantiation of a member function.
|
||||
Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
|
||||
|
@ -2125,7 +2125,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
|
|||
|
||||
// Add this partial specialization to the set of class template partial
|
||||
// specializations.
|
||||
ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos);
|
||||
ClassTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0);
|
||||
return InstPartialSpec;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue