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
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e767f6a..8e49429 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1014,11 +1014,11 @@
   // 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 @@
                             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 @@
                                       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 @@
     std::pair<const TemplateArgument *, unsigned> Innermost
       = TemplateArgs.getInnermost();
 
+    void *InsertPos = 0;
     FunctionDecl *SpecFunc
       = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
                                              InsertPos);
@@ -1476,7 +1476,7 @@
                          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 @@
 
   // Add this partial specialization to the set of class template partial
   // specializations.
-  ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos);
+  ClassTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0);
   return InstPartialSpec;
 }