diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 07cc83d98f4..638f00716c8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2021-08-20 Paul Keir + + * libsupc++/compare: Avoid constexpr pointer comparison failure + in std::compare_three_way with Clang. + * testsuite/18_support/comparisons/pointers/constexpr.cc: + New test. + 2021-08-19 Jonathan Wakely * doc/xml/manual/status_cxx2020.xml: Move row earlier in table. diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare index 5aee89e3a6e..4081a3f2315 100644 --- a/libstdc++-v3/libsupc++/compare +++ b/libstdc++-v3/libsupc++/compare @@ -553,10 +553,10 @@ namespace std { if constexpr (__detail::__3way_builtin_ptr_cmp<_Tp, _Up>) { + if (__builtin_is_constant_evaluated()) + return static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u); auto __pt = static_cast(__t); auto __pu = static_cast(__u); - if (__builtin_is_constant_evaluated()) - return __pt <=> __pu; auto __it = reinterpret_cast<__UINTPTR_TYPE__>(__pt); auto __iu = reinterpret_cast<__UINTPTR_TYPE__>(__pu); return __it <=> __iu; diff --git a/libstdc++-v3/testsuite/18_support/comparisons/pointers/constexpr.cc b/libstdc++-v3/testsuite/18_support/comparisons/pointers/constexpr.cc new file mode 100644 index 00000000000..8e1dc2ed6d1 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/comparisons/pointers/constexpr.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2021 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 + +constexpr bool check01() +{ + int arr[2]; + bool b1 = &arr[0] < &arr[1]; + bool b2 = std::less{}(&arr[0], &arr[1]); + bool b3 = std::compare_three_way{}(&arr[0],&arr[1]) < 0; + return b1 && b2 && b3; +} + +constexpr bool check02() +{ + int *p = new int[2]; + bool b1 = &p[0] < &p[1]; + bool b2 = std::less{}(&p[0], &p[1]); + bool b3 = std::compare_three_way{}(&p[0],&p[1]) < 0; + delete [] p; + return b1 && b2 && b3; +} + +static_assert(check01()); +static_assert(check02());