[PATCH] libstdc++: Fix constexpr basic_string union member [PR113294]
A call to `basic_string::clear()` in the std::string move assignment operator leads to a constexpr error from an access of inactive union member `_M_local_buf` in the added test (`test_move()`). Changing `__str._M_local_buf` to `__str._M_use_local_data()` in `operator=(basic_string&& __str)` fixes this. Running `make check RUNTESTFLAGS="conformance.exp=21_strings/basic_string/*"` on x86_64-pc-linux-gnu gave unchanged summary results (# of expected passes 570 # of expected failures 4 # of unsupported tests 4). I don't have write access. Signed-off-by: Paul Keir diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 43efc99bea9..8a695a494ef 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -909,7 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 __str._M_capacity(__capacity); } else - __str._M_data(__str._M_local_buf); + __str._M_data(__str._M_use_local_data()); } else // Need to do a deep copy assign(__str); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/constexpr.cc index 0e28a6d4487..ad7548f3236 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/constexpr.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/constexpr.cc @@ -50,3 +50,16 @@ test_erasure() } static_assert( test_erasure() ); + +constexpr bool +test_move() +{ + std::string s1; + std::string s2 = "1234567890123456"; // 16 chars: more than _S_local_capacity + s1 = std::move(s2); + VERIFY( s1 == "1234567890123456" ); + + return true; +} + +static_assert( test_move() ); -- Please consider the environment and think before you print. The University of the West of Scotland is a registered Scottish charity. Charity number SC002520. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland. As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002.
[PATCH] libstdc++: Fix char_traits move with overlap
Hi, Upon constexpr evaluation, char_traits move uses copy_backward, but its last argument should be to the range end rather than its beginning. I include the fix and a test. This is my first patch, so if it looks OK, perhaps someone could commit for me. Regards, Paul Please consider the environment and think before you print. The University of the West of Scotland is a registered Scottish charity. Charity number SC002520. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland. As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002. diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ee252236a..b54dccd2d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2020-06-12 Paul Keir + + * include/bits/char_traits.h: constexpr char_traits + move with overlap was using copy_backward incorrectly. + * testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc: New test. + 2020-06-04 Jonathan Wakely * include/bits/iterator_concepts.h (__detail::__ptr, __detail::__ref) diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index c6da184e4..c623a6713 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -196,7 +196,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (std::is_constant_evaluated()) { if (__s1 > __s2 && __s1 < __s2 + __n) - std::copy_backward(__s2, __s2 + __n, __s1); + std::copy_backward(__s2, __s2 + __n, __s1 + __n); else std::copy(__s2, __s2 + __n, __s1); return __s1; diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc new file mode 100644 index 0..6358640c1 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++20.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2017-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/>. + +#include + +template + constexpr bool + test_move() + { +using char_type = typename CT::char_type; +char_type s1[3] = {1, 2, 3}; +CT::move(s1+1, s1, 2); +return s1[0]==char_type{1} && s1[1]==char_type{1} && s1[2]==char_type{2}; + } + +#ifndef __cpp_lib_constexpr_char_traits +# error Feature-test macro for constexpr char_traits is missing +#elif __cpp_lib_constexpr_char_traits != 201611 +# error Feature-test macro for constexpr char_traits has the wrong value +#endif + +static_assert( test_move>() ); +#ifdef _GLIBCXX_USE_WCHAR_T +static_assert( test_move>() ); +#endif +#ifdef _GLIBCXX_USE_CHAR8_T +static_assert( test_move>() ); +#endif +static_assert( test_move>() ); +static_assert( test_move>() ); + +struct C { unsigned char c; }; +constexpr bool operator==(const C& c1, const C& c2) { return c1.c == c2.c; } +constexpr bool operator<(const C& c1, const C& c2) { return c1.c < c2.c; } +static_assert( test_move>() );
Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2
Let me know if this needs a refresh. From: Paul Keir Sent: 06 June 2025 5:32 PM To: Jonathan Wakely Cc: gcc-patches@gcc.gnu.org; libstd...@gcc.gnu.org Subject: Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2 No problem. That should be it included below. Github diff for convenience: https://github.com/gcc-mirror/gcc/compare/e37eb85...pkeir:gcc:1b7c7c1a Signed-off-by: Paul Keir Tested on x86_64-linux. libstdc++-v3/ChangeLog: * include/bits/shared_ptr.h: Added owner_equal and owner_hash members to shared_ptr and weak_ptr. * include/bits/shared_ptr_base.h: Added owner_equal and owner_hash structs. * include/bits/version.def: Added __cpp_lib_smart_ptr_owner_equality feature macro. * include/bits/version.h: Update generated for __cpp_lib_smart_ptr_owner_equality feature macro. * include/std/memory: Added define for __glibcxx_want_smart_ptr_owner_equality. * testsuite/20_util/owner_equal/version.cc: New test. * testsuite/20_util/owner_equal/cmp.cc: New test. * testsuite/20_util/owner_equal/noexcept.cc: New test. * testsuite/20_util/owner_hash/cmp.cc: New test. * testsuite/20_util/owner_hash/noexcept.cc: New test. * testsuite/20_util/shared_ptr/observers/owner_equal.cc: New test. * testsuite/20_util/shared_ptr/observers/owner_hash.cc: New test. * testsuite/20_util/weak_ptr/observers/owner_equal.cc: New test. * testsuite/20_util/weak_ptr/observers/owner_hash.cc: New test. --- include/bits/shared_ptr.h | 57 +++ include/bits/shared_ptr_base.h | 40 include/bits/version.def | 9 ++ include/bits/version.h | 10 ++ include/std/memory | 1 + testsuite/20_util/owner_equal/cmp.cc | 105 + testsuite/20_util/owner_equal/noexcept.cc | 30 ++ testsuite/20_util/owner_equal/version.cc | 13 +++ testsuite/20_util/owner_hash/cmp.cc| 87 + testsuite/20_util/owner_hash/noexcept.cc | 16 .../20_util/shared_ptr/observers/owner_equal.cc| 74 +++ .../20_util/shared_ptr/observers/owner_hash.cc | 71 ++ .../20_util/weak_ptr/observers/owner_equal.cc | 52 ++ testsuite/20_util/weak_ptr/observers/owner_hash.cc | 50 ++ 14 files changed, 615 insertions(+) diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index a196a0f1212..dd02ab16e59 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -909,6 +909,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Sp_owner_less, shared_ptr<_Tp>> { }; +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + + /** + * @brief Provides ownership-based hashing. + * @headerfile memory + * @since C++26 + */ + struct owner_hash + { +template +size_t operator()(const shared_ptr<_Tp>& __s) const noexcept +{ return __s.owner_hash(); } + +template +size_t operator()(const weak_ptr<_Tp>& __s) const noexcept +{ return __s.owner_hash(); } + +using is_transparent = void; + }; + + /** + * @brief Provides ownership-based mixed equality comparisons of + *shared and weak pointers. + * @headerfile memory + * @since C++26 + */ + struct owner_equal + { +template +bool +operator()(const shared_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const shared_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const weak_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const weak_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +using is_transparent = void; + }; + +#endif + /** * @brief Base class allowing use of the member function `shared_from_this`. * @headerfile memory diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index b4be1b49e4d..f820d31e56b 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1122,6 +1122,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __weak_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*
Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2
Thanks Jonathan. From: Jonathan Wakely Sent: 08 July 2025 1:37 PM To: Paul Keir Cc: gcc-patches@gcc.gnu.org; libstd...@gcc.gnu.org Subject: Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2 Warning: Do not open attachments or click on links unless you trust the sender On Tue, 8 Jul 2025 at 13:24, Jonathan Wakely wrote: > > On Tue, 8 Jul 2025 at 12:54, Paul Keir wrote: > > > > Let me know if this needs a refresh. > > The patch fails to apply: > > error: patch failed: libstdc++-v3/include/bits/shared_ptr_base.h:1715 > error: libstdc++-v3/include/bits/shared_ptr_base.h: patch does not apply > > but I think it's your mail client munging whitespace, not something > that can be fixed by rebasing on trunk. > I'll figure it out and apply it by hand. OK, I added your github fork and did a merge --squash from there > > > > > > > > From: Paul Keir > > Sent: 06 June 2025 5:32 PM > > To: Jonathan Wakely > > Cc: gcc-patches@gcc.gnu.org; libstd...@gcc.gnu.org > > Subject: Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash > > structs and members for P1901R2 > > > > No problem. That should be it included below. Github diff for convenience: > > https://github.com/gcc-mirror/gcc/compare/e37eb85...pkeir:gcc:1b7c7c1a > > > > Signed-off-by: Paul Keir > > > > Tested on x86_64-linux. > > > > libstdc++-v3/ChangeLog: > > > > * include/bits/shared_ptr.h: Added owner_equal and owner_hash > > members to shared_ptr and weak_ptr. > > * include/bits/shared_ptr_base.h: Added owner_equal and owner_hash > > structs. > > * include/bits/version.def: Added > > __cpp_lib_smart_ptr_owner_equality feature macro. > > * include/bits/version.h: Update generated for > > __cpp_lib_smart_ptr_owner_equality feature macro. > > * include/std/memory: Added define for > > __glibcxx_want_smart_ptr_owner_equality. > > * testsuite/20_util/owner_equal/version.cc: New test. > > * testsuite/20_util/owner_equal/cmp.cc: New test. > > * testsuite/20_util/owner_equal/noexcept.cc: New test. > > * testsuite/20_util/owner_hash/cmp.cc: New test. > > * testsuite/20_util/owner_hash/noexcept.cc: New test. > > * testsuite/20_util/shared_ptr/observers/owner_equal.cc: New test. > > * testsuite/20_util/shared_ptr/observers/owner_hash.cc: New test. > > * testsuite/20_util/weak_ptr/observers/owner_equal.cc: New test. > > * testsuite/20_util/weak_ptr/observers/owner_hash.cc: New test. > > > > --- > > > > include/bits/shared_ptr.h | 57 +++ > > include/bits/shared_ptr_base.h | 40 > > include/bits/version.def | 9 ++ > > include/bits/version.h | 10 ++ > > include/std/memory | 1 + > > testsuite/20_util/owner_equal/cmp.cc | 105 > > + > > testsuite/20_util/owner_equal/noexcept.cc | 30 ++ > > testsuite/20_util/owner_equal/version.cc | 13 +++ > > testsuite/20_util/owner_hash/cmp.cc| 87 + > > testsuite/20_util/owner_hash/noexcept.cc | 16 > > .../20_util/shared_ptr/observers/owner_equal.cc| 74 +++ > > .../20_util/shared_ptr/observers/owner_hash.cc | 71 ++ > > .../20_util/weak_ptr/observers/owner_equal.cc | 52 ++ > > testsuite/20_util/weak_ptr/observers/owner_hash.cc | 50 ++ > > 14 files changed, 615 insertions(+) > > > > diff --git a/libstdc++-v3/include/bits/shared_ptr.h > > b/libstdc++-v3/include/bits/shared_ptr.h > > index a196a0f1212..dd02ab16e59 100644 > > --- a/libstdc++-v3/include/bits/shared_ptr.h > > +++ b/libstdc++-v3/include/bits/shared_ptr.h > > @@ -909,6 +909,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > : public _Sp_owner_less, shared_ptr<_Tp>> > > { }; > > > > +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 > > + > > + /** > > + * @brief Provides ownership-based hashing. > > + * @headerfile memory > > + * @since C++26 > > + */ > > + struct owner_hash > > + { > > +template > > +size_t operator()(const shared_ptr<_Tp>& __s) const noexcept > > +{ return __s.owner_hash(); } > > +
[PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2
This patch implements C++26 "Enabling the Use of weak_ptr as Keys in Unordered Associative Containers", as specified in P1901R2. I don't have write access. Signed-off-by: Paul Keir Tested on x86_64-linux. libstdc++-v3/ChangeLog: * include/bits/shared_ptr.h: Added owner_equal and owner_hash members to shared_ptr and weak_ptr * include/bits/shared_ptr_base.h: Added owner_equal and owner_hash structs * testsuite/20_util/owner_equal/cmp.cc: New test. * testsuite/20_util/owner_equal/noexcept.cc: New test. * testsuite/20_util/owner_hash/cmp.cc: New test. * testsuite/20_util/owner_hash/noexcept.cc: New test. * testsuite/20_util/shared_ptr/observers/owner_equal.cc: New test. * testsuite/20_util/shared_ptr/observers/owner_hash.cc: New test. * testsuite/20_util/weak_ptr/observers/owner_equal.cc: New test. * testsuite/20_util/weak_ptr/observers/owner_hash.cc: New test. --- libstdc++-v3/include/bits/shared_ptr.h | 57 ++ libstdc++-v3/include/bits/shared_ptr_base.h| 40 +++ libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc | 122 + .../testsuite/20_util/owner_equal/noexcept.cc | 39 +++ libstdc++-v3/testsuite/20_util/owner_hash/cmp.cc | 104 ++ .../testsuite/20_util/owner_hash/noexcept.cc | 31 ++ .../20_util/shared_ptr/observers/owner_equal.cc| 93 .../20_util/shared_ptr/observers/owner_hash.cc | 90 +++ .../20_util/weak_ptr/observers/owner_equal.cc | 71 .../20_util/weak_ptr/observers/owner_hash.cc | 69 10 files changed, 716 insertions(+) diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index a196a0f1212..9f25f6ccc23 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -909,6 +909,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Sp_owner_less, shared_ptr<_Tp>> { }; +#if __cplusplus > 202302L + + /** + * @brief Provides ownership-based hashing. + * @headerfile memory + * @since C++26 + */ + struct owner_hash + { +template +size_t operator()(const shared_ptr<_Tp>& __s) const noexcept +{ return __s.owner_hash(); } + +template +size_t operator()(const weak_ptr<_Tp>& __s) const noexcept +{ return __s.owner_hash(); } + +using is_transparent = void; + }; + + /** + * @brief Provides ownership-based mixed equality comparisons of + *shared and weak pointers. + * @headerfile memory + * @since C++26 + */ + struct owner_equal + { +template +bool +operator()(const shared_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const shared_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const weak_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const weak_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +using is_transparent = void; + }; + +#endif + /** * @brief Base class allowing use of the member function `shared_from_this`. * @headerfile memory diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index b4be1b49e4d..6db8095f583 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1122,6 +1122,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __weak_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } +#if __cplusplus > 202302L + size_t + _M_owner_hash() const noexcept + { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); } +#endif + // Friend function injected into enclosing namespace and found by ADL friend inline bool operator==(const __shared_count& __a, const __shared_count& __b) noexcept @@ -1225,6 +1231,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __shared_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } +#if __cplusplus > 202302L + size_t + _M_owner_hash() const noexcept + { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); } +#endif + // Friend function injected into enclosing namespace and found
Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2
Sounds good. I've added the changes you suggested (diff is linked below). I'll send an updated patch after your review. https://github.com/gcc-mirror/gcc/compare/97e8cd9...pkeir:gcc:4f699d8 From: Jonathan Wakely Sent: 23 May 2025 8:11 PM To: Paul Keir Cc: gcc-patches@gcc.gnu.org; libstd...@gcc.gnu.org Subject: Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2 Warning: Do not open attachments or click on links unless you trust the sender On Fri, 23 May 2025 at 18:56, Paul Keir wrote: > > This patch implements C++26 "Enabling the Use of weak_ptr as Keys in > Unordered Associative Containers", as specified in P1901R2. Splendid, thanks. I'll review this more carefully next week. Some quick comments: This should define the __cpp_lib_smart_pointer_owner_equality feature test macro. To do that you need to add a new entry in include/bits/version.def (see the comments at the top and the existing entries which should be fairly clear - I am in the middle of documenting this process). Then in the $objdir/x86_64-pc-linux-gnu/libstdc++-v3/include directory run 'make update-version' which should regenerate the bits/version.h file to include your new macro. Then in define __glibcxx_want_smart_pointer_owner_equality before including . > diff --git a/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc > b/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc > new file mode 100644 > index 000..c958d9c62ea > --- /dev/null > +++ b/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc > @@ -0,0 +1,122 @@ > +// { dg-do run { target c++26 } } > +// { dg-require-effective-target hosted } > + > +// Copyright (C) 2008-2025 Free Software Foundation, Inc. I see that all the new tests have copyright dates varying from 2008 to 2017, but they're all new files (I don't think they copy anythign from existing tests, right?). So they should not have copyright dates claiming to be written in the past. They also shouldn't have copyright notices claiming to be owned by the FSF if you're contributing them under the DCO terms, because you retain your own copyright. My preference for new tests is not to bother with the copyright notice or license text at all. Nothing in those tests looks very novel or inventive, it's just repetitive, fairly mechanical testing of the API. I am sceptical whether such things are even copyrightable. So I don't both with the 20 lines of comments in each file, e.g. see testsuite/20_util/weak_ptr/atomic_weak_ptr.cc from 2022. > +// 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/>. > + > +// 20.3.2.6 Struct owner_equal [util.smartptr.owner.equal] Please put the C++ standard version, or in this case working draft number, in these comments, e.g. // N5008 20.3.2.6 Struct owner_equal [util.smartptr.owner.equal] We didn't used to do that (as you'll see in the old tests) and it becomes pretty pointless to just have a subclause number in some unspecified document (unlike the C standard, the C++ subclause numbers change dramatically between standards). I have been trying to add "C++11" or "C++03" those comments in old tests when I touch the file for some other reason. Please consider the environment and think before you print. The University of the West of Scotland is a registered Scottish charity. Charity number SC002520. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland. As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002.
Re: [PATCH] libstdc++: Add smart ptr owner_equals and owner_hash structs and members for P1901R2
No problem. That should be it included below. Github diff for convenience: https://github.com/gcc-mirror/gcc/compare/e37eb85...pkeir:gcc:1b7c7c1a Signed-off-by: Paul Keir Tested on x86_64-linux. libstdc++-v3/ChangeLog: * include/bits/shared_ptr.h: Added owner_equal and owner_hash members to shared_ptr and weak_ptr. * include/bits/shared_ptr_base.h: Added owner_equal and owner_hash structs. * include/bits/version.def: Added __cpp_lib_smart_ptr_owner_equality feature macro. * include/bits/version.h: Update generated for __cpp_lib_smart_ptr_owner_equality feature macro. * include/std/memory: Added define for __glibcxx_want_smart_ptr_owner_equality. * testsuite/20_util/owner_equal/version.cc: New test. * testsuite/20_util/owner_equal/cmp.cc: New test. * testsuite/20_util/owner_equal/noexcept.cc: New test. * testsuite/20_util/owner_hash/cmp.cc: New test. * testsuite/20_util/owner_hash/noexcept.cc: New test. * testsuite/20_util/shared_ptr/observers/owner_equal.cc: New test. * testsuite/20_util/shared_ptr/observers/owner_hash.cc: New test. * testsuite/20_util/weak_ptr/observers/owner_equal.cc: New test. * testsuite/20_util/weak_ptr/observers/owner_hash.cc: New test. --- include/bits/shared_ptr.h | 57 +++ include/bits/shared_ptr_base.h | 40 include/bits/version.def | 9 ++ include/bits/version.h | 10 ++ include/std/memory | 1 + testsuite/20_util/owner_equal/cmp.cc | 105 + testsuite/20_util/owner_equal/noexcept.cc | 30 ++ testsuite/20_util/owner_equal/version.cc | 13 +++ testsuite/20_util/owner_hash/cmp.cc| 87 + testsuite/20_util/owner_hash/noexcept.cc | 16 .../20_util/shared_ptr/observers/owner_equal.cc| 74 +++ .../20_util/shared_ptr/observers/owner_hash.cc | 71 ++ .../20_util/weak_ptr/observers/owner_equal.cc | 52 ++ testsuite/20_util/weak_ptr/observers/owner_hash.cc | 50 ++ 14 files changed, 615 insertions(+) diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index a196a0f1212..dd02ab16e59 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -909,6 +909,63 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Sp_owner_less, shared_ptr<_Tp>> { }; +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + + /** + * @brief Provides ownership-based hashing. + * @headerfile memory + * @since C++26 + */ + struct owner_hash + { +template +size_t operator()(const shared_ptr<_Tp>& __s) const noexcept +{ return __s.owner_hash(); } + +template +size_t operator()(const weak_ptr<_Tp>& __s) const noexcept +{ return __s.owner_hash(); } + +using is_transparent = void; + }; + + /** + * @brief Provides ownership-based mixed equality comparisons of + *shared and weak pointers. + * @headerfile memory + * @since C++26 + */ + struct owner_equal + { +template +bool +operator()(const shared_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const shared_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const weak_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +template +bool +operator()(const weak_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept +{ return __lhs.owner_equal(__rhs); } + +using is_transparent = void; + }; + +#endif + /** * @brief Base class allowing use of the member function `shared_from_this`. * @headerfile memory diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index b4be1b49e4d..f820d31e56b 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1122,6 +1122,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __weak_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t + _M_owner_hash() const noexcept + { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); } +#endif + // Friend function injected into enclosin
[PATCH] libstdc++: Fix compare_three_way for constexpr and Clang
Hi, The current compare_three_way implementation makes provision for constant evaluation contexts (avoiding reinterpret_cast etc.), but the approach fails with Clang; when it compares two const volatile void pointers: "comparison between unequal pointers to void has unspecified result". I include a fix and test. Could someone commit the attached patch for me? Thanks, Paul Please consider the environment and think before you print. The University of the West of Scotland is a registered Scottish charity. Charity number SC002520. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland. As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002. 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 000..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 +// <http://www.gnu.org/licenses/>. + +// { 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());
Re: [PATCH] libstdc++: Fix compare_three_way for constexpr and Clang
*ping* From: Paul Keir Sent: 20 August 2021 21:17 To: gcc-patches@gcc.gnu.org Cc: libstd...@gcc.gnu.org Subject: [PATCH] libstdc++: Fix compare_three_way for constexpr and Clang Hi, The current compare_three_way implementation makes provision for constant evaluation contexts (avoiding reinterpret_cast etc.), but the approach fails with Clang; when it compares two const volatile void pointers: "comparison between unequal pointers to void has unspecified result". I include a fix and test. Could someone commit the attached patch for me? Thanks, Paul Please consider the environment and think before you print. The University of the West of Scotland is a registered Scottish charity. Charity number SC002520. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland. As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002.
Re: [PATCH] libstdc++: Fix compare_three_way for constexpr and Clang
*ping* From: Paul Keir Sent: 03 September 2021 11:31 To: gcc-patches@gcc.gnu.org Cc: libstd...@gcc.gnu.org Subject: Re: [PATCH] libstdc++: Fix compare_three_way for constexpr and Clang *ping* From: Paul Keir Sent: 20 August 2021 21:17 To: gcc-patches@gcc.gnu.org Cc: libstd...@gcc.gnu.org Subject: [PATCH] libstdc++: Fix compare_three_way for constexpr and Clang Hi, The current compare_three_way implementation makes provision for constant evaluation contexts (avoiding reinterpret_cast etc.), but the approach fails with Clang; when it compares two const volatile void pointers: "comparison between unequal pointers to void has unspecified result". I include a fix and test. Could someone commit the attached patch for me? Thanks, Paul Please consider the environment and think before you print. The University of the West of Scotland is a registered Scottish charity. Charity number SC002520. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland. As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002.
Re: [PATCH] libstdc++: Fix compare_three_way for constexpr and Clang
I'd like to cancel the request to apply that patch. At the time I had actually assumed that Clang was at fault, but your comment made me pause. I'll submit a bug report as you suggest. We can reconsider the patch in future once that bug is resolved. From: Jonathan Wakely Sent: 11 October 2021 22:04 To: Paul Keir Cc: gcc-patches@gcc.gnu.org; libstd...@gcc.gnu.org Subject: Re: [PATCH] libstdc++: Fix compare_three_way for constexpr and Clang The source of this email is EXTERNAL to UWS On Mon, 11 Oct 2021 at 20:48, Jonathan Wakely wrote: > > On Fri, 20 Aug 2021 at 21:19, Paul Keir wrote: > > > > Hi, > > > > The current compare_three_way implementation makes provision for constant > > evaluation contexts (avoiding reinterpret_cast etc.), but the approach > > fails with Clang; when it compares two const volatile void pointers: > > "comparison between unequal pointers to void has unspecified result". I > > include a fix and test. > > > > Could someone commit the attached patch for me? > > Sorry for dropping the ball on this again. I've applied the patch > locally and I'm testing it now. Unless I'm mistaken, you do not have a > copyright assignment on file with the FSF, is that right? Are you able > to certify that you have the right to submit this to GCC, as described > at > https://eu-west-1.protection.sophos.com?d=gnu.org&u=aHR0cHM6Ly9nY2MuZ251Lm9yZy9kY28uaHRtbA==&i=NWY2MGNhZjMzZTA5NzkwZGZlNmJhMzUy&t=SlR2SzN4czZueWZRZGdubVA0Z2M4M2FGbC9YLzIrWEVZaUpTMEhaZUJLND0=&h=929febb5b144486493bd3fc3c8522cfe > ? P.S. patches should not touch the ChangeLog file. It was always wrong, because it usually makes the patch fail to apply. Since we moved to Git the ChangeLog files are automatically generated from the Git commits anyway, so are never touched as part of the commit. The changelog entry is still needed, but should be in the Git commit message not as a patch against the actual ChangeLog file. > > Also, if GCC is failing to diagnose the invalid comparisons here then > that should be reported to bugzilla as a c++ "accepts-invalid" bug. Please consider the environment and think before you print. The University of the West of Scotland is a registered Scottish charity. Charity number SC002520. This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Please note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of the University of the West of Scotland. As a public body, the University of the West of Scotland may be required to make available emails as well as other written forms of information as a result of a request made under the Freedom of Information (Scotland) Act 2002.