diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index b4e8e4d3fb25a03f66b73f3d88f8edda71789163..efc155bdfa4b6e09218246fb91bc864009b18004 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -930,10 +930,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	_M_insert_unique(_Kt&&, _Arg&&, _NodeGenerator&);
 
       template<typename _Kt>
-	static __conditional_t<
-	  __and_<__is_nothrow_invocable<_Hash&, const key_type&>,
-		 __not_<__is_nothrow_invocable<_Hash&, _Kt>>>::value,
-	  key_type, _Kt&&>
+	key_type
 	_S_forward_key(_Kt&& __k)
 	{ return std::forward<_Kt>(__k); }
 
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
index 2065caab6c5c1082d9d89f7c0af6016ac8052d61..b5be7d06aa0348e2b667953109b2e5795fa65682 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/96088.cc
@@ -29,46 +29,45 @@
 #include <testsuite_hooks.h>
 #include <replacement_memory_operators.h>
 
-static constexpr std::initializer_list<std::pair<const char*, int>> lst = {
-    {"long_str_for_dynamic_allocating", 1}
-};
+static constexpr std::initializer_list<std::pair<const char*, const char*>> lst =
+  { { "long_str_for_dynamic_allocation", "long_str_for_dynamic_allocation" } };
 
 void
 test01()
 {
   __gnu_test::counter::reset();
-  std::unordered_map<std::string, int> um;
+  std::unordered_map<std::string, std::string> um;
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );
 }
 
 void
 test02()
 {
   __gnu_test::counter::reset();
-  std::unordered_map<std::string, int,
+  std::unordered_map<std::string, std::string,
 		     std::hash<std::string_view>,
 		     std::equal_to<std::string_view>> um;
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );
 }
 
 std::size_t
@@ -84,20 +83,20 @@ test11()
   typedef std::size_t (*hash_string_t)(const std::string&) noexcept;
   __gnu_test::counter::reset();
   hash_string_t hasher = &hash_string_f;
-  std::unordered_map<std::string, int,
+  std::unordered_map<std::string, std::string,
 		     hash_string_t,
 		     std::equal_to<std::string>> um(0, hasher);
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );
 }
 
 std::size_t
@@ -113,19 +112,19 @@ test12()
   typedef std::size_t (*hash_stringview_t) (const std::string_view&) noexcept;
   __gnu_test::counter::reset();
   hash_stringview_t hasher = &hash_string_view_f;
-  std::unordered_map<std::string, int, hash_stringview_t,
+  std::unordered_map<std::string, std::string, hash_stringview_t,
 		     std::equal_to<std::string_view>> um(0, hasher);
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );
 }
 
 struct hash_string_functor
@@ -142,20 +141,20 @@ void
 test21()
 {
   __gnu_test::counter::reset();
-  std::unordered_map<std::string, int,
+  std::unordered_map<std::string, std::string,
 		     hash_string_functor,
 		     std::equal_to<std::string>> um;
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );
 }
 
 struct hash_string_view_noexcept_functor
@@ -172,20 +171,20 @@ void
 test22()
 {
   __gnu_test::counter::reset();
-  std::unordered_map<std::string, int,
+  std::unordered_map<std::string, std::string,
 		     hash_string_view_noexcept_functor,
 		     std::equal_to<std::string_view>> um;
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );
 }
 
 struct hash_string_view_functor
@@ -202,40 +201,41 @@ void
 test23()
 {
   __gnu_test::counter::reset();
-  std::unordered_map<std::string, int,
+  std::unordered_map<std::string, std::string,
 		     hash_string_view_functor,
 		     std::equal_to<std::string_view>> um;
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 
   um.insert(lst.begin(), lst.end());
   VERIFY( um.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 5 );
 }
 
 void
 test03()
 {
-  std::vector<std::pair<std::string, int>> v;
+  std::vector<std::pair<std::string, std::string>> v;
   v.insert(v.end(), lst.begin(), lst.end());
 
   const auto origin = __gnu_test::counter::count();
 
   {
     __gnu_test::counter::reset();
-    std::unordered_map<std::string, int,
+    std::unordered_map<std::string, std::string,
 		       std::hash<std::string_view>,
 		       std::equal_to<std::string_view>> um;
     um.insert(v.begin(), v.end());
     VERIFY( um.size() == 1 );
 
-    // Allocate array of buckets, a node, and the std::string (unless COW).
-    constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 3 : 2;
+    // Allocate array of buckets, a node, the std::string value and the
+    // std::string key (unless COW).
+    constexpr std::size_t increments = _GLIBCXX_USE_CXX11_ABI ? 4 : 3;
 
     VERIFY( __gnu_test::counter::count() == origin + increments );
     VERIFY( __gnu_test::counter::get()._M_increments == increments );
@@ -250,7 +250,7 @@ test03()
 
   {
     __gnu_test::counter::reset();
-    std::unordered_map<std::string, int,
+    std::unordered_map<std::string, std::string,
 		       std::hash<std::string_view>,
 		       std::equal_to<std::string_view>> um;
     um.insert(std::make_move_iterator(v.begin()),
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
index b1b33708cde8bb406d3dff68d3532fe295e9b7b7..562ec76e69744bbc1a2cb312168e09ca7e6a53e4 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/96088.cc
@@ -28,34 +28,33 @@
 #include <testsuite_hooks.h>
 #include <replacement_memory_operators.h>
 
-static constexpr std::initializer_list<std::pair<const char*, int>> lst = {
-    {"long_str_for_dynamic_allocating", 1}
-};
+static constexpr std::initializer_list<std::pair<const char*, const char*>> lst =
+  { { "long_str_for_dynamic_allocation", "long_str_for_dynamic_allocation" } };
 
 void
 test01()
 {
   __gnu_test::counter::reset();
-  std::unordered_multimap<std::string, int,
+  std::unordered_multimap<std::string, std::string,
 			  std::hash<std::string_view>,
 			  std::equal_to<std::string_view>> foo;
   foo.insert(lst.begin(), lst.end());
   VERIFY( foo.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 }
 
 void
 test02()
 {
   __gnu_test::counter::reset();
-  std::unordered_multimap<std::string, int> foo;
+  std::unordered_multimap<std::string, std::string> foo;
   foo.insert(lst.begin(), lst.end());
   VERIFY( foo.size() == 1 );
 
-  VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::count() == 4 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 }
 
 int
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
index d525bd532beb9aaf77e1522dbb81152763f44435..1efd5be7f104d1c5411d8a661f66b6789e918bf0 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/96088.cc
@@ -28,9 +28,8 @@
 #include <testsuite_hooks.h>
 #include <replacement_memory_operators.h>
 
-static constexpr std::initializer_list<const char*> lst = {
-  "long_str_for_dynamic_allocating"
-};
+static constexpr std::initializer_list<const char*> lst =
+  { "long_str_for_dynamic_allocation" };
 
 void
 test01()
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
index f9ef94eac5311c64bf427a7f10a4ef0392bd63c0..bc2f093f47c33dabb739815f423548e36d1838fe 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/96088.cc
@@ -29,9 +29,8 @@
 #include <testsuite_hooks.h>
 #include <replacement_memory_operators.h>
 
-static constexpr std::initializer_list<const char*> lst = {
-  "long_str_for_dynamic_allocating"
-};
+static constexpr std::initializer_list<const char*> lst =
+  { "long_str_for_dynamic_allocation" };
 
 void
 test01()
@@ -68,7 +67,7 @@ test02()
   VERIFY( us.size() == 1 );
 
   VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 }
 
 std::size_t
@@ -126,7 +125,7 @@ test12()
   VERIFY( us.size() == 1 );
 
   VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 }
 
 struct hash_string_functor
@@ -186,7 +185,7 @@ test22()
   VERIFY( us.size() == 1 );
 
   VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 }
 
 struct hash_string_view_functor
@@ -216,7 +215,7 @@ test23()
   VERIFY( us.size() == 1 );
 
   VERIFY( __gnu_test::counter::count() == 3 );
-  VERIFY( __gnu_test::counter::get()._M_increments == 3 );
+  VERIFY( __gnu_test::counter::get()._M_increments == 4 );
 }
 
 void
@@ -245,7 +244,7 @@ test03()
     VERIFY( us.size() == 1 );
 
     VERIFY( __gnu_test::counter::count() == origin + increments );
-    VERIFY( __gnu_test::counter::get()._M_increments == increments );
+    VERIFY( __gnu_test::counter::get()._M_increments == increments + 1 );
   }
   VERIFY( __gnu_test::counter::count() == origin );
 
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6c5cc24930ce294f7ba1b3630d3a8030d1193fa4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc
@@ -0,0 +1,40 @@
+// { dg-do run { target c++11 } }
+
+// libstdc++/115285
+
+#include <string>
+#include <unordered_set>
+
+#include <testsuite_hooks.h>
+
+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}} {}
+};
+
+int main()
+{
+  std::unordered_set<TrimmedStr, std::hash<std::string>, std::equal_to<std::string>>
+    set_from_initializer_list{ "foo", "bar", " foo ", " bar " };
+
+  VERIFY( set_from_initializer_list.size() == 2 );
+
+  std::vector<std::string> args{ "foo", "bar", " foo ", " bar " };
+  std::unordered_set<TrimmedStr, std::hash<std::string>, std::equal_to<std::string>>
+    set_from_iterators;
+  set_from_iterators.insert(args.begin(), args.end());
+  VERIFY( set_from_iterators.size() == 2 );
+}