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]>

Reply via email to