https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124229
--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Marek Polacek <[email protected]>: https://gcc.gnu.org/g:b95955b8854ae1e859cc7c87700922924e9a5e5f commit r16-7899-gb95955b8854ae1e859cc7c87700922924e9a5e5f Author: Marek Polacek <[email protected]> Date: Mon Mar 2 17:12:56 2026 -0500 c++: reusing typedefs in template for [PR124229] This is a crash on code like: template for (constexpr auto val : define_static_array (enumerators_of (^^E))) { constexpr auto a = annotations_of(val)[0]; using U = [:type_of(a):]; constexpr auto m1 = extract<U>(a); } because the template arg to extract wasn't substituted to "info". Once I dug deeper I realized this problem isn't tied to Reflection: we also crash here: template for (constexpr auto val : { 42 }) { using U = decltype(val); foo<U>(); } because we emit code for foo() that still has a DECLTYPE_TYPE in it. The problem is in tsubst and reusing typedefs. Normally, for code like template<typename T> void foo () { using U = T; U u; } we do the DECL_FUNCTION_SCOPE_P -> retrieve_local_specialization call. This call only happens in function templates (that are not explicit specializations), but the "template for" above are both in non-template functions. So we end up returning the original tree: /* The typedef is from a non-template context. */ return t; It seems clear that this is the wrong thing to do, and that the DECL_FUNCTION_SCOPE_P code should happen in this scenario as well. [temp.decls.general] tells me that "For the purpose of name lookup and instantiation, the compound-statement of an expansion-statement is considered a template definition." so I'm guessing that we want to check for an expansion-statement as well. As decl_dependent_p says, in_expansion_stmt is false when instantiating, so I'm looking for sk_template_for. PR c++/124229 gcc/cp/ChangeLog: * pt.cc (in_expansion_stmt_p): New. (tsubst): When reusing typedefs, do retrieve_local_specialization also when in_expansion_stmt_p is true. gcc/testsuite/ChangeLog: * g++.dg/cpp26/expansion-stmt32.C: New test. * g++.dg/reflect/expansion-stmt2.C: New test. Reviewed-by: Jason Merrill <[email protected]>
