Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2796,6 +2796,11 @@ isa(D)) return nullptr; + // If the declaration we are looking for is an incomplete or forward type + // declaration, we may not have a chance to instantiate it. + if (const TagDecl *TD = dyn_cast(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: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4409,6 +4409,14 @@ if (D->isInvalidDecl()) return nullptr; + // If the declaration we are looking for is an incomplete or forward type + // declaration, we may not have a chance to instantiate it. + if (const TagDecl *TD = dyn_cast(D)) { + Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); + CurrentInstantiationScope->InstantiatedLocal(D, 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)); Index: test/SemaTemplate/instantiate-local-class.cpp =================================================================== --- test/SemaTemplate/instantiate-local-class.cpp +++ test/SemaTemplate/instantiate-local-class.cpp @@ -194,3 +194,22 @@ void f() { F(); } }; } + +namespace PR18653 { + template void f(); + template struct str { + void m() { + f(); + } + }; + template struct str; + + template void f() { void g(struct x); } + template void f(); + + template void f2() { + void g2(struct x2); + struct x2 {}; + } + template void f2(); +}