# define _GLIBCXX_USE_BUILTIN_TRAIT(BT) 0
#endif
+#if __has_cpp_attribute(_Clang::__no_specializations__)
+# define _GLIBCXX_NO_SPECIALIZATIONS [[_Clang::__no_specializations__]]
+#else
+# define _GLIBCXX_NO_SPECIALIZATIONS
+#endif
+
// Whether deducing this is usable either officially, if in C++23 mode, or
// as an extension (Clang doesn't support the latter).
#if __cpp_explicit_this_parameter \
#endif
template<typename _CharT>
- class basic_format_parse_context
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3975. Specializations of basic_format_context should not be permitted
+ class _GLIBCXX_NO_SPECIALIZATIONS basic_format_parse_context
{
public:
using char_type = _CharT;
* @since C++20
*/
template<typename _Out, typename _CharT>
- class basic_format_context
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3975. Specializations of basic_format_context should not be permitted
+ class _GLIBCXX_NO_SPECIALIZATIONS basic_format_context
{
static_assert( output_iterator<_Out, const _CharT&> );
/// Primary class template, tuple
template<typename... _Elements>
- class tuple : public _Tuple_impl<0, _Elements...>
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3990. Program-defined specializations of std::tuple and std::variant
+ // can't be properly supported
+ class _GLIBCXX_NO_SPECIALIZATIONS tuple
+ : public _Tuple_impl<0, _Elements...>
{
using _Inherited = _Tuple_impl<0, _Elements...>;
tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
#endif
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winvalid-specialization"
// Explicit specialization, zero-element tuple.
template<>
class tuple<>
{ _Inherited::_M_swap(__in); }
};
#endif // concepts && conditional_explicit
+#pragma GCC diagnostic pop
/// class tuple_size
template<typename... _Elements>
};
template<typename... _Types>
- class variant
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3990. Program-defined specializations of std::tuple and std::variant
+ // can't be properly supported
+ class _GLIBCXX_NO_SPECIALIZATIONS variant
: private __detail::__variant::_Variant_base<_Types...>,
private _Enable_copy_move<
__detail::__variant::_Traits<_Types...>::_S_copy_ctor,
/// @since C++26
template<typename _Tp, typename _Up>
- struct type_order
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4305. Missing user requirements on type_order template
+ struct _GLIBCXX_NO_SPECIALIZATIONS type_order
{
static constexpr strong_ordering value = __builtin_type_order(_Tp, _Up);
using value_type = strong_ordering;
{
/// initializer_list
template<class _E>
- class initializer_list
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2129. User specializations of std::initializer_list
+ class _GLIBCXX_NO_SPECIALIZATIONS initializer_list
{
public:
typedef _E value_type;
--- /dev/null
+// { dg-do compile { target c++26 } }
+
+// LWG 4305. Missing user requirements on type_order template
+
+#include <compare>
+
+struct A {};
+template<typename T>
+struct B {};
+
+template<>
+struct std::type_order<A, A> {}; // { dg-error "cannot be specialized" }
+
+template<typename T>
+struct std::type_order<B<T>, T> {}; // { dg-error "cannot be specialized" }
--- /dev/null
+// { dg-do compile { target c++11 } }
+
+// LWG 2129. User specializations of std::initializer_list
+
+#include <initializer_list>
+
+template<class T>
+class std::initializer_list<T*> { // { dg-error "cannot be specialized" }
+private:
+ void* array;
+ decltype(sizeof(0)) len;
+};
--- /dev/null
+// { dg-do compile { target c++11 } }
+
+// LWG 3990. Program-defined specializations of std::tuple and std::variant
+// can't be properly supported
+
+#include <tuple>
+
+struct A {};
+template<typename T>
+struct B {};
+
+template<>
+class std::tuple<A, A> {}; // { dg-error "cannot be specialized" }
+
+template<typename T>
+class std::tuple<B<T>, T> {}; // { dg-error "cannot be specialized" }
--- /dev/null
+// { dg-do compile { target c++11 } }
+
+// LWG 3990. Program-defined specializations of std::tuple and std::variant
+// can't be properly supported
+
+#include <variant>
+
+struct A {};
+template<typename T>
+struct B {};
+
+template<>
+class std::variant<A, A> {}; // { dg-error "cannot be specialized" }
+
+template<typename T>
+class std::variant<B<T>, T> {}; // { dg-error "cannot be specialized" }
--- /dev/null
+// { dg-do compile { target c++20 } }
+
+// LWG 3975. Specializations of basic_format_context should not be permitted
+
+#include <format>
+
+struct A {};
+template<typename T>
+struct B {};
+
+template<>
+class std::basic_format_parse_context<A> {}; // { dg-error "cannot be specialized" }
+
+template<>
+class std::basic_format_context<std::back_insert_iterator<std::string>, A> {}; // { dg-error "cannot be specialized" }
+
+template<typename T>
+class std::basic_format_context<B<T>, T> {}; // { dg-error "cannot be specialized" }