From 98cf2c265962e260f2f95617983915c754f446ea Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 17 Feb 2020 13:20:57 +0000 Subject: [PATCH] libstdc++: Implement "Safe Integral Comparisons" (P0586R2) * include/std/type_traits (__is_standard_integer): New helper trait. * include/std/utility (cmp_equal, cmp_not_equal, cmp_less, cmp_greater) (cmp_less_equal, cmp_greater_equal, in_range): Define for C++20. * include/std/version (__cpp_lib_integer_comparison_functions): Define. * testsuite/20_util/integer_comparisons/1.cc: New test. * testsuite/20_util/integer_comparisons/2.cc: New test. * testsuite/20_util/integer_comparisons/equal.cc: New test. * testsuite/20_util/integer_comparisons/equal_neg.cc: New test. * testsuite/20_util/integer_comparisons/greater_equal.cc: New test. * testsuite/20_util/integer_comparisons/greater_equal_neg.cc: New test. * testsuite/20_util/integer_comparisons/greater_neg.cc: New test. * testsuite/20_util/integer_comparisons/in_range.cc: New test. * testsuite/20_util/integer_comparisons/in_range_neg.cc: New test. * testsuite/20_util/integer_comparisons/less.cc: New test. * testsuite/20_util/integer_comparisons/less_equal.cc: New test. * testsuite/20_util/integer_comparisons/less_equal_neg.cc: New test. * testsuite/20_util/integer_comparisons/less_neg.cc: New test. * testsuite/20_util/integer_comparisons/not_equal.cc: New test. * testsuite/20_util/integer_comparisons/not_equal_neg.cc: New test. --- libstdc++-v3/ChangeLog | 22 +++++ libstdc++-v3/include/std/type_traits | 4 + libstdc++-v3/include/std/utility | 74 +++++++++++++++++ libstdc++-v3/include/std/version | 1 + .../20_util/integer_comparisons/1.cc | 27 +++++++ .../20_util/integer_comparisons/2.cc | 27 +++++++ .../20_util/integer_comparisons/equal.cc | 74 +++++++++++++++++ .../20_util/integer_comparisons/equal_neg.cc | 36 +++++++++ .../integer_comparisons/greater_equal.cc | 81 +++++++++++++++++++ .../integer_comparisons/greater_equal_neg.cc | 36 +++++++++ .../integer_comparisons/greater_neg.cc | 36 +++++++++ .../20_util/integer_comparisons/in_range.cc | 81 +++++++++++++++++++ .../integer_comparisons/in_range_neg.cc | 36 +++++++++ .../20_util/integer_comparisons/less.cc | 78 ++++++++++++++++++ .../20_util/integer_comparisons/less_equal.cc | 81 +++++++++++++++++++ .../integer_comparisons/less_equal_neg.cc | 36 +++++++++ .../20_util/integer_comparisons/less_neg.cc | 36 +++++++++ .../20_util/integer_comparisons/not_equal.cc | 75 +++++++++++++++++ .../integer_comparisons/not_equal_neg.cc | 36 +++++++++ 19 files changed, 877 insertions(+) create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/1.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/2.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/equal_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/in_range.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/less_neg.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc create mode 100644 libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal_neg.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 25fa9ba6098..2dca4b50dd7 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2020-02-17 Jonathan Wakely + + * include/std/type_traits (__is_standard_integer): New helper trait. + * include/std/utility (cmp_equal, cmp_not_equal, cmp_less, cmp_greater) + (cmp_less_equal, cmp_greater_equal, in_range): Define for C++20. + * include/std/version (__cpp_lib_integer_comparison_functions): Define. + * testsuite/20_util/integer_comparisons/1.cc: New test. + * testsuite/20_util/integer_comparisons/2.cc: New test. + * testsuite/20_util/integer_comparisons/equal.cc: New test. + * testsuite/20_util/integer_comparisons/equal_neg.cc: New test. + * testsuite/20_util/integer_comparisons/greater_equal.cc: New test. + * testsuite/20_util/integer_comparisons/greater_equal_neg.cc: New test. + * testsuite/20_util/integer_comparisons/greater_neg.cc: New test. + * testsuite/20_util/integer_comparisons/in_range.cc: New test. + * testsuite/20_util/integer_comparisons/in_range_neg.cc: New test. + * testsuite/20_util/integer_comparisons/less.cc: New test. + * testsuite/20_util/integer_comparisons/less_equal.cc: New test. + * testsuite/20_util/integer_comparisons/less_equal_neg.cc: New test. + * testsuite/20_util/integer_comparisons/less_neg.cc: New test. + * testsuite/20_util/integer_comparisons/not_equal.cc: New test. + * testsuite/20_util/integer_comparisons/not_equal_neg.cc: New test. + 2020-02-16 Patrick Palka * include/bits/ranges_algo.h (__lexicographical_compare_fn::operator()): diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 6aa2cedfa0a..684a792d02c 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -622,6 +622,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif >; + // Check if a type is one of the signed or unsigned integer types. + template + using __is_standard_integer + = __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>; // __void_t (std::void_t for C++11) template using __void_t = void; diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 991113e1c8a..380c059395c 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -75,6 +75,10 @@ #include #include +#if __cplusplus > 201703L +#include +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -397,6 +401,76 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template void as_const(const _Tp&&) = delete; +#if __cplusplus > 201703L +#define __cpp_lib_integer_comparison_functions 202002L + + template + constexpr bool + cmp_equal(_Tp __t, _Up __u) noexcept + { + static_assert(__is_standard_integer<_Tp>::value); + static_assert(__is_standard_integer<_Up>::value); + + if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) + return __t == __u; + else if constexpr (is_signed_v<_Tp>) + return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u; + else + return __u >= 0 && __t == make_unsigned_t<_Up>(__u); + } + + template + constexpr bool + cmp_not_equal(_Tp __t, _Up __u) noexcept + { return !std::cmp_equal(__t, __u); } + + template + constexpr bool + cmp_less(_Tp __t, _Up __u) noexcept + { + static_assert(__is_standard_integer<_Tp>::value); + static_assert(__is_standard_integer<_Up>::value); + + if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) + return __t < __u; + else if constexpr (is_signed_v<_Tp>) + return __t < 0 || make_unsigned_t<_Tp>(__t) < __u; + else + return __u >= 0 && __t < make_unsigned_t<_Up>(__u); + } + + template + constexpr bool + cmp_greater(_Tp __t, _Up __u) noexcept + { return std::cmp_less(__u, __t); } + + template + constexpr bool + cmp_less_equal(_Tp __t, _Up __u) noexcept + { return !std::cmp_less(__u, __t); } + + template + constexpr bool + cmp_greater_equal(_Tp __t, _Up __u) noexcept + { return !std::cmp_less(__t, __u); } + + template + constexpr bool + in_range(_Tp __t) noexcept + { + static_assert(__is_standard_integer<_Up>::value); + static_assert(__is_standard_integer<_Tp>::value); + + if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) + return numeric_limits<_Up>::min() <= __t + && __t <= numeric_limits<_Up>::max(); + else if constexpr (is_signed_v<_Tp>) + return __t >= 0 + && make_unsigned_t<_Tp>(__t) <= numeric_limits<_Up>::max(); + else + return __t <= make_unsigned_t<_Up>(numeric_limits<_Up>::max()); + } +#endif // C++20 #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version index 8a4affa60a0..6db569c2ff2 100644 --- a/libstdc++-v3/include/std/version +++ b/libstdc++-v3/include/std/version @@ -180,6 +180,7 @@ #if _GLIBCXX_HOSTED #define __cpp_lib_bind_front 201907L +#define __cpp_lib_integer_comparison_functions 202002L #define __cpp_lib_constexpr_algorithms 201806L #define __cpp_lib_constexpr_complex 201711L #define __cpp_lib_constexpr_dynamic_alloc 201907L diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/1.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/1.cc new file mode 100644 index 00000000000..e76da7f1c17 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/1.cc @@ -0,0 +1,27 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do preprocess { target c++2a } } + +#include + +#ifndef __cpp_lib_integer_comparison_functions +# error "Feature test macro for comparison functions is missing in " +#elif __cpp_lib_integer_comparison_functions < 202002L +# error "Feature test macro for comparison functions has wrong value in " +#endif diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/2.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/2.cc new file mode 100644 index 00000000000..71007aef815 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/2.cc @@ -0,0 +1,27 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do preprocess { target c++2a } } + +#include + +#ifndef __cpp_lib_integer_comparison_functions +# error "Feature test macro for comparison functions is missing in " +#elif __cpp_lib_integer_comparison_functions < 202002L +# error "Feature test macro for comparison functions has wrong value in " +#endif diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc new file mode 100644 index 00000000000..16d4e3bd65c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc @@ -0,0 +1,74 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include + +void +test01() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + VERIFY( !std::cmp_equal(s, u) ); +} + +constexpr bool +test02() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + if (std::cmp_equal(s, u)) + throw 1; + if (std::cmp_equal(u, s)) + throw 2; + return true; +} + +void +test03() +{ + short ss = -1; + int s = -1; + VERIFY( std::cmp_equal(s, ss) ); + VERIFY( std::cmp_equal(ss, s) ); + + unsigned int u = (unsigned int) -1; + VERIFY( !std::cmp_equal(s, u) ); + VERIFY( !std::cmp_equal(u, s) ); + VERIFY( !std::cmp_equal(ss, u) ); + VERIFY( !std::cmp_equal(u, ss) ); + + unsigned long ul = (unsigned long) -1; + VERIFY( !std::cmp_equal(s, ul) ); + VERIFY( !std::cmp_equal(ul, s) ); + VERIFY( !std::cmp_equal(ss, ul) ); + VERIFY( !std::cmp_equal(ul, ss) ); + VERIFY( !std::cmp_equal(u, ul) ); + VERIFY( !std::cmp_equal(ul, u) ); +} + +int +main() +{ + test01(); + static_assert( test02() ); + test03(); +} diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/equal_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/equal_neg.cc new file mode 100644 index 00000000000..dc70d8dfe82 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/equal_neg.cc @@ -0,0 +1,36 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +bool a = std::cmp_equal('1', 49); // { dg-error "here" } +bool b = std::cmp_equal(50, '2'); // { dg-error "here" } +bool c = std::cmp_equal(2, L'2'); // { dg-error "here" } +bool d = std::cmp_equal(L'2', 2); // { dg-error "here" } +bool e = std::cmp_equal(true, 1); // { dg-error "here" } +bool f = std::cmp_equal(0, false); // { dg-error "here" } +bool g = std::cmp_equal(97, u8'a'); // { dg-error "here" } +bool h = std::cmp_equal(u8'a', 97); // { dg-error "here" } +bool i = std::cmp_equal(97, u'a'); // { dg-error "here" } +bool j = std::cmp_equal(u'a', 97); // { dg-error "here" } +bool k = std::cmp_equal(97, U'a'); // { dg-error "here" } +bool l = std::cmp_equal(U'a', 97); // { dg-error "here" } + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc new file mode 100644 index 00000000000..61f461b4056 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc @@ -0,0 +1,81 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include + +void +test01() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + VERIFY( !std::cmp_greater_equal(s, u) ); + VERIFY( std::cmp_greater_equal(u, s) ); + u = (unsigned) std::numeric_limits::max() + 1U; + VERIFY( !std::cmp_greater_equal(s, u) ); + VERIFY( std::cmp_greater_equal(u, s) ); +} + +constexpr bool +test02() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + if (std::cmp_greater_equal(s, u)) + throw 1; + if (!std::cmp_greater_equal(u, s)) + throw 2; + return true; +} + +void +test03() +{ + short ss = -1; + int s = -1; + VERIFY( std::cmp_greater_equal(s, ss) ); + VERIFY( std::cmp_greater_equal(ss, s) ); + VERIFY( std::cmp_greater_equal(ss, -2) ); + + unsigned int u = (unsigned int) -1; + VERIFY( !std::cmp_greater_equal(s, u) ); + VERIFY( std::cmp_greater_equal(u, s) ); + VERIFY( !std::cmp_greater_equal(ss, u) ); + VERIFY( std::cmp_greater_equal(u, ss) ); + VERIFY( std::cmp_greater_equal(u, -2U) ); + + unsigned long ul = (unsigned long) -1; + VERIFY( !std::cmp_greater_equal(s, ul) ); + VERIFY( std::cmp_greater_equal(ul, s) ); + VERIFY( !std::cmp_greater_equal(ss, ul) ); + VERIFY( std::cmp_greater_equal(ul, ss) ); + VERIFY( !std::cmp_greater_equal(u, ul) ); + VERIFY( std::cmp_greater_equal(ul, u) ); + VERIFY( std::cmp_greater_equal(ul, -2UL) ); +} + +int +main() +{ + test01(); + static_assert( test02() ); + test03(); +} diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc new file mode 100644 index 00000000000..52657c159ba --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal_neg.cc @@ -0,0 +1,36 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +bool a = std::cmp_greater_equal('1', 49); // { dg-error "here" } +bool b = std::cmp_greater_equal(50, '2'); // { dg-error "here" } +bool c = std::cmp_greater_equal(2, L'2'); // { dg-error "here" } +bool d = std::cmp_greater_equal(L'2', 2); // { dg-error "here" } +bool e = std::cmp_greater_equal(true, 1); // { dg-error "here" } +bool f = std::cmp_greater_equal(0, false); // { dg-error "here" } +bool g = std::cmp_greater_equal(97, u8'a'); // { dg-error "here" } +bool h = std::cmp_greater_equal(u8'a', 97); // { dg-error "here" } +bool i = std::cmp_greater_equal(97, u'a'); // { dg-error "here" } +bool j = std::cmp_greater_equal(u'a', 97); // { dg-error "here" } +bool k = std::cmp_greater_equal(97, U'a'); // { dg-error "here" } +bool l = std::cmp_greater_equal(U'a', 97); // { dg-error "here" } + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc new file mode 100644 index 00000000000..e878e26a480 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_neg.cc @@ -0,0 +1,36 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +bool a = std::cmp_greater('1', 49); // { dg-error "here" } +bool b = std::cmp_greater(50, '2'); // { dg-error "here" } +bool c = std::cmp_greater(2, L'2'); // { dg-error "here" } +bool d = std::cmp_greater(L'2', 2); // { dg-error "here" } +bool e = std::cmp_greater(true, 1); // { dg-error "here" } +bool f = std::cmp_greater(0, false); // { dg-error "here" } +bool g = std::cmp_greater(97, u8'a'); // { dg-error "here" } +bool h = std::cmp_greater(u8'a', 97); // { dg-error "here" } +bool i = std::cmp_greater(97, u'a'); // { dg-error "here" } +bool j = std::cmp_greater(u'a', 97); // { dg-error "here" } +bool k = std::cmp_greater(97, U'a'); // { dg-error "here" } +bool l = std::cmp_greater(U'a', 97); // { dg-error "here" } + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range.cc new file mode 100644 index 00000000000..218f1f881e7 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range.cc @@ -0,0 +1,81 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include + +void +test01() +{ + unsigned int u = std::numeric_limits::max(); + VERIFY( std::in_range(u) ); + VERIFY( !std::in_range(u) ); + int s = -1; + VERIFY( !std::in_range(s) ); + s = std::numeric_limits::max(); + VERIFY( std::in_range(s) ); +} + +constexpr bool +test02() +{ + unsigned int u = std::numeric_limits::max(); + if (std::in_range(u)) + throw 1; + int s = -1; + if (std::in_range(s)) + throw 2; + s = std::numeric_limits::max(); + if (!std::in_range(s)) + throw 3; + return true; +} + +void +test03() +{ + short ss = -1; + VERIFY( std::in_range(ss) ); + VERIFY( !std::in_range(ss) ); + int s = -1; + VERIFY( std::in_range(s) ); + VERIFY( !std::in_range(s) ); + VERIFY( !std::in_range(s) ); + VERIFY( std::in_range(s) ); + s = std::numeric_limits::min() - 1; + VERIFY( !std::in_range(s) ); + + unsigned int u = (unsigned int) -1; + VERIFY( !std::in_range(u) ); + VERIFY( !std::in_range(u) ); + + unsigned long ul = (unsigned long) -1; + VERIFY( !std::in_range(ul) ); + VERIFY( std::in_range(ul) ); +} + +int +main() +{ + test01(); + static_assert( test02() ); + test03(); +} diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc new file mode 100644 index 00000000000..13e2bf75a8a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/in_range_neg.cc @@ -0,0 +1,36 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +bool a = std::in_range('1'); // { dg-error "here" } +bool b = std::in_range(50); // { dg-error "here" } +bool c = std::in_range(L'2'); // { dg-error "here" } +bool d = std::in_range(2); // { dg-error "here" } +bool e = std::in_range(true); // { dg-error "here" } +bool f = std::in_range(0); // { dg-error "here" } +bool g = std::in_range(u8'a'); // { dg-error "here" } +bool h = std::in_range(97); // { dg-error "here" } +bool i = std::in_range(u'a'); // { dg-error "here" } +bool j = std::in_range(97); // { dg-error "here" } +bool k = std::in_range(U'a'); // { dg-error "here" } +bool l = std::in_range(97); // { dg-error "here" } + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc new file mode 100644 index 00000000000..a35006fc2fb --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc @@ -0,0 +1,78 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include + +void +test01() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + VERIFY( std::cmp_less(s, u) ); + VERIFY( !std::cmp_less(u, s) ); + u = (unsigned) std::numeric_limits::max() + 1U; + VERIFY( std::cmp_less(s, u) ); + VERIFY( !std::cmp_less(u, s) ); +} + +constexpr bool +test02() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + if (!std::cmp_less(s, u)) + throw 1; + if (std::cmp_less(u, s)) + throw 2; + return true; +} + +void +test03() +{ + short ss = -1; + int s = -1; + VERIFY( !std::cmp_less(s, ss) ); + VERIFY( !std::cmp_less(ss, s) ); + + unsigned int u = (unsigned int) -1; + VERIFY( std::cmp_less(s, u) ); + VERIFY( !std::cmp_less(u, s) ); + VERIFY( std::cmp_less(ss, u) ); + VERIFY( !std::cmp_less(u, ss) ); + + unsigned long ul = (unsigned long) -1; + VERIFY( std::cmp_less(s, ul) ); + VERIFY( !std::cmp_less(ul, s) ); + VERIFY( std::cmp_less(ss, ul) ); + VERIFY( !std::cmp_less(ul, ss) ); + VERIFY( std::cmp_less(u, ul) ); + VERIFY( !std::cmp_less(ul, u) ); +} + +int +main() +{ + test01(); + static_assert( test02() ); + test03(); +} diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc new file mode 100644 index 00000000000..7875802856c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc @@ -0,0 +1,81 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include + +void +test01() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + VERIFY( std::cmp_less_equal(s, u) ); + VERIFY( !std::cmp_less_equal(u, s) ); + u = (unsigned) std::numeric_limits::max() + 1U; + VERIFY( std::cmp_less_equal(s, u) ); + VERIFY( !std::cmp_less_equal(u, s) ); +} + +constexpr bool +test02() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + if (!std::cmp_less_equal(s, u)) + throw 1; + if (std::cmp_less_equal(u, s)) + throw 2; + return true; +} + +void +test03() +{ + short ss = -1; + int s = -1; + VERIFY( std::cmp_less_equal(s, ss) ); + VERIFY( std::cmp_less_equal(ss, s) ); + VERIFY( std::cmp_less_equal(-2, ss) ); + + unsigned int u = (unsigned int) -1; + VERIFY( std::cmp_less_equal(s, u) ); + VERIFY( !std::cmp_less_equal(u, s) ); + VERIFY( std::cmp_less_equal(ss, u) ); + VERIFY( !std::cmp_less_equal(u, ss) ); + VERIFY( std::cmp_less_equal(-2U, u) ); + + unsigned long ul = (unsigned long) -1; + VERIFY( std::cmp_less_equal(s, ul) ); + VERIFY( !std::cmp_less_equal(ul, s) ); + VERIFY( std::cmp_less_equal(ss, ul) ); + VERIFY( !std::cmp_less_equal(ul, ss) ); + VERIFY( std::cmp_less_equal(u, ul) ); + VERIFY( !std::cmp_less_equal(ul, u) ); + VERIFY( std::cmp_less_equal(-2UL, ul) ); +} + +int +main() +{ + test01(); + static_assert( test02() ); + test03(); +} diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc new file mode 100644 index 00000000000..39b558dac0b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal_neg.cc @@ -0,0 +1,36 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +bool a = std::cmp_less_equal('1', 49); // { dg-error "here" } +bool b = std::cmp_less_equal(50, '2'); // { dg-error "here" } +bool c = std::cmp_less_equal(2, L'2'); // { dg-error "here" } +bool d = std::cmp_less_equal(L'2', 2); // { dg-error "here" } +bool e = std::cmp_less_equal(true, 1); // { dg-error "here" } +bool f = std::cmp_less_equal(0, false); // { dg-error "here" } +bool g = std::cmp_less_equal(97, u8'a'); // { dg-error "here" } +bool h = std::cmp_less_equal(u8'a', 97); // { dg-error "here" } +bool i = std::cmp_less_equal(97, u'a'); // { dg-error "here" } +bool j = std::cmp_less_equal(u'a', 97); // { dg-error "here" } +bool k = std::cmp_less_equal(97, U'a'); // { dg-error "here" } +bool l = std::cmp_less_equal(U'a', 97); // { dg-error "here" } + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/less_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_neg.cc new file mode 100644 index 00000000000..171e7279e99 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_neg.cc @@ -0,0 +1,36 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +bool a = std::cmp_less('1', 49); // { dg-error "here" } +bool b = std::cmp_less(50, '2'); // { dg-error "here" } +bool c = std::cmp_less(2, L'2'); // { dg-error "here" } +bool d = std::cmp_less(L'2', 2); // { dg-error "here" } +bool e = std::cmp_less(true, 1); // { dg-error "here" } +bool f = std::cmp_less(0, false); // { dg-error "here" } +bool g = std::cmp_less(97, u8'a'); // { dg-error "here" } +bool h = std::cmp_less(u8'a', 97); // { dg-error "here" } +bool i = std::cmp_less(97, u'a'); // { dg-error "here" } +bool j = std::cmp_less(u'a', 97); // { dg-error "here" } +bool k = std::cmp_less(97, U'a'); // { dg-error "here" } +bool l = std::cmp_less(U'a', 97); // { dg-error "here" } + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc new file mode 100644 index 00000000000..81cbb3f4921 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc @@ -0,0 +1,75 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include + +void +test01() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + VERIFY( std::cmp_not_equal(s, u) ); + VERIFY( std::cmp_not_equal(u, s) ); +} + +constexpr bool +test02() +{ + unsigned int u = std::numeric_limits::max(); + int s = -1; + if (!std::cmp_not_equal(s, u)) + throw 1; + if (!std::cmp_not_equal(u, s)) + throw 2; + return true; +} + +void +test03() +{ + short ss = -1; + int s = -1; + VERIFY( !std::cmp_not_equal(s, ss) ); + VERIFY( !std::cmp_not_equal(ss, s) ); + + unsigned int u = (unsigned int) -1; + VERIFY( std::cmp_not_equal(s, u) ); + VERIFY( std::cmp_not_equal(u, s) ); + VERIFY( std::cmp_not_equal(ss, u) ); + VERIFY( std::cmp_not_equal(u, ss) ); + + unsigned long ul = (unsigned long) -1; + VERIFY( std::cmp_not_equal(s, ul) ); + VERIFY( std::cmp_not_equal(ul, s) ); + VERIFY( std::cmp_not_equal(ss, ul) ); + VERIFY( std::cmp_not_equal(ul, ss) ); + VERIFY( std::cmp_not_equal(u, ul) ); + VERIFY( std::cmp_not_equal(ul, u) ); +} + +int +main() +{ + test01(); + static_assert( test02() ); + test03(); +} diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal_neg.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal_neg.cc new file mode 100644 index 00000000000..dc70d8dfe82 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal_neg.cc @@ -0,0 +1,36 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +bool a = std::cmp_equal('1', 49); // { dg-error "here" } +bool b = std::cmp_equal(50, '2'); // { dg-error "here" } +bool c = std::cmp_equal(2, L'2'); // { dg-error "here" } +bool d = std::cmp_equal(L'2', 2); // { dg-error "here" } +bool e = std::cmp_equal(true, 1); // { dg-error "here" } +bool f = std::cmp_equal(0, false); // { dg-error "here" } +bool g = std::cmp_equal(97, u8'a'); // { dg-error "here" } +bool h = std::cmp_equal(u8'a', 97); // { dg-error "here" } +bool i = std::cmp_equal(97, u'a'); // { dg-error "here" } +bool j = std::cmp_equal(u'a', 97); // { dg-error "here" } +bool k = std::cmp_equal(97, U'a'); // { dg-error "here" } +bool l = std::cmp_equal(U'a', 97); // { dg-error "here" } + +// { dg-error "static assertion failed" "" { target *-*-* } 0 } -- 2.30.2