libstdc++: Fix regression in hash containers
authorJonathan Wakely <jwakely@redhat.com>
Wed, 26 Aug 2020 16:30:31 +0000 (17:30 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 26 Aug 2020 16:44:23 +0000 (17:44 +0100)
A recent change altered the layout of EBO-helper base classes, resulting
in an ambiguity when the hash function and equality predicate are the
same type.

This modifies the type of one of the base classes, so that we don't get
two base classes of the same type.

libstdc++-v3/ChangeLog:

* include/bits/hashtable_policy.h (_Hash_code_base): Change
index of _Hashtable_ebo_helper base class.
* testsuite/23_containers/unordered_map/dup_types.cc: New test.

libstdc++-v3/include/bits/hashtable_policy.h
libstdc++-v3/testsuite/23_containers/unordered_map/dup_types.cc [new file with mode: 0644]

index 38bd5ae4e8180ab92d835b3201f00d4cad425fb6..0109ef86a7b524453906fd13e9eafcb17f5fe396 100644 (file)
@@ -1190,10 +1190,10 @@ namespace __detail
           typename _Hash, typename _RangeHash, typename _Unused>
     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Hash, _RangeHash,
                           _Unused, false>
-    : private _Hashtable_ebo_helper<0, _Hash>
+    : private _Hashtable_ebo_helper<1, _Hash>
     {
     private:
-      using __ebo_hash = _Hashtable_ebo_helper<0, _Hash>;
+      using __ebo_hash = _Hashtable_ebo_helper<1, _Hash>;
 
       // Gives the local iterator implementation access to _M_bucket_index().
       friend struct _Local_iterator_base<_Key, _Value, _ExtractKey,
@@ -1260,10 +1260,10 @@ namespace __detail
           typename _Hash, typename _RangeHash, typename _Unused>
     struct _Hash_code_base<_Key, _Value, _ExtractKey, _Hash, _RangeHash,
                           _Unused, true>
-    : private _Hashtable_ebo_helper<0, _Hash>
+    : private _Hashtable_ebo_helper<1, _Hash>
     {
     private:
-      using __ebo_hash = _Hashtable_ebo_helper<0, _Hash>;
+      using __ebo_hash = _Hashtable_ebo_helper<1, _Hash>;
 
     public:
       typedef _Hash                                    hasher;
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/dup_types.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/dup_types.cc
new file mode 100644 (file)
index 0000000..0a6053e
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) 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/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <unordered_map>
+
+struct Evil : std::hash<int>, std::equal_to<int>
+{ };
+
+void test01()
+{
+  std::unordered_map<int, int, Evil, Evil> h;
+  (void) h.key_eq();
+}