https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119447
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- pop_nested_class assumes push_nested_class actually did something, but that is not always the case: void push_nested_class (tree type) { /* A namespace might be passed in error cases, like A::B:C. */ if (type == NULL_TREE || !CLASS_TYPE_P (type)) return; push_nested_class (DECL_CONTEXT (TYPE_MAIN_DECL (type))); pushclass (type); } /* Undoes a push_nested_class call. */ void pop_nested_class (void) { tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type)); popclass (); if (context && CLASS_TYPE_P (context)) pop_nested_class (); } instantiate_template in particular does: if (DECL_CLASS_SCOPE_P (gen_tmpl)) { tree ctx; if (!uses_template_parms (DECL_CONTEXT (tmpl))) /* If the context of the partially instantiated template is already non-dependent, then we might as well use it. */ ctx = DECL_CONTEXT (tmpl); else ctx = tsubst_entering_scope (DECL_CONTEXT (gen_tmpl), targ_ptr, complain, gen_tmpl); push_nested_class (ctx); } ... if (DECL_CLASS_SCOPE_P (gen_tmpl)) pop_nested_class (); uses_template_parms (DECL_CONTEXT (tmpl)) is true and tsubst_entering_scope diagnoses and error and returns error_mark_node, so push_nested_class returns early, but nothing tells the caller when it didn't do anything. --- gcc/cp/pt.cc.jj 2025-03-23 10:24:27.462152570 +0100 +++ gcc/cp/pt.cc 2025-03-25 11:23:14.284793145 +0100 @@ -11955,7 +11955,7 @@ tsubst_friend_class (tree friend_tmpl, t if (TREE_CODE (context) == NAMESPACE_DECL) pop_nested_namespace (context); - else + else if (CLASS_TYPE_P (context)) pop_nested_class (); return TREE_TYPE (tmpl); @@ -22659,9 +22659,9 @@ instantiate_template (tree tmpl, tree or ++processing_template_decl; complain |= tf_partial; } + tree ctx = NULL_TREE; if (DECL_CLASS_SCOPE_P (gen_tmpl)) { - tree ctx; if (!uses_template_parms (DECL_CONTEXT (tmpl))) /* If the context of the partially instantiated template is already non-dependent, then we might as well use it. */ @@ -22698,7 +22698,7 @@ instantiate_template (tree tmpl, tree or /* Substitute template parameters to obtain the specialization. */ if (fndecl == NULL_TREE) fndecl = tsubst_decl (pattern, targ_ptr, complain, /*use_spec_table=*/false); - if (DECL_CLASS_SCOPE_P (gen_tmpl)) + if (ctx && CLASS_TYPE_P (ctx)) pop_nested_class (); pop_from_top_level (); fixes the ICE for me, but dunno if that is the right approach.