On Tue, Mar 11, 2025 at 10:14 PM Jonathan Wakely <jwak...@redhat.com> wrote:

> LWG 4142 (approved in Wrocław, November 2024) made it ill-formed to call
> basic_format_parse_context::check_dynamic_spec with an empty template
> argument list.
>
> This adds a static_assert to enforce that, and adjusts the tests.
>
> libstdc++-v3/ChangeLog:
>
>         * include/std/format
>         (basic_format_parse_context::check_dynamic_spec): Require a
>         non-empty parameter pack, as per LWG 4142.
>         * testsuite/std/format/parse_ctx.cc: Remove call of
>         check_dynamic_spec with empty template argument list.
>         * testsuite/std/format/parse_ctx_neg.cc: Add dg-error to call of
>         check_dynamic_spec with empty template argument list.
> ---
>
> Tested x86_64-linux.
>
LGTM

>
>  libstdc++-v3/include/std/format                    | 3 +++
>  libstdc++-v3/testsuite/std/format/parse_ctx.cc     | 1 -
>  libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc | 8 ++++++--
>  3 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/format
> b/libstdc++-v3/include/std/format
> index e7e0d2d142b..0d6cc7f6bef 100644
> --- a/libstdc++-v3/include/std/format
> +++ b/libstdc++-v3/include/std/format
> @@ -4338,6 +4338,9 @@ namespace __format
>      constexpr void
>      basic_format_parse_context<_CharT>::check_dynamic_spec(size_t __id)
> noexcept
>      {
> +      // _GLIBCXX_RESOLVE_LIB_DEFECTS
> +      // 4142. check_dynamic_spec should require at least one type
> +      static_assert(sizeof...(_Ts) >= 1);
>        // This call enforces the Mandates: condition that _Ts contains
> valid
>        // types and each type appears at most once. It could be a
> static_assert
>        // but this way failures give better diagnostics, due to calling the
> diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx.cc
> b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
> index 88ffd77debe..b5dd7cdba78 100644
> --- a/libstdc++-v3/testsuite/std/format/parse_ctx.cc
> +++ b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
> @@ -491,7 +491,6 @@ test_dynamic_type_check()
>    std::format_parse_context pc("{1}.{2}");
>
>    // None of these calls should do anything at runtime, only during
> consteval:
> -  pc.check_dynamic_spec<>(0);
>    pc.check_dynamic_spec<int, const char*>(0);
>    pc.check_dynamic_spec_integral(0);
>    pc.check_dynamic_spec_string(0);
> diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc
> b/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc
> index f19107c886f..d83fd8c7a7b 100644
> --- a/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc
> +++ b/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc
> @@ -12,8 +12,9 @@ test_invalid()
>    pc.check_dynamic_spec<bool, char, int, unsigned, long long,
>                         unsigned long long, float, double, long double,
>                         const char*, std::string_view, const void*>(0);
> -  // For some reason, an empty pack of types is valid:
> -  pc.check_dynamic_spec<>(0);
> +
> +  // LWG 4142. check_dynamic_spec should require at least one type
> +  pc.check_dynamic_spec<>(0); // { dg-error "here" }
>
>    pc.check_dynamic_spec<void>(0); // { dg-error "here" }
>    // const void* is allowed, but void* is not
> @@ -25,6 +26,7 @@ test_invalid()
>    pc.check_dynamic_spec<char8_t>(0); // { dg-error "here" }
>    // std::string_view is allowed, but std::string is not
>    pc.check_dynamic_spec<std::string>(0); // { dg-error "here" }
> +  // The types in the pack must be unique.
>    pc.check_dynamic_spec<int, bool, int>(0); // { dg-error "here" }
>
>    std::wformat_parse_context wpc(L"");
> @@ -38,3 +40,5 @@ test_invalid()
>
>  // Each failure above will point to a call to this non-constexpr function:
>  // { dg-error "__invalid_dynamic_spec" "" { target *-*-* } 0 }
> +// Except the check_dynamic_spec<>(0) one for LWG 4142 which matches this:
> +// { dg-error "static assertion failed" "" { target *-*-* } 0 }
> --
> 2.48.1
>
>

Reply via email to