]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Reject basic_format_parse_context::check_dynamic_spec<>(n)
authorJonathan Wakely <jwakely@redhat.com>
Sat, 8 Mar 2025 11:58:49 +0000 (11:58 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 12 Mar 2025 10:06:57 +0000 (10:06 +0000)
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.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
libstdc++-v3/include/std/format
libstdc++-v3/testsuite/std/format/parse_ctx.cc
libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc

index e7e0d2d142bb46928e01f7c3cf3df0ada0c153c7..0d6cc7f6bef47bb6e6192acfefda2e455ef88621 100644 (file)
@@ -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
index 88ffd77debe0ab98d697b83e183cdb4e6b69deea..b5dd7cdba7829bb8429c86dea6b629cd64d9e42a 100644 (file)
@@ -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);
index f19107c886fc91ab4ef0d3e502436c24bef31fe5..d83fd8c7a7b068aeb7da9916648b8ee4222631dc 100644 (file)
@@ -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 }