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.