aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2025-05-15 11:01:05 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2025-05-19 10:45:17 +0100
commit53680c1aa92d9f78e8255fbf696c0ed36f160650 (patch)
tree62199940c62de519ceb2624222bba26adaf6f6a5
parent57f73c3956572f30f3e0f7a350d958985b11daa5 (diff)
downloadgcc-53680c1aa92d9f78e8255fbf696c0ed36f160650.zip
gcc-53680c1aa92d9f78e8255fbf696c0ed36f160650.tar.gz
gcc-53680c1aa92d9f78e8255fbf696c0ed36f160650.tar.bz2
libstdc++: Fix std::format_kind primary template for Clang [PR120190]
Although Clang trunk has been adjusted to handle our std::format_kind definition (because they need to be able to compile the GCC 15.1.0 release), it's probably better to not rely on something that they might start diagnosing again in future. Define the primary template in terms of an immediately invoked function expression, so that we can put a static_assert(false) in the body. libstdc++-v3/ChangeLog: PR libstdc++/120190 * include/std/format (format_kind): Adjust primary template to not depend on itself. * testsuite/std/format/ranges/format_kind_neg.cc: Adjust expected errors. Check more invalid specializations. Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> Reviewed-by: Daniel Krügler <daniel.kruegler@gmail.com> (cherry picked from commit c65725eccbabf3b9b5965f27fff2d3b9f6c75930)
-rw-r--r--libstdc++-v3/include/std/format19
-rw-r--r--libstdc++-v3/testsuite/std/format/ranges/format_kind_neg.cc15
2 files changed, 24 insertions, 10 deletions
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 7d30670..8beef93 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -5111,13 +5111,22 @@ namespace __format
debug_string
};
- /// @cond undocumented
+ /** @brief A constant determining how a range should be formatted.
+ *
+ * The primary template of `std::format_kind` cannot be instantiated.
+ * There is a partial specialization for input ranges and you can
+ * specialize the variable template for your own cv-unqualified types
+ * that satisfy the `ranges::input_range` concept.
+ *
+ * @since C++23
+ */
template<typename _Rg>
- constexpr auto format_kind =
- __primary_template_not_defined(
- format_kind<_Rg> // you can specialize this for non-const input ranges
- );
+ constexpr auto format_kind = []{
+ static_assert(false, "cannot use primary template of 'std::format_kind'");
+ return type_identity<_Rg>{};
+ }();
+ /// @cond undocumented
template<typename _Tp>
consteval range_format
__fmt_kind()
diff --git a/libstdc++-v3/testsuite/std/format/ranges/format_kind_neg.cc b/libstdc++-v3/testsuite/std/format/ranges/format_kind_neg.cc
index bf8619d..0d761ae 100644
--- a/libstdc++-v3/testsuite/std/format/ranges/format_kind_neg.cc
+++ b/libstdc++-v3/testsuite/std/format/ranges/format_kind_neg.cc
@@ -5,9 +5,14 @@
#include <format>
-template<auto> struct Tester { };
+void test()
+{
+ (void) std::format_kind<void>; // { dg-error "here" }
+ (void) std::format_kind<const void>; // { dg-error "here" }
+ (void) std::format_kind<int>; // { dg-error "here" }
+ (void) std::format_kind<int&>; // { dg-error "here" }
+ (void) std::format_kind<const int(&)[10]>; // { dg-error "here" }
+ (void) std::format_kind<void()>; // { dg-error "here" }
+}
-Tester<std::format_kind<const int(&)[1]>> t; // { dg-error "here" }
-
-// { dg-error "use of 'std::format_kind" "" { target *-*-* } 0 }
-// { dg-error "primary_template_not_defined" "" { target *-*-* } 0 }
+// { dg-error "cannot use primary template of 'std::format_kind'" "" { target *-*-* } 0 }