Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2974,6 +2974,11 @@ if (isa(D)) return nullptr; + // Default arguments with a decltype referencing arguments prior to definition + // may require instantiation. + if (isa(D)) + return nullptr; + // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that // we have an uninstantiated label. Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5287,29 +5287,33 @@ // } // // In this case instantiation of the type of 'g1' requires definition of - // 'x1', which is defined later. Error recovery may produce an enum used - // before definition. In these cases we need to instantiate relevant - // declarations here. + // 'x1', which is defined later. + // + // Error recovery may produce an enum used before definition. + // + // Default arguments with a decltype referencing arguments: + // + // template void bar(T t = decltype(t)()) {} + // + // Else we must have a label decl that hasn't been found yet. + // + // In these cases we need to instantiate relevant declarations here. bool NeedInstantiate = false; if (CXXRecordDecl *RD = dyn_cast(D)) NeedInstantiate = RD->isLocalClass(); else - NeedInstantiate = isa(D); + NeedInstantiate = + isa(D) || isa(D) || isa(D); if (NeedInstantiate) { Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); + assert(Inst && "Failed to instantiate"); CurrentInstantiationScope->InstantiatedLocal(D, Inst); - return cast(Inst); + return cast(Inst); } - // If we didn't find the decl, then we must have a label decl that hasn't - // been found yet. Lazily instantiate it and return it now. - assert(isa(D)); - - Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); - assert(Inst && "Failed to instantiate label??"); + assert(0 && "Failed to instantiate"); - CurrentInstantiationScope->InstantiatedLocal(D, Inst); - return cast(Inst); + return nullptr; } if (CXXRecordDecl *Record = dyn_cast(D)) { Index: clang/test/SemaTemplate/default-arguments-cxx0x.cpp =================================================================== --- clang/test/SemaTemplate/default-arguments-cxx0x.cpp +++ clang/test/SemaTemplate/default-arguments-cxx0x.cpp @@ -114,3 +114,34 @@ S _a{}; }; } + +// https://bugs.llvm.org/show_bug.cgi?id=28500 +// Failure to resolve the decltype part during instantiation caused an +// assertion failure +namespace PR28500 { +namespace original { +template +void bar(T t = [](decltype(t) i) { return 0; }(0)) {} +void foo() { + bar(); +} +} // namespace original + +namespace cast { +template +void bar(T t = decltype(t)(0)) {} +void foo() { + bar(); + bar(); +} +} // namespace cast + +namespace value { +template +void bar(T t = decltype(t)()) {} +void foo() { + bar(); + bar(); +} +} // namespace value +} // namespace PR28500