aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2011-12-15 22:15:21 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2011-12-15 22:15:21 +0000
commit92637e93ed8cc9c607a6b544ed5944530ee99b03 (patch)
treee4fdba9c406221d03d29a59d8b97dba4ecb88f20
parent5058651d6382e0f307f9c96c356cca2d41cbddba (diff)
downloadgcc-92637e93ed8cc9c607a6b544ed5944530ee99b03.zip
gcc-92637e93ed8cc9c607a6b544ed5944530ee99b03.tar.gz
gcc-92637e93ed8cc9c607a6b544ed5944530ee99b03.tar.bz2
re PR libstdc++/51558 (Declaration of unspecialized std::hash<_Tp>::operator()(_Tp) turns compile-time errors into link-time errors)
2011-12-15 Paolo Carlini <paolo.carlini@oracle.com> Jonathan Wakely <jwakely.gcc@gmail.com> PR libstdc++/51558 * include/bits/functional_hash.h (struct hash): Add static_assert. * src/compatibility-c++0x.cc: Adjust compatibility definitions. * testsuite/23_containers/unordered_map/erase/51142.cc: Adjust. * testsuite/23_containers/unordered_set/erase/51142.cc: Likewise. * testsuite/23_containers/unordered_multimap/erase/51142.cc: Likewise. * testsuite/23_containers/unordered_multiset/erase/51142.cc: Likewise. Co-Authored-By: Jonathan Wakely <jwakely.gcc@gmail.com> From-SVN: r182392
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/bits/functional_hash.h5
-rw-r--r--libstdc++-v3/src/compatibility-c++0x.cc58
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/erase/51142.cc7
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51142.cc7
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/51142.cc7
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/erase/51142.cc7
7 files changed, 75 insertions, 27 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 38e0ff2..f050ad9 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2011-12-15 Paolo Carlini <paolo.carlini@oracle.com>
+ Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR libstdc++/51558
+ * include/bits/functional_hash.h (struct hash): Add static_assert.
+ * src/compatibility-c++0x.cc: Adjust compatibility definitions.
+ * testsuite/23_containers/unordered_map/erase/51142.cc: Adjust.
+ * testsuite/23_containers/unordered_set/erase/51142.cc: Likewise.
+ * testsuite/23_containers/unordered_multimap/erase/51142.cc: Likewise.
+ * testsuite/23_containers/unordered_multiset/erase/51142.cc: Likewise.
+
2011-12-15 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/22_locale/num_put/put/char/9780-2.cc: Add test for "C"
diff --git a/libstdc++-v3/include/bits/functional_hash.h b/libstdc++-v3/include/bits/functional_hash.h
index 2b82b21..e892159 100644
--- a/libstdc++-v3/include/bits/functional_hash.h
+++ b/libstdc++-v3/include/bits/functional_hash.h
@@ -57,8 +57,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct hash : public __hash_base<size_t, _Tp>
{
- size_t
- operator()(_Tp __val) const;
+ static_assert(sizeof(_Tp) < 0,
+ "std::hash is not specialized for this type");
+ size_t operator()(const _Tp&) const noexcept;
};
/// Partial specializations for pointer types.
diff --git a/libstdc++-v3/src/compatibility-c++0x.cc b/libstdc++-v3/src/compatibility-c++0x.cc
index c5e1db0..03c58d2 100644
--- a/libstdc++-v3/src/compatibility-c++0x.cc
+++ b/libstdc++-v3/src/compatibility-c++0x.cc
@@ -52,36 +52,60 @@ namespace std _GLIBCXX_VISIBILITY(default)
#ifndef _GLIBCXX_LONG_DOUBLE_COMPAT_IMPL
template<>
- size_t
- hash<string>::operator()(string __s) const
- { return _Hash_impl::hash(__s.data(), __s.length()); }
+ struct hash<string>
+ {
+ size_t operator()(string) const;
+ };
+
+ size_t
+ hash<string>::operator()(string __s) const
+ { return _Hash_impl::hash(__s.data(), __s.length()); }
template<>
- size_t
- hash<const string&>::operator()(const string& __s) const
- { return _Hash_impl::hash(__s.data(), __s.length()); }
+ struct hash<const string&>
+ {
+ size_t operator()(const string&) const;
+ };
+
+ size_t
+ hash<const string&>::operator()(const string& __s) const
+ { return _Hash_impl::hash(__s.data(), __s.length()); }
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
- size_t
- hash<wstring>::operator()(wstring __s) const
- { return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
+ struct hash<wstring>
+ {
+ size_t operator()(wstring) const;
+ };
+
+ size_t
+ hash<wstring>::operator()(wstring __s) const
+ { return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
template<>
- size_t
- hash<const wstring&>::operator()(const wstring& __s) const
- { return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
+ struct hash<const wstring&>
+ {
+ size_t operator()(const wstring&) const;
+ };
+
+ size_t
+ hash<const wstring&>::operator()(const wstring& __s) const
+ { return _Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); }
#endif
#endif
template<>
- size_t
- hash<error_code>::operator()(error_code __e) const
+ struct hash<error_code>
{
- const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
- return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
- }
+ size_t operator()(error_code) const;
+ };
+ size_t
+ hash<error_code>::operator()(error_code __e) const
+ {
+ const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
+ return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
+ }
// gcc-4.7.0
// <chrono> changes is_monotonic to is_steady.
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/erase/51142.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/erase/51142.cc
index eab637d..7986fb2 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/erase/51142.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/erase/51142.cc
@@ -27,12 +27,15 @@ struct X
X(T&) {}
};
+struct X_hash
+{ std::size_t operator()(const X&) const { return 0; } };
+
bool operator==(const X&, const X&) { return false; }
// LWG 2059.
-void erasor(std::unordered_map<X, int>& s, X x)
+void erasor(std::unordered_map<X, int, X_hash>& s, X x)
{
- std::unordered_map<X, int>::iterator it = s.find(x);
+ std::unordered_map<X, int, X_hash>::iterator it = s.find(x);
if (it != s.end())
s.erase(it);
}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51142.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51142.cc
index 678aa5d..0d434ac 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51142.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51142.cc
@@ -27,12 +27,15 @@ struct X
X(T&) {}
};
+struct X_hash
+{ std::size_t operator()(const X&) const { return 0; } };
+
bool operator==(const X&, const X&) { return false; }
// LWG 2059.
-void erasor(std::unordered_multimap<X, int>& s, X x)
+void erasor(std::unordered_multimap<X, int, X_hash>& s, X x)
{
- std::unordered_multimap<X, int>::iterator it = s.find(x);
+ std::unordered_multimap<X, int, X_hash>::iterator it = s.find(x);
if (it != s.end())
s.erase(it);
}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/51142.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/51142.cc
index 4db6af0..7a0a183 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/51142.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/51142.cc
@@ -27,12 +27,15 @@ struct X
X(T&) {}
};
+struct X_hash
+{ std::size_t operator()(const X&) const { return 0; } };
+
bool operator==(const X&, const X&) { return false; }
// LWG 2059.
-void erasor(std::unordered_multiset<X>& s, X x)
+void erasor(std::unordered_multiset<X, X_hash>& s, X x)
{
- std::unordered_multiset<X>::iterator it = s.find(x);
+ std::unordered_multiset<X, X_hash>::iterator it = s.find(x);
if (it != s.end())
s.erase(it);
}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/erase/51142.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/erase/51142.cc
index 1486460..ec5aeb1 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/erase/51142.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/erase/51142.cc
@@ -27,12 +27,15 @@ struct X
X(T&) {}
};
+struct X_hash
+{ std::size_t operator()(const X&) const { return 0; } };
+
bool operator==(const X&, const X&) { return false; }
// LWG 2059.
-void erasor(std::unordered_set<X>& s, X x)
+void erasor(std::unordered_set<X, X_hash>& s, X x)
{
- std::unordered_set<X>::iterator it = s.find(x);
+ std::unordered_set<X, X_hash>::iterator it = s.find(x);
if (it != s.end())
s.erase(it);
}