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,
|
TemplateArgsAsWritten,
|
||||||
PointOfInstantiation);
|
PointOfInstantiation);
|
||||||
TemplateOrSpecialization = Info;
|
TemplateOrSpecialization = Info;
|
||||||
|
Template->addSpecialization(Info, InsertPos);
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -238,7 +238,10 @@ FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
|
||||||
|
|
||||||
void FunctionTemplateDecl::addSpecialization(
|
void FunctionTemplateDecl::addSpecialization(
|
||||||
FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
|
FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
|
||||||
getSpecializations().InsertNode(Info, InsertPos);
|
if (InsertPos)
|
||||||
|
getSpecializations().InsertNode(Info, InsertPos);
|
||||||
|
else
|
||||||
|
getSpecializations().GetOrInsertNode(Info);
|
||||||
if (ASTMutationListener *L = getASTMutationListener())
|
if (ASTMutationListener *L = getASTMutationListener())
|
||||||
L->AddedCXXTemplateSpecialization(this, Info->Function);
|
L->AddedCXXTemplateSpecialization(this, Info->Function);
|
||||||
}
|
}
|
||||||
|
@ -322,7 +325,14 @@ ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
|
||||||
|
|
||||||
void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
|
void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
|
||||||
void *InsertPos) {
|
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())
|
if (ASTMutationListener *L = getASTMutationListener())
|
||||||
L->AddedCXXTemplateSpecialization(this, D);
|
L->AddedCXXTemplateSpecialization(this, D);
|
||||||
}
|
}
|
||||||
|
@ -338,7 +348,15 @@ ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
|
||||||
void ClassTemplateDecl::AddPartialSpecialization(
|
void ClassTemplateDecl::AddPartialSpecialization(
|
||||||
ClassTemplatePartialSpecializationDecl *D,
|
ClassTemplatePartialSpecializationDecl *D,
|
||||||
void *InsertPos) {
|
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())
|
if (ASTMutationListener *L = getASTMutationListener())
|
||||||
L->AddedCXXTemplateSpecialization(this, D);
|
L->AddedCXXTemplateSpecialization(this, D);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1014,11 +1014,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
|
||||||
// Check whether there is already a function template specialization for
|
// Check whether there is already a function template specialization for
|
||||||
// this declaration.
|
// this declaration.
|
||||||
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
|
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
|
||||||
void *InsertPos = 0;
|
|
||||||
if (FunctionTemplate && !TemplateParams) {
|
if (FunctionTemplate && !TemplateParams) {
|
||||||
std::pair<const TemplateArgument *, unsigned> Innermost
|
std::pair<const TemplateArgument *, unsigned> Innermost
|
||||||
= TemplateArgs.getInnermost();
|
= TemplateArgs.getInnermost();
|
||||||
|
|
||||||
|
void *InsertPos = 0;
|
||||||
FunctionDecl *SpecFunc
|
FunctionDecl *SpecFunc
|
||||||
= FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
|
= FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
|
||||||
InsertPos);
|
InsertPos);
|
||||||
|
@ -1148,7 +1148,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
|
||||||
TemplateArgumentList::CreateCopy(SemaRef.Context,
|
TemplateArgumentList::CreateCopy(SemaRef.Context,
|
||||||
Innermost.first,
|
Innermost.first,
|
||||||
Innermost.second),
|
Innermost.second),
|
||||||
InsertPos);
|
/*InsertPos=*/0);
|
||||||
} else if (isFriend) {
|
} else if (isFriend) {
|
||||||
// Note, we need this connection even if the friend doesn't have a body.
|
// 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
|
// Its body may exist but not have been attached yet due to deferred
|
||||||
|
@ -1316,7 +1316,6 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
||||||
TemplateParameterList *TemplateParams,
|
TemplateParameterList *TemplateParams,
|
||||||
bool IsClassScopeSpecialization) {
|
bool IsClassScopeSpecialization) {
|
||||||
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
|
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
|
||||||
void *InsertPos = 0;
|
|
||||||
if (FunctionTemplate && !TemplateParams) {
|
if (FunctionTemplate && !TemplateParams) {
|
||||||
// We are creating a function template specialization from a function
|
// We are creating a function template specialization from a function
|
||||||
// template. Check whether there is already a function template
|
// template. Check whether there is already a function template
|
||||||
|
@ -1324,6 +1323,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
||||||
std::pair<const TemplateArgument *, unsigned> Innermost
|
std::pair<const TemplateArgument *, unsigned> Innermost
|
||||||
= TemplateArgs.getInnermost();
|
= TemplateArgs.getInnermost();
|
||||||
|
|
||||||
|
void *InsertPos = 0;
|
||||||
FunctionDecl *SpecFunc
|
FunctionDecl *SpecFunc
|
||||||
= FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
|
= FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
|
||||||
InsertPos);
|
InsertPos);
|
||||||
|
@ -1476,7 +1476,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
||||||
TemplateArgumentList::CreateCopy(SemaRef.Context,
|
TemplateArgumentList::CreateCopy(SemaRef.Context,
|
||||||
Innermost.first,
|
Innermost.first,
|
||||||
Innermost.second),
|
Innermost.second),
|
||||||
InsertPos);
|
/*InsertPos=*/0);
|
||||||
} else if (!isFriend) {
|
} else if (!isFriend) {
|
||||||
// Record that this is an instantiation of a member function.
|
// Record that this is an instantiation of a member function.
|
||||||
Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
|
Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
|
||||||
|
@ -2125,7 +2125,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
|
||||||
|
|
||||||
// Add this partial specialization to the set of class template partial
|
// Add this partial specialization to the set of class template partial
|
||||||
// specializations.
|
// specializations.
|
||||||
ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos);
|
ClassTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0);
|
||||||
return InstPartialSpec;
|
return InstPartialSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue