From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 8C03F3858417; Wed, 29 Dec 2021 10:12:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8C03F3858417 From: "redi at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/103853] std::forward_list::merge should check if __list != this Date: Wed, 29 Dec 2021 10:12:32 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 12.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: redi at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cf_reconfirmed_on bug_status everconfirmed Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Dec 2021 10:12:32 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D103853 Jonathan Wakely changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2021-12-29 Status|UNCONFIRMED |NEW Ever confirmed|0 |1 --- Comment #1 from Jonathan Wakely --- (In reply to Pavel I. Kryukov from comment #0) > C++ standard does not require 'do nothing' if std::forward_list::merge > argument equals to 'this', however it does not say 'undefined behavior' or > 'infinite loop' too. It does say undefined behaviour for the overload your patch changes. [res.on.arguments] says: > If a function argument is bound to an rvalue reference parameter, the > implementation may assume that this parameter is a unique reference to th= is > argument, except that the argument passed to a move-assignment operator m= ay > be a reference to *this ([lib.types.movedfrom]). Passing *this as the first parameter of merge(forward_list&&) or merge(forward_list&&, Comp) breaks this assumption, resulting in undefined behaviour. The check is only needed for the overloads taking forward_list& parameters: --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -1267,7 +1267,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void merge(forward_list& __list) - { merge(std::move(__list)); } + { + if (std::__addressof(__list) =3D=3D this) + return; + + merge(std::move(__list)); + } /** * @brief Merge sorted lists according to comparison function. @@ -1287,7 +1292,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template void merge(forward_list& __list, _Comp __comp) - { merge(std::move(__list), __comp); } + { + if (std::__addressof(__list) =3D=3D this) + return; + + merge(std::move(__list), __comp); + } /** * @brief Sort the elements of the list. > I've attached my patch to fix and test it, but since I'm not an experienc= ed > GCC contributor, I don't know how to run the tests. Following instructions > on CONTRIBUTING page builds whole GCC ending with some problems with my > machine. I would be grateful if you tell how I can test only libstdc++. You need to build the whole of GCC to test libstdc++, so if you can't get t= hat working, you should fix that first. Testing libstdc++ is documented at https://gcc.gnu.org/onlinedocs/libstdc++/manual/test.html#test.run=