public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/115285] New: std::unordered_set can have duplicate values
@ 2024-05-30  1:36 bugs at phlexo dot com
  2024-05-30  1:40 ` [Bug libstdc++/115285] " bugs at phlexo dot com
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: bugs at phlexo dot com @ 2024-05-30  1:36 UTC (permalink / raw)
  To: gcc-bugs

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.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-06-20  9:15 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-30  1:36 [Bug libstdc++/115285] New: std::unordered_set can have duplicate values bugs at phlexo dot com
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

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).