diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-03-28 14:34:23 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-03-28 14:34:23 +0000 |
commit | 1e1e9722cb4ea6027e2c4885c7a8f26d3726ca7d (patch) | |
tree | 30896acb268f5b20f658960e6d2b54384317d547 | |
parent | 6488dc31153be6f98b404c7860be6c66bb4ec917 (diff) |
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>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153575 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/Decl.cpp | 17 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 10 |
3 files changed, 27 insertions, 24 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e476bfb6f1..399f2e48ab 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -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 diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index dc16379554..4590195d6b 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -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); } diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index e767f6a7d9..8e4942988d 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } |