diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index c3cb67a457dbba7510ed49e2d93eb769985b7cce..7d36c3414a1b26899a34e47ebf9b7908076c5a40 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -91,6 +91,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<bool, typename, typename> struct conditional; + template <class _Type> + struct __type_identity { + using type = _Type; + }; + template<typename...> struct __or_; @@ -177,6 +182,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // C++17 + // Forward declarations + template<typename _Tp> + struct is_reference; + template<typename _Tp> + struct is_enum; + template<typename _Tp> + struct is_function; + template<typename _Tp> + struct is_void; + + // Incomplete types of unknown size detection + template <class _T, size_t = sizeof(_T)> + constexpr true_type __is_size_known(__type_identity<_T>) + { return {}; }; + + template <class _T> + constexpr typename __or_< + is_reference<typename _T::type>, + is_enum<typename _T::type>, + is_function<typename _T::type>, + is_void<typename _T::type> + >::type __is_size_known(_T) + { return {}; }; + // For several sfinae-friendly trait implementations we transport both the // result information (as the member type) and the failure information (no // member type). This is very similar to std::enable_if, but we cannot use @@ -671,44 +700,65 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_trivial : public integral_constant<bool, __is_trivial(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; // is_trivially_copyable template<typename _Tp> struct is_trivially_copyable : public integral_constant<bool, __is_trivially_copyable(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_standard_layout template<typename _Tp> struct is_standard_layout : public integral_constant<bool, __is_standard_layout(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_pod // Could use is_standard_layout && is_trivial instead of the builtin. template<typename _Tp> struct is_pod : public integral_constant<bool, __is_pod(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_literal_type template<typename _Tp> struct is_literal_type : public integral_constant<bool, __is_literal_type(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_empty template<typename _Tp> struct is_empty : public integral_constant<bool, __is_empty(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_polymorphic template<typename _Tp> struct is_polymorphic : public integral_constant<bool, __is_polymorphic(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; #if __cplusplus >= 201402L #define __cpp_lib_is_final 201402L @@ -716,14 +766,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_final : public integral_constant<bool, __is_final(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; #endif /// is_abstract template<typename _Tp> struct is_abstract : public integral_constant<bool, __is_abstract(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp, bool = is_arithmetic<_Tp>::value> @@ -828,7 +884,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_destructible : public __is_destructible_safe<_Tp>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; // is_nothrow_destructible requires that is_destructible is // satisfied as well. We realize that by mimicing the @@ -876,7 +935,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_nothrow_destructible : public __is_nt_destructible_safe<_Tp>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; struct __do_is_default_constructible_impl { @@ -924,14 +986,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_default_constructible : public __is_default_constructible_safe<_Tp>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_constructible - template<typename _Tp, typename... _Args> - struct is_constructible + template<typename _Tp, typename... _Args> + struct __is_constructible_impl : public __bool_constant<__is_constructible(_Tp, _Args...)> { }; + template<typename _Tp, typename... _Args> + struct is_constructible + : public __is_constructible_impl<_Tp, _Args...> + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; + template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_copy_constructible_impl; @@ -941,14 +1014,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_copy_constructible_impl<_Tp, true> - : public is_constructible<_Tp, const _Tp&> + : public __is_constructible_impl<_Tp, const _Tp&> { }; /// is_copy_constructible template<typename _Tp> struct is_copy_constructible : public __is_copy_constructible_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_move_constructible_impl; @@ -959,14 +1035,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_move_constructible_impl<_Tp, true> - : public is_constructible<_Tp, _Tp&&> + : public __is_constructible_impl<_Tp, _Tp&&> { }; /// is_move_constructible template<typename _Tp> struct is_move_constructible : public __is_move_constructible_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp> struct __is_nt_default_constructible_atom @@ -989,12 +1068,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; /// is_nothrow_default_constructible - template<typename _Tp> - struct is_nothrow_default_constructible - : public __and_<is_default_constructible<_Tp>, + template<typename _Tp> + struct __is_nothrow_default_constructible_impl + : public __and_<__is_default_constructible_safe<_Tp>, __is_nt_default_constructible_impl<_Tp>> { }; + template<typename _Tp> + struct is_nothrow_default_constructible + : public __is_nothrow_default_constructible_impl<_Tp> + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; + template<typename _Tp, typename... _Args> struct __is_nt_constructible_impl : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> @@ -1008,16 +1095,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_nt_constructible_impl<_Tp> - : public is_nothrow_default_constructible<_Tp> + : public __is_nothrow_default_constructible_impl<_Tp> { }; /// is_nothrow_constructible template<typename _Tp, typename... _Args> - struct is_nothrow_constructible - : public __and_<is_constructible<_Tp, _Args...>, + struct __is_nothrow_constructible_impl + : public __and_<__is_constructible_impl<_Tp, _Args...>, __is_nt_constructible_impl<_Tp, _Args...>> { }; + template<typename _Tp, typename... _Args> + struct is_nothrow_constructible + : public __is_nothrow_constructible_impl<_Tp, _Args...> + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; + template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nothrow_copy_constructible_impl; @@ -1027,14 +1122,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_nothrow_copy_constructible_impl<_Tp, true> - : public is_nothrow_constructible<_Tp, const _Tp&> + : public __is_nothrow_constructible_impl<_Tp, const _Tp&> { }; /// is_nothrow_copy_constructible template<typename _Tp> struct is_nothrow_copy_constructible : public __is_nothrow_copy_constructible_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nothrow_move_constructible_impl; @@ -1045,20 +1143,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_nothrow_move_constructible_impl<_Tp, true> - : public is_nothrow_constructible<_Tp, _Tp&&> + : public __is_nothrow_constructible_impl<_Tp, _Tp&&> { }; /// is_nothrow_move_constructible template<typename _Tp> struct is_nothrow_move_constructible : public __is_nothrow_move_constructible_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_assignable template<typename _Tp, typename _Up> struct is_assignable : public __bool_constant<__is_assignable(_Tp, _Up)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_copy_assignable_impl; @@ -1069,14 +1173,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_copy_assignable_impl<_Tp, true> - : public is_assignable<_Tp&, const _Tp&> + : public __bool_constant<__is_assignable(_Tp&, const _Tp&)> { }; /// is_copy_assignable template<typename _Tp> struct is_copy_assignable : public __is_copy_assignable_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_move_assignable_impl; @@ -1087,14 +1194,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_move_assignable_impl<_Tp, true> - : public is_assignable<_Tp&, _Tp&&> + : public __bool_constant<__is_assignable(_Tp&, _Tp&&)> { }; /// is_move_assignable template<typename _Tp> struct is_move_assignable : public __is_move_assignable_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp, typename _Up> struct __is_nt_assignable_impl @@ -1102,12 +1212,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; /// is_nothrow_assignable - template<typename _Tp, typename _Up> - struct is_nothrow_assignable - : public __and_<is_assignable<_Tp, _Up>, + template<typename _Tp, typename _Up> + struct __is_nothrow_assignable_impl + : public __and_<__bool_constant<__is_assignable(_Tp, _Up)>, __is_nt_assignable_impl<_Tp, _Up>> { }; + template<typename _Tp, typename _Up> + struct is_nothrow_assignable + : public __is_nothrow_assignable_impl<_Tp, _Up> + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; + template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nt_copy_assignable_impl; @@ -1117,14 +1235,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_nt_copy_assignable_impl<_Tp, true> - : public is_nothrow_assignable<_Tp&, const _Tp&> + : public __is_nothrow_assignable_impl<_Tp&, const _Tp&> { }; /// is_nothrow_copy_assignable template<typename _Tp> struct is_nothrow_copy_assignable : public __is_nt_copy_assignable_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nt_move_assignable_impl; @@ -1135,26 +1256,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_nt_move_assignable_impl<_Tp, true> - : public is_nothrow_assignable<_Tp&, _Tp&&> + : public __is_nothrow_assignable_impl<_Tp&, _Tp&&> { }; /// is_nothrow_move_assignable template<typename _Tp> struct is_nothrow_move_assignable : public __is_nt_move_assignable_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_trivially_constructible template<typename _Tp, typename... _Args> struct is_trivially_constructible : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_trivially_default_constructible template<typename _Tp> struct is_trivially_default_constructible - : public is_trivially_constructible<_Tp>::type - { }; + : public __bool_constant<__is_trivially_constructible(_Tp)> + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; struct __do_is_implicitly_default_constructible_impl { @@ -1182,7 +1312,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template <typename _Tp> struct __is_implicitly_default_constructible - : public __and_<is_default_constructible<_Tp>, + : public __and_<__is_default_constructible_safe<_Tp>, __is_implicitly_default_constructible_safe<_Tp>> { }; @@ -1197,7 +1327,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_trivially_copy_constructible_impl<_Tp, true> - : public __and_<is_copy_constructible<_Tp>, + : public __and_<__is_copy_constructible_impl<_Tp>, integral_constant<bool, __is_trivially_constructible(_Tp, const _Tp&)>> { }; @@ -1205,7 +1335,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_trivially_copy_constructible : public __is_trivially_copy_constructible_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_trivially_move_constructible @@ -1218,7 +1351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct __is_trivially_move_constructible_impl<_Tp, true> - : public __and_<is_move_constructible<_Tp>, + : public __and_<__is_move_constructible_impl<_Tp>, integral_constant<bool, __is_trivially_constructible(_Tp, _Tp&&)>> { }; @@ -1226,13 +1359,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_trivially_move_constructible : public __is_trivially_move_constructible_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_trivially_assignable template<typename _Tp, typename _Up> struct is_trivially_assignable : public __bool_constant<__is_trivially_assignable(_Tp, _Up)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_trivially_copy_assignable @@ -1251,7 +1390,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_trivially_copy_assignable : public __is_trivially_copy_assignable_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_trivially_move_assignable @@ -1270,21 +1412,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_trivially_move_assignable : public __is_trivially_move_assignable_impl<_Tp> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_trivially_destructible template<typename _Tp> struct is_trivially_destructible - : public __and_<is_destructible<_Tp>, + : public __and_<__is_destructible_impl<_Tp>, __bool_constant<__has_trivial_destructor(_Tp)>> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// has_virtual_destructor template<typename _Tp> struct has_virtual_destructor : public integral_constant<bool, __has_virtual_destructor(_Tp)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; // type property queries. @@ -1292,7 +1443,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// alignment_of template<typename _Tp> struct alignment_of - : public integral_constant<std::size_t, alignof(_Tp)> { }; + : public integral_constant<std::size_t, alignof(_Tp)> + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// rank template<typename> @@ -1342,7 +1497,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Base, typename _Derived> struct is_base_of : public integral_constant<bool, __is_base_of(_Base, _Derived)> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Base>{}), + "_Base must be a complete class"); + static_assert(std::__is_size_known(__type_identity<_Derived>{}), + "_Derived must be a complete class"); + }; template<typename _From, typename _To, bool = __or_<is_void<_From>, is_function<_To>, @@ -2597,13 +2757,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct is_swappable : public __is_swappable_impl<_Tp>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_nothrow_swappable template<typename _Tp> struct is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; #if __cplusplus >= 201402L /// is_swappable_v @@ -2794,20 +2960,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Fn, typename... _ArgTypes> struct is_invocable : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Fn>{}), + "_Fn must be a complete class"); + }; /// std::is_invocable_r template<typename _Ret, typename _Fn, typename... _ArgTypes> struct is_invocable_r : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Fn>{}), + "_Fn must be a complete class"); + }; /// std::is_nothrow_invocable template<typename _Fn, typename... _ArgTypes> struct is_nothrow_invocable : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type - { }; + { + static_assert(std::__is_size_known(__type_identity<_Fn>{}), + "_Fn must be a complete class"); + }; template<typename _Result, typename _Ret, typename = void> struct __is_nt_invocable_impl : false_type { }; @@ -3014,7 +3189,10 @@ template <typename _From, typename _To> : bool_constant<__has_unique_object_representations( remove_cv_t<remove_all_extents_t<_Tp>> )> - { }; + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; template<typename _Tp> inline constexpr bool has_unique_object_representations_v @@ -3026,7 +3204,11 @@ template <typename _From, typename _To> /// is_aggregate template<typename _Tp> struct is_aggregate - : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> { }; + : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> + { + static_assert(std::__is_size_known(__type_identity<_Tp>{}), + "template argument must be a complete class"); + }; /// is_aggregate_v template<typename _Tp> diff --git a/libstdc++-v3/testsuite/20_util/__is_size_known/memoization.cc b/libstdc++-v3/testsuite/20_util/__is_size_known/memoization.cc new file mode 100644 index 0000000000000000000000000000000000000000..12b978f92b4d765399da51d1410617a92feea1f1 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/__is_size_known/memoization.cc @@ -0,0 +1,26 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <type_traits> + +struct X; +static_assert(!std::__is_size_known(std::__type_identity<X>{}), ""); + +struct X{}; +static_assert(std::__is_size_known(std::__type_identity<X>{}), "Result memoized. This leads to worse diagnostics"); diff --git a/libstdc++-v3/testsuite/20_util/__is_size_known/memoization_err.cc b/libstdc++-v3/testsuite/20_util/__is_size_known/memoization_err.cc new file mode 100644 index 0000000000000000000000000000000000000000..6cf5bd254996e1b154ea262a3605531262a0a2e7 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/__is_size_known/memoization_err.cc @@ -0,0 +1,30 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + + +// { dg-error "must be a complete class" "" { target *-*-* } 0 } + +#include <type_traits> + +struct X; +constexpr bool res_incomplete = std::is_move_constructible<X>::value; // { dg-error "required from here" } + +struct X{}; +constexpr bool res_complete = std::is_default_constructible<X>::value; // { dg-bogus "required from here" } + diff --git a/libstdc++-v3/testsuite/20_util/__is_size_known/value.cc b/libstdc++-v3/testsuite/20_util/__is_size_known/value.cc new file mode 100644 index 0000000000000000000000000000000000000000..5cc4122a4ac57c3d5bfed4b1b8d2b379cf377057 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/__is_size_known/value.cc @@ -0,0 +1,100 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <type_traits> + + +struct incomplete_type; +class incomplete_type2; +union incomplete_union; +enum class incomplete_enum: int; +enum incomplete_enum2: int; +static_assert(!std::__is_size_known(std::__type_identity<incomplete_type>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_type2>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_union>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<incomplete_enum>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<incomplete_enum2>{}), ""); + +static_assert(!std::__is_size_known(std::__type_identity<incomplete_type[42]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_type2[42]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_union[42]>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<incomplete_enum[42]>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<incomplete_enum2[42]>{}), ""); + +static_assert(!std::__is_size_known(std::__type_identity<incomplete_type[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_type2[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_union[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_enum[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<incomplete_enum2[]>{}), ""); + + +struct complete_type{ ~complete_type() = delete; }; +class complete_type2{ int i; }; +union complete_union{}; +enum class complete_enum: int {}; +enum complete_enum2: int {}; +static_assert(std::__is_size_known(std::__type_identity<complete_type>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_type2>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_union>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_enum>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_enum2>{}), ""); + +static_assert(std::__is_size_known(std::__type_identity<complete_type[42]>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_type2[42]>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_union[42]>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_enum[42]>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_enum2[42]>{}), ""); + +static_assert(!std::__is_size_known(std::__type_identity<complete_type[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<complete_type2[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<complete_union[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<complete_enum[]>{}), ""); +static_assert(!std::__is_size_known(std::__type_identity<complete_enum2[]>{}), ""); + + +static_assert(std::__is_size_known(std::__type_identity<const complete_type>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<const complete_type2>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<const complete_union>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<const complete_enum>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<const complete_enum2>{}), ""); + +static_assert(std::__is_size_known(std::__type_identity<incomplete_type*>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_type*>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<const incomplete_type*>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<const complete_type*>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<incomplete_type&>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_type&>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<incomplete_type&&>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<complete_type&&>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<int complete_type::*>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<int (complete_type::*)(int)>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<int incomplete_type::*>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<int (incomplete_type::*)(int)>{}), ""); + +static_assert(std::__is_size_known(std::__type_identity<void(*)() noexcept>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<void(...) noexcept>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<void(&)(int)>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<void(*)()>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<void(incomplete_type)>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<void(&)()>{}), ""); + +static_assert(std::__is_size_known(std::__type_identity<std::nullptr_t>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<void>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<void*>{}), ""); +static_assert(std::__is_size_known(std::__type_identity<const void* const>{}), ""); diff --git a/libstdc++-v3/testsuite/20_util/is_abstract/incomplete.cc b/libstdc++-v3/testsuite/20_util/is_abstract/incomplete.cc new file mode 100644 index 0000000000000000000000000000000000000000..a1fa126f3dd7d357e80be702620444e1a1cc61dd --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_abstract/incomplete.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++11 } } +// +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-error "must be a complete class" "" { target *-*-* } 0 } + +#include <type_traits> + +class X; + +void test01() +{ + std::is_abstract<X>(); // { dg-error "required from here" } +} diff --git a/libstdc++-v3/testsuite/20_util/is_aggregate/incomplete.cc b/libstdc++-v3/testsuite/20_util/is_aggregate/incomplete.cc new file mode 100644 index 0000000000000000000000000000000000000000..8a3dd551cbb856df5a213fc265177612e6bac176 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_aggregate/incomplete.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++17 } } +// +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-error "must be a complete class" "" { target *-*-* } 0 } + +#include <type_traits> + +class X; + +void test01() +{ + std::is_aggregate<X>(); // { dg-error "required from here" } +} diff --git a/libstdc++-v3/testsuite/20_util/is_class/value.cc b/libstdc++-v3/testsuite/20_util/is_class/value.cc index 6391e2861475353209c87dce92b660247fbb79f8..f541943021bdde67549d5606ca35e18a26297908 100644 --- a/libstdc++-v3/testsuite/20_util/is_class/value.cc +++ b/libstdc++-v3/testsuite/20_util/is_class/value.cc @@ -27,6 +27,7 @@ void test01() // Positive tests. static_assert(test_category<is_class, ClassType>(true), ""); + static_assert(test_category<is_class, IncompleteClass>(true), ""); static_assert(test_category<is_class, DerivedType>(true), ""); static_assert(test_category<is_class, ConvType>(true), ""); static_assert(test_category<is_class, AbstractClass>(true), ""); diff --git a/libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete.cc b/libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete.cc new file mode 100644 index 0000000000000000000000000000000000000000..d6a08d7763971fb5610c8cd7cf531f2f4aad1232 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++11 } } +// +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-error "must be a complete class" "" { target *-*-* } 0 } + +#include <type_traits> + +class X; + +void test01() +{ + std::is_move_constructible<X>(); // { dg-error "required from here" } +} diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_move_assignable/incomplete.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_move_assignable/incomplete.cc new file mode 100644 index 0000000000000000000000000000000000000000..ebceec5474bde86a15de091e108be5bd4ee5d57c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_move_assignable/incomplete.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++11 } } +// +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-error "must be a complete class" "" { target *-*-* } 0 } + +#include <type_traits> + +class X; + +void test01() +{ + std::is_nothrow_move_assignable<X>(); // { dg-error "required from here" } +} diff --git a/libstdc++-v3/testsuite/20_util/is_polymorphic/incomplete.cc b/libstdc++-v3/testsuite/20_util/is_polymorphic/incomplete.cc new file mode 100644 index 0000000000000000000000000000000000000000..64b3947e283193eac016c43a1e63e82acfba26d6 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_polymorphic/incomplete.cc @@ -0,0 +1,29 @@ +// { dg-do compile { target c++11 } } +// +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-error "must be a complete class" "" { target *-*-* } 0 } + +#include <type_traits> + +class X; + +void test01() +{ + std::is_polymorphic<X>(); // { dg-error "required from here" } +}