public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "bugs at phlexo dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug libstdc++/115285] New: std::unordered_set can have duplicate values
Date: Thu, 30 May 2024 01:36:53 +0000	[thread overview]
Message-ID: <bug-115285-4@http.gcc.gnu.org/bugzilla/> (raw)

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

            Bug ID: 115285
           Summary: std::unordered_set can have duplicate values
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bugs at phlexo dot com
  Target Milestone: ---

When a derived class, which uses its base class' hasher and performs a
conversion during the base class constructor call, is used as the value_type of
a std::unordered_set object, the std::unordered_set will contain duplicates if
it's constructed from iterators of a container holding base class objects that
result in duplicate values after the conversion.

Example:

#include <string>
#include <vector>
#include <unordered_set>
#include <cassert>

class TrimmedStr : public std::string {
        static std::string trim_str(std::string const &str) {
                auto start = str.find_first_not_of(" \r\n\t");

                return start == std::string::npos
                        ? str
                        : str.substr(start, str.find_last_not_of(" \r\n\t") -
start + 1);
        }

        public:
        TrimmedStr(std::string const &arg) : std::string{trim_str(arg)} {}
        TrimmedStr(char const *arg) : TrimmedStr{std::string{arg}} {}
};

namespace std {
        template<> struct hash<TrimmedStr> : public std::hash<std::string> {};
}

int main() {
        assert(TrimmedStr{"foo "} == std::string{"foo"});
        assert(TrimmedStr{" foo"} == std::string{"foo"});
        assert(TrimmedStr{" foo "} == std::string{"foo"});

        std::unordered_set<TrimmedStr> set_from_initializer_list{"foo", "bar",
" foo ", " bar "};
        assert(set_from_initializer_list.size() == 2); //Passes.

        std::vector<std::string> args{"foo", "bar", " foo ", " bar "};
        std::unordered_set<TrimmedStr> set_from_iterators{args.begin(),
args.end()};
        assert(set_from_iterators.size() == 2); //Fails.
}

The final assertion in this code fails with libstdc++ v13 and above, but works
as expected with libstdc++, and libstdc++ < v13.

Bisecting suggests this was introduced in commit
dc9b92facf87a6f2d8b0e5d5fc404f30c3b15a74.

             reply	other threads:[~2024-05-30  1:36 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-30  1:36 bugs at phlexo dot com [this message]
2024-05-30  1:40 ` [Bug libstdc++/115285] " bugs at phlexo dot com
2024-05-30  1:43 ` [Bug libstdc++/115285] [13/14/15 Regression] std::unordered_set can have duplicate values since r13-1114 pinskia at gcc dot gnu.org
2024-05-30  1:46 ` pinskia at gcc dot gnu.org
2024-05-30  1:49 ` pinskia at gcc dot gnu.org
2024-05-30  1:51 ` pinskia at gcc dot gnu.org
2024-05-30  1:52 ` [Bug libstdc++/115285] [13/14/15 Regression] std::unordered_set can have duplicate value pinskia at gcc dot gnu.org
2024-05-30  1:52 ` pinskia at gcc dot gnu.org
2024-05-30  1:55 ` pinskia at gcc dot gnu.org
2024-05-30 10:09 ` [Bug libstdc++/115285] [12/13/14/15 " redi at gcc dot gnu.org
2024-05-30 10:24 ` redi at gcc dot gnu.org
2024-05-30 10:40 ` redi at gcc dot gnu.org
2024-06-20  9:15 ` rguenth 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-115285-4@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).