<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><span class="Apple-style-span" style="line-height: 21px; "><div style="font-family: 'Andale Mono'; "></div><div style="font-family: 'Andale Mono'; "><br></div><div style="font-family: 'Andale Mono'; ">UNREACHABLE executed at ASTContext.cpp:820!</div><div style="font-family: 'Andale Mono'; ">0  clang             0x0000000102326955 PrintStackTrace(void*) + 53</div><div style="font-family: 'Andale Mono'; ">1  clang             0x000000010232700b SignalHandler(int) + 379</div><div style="font-family: 'Andale Mono'; ">2  libSystem.B.dylib 0x00007fff8a58f1ba _sigtramp + 26</div><div style="font-family: 'Andale Mono'; ">3  libSystem.B.dylib 0x00007fff8a5331e1 szone_malloc_should_clear + 2070</div><div style="font-family: 'Andale Mono'; ">4  clang             0x0000000102326cdb raise + 27</div><div style="font-family: 'Andale Mono'; ">5  clang             0x0000000102326d9a abort + 26</div><div style="font-family: 'Andale Mono'; ">6  clang             0x000000010230ada4 llvm::llvm_unreachable_internal(char const*, char const*, unsigned int) + 244</div><div style="font-family: 'Andale Mono'; ">7  clang             0x0000000100f06278 clang::ASTContext::getTypeInfo(clang::Type const*) const + 120</div><div style="font-family: 'Andale Mono'; ">8  clang             0x0000000100f2e8e9 clang::ASTContext::getTypeAlign(clang::Type const*) const + 25</div><div style="font-family: 'Andale Mono'; ">9  clang             0x0000000100f06025 clang::ASTContext::getPreferredTypeAlign(clang::Type const*) const + 37</div><div style="font-family: 'Andale Mono'; ">10 clang             0x0000000100f055ae clang::ASTContext::getDeclAlign(clang::Decl const*, bool) const + 1166</div><div style="font-family: 'Andale Mono'; ">11 clang             0x00000001002b6977 clang::CodeGen::CodeGenFunction::EmitAutoVarAlloca(clang::VarDecl const&) + 215</div><div style="font-family: 'Andale Mono'; ">12 clang             0x00000001002b4cbd clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(clang::VarDecl const&) + 45</div><div style="font-family: 'Andale Mono'; ">13 clang             0x00000001002b4b91 clang::CodeGen::CodeGenFunction::EmitVarDecl(clang::VarDecl const&) + 81</div><div style="font-family: 'Andale Mono'; ">14 clang             0x00000001002b49f4 clang::CodeGen::CodeGenFunction::EmitDecl(clang::Decl const&) + 212</div><div style="font-family: 'Andale Mono'; ">15 clang             0x000000010038b84f clang::CodeGen::CodeGenFunction::EmitDeclStmt(clang::DeclStmt const&) + 143</div><div style="font-family: 'Andale Mono'; ">16 clang             0x0000000100385c92 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*) + 290</div><div style="font-family: 'Andale Mono'; ">17 clang             0x0000000100385591 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*) + 113</div><div style="font-family: 'Andale Mono'; ">18 clang             0x000000010038b59f clang::CodeGen::CodeGenFunction::EmitCompoundStmt(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) + 447</div><div style="font-family: 'Andale Mono'; ">19 clang             0x0000000100385c70 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*) + 256</div><div style="font-family: 'Andale Mono'; ">20 clang             0x0000000100385591 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*) + 113</div><div style="font-family: 'Andale Mono'; ">21 clang             0x00000001003a62ac clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::CodeGen::FunctionArgList&) + 172</div><div style="font-family: 'Andale Mono'; ">22 clang             0x00000001003a6751 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) + 1169</div><div style="font-family: 'Andale Mono'; ">23 clang             0x00000001003b2bfd clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl) + 1277</div><div style="font-family: 'Andale Mono'; ">24 clang             0x00000001003b011f clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl) + 623</div><div style="font-family: 'Andale Mono'; ">25 clang             0x00000001003ad161 clang::CodeGen::CodeGenModule::EmitDeferred() + 561</div><div style="font-family: 'Andale Mono'; ">26 clang             0x00000001003acd99 clang::CodeGen::CodeGenModule::Release() + 25</div><div style="font-family: 'Andale Mono'; ">27 clang             0x00000001003fbea1 (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) + 161</div><div style="font-family: 'Andale Mono'; ">28 clang             0x00000001003a2fb3 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) + 163</div><div style="font-family: 'Andale Mono'; ">29 clang             0x000000010040ea1c clang::ParseAST(clang::Sema&, bool) + 924</div><div style="font-family: 'Andale Mono'; ">30 clang             0x0000000100083526 clang::ASTFrontendAction::ExecuteAction() + 278</div><div style="font-family: 'Andale Mono'; ">31 clang             0x00000001003a0a7b clang::CodeGenAction::ExecuteAction() + 1291</div><div style="font-family: 'Andale Mono'; ">32 clang             0x00000001000830e8 clang::FrontendAction::Execute() + 360</div><div style="font-family: 'Andale Mono'; ">33 clang             0x000000010004c4a6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 1078</div><div style="font-family: 'Andale Mono'; ">34 clang             0x000000010001a125 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1237</div><div style="font-family: 'Andale Mono'; ">35 clang             0x0000000100001763 cc1_main(char const**, char const**, char const*, void*) + 1283</div><div style="font-family: 'Andale Mono'; ">36 clang             0x000000010001328d main + 701</div><div style="font-family: 'Andale Mono'; ">37 clang             0x0000000100001234 start + 52</div><div style="font-family: 'Andale Mono'; "><br></div></span><div><div>On Nov 2, 2011, at 10:38 AM, Douglas Gregor wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Author: dgregor<br>Date: Wed Nov  2 12:38:53 2011<br>New Revision: 143551<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=143551&view=rev">http://llvm.org/viewvc/llvm-project?rev=143551&view=rev</a><br>Log:<br>Drastically simplify the mapping from the declaration corresponding to<br>the injected-class-name of a class (or class template) to the<br>declaration that results from substituting the given template<br>arguments. Previously, we would actually perform a substitution into<br>the injected-class-name type and then retrieve the resulting<br>declaration. However, in certain, rare circumstances involving<br>deeply-nested member templates, we would get the wrong substitution<br>arguments.<br><br>This new approach just matches up the declaration with a declaration<br>that's part of the current context (or one of its parents), which will<br>either be an instantiation (during template instantiation) or the<br>declaration itself (during the definition of the template). This is<br>both more efficient (we're avoiding a substitution) and more correct<br>(we can't get the template arguments wrong in the member-template<br>case). <br><br>Fixes <<a href="rdar://problem/9676205">rdar://problem/9676205</a>>.<br><br>Modified:<br>    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>    cfe/trunk/test/SemaTemplate/class-template-decl.cpp<br><br>Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=143551&r1=143550&r2=143551&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=143551&r1=143550&r2=143551&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)<br>+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Nov  2 12:38:53 2011<br>@@ -3148,75 +3148,49 @@<br>     if (!Record->isDependentContext())<br>       return D;<br><br>-    // If the RecordDecl is actually the injected-class-name or a<br>-    // "templated" declaration for a class template, class template<br>-    // partial specialization, or a member class of a class template,<br>-    // substitute into the injected-class-name of the class template<br>-    // or partial specialization to find the new DeclContext.<br>-    QualType T;<br>+    // Determine whether this record is the "templated" declaration describing<br>+    // a class template or class template partial specialization.<br>     ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();<br>-<br>-    if (ClassTemplate) {<br>-      T = ClassTemplate->getInjectedClassNameSpecialization();<br>-    } else if (ClassTemplatePartialSpecializationDecl *PartialSpec<br>-                 = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) {<br>-      ClassTemplate = PartialSpec->getSpecializedTemplate();<br>-<br>-      // If we call SubstType with an InjectedClassNameType here we<br>-      // can end up in an infinite loop.<br>-      T = Context.getTypeDeclType(Record);<br>-      assert(isa<InjectedClassNameType>(T) &&<br>-             "type of partial specialization is not an InjectedClassNameType");<br>-      T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType();<br>-    }<br>-<br>-    if (!T.isNull()) {<br>-      // Substitute into the injected-class-name to get the type<br>-      // corresponding to the instantiation we want, which may also be<br>-      // the current instantiation (if we're in a template<br>-      // definition). This substitution should never fail, since we<br>-      // know we can instantiate the injected-class-name or we<br>-      // wouldn't have gotten to the injected-class-name!<br>-<br>-      // FIXME: Can we use the CurrentInstantiationScope to avoid this<br>-      // extra instantiation in the common case?<br>-      T = SubstType(T, TemplateArgs, Loc, DeclarationName());<br>-      assert(!T.isNull() && "Instantiation of injected-class-name cannot fail.");<br>-<br>-      if (!T->isDependentType()) {<br>-        assert(T->isRecordType() && "Instantiation must produce a record type");<br>-        return T->getAs<RecordType>()->getDecl();<br>+    if (ClassTemplate)<br>+      ClassTemplate = ClassTemplate->getCanonicalDecl();<br>+    else if (ClassTemplatePartialSpecializationDecl *PartialSpec<br>+               = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record))<br>+      ClassTemplate = PartialSpec->getSpecializedTemplate()->getCanonicalDecl();<br>+    <br>+    // Walk the current context to find either the record or an instantiation of<br>+    // it.<br>+    DeclContext *DC = CurContext;<br>+    while (!DC->isFileContext()) {<br>+      // If we're performing substitution while we're inside the template<br>+      // definition, we'll find our own context. We're done.<br>+      if (DC->Equals(Record))<br>+        return Record;<br>+      <br>+      if (CXXRecordDecl *InstRecord = dyn_cast<CXXRecordDecl>(DC)) {<br>+        // Check whether we're in the process of instantiating a class template<br>+        // specialization of the template we're mapping.<br>+        if (ClassTemplateSpecializationDecl *InstSpec<br>+                      = dyn_cast<ClassTemplateSpecializationDecl>(InstRecord)){<br>+          ClassTemplateDecl *SpecTemplate = InstSpec->getSpecializedTemplate();<br>+          if (ClassTemplate && isInstantiationOf(ClassTemplate, SpecTemplate))<br>+            return InstRecord;<br>+        }<br>+      <br>+        // Check whether we're in the process of instantiating a member class.<br>+        if (isInstantiationOf(Record, InstRecord))<br>+          return InstRecord;<br>       }<br>-<br>-      // We are performing "partial" template instantiation to create<br>-      // the member declarations for the members of a class template<br>-      // specialization. Therefore, D is actually referring to something<br>-      // in the current instantiation. Look through the current<br>-      // context, which contains actual instantiations, to find the<br>-      // instantiation of the "current instantiation" that D refers<br>-      // to.<br>-      bool SawNonDependentContext = false;<br>-      for (DeclContext *DC = CurContext; !DC->isFileContext();<br>-           DC = DC->getParent()) {<br>-        if (ClassTemplateSpecializationDecl *Spec<br>-                          = dyn_cast<ClassTemplateSpecializationDecl>(DC))<br>-          if (isInstantiationOf(ClassTemplate,<br>-                                Spec->getSpecializedTemplate()))<br>-            return Spec;<br>-<br>-        if (!DC->isDependentContext())<br>-          SawNonDependentContext = true;<br>+      <br>+      <br>+      // Move to the outer template scope.<br>+      if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) {<br>+        if (FD->getFriendObjectKind() && FD->getDeclContext()->isFileContext()){<br>+          DC = FD->getLexicalDeclContext();<br>+          continue;<br>+        }<br>       }<br>-<br>-      // We're performing "instantiation" of a member of the current<br>-      // instantiation while we are type-checking the<br>-      // definition. Compute the declaration context and return that.<br>-      assert(!SawNonDependentContext &&<br>-             "No dependent context while instantiating record");<br>-      DeclContext *DC = computeDeclContext(T);<br>-      assert(DC &&<br>-             "Unable to find declaration for the current instantiation");<br>-      return cast<CXXRecordDecl>(DC);<br>+      <br>+      DC = DC->getParent();<br>     }<br><br>     // Fall through to deal with other dependent record types (e.g.,<br><br>Modified: cfe/trunk/test/SemaTemplate/class-template-decl.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-decl.cpp?rev=143551&r1=143550&r2=143551&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-decl.cpp?rev=143551&r1=143550&r2=143551&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/SemaTemplate/class-template-decl.cpp (original)<br>+++ cfe/trunk/test/SemaTemplate/class-template-decl.cpp Wed Nov  2 12:38:53 2011<br>@@ -75,3 +75,23 @@<br>   }<br> }<br><br>+namespace rdar9676205 {<br>+  template <unsigned, class _Tp> class tuple_element;<br>+<br>+  template <class _T1, class _T2> class pair;<br>+<br>+  template <class _T1, class _T2><br>+  class tuple_element<0, pair<_T1, _T2> ><br>+  {<br>+    template <class _Tp><br>+    struct X<br>+    {<br>+      template <class _Up, bool = X<_Up>::value><br>+      struct Y<br>+        : public X<_Up>,<br>+          public Y<_Up><br>+      { };<br>+    };<br>+  };<br>+}<br>+<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br></div></blockquote></div><br></div></body></html>