[committed] libstdc++: Implement "Safe Integral Comparisons" (P0586R2)

Message ID 20200217132159.GA1504927@redhat.com
State New
Headers show
Series
  • [committed] libstdc++: Implement "Safe Integral Comparisons" (P0586R2)
Related show

Commit Message

Jonathan Wakely Feb. 17, 2020, 1:21 p.m.
* 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.

Tested powerpc64le-linux, committed to master.
commit 98cf2c265962e260f2f95617983915c754f446ea
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Feb 17 13:20:57 2020 +0000

    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.

Comments

Christophe Lyon Feb. 18, 2020, 1:04 p.m. | #1
Hi,

On Mon, 17 Feb 2020 at 14:22, Jonathan Wakely <jwakely@redhat.com> wrote:
>

>         * 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.

>

> Tested powerpc64le-linux, committed to master.

>


Some of these new tests fail on arm (and s390 according to gcc-testresults):
FAIL: 20_util/integer_comparisons/equal.cc execution test
FAIL: 20_util/integer_comparisons/greater_equal.cc execution test
FAIL: 20_util/integer_comparisons/less.cc execution test
FAIL: 20_util/integer_comparisons/less_equal.cc execution test
FAIL: 20_util/integer_comparisons/not_equal.cc execution test

The log says:
/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc:64: void
test03(): Assertion '!std::cmp_equal(u, ul)' failed.
/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc:70:
void test03(): Assertion '!std::cmp_greater_equal(u, ul)' failed.
/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc:68: void
test03(): Assertion 'std::cmp_less(u, ul)' failed.
/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc:71:
void test03(): Assertion '!std::cmp_less_equal(ul, u)' failed.
/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc:65:
void test03(): Assertion 'std::cmp_not_equal(u, ul)' failed.

Christophe
Jonathan Wakely Feb. 18, 2020, 6:58 p.m. | #2
On 18/02/20 14:04 +0100, Christophe Lyon wrote:
>Hi,

>

>On Mon, 17 Feb 2020 at 14:22, Jonathan Wakely <jwakely@redhat.com> wrote:

>>

>>         * 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.

>>

>> Tested powerpc64le-linux, committed to master.

>>

>

>Some of these new tests fail on arm (and s390 according to gcc-testresults):

>FAIL: 20_util/integer_comparisons/equal.cc execution test

>FAIL: 20_util/integer_comparisons/greater_equal.cc execution test

>FAIL: 20_util/integer_comparisons/less.cc execution test

>FAIL: 20_util/integer_comparisons/less_equal.cc execution test

>FAIL: 20_util/integer_comparisons/not_equal.cc execution test

>

>The log says:

>/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc:64: void

>test03(): Assertion '!std::cmp_equal(u, ul)' failed.

>/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc:70:

>void test03(): Assertion '!std::cmp_greater_equal(u, ul)' failed.

>/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc:68: void

>test03(): Assertion 'std::cmp_less(u, ul)' failed.

>/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc:71:

>void test03(): Assertion '!std::cmp_less_equal(ul, u)' failed.

>/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc:65:

>void test03(): Assertion 'std::cmp_not_equal(u, ul)' failed.


Fixed with this patch, committed to master.
commit ce7b39d0fc694e5ec80520b7cc76f91a5476d7db
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Feb 18 18:56:30 2020 +0000

    libstdc++: Fix new tests that fail for ILP32 targets
    
            * testsuite/20_util/integer_comparisons/equal.cc: Fix invalid
            assumption that long is wider than int.
            * testsuite/20_util/integer_comparisons/greater_equal.cc: Likewise.
            * testsuite/20_util/integer_comparisons/less.cc: Likewise.
            * testsuite/20_util/integer_comparisons/less_equal.cc: Likewise.
            * testsuite/20_util/integer_comparisons/not_equal.cc: Likewise.

diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc
index 16d4e3bd65c..10ba39432be 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/equal.cc
@@ -56,7 +56,7 @@ test03()
   VERIFY( !std::cmp_equal(ss, u) );
   VERIFY( !std::cmp_equal(u, ss) );
 
-  unsigned long ul = (unsigned long) -1;
+  unsigned long long ul = (unsigned long long) -1;
   VERIFY( !std::cmp_equal(s, ul) );
   VERIFY( !std::cmp_equal(ul, s) );
   VERIFY( !std::cmp_equal(ss, ul) );
diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc
index 61f461b4056..f80c62f1274 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/greater_equal.cc
@@ -62,7 +62,7 @@ test03()
   VERIFY( std::cmp_greater_equal(u, ss) );
   VERIFY( std::cmp_greater_equal(u, -2U) );
 
-  unsigned long ul = (unsigned long) -1;
+  unsigned long long ul = (unsigned long long) -1;
   VERIFY( !std::cmp_greater_equal(s, ul) );
   VERIFY( std::cmp_greater_equal(ul, s) );
   VERIFY( !std::cmp_greater_equal(ss, ul) );
diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc
index a35006fc2fb..b70f4917103 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/less.cc
@@ -60,7 +60,7 @@ test03()
   VERIFY( std::cmp_less(ss, u) );
   VERIFY( !std::cmp_less(u, ss) );
 
-  unsigned long ul = (unsigned long) -1;
+  unsigned long long ul = (unsigned long long) -1;
   VERIFY( std::cmp_less(s, ul) );
   VERIFY( !std::cmp_less(ul, s) );
   VERIFY( std::cmp_less(ss, ul) );
diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc
index 7875802856c..b3a3ac8d2fa 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/less_equal.cc
@@ -62,7 +62,7 @@ test03()
   VERIFY( !std::cmp_less_equal(u, ss) );
   VERIFY( std::cmp_less_equal(-2U, u) );
 
-  unsigned long ul = (unsigned long) -1;
+  unsigned long long ul = (unsigned long long) -1;
   VERIFY( std::cmp_less_equal(s, ul) );
   VERIFY( !std::cmp_less_equal(ul, s) );
   VERIFY( std::cmp_less_equal(ss, ul) );
diff --git a/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc b/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc
index 81cbb3f4921..97f6fe6cfc3 100644
--- a/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc
+++ b/libstdc++-v3/testsuite/20_util/integer_comparisons/not_equal.cc
@@ -57,7 +57,7 @@ test03()
   VERIFY( std::cmp_not_equal(ss, u) );
   VERIFY( std::cmp_not_equal(u, ss) );
 
-  unsigned long ul = (unsigned long) -1;
+  unsigned long long ul = (unsigned long long) -1;
   VERIFY( std::cmp_not_equal(s, ul) );
   VERIFY( std::cmp_not_equal(ul, s) );
   VERIFY( std::cmp_not_equal(ss, ul) );

Patch

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<typename _Tp>
+    using __is_standard_integer
+      = __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>;
 
   // __void_t (std::void_t for C++11)
   template<typename...> 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 <bits/move.h>
 #include <initializer_list>
 
+#if __cplusplus > 201703L
+#include <limits>
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -397,6 +401,76 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     void as_const(const _Tp&&) = delete;
 
+#if __cplusplus > 201703L
+#define __cpp_lib_integer_comparison_functions 202002L
+
+  template<typename _Tp, typename _Up>
+    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<typename _Tp, typename _Up>
+    constexpr bool
+    cmp_not_equal(_Tp __t, _Up __u) noexcept
+    { return !std::cmp_equal(__t, __u); }
+
+  template<typename _Tp, typename _Up>
+    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<typename _Tp, typename _Up>
+    constexpr bool
+    cmp_greater(_Tp __t, _Up __u) noexcept
+    { return std::cmp_less(__u, __t); }
+
+  template<typename _Tp, typename _Up>
+    constexpr bool
+    cmp_less_equal(_Tp __t, _Up __u) noexcept
+    { return !std::cmp_less(__u, __t); }
+
+  template<typename _Tp, typename _Up>
+    constexpr bool
+    cmp_greater_equal(_Tp __t, _Up __u) noexcept
+    { return !std::cmp_less(__t, __u); }
+
+  template<typename _Up, typename _Tp>
+    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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do preprocess { target c++2a } }
+
+#include <utility>
+
+#ifndef __cpp_lib_integer_comparison_functions
+# error "Feature test macro for comparison functions is missing in <utility>"
+#elif __cpp_lib_integer_comparison_functions < 202002L
+# error "Feature test macro for comparison functions has wrong value in <utility>"
+#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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do preprocess { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_integer_comparison_functions
+# error "Feature test macro for comparison functions is missing in <version>"
+#elif __cpp_lib_integer_comparison_functions < 202002L
+# error "Feature test macro for comparison functions has wrong value in <version>"
+#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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <utility>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::max();
+  int s = -1;
+  VERIFY( !std::cmp_equal(s, u) );
+}
+
+constexpr bool
+test02()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <utility>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::max();
+  int s = -1;
+  VERIFY( !std::cmp_greater_equal(s, u) );
+  VERIFY( std::cmp_greater_equal(u, s) );
+  u = (unsigned) std::numeric_limits<int>::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<unsigned int>::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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <utility>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::max();
+  VERIFY( std::in_range<unsigned int>(u) );
+  VERIFY( !std::in_range<int>(u) );
+  int s = -1;
+  VERIFY( !std::in_range<unsigned int>(s) );
+  s = std::numeric_limits<int>::max();
+  VERIFY( std::in_range<unsigned int>(s) );
+}
+
+constexpr bool
+test02()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::max();
+  if (std::in_range<int>(u))
+    throw 1;
+  int s = -1;
+  if (std::in_range<unsigned>(s))
+    throw 2;
+  s = std::numeric_limits<int>::max();
+  if (!std::in_range<unsigned>(s))
+    throw 3;
+  return true;
+}
+
+void
+test03()
+{
+  short ss = -1;
+  VERIFY( std::in_range<int>(ss) );
+  VERIFY( !std::in_range<unsigned>(ss) );
+  int s = -1;
+  VERIFY( std::in_range<short>(s) );
+  VERIFY( !std::in_range<unsigned>(s) );
+  VERIFY( !std::in_range<unsigned long>(s) );
+  VERIFY( std::in_range<long>(s) );
+  s = std::numeric_limits<short>::min() - 1;
+  VERIFY( !std::in_range<short>(s) );
+
+  unsigned int u = (unsigned int) -1;
+  VERIFY( !std::in_range<int>(u) );
+  VERIFY( !std::in_range<unsigned short>(u) );
+
+  unsigned long ul = (unsigned long) -1;
+  VERIFY( !std::in_range<unsigned short>(ul) );
+  VERIFY( std::in_range<unsigned long long>(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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+bool a = std::in_range<int>('1'); // { dg-error "here" }
+bool b = std::in_range<char>(50); // { dg-error "here" }
+bool c = std::in_range<int>(L'2'); // { dg-error "here" }
+bool d = std::in_range<wchar_t>(2); // { dg-error "here" }
+bool e = std::in_range<int>(true); // { dg-error "here" }
+bool f = std::in_range<bool>(0); // { dg-error "here" }
+bool g = std::in_range<int>(u8'a'); // { dg-error "here" }
+bool h = std::in_range<char8_t>(97); // { dg-error "here" }
+bool i = std::in_range<int>(u'a'); // { dg-error "here" }
+bool j = std::in_range<char16_t>(97); // { dg-error "here" }
+bool k = std::in_range<int>(U'a'); // { dg-error "here" }
+bool l = std::in_range<char32_t>(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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <utility>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::max();
+  int s = -1;
+  VERIFY( std::cmp_less(s, u) );
+  VERIFY( !std::cmp_less(u, s) );
+  u = (unsigned) std::numeric_limits<int>::max() + 1U;
+  VERIFY( std::cmp_less(s, u) );
+  VERIFY( !std::cmp_less(u, s) );
+}
+
+constexpr bool
+test02()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <utility>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::max();
+  int s = -1;
+  VERIFY( std::cmp_less_equal(s, u) );
+  VERIFY( !std::cmp_less_equal(u, s) );
+  u = (unsigned) std::numeric_limits<int>::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<unsigned int>::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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <utility>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  unsigned int u = std::numeric_limits<unsigned int>::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<unsigned int>::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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+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 }