public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "redi at gcc dot gnu.org" <gcc-bugzilla@gcc.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	[thread overview]
Message-ID: <bug-103853-4-40Wc3KXGg1@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-103853-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103853

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2021-12-29
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(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 this
> argument, except that the argument passed to a move-assignment operator may
> 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) == this)
+         return;
+
+       merge(std::move(__list));
+      }

       /**
        *  @brief  Merge sorted lists according to comparison function.
@@ -1287,7 +1292,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       template<typename _Comp>
        void
        merge(forward_list& __list, _Comp __comp)
-       { merge(std::move(__list), __comp); }
+       {
+         if (std::__addressof(__list) == 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 experienced
> 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 that
working, you should fix that first.

Testing libstdc++ is documented at
https://gcc.gnu.org/onlinedocs/libstdc++/manual/test.html#test.run

  reply	other threads:[~2021-12-29 10:12 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-28 20:43 [Bug libstdc++/103853] New: " pavel.kryukov at phystech dot edu
2021-12-29 10:12 ` redi at gcc dot gnu.org [this message]
2021-12-29 10:22 ` [Bug libstdc++/103853] " redi at gcc dot gnu.org
2022-01-05 10:06 ` redi at gcc dot gnu.org
2022-01-05 10:48 ` redi at gcc dot gnu.org
2022-01-05 14:40 ` pavel.kryukov at phystech dot edu
2022-01-05 14:47 ` redi at gcc dot gnu.org
2022-01-06 10:50 ` pavel.kryukov at phystech dot edu
2022-01-06 15:00 ` cvs-commit at gcc dot gnu.org
2022-01-06 15:39 ` redi at gcc dot gnu.org
2022-01-06 19:02 ` pavel.kryukov at phystech dot edu
2022-04-21 12:33 ` cvs-commit at gcc dot gnu.org
2022-04-26 13:11 ` cvs-commit at gcc dot gnu.org
2022-05-09 16:40 ` cvs-commit at gcc dot gnu.org
2022-05-09 19:45 ` redi at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-103853-4-40Wc3KXGg1@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).