https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127220

--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <[email protected]>:

https://gcc.gnu.org/g:3a26070979bcd3f8d2594a9c08b02addd9369cde

commit r17-4072-g3a26070979bcd3f8d2594a9c08b02addd9369cde
Author: Jonathan Wakely <[email protected]>
Date:   Wed Sep 9 16:06:40 2026 +0100

    libstdc++: Make dynamic format string checking work with Clang [PR127220]

    Clang cannot compile format_parse_context::check_dynamic_spec due to a
    longstanding bug[1] with out-of-line function templates called during
    constant evaluation. This patch refactors check_dynamic_spec and related
    functions, so that the definitions are inline in the class body.

    To make this work we move the definition of __format::_Arg_t earlier,
    and redefine _Scanner<C>::_Parse_context earlier by making it a nested
    class within basic_format_parse_context<C>, called _Scan_parse_context.
    The __check_dynamic_spec function is changed to take a span<_Arg_t>
    instead of being instantiated with a template parameter pack of arg
    types. The callers that have fixed arg types can pass a span that refers
    to an array of the fixed integer or string enumerators, reducing the
    template instantiations needed for those common cases. The generic form
    (which is rarely needed in user code) uses the __to_arg_t_enum to
    convert arbitrary types to _Arg_t enums, and then passes a span
    referring to that.

    As well as simplifying the code a little, this allows checking dynamic
    spec to work with Clang because it no longer needs to instantiate an
    out-of-line function template.

    [1]: https://github.com/llvm/llvm-project/issues/73232

    libstdc++-v3/ChangeLog:

            PR libstdc++/127220
            * include/std/format (__format::_Arg_t): Move definition
            earlier.
            (basic_format_parse_context::check_dynamic_spec): Construct
            array of _Arg_t from template parameter list.
            (basic_format_parse_context::check_dynamic_spec_integral):
            Construct array of _Arg_t based on supported types.
            (basic_format_parse_context::check_dynamic_spec_string):
            Likewise.
            (basic_format_parse_context::__check_dynamic_spec): Replace
            template parameter list with span<const _Arg_t> function
            parameter and simplify accordingly. Define in class body.
            (basic_format_parse_context::_Scan_parse_context): New struct
            the replaces _Scanner::_Parse_context.
            (__format::_Scanner::_M_pc): Change type to _Scan_parse_context.

    Reviewed-by: Tomasz KamiÅski <[email protected]>

Reply via email to