* [PATCH] PR libstdc++/48101 improve errors for invalid container specializations
@ 2017-11-21 22:47 Jonathan Wakely
2017-11-22 10:31 ` Rainer Orth
0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2017-11-21 22:47 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 4764 bytes --]
This uses static_assert to improve the errors when attempting to
instantiate invalid specializations of containers, e.g. set<const T>,
or unordered_set<int, equal_to<int>, hash<int>> (which mixes up the
order of the hasher and equality predicate arguments).
This means instead of more than 100 lines of confusing errors for
https://wandbox.org/permlink/kL1YVNVOzrAsLPyS we get only this:
In file included from /home/jwakely/gcc/8/include/c++/8.0.0/set:61:0,
from s.cc:2:
/home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h: In instantiation of âclass std::set<const int>â:
s.cc:8:18: required from here
/home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h:108:7: error: static assertion failed: std::set must have a non-const, non-volatile value_type
static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value,
^~~~~~~~~~~~~
In file included from /home/jwakely/gcc/8/include/c++/8.0.0/unordered_set:46:0,
from s.cc:1:
/home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h: In instantiation of âclass std::_Hashtable<int, int, std::allocator<int>, std::__detail::_Identity, std::hash<int>, std::equal_to<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, true, false> >â:
/home/jwakely/gcc/8/include/c++/8.0.0/bits/unordered_set.h:898:18: required from âclass std::unordered_multiset<int, std::equal_to<int>, std::hash<int> >â
s.cc:10:53: required from here
/home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:195:7: error: static assertion failed: hash function must be invocable with an argument of key type
static_assert(__is_invocable<const _H1&, const _Key&>{},
^~~~~~~~~~~~~
/home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:197:7: error: static assertion failed: key equality predicate must be invocable with two arguments of key type
static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
^~~~~~~~~~~~~
Tested powerpc64le-linux, committed to trunk.
PR libstdc++/48101
* include/bits/allocator.h (allocator<const _Tp>)
(allocator<volatile _Tp>, allocator<const volatile _Tp>): Add partial
specializations.
* include/bits/forward_list.h (forward_list): Add static assertions.
* include/bits/hashtable.h (__cache_default): Use
__is_nothrow_invocable instead of __is_noexcept_hash.
(_Hashtable): Add static assertions.
* include/bits/hashtable_policy.h (__is_noexcept_hash): Remove.
* include/bits/stl_deque.h (deque): Add static assertions.
* include/bits/stl_function.h (_Identity<const _Tp>): Add partial
specialization.
* include/bits/stl_list.h (list): Add static assertions.
* include/bits/stl_map.h (map): Likewise.
* include/bits/stl_multimap.h (multimap): Likewise.
* include/bits/stl_multiset.h (multiset): Likewise.
* include/bits/stl_set.h (set): Likewise.
* include/bits/stl_tree.h (_Rb_tree): Likewise.
* include/bits/stl_vector.h (vector): Likewise.
* include/bits/unordered_map.h (unordered_map, unordered_multimap):
Use typename instead of class in template-parameter-list and remove
spaces.
* include/bits/unordered_set.h (unordered_set, unordered_multiset):
Likewise.
* testsuite/23_containers/deque/48101-2_neg.cc: New test.
* testsuite/23_containers/deque/48101_neg.cc: New test.
* testsuite/23_containers/forward_list/48101-2_neg.cc: New test.
* testsuite/23_containers/forward_list/48101_neg.cc: New test.
* testsuite/23_containers/list/48101-2_neg.cc: New test.
* testsuite/23_containers/list/48101_neg.cc: New test.
* testsuite/23_containers/map/48101-2_neg.cc: New test.
* testsuite/23_containers/map/48101_neg.cc: New test.
* testsuite/23_containers/multimap/48101-2_neg.cc: New test.
* testsuite/23_containers/multimap/48101_neg.cc: New test.
* testsuite/23_containers/multiset/48101-2_neg.cc: New test.
* testsuite/23_containers/multiset/48101_neg.cc: New test.
* testsuite/23_containers/set/48101-2_neg.cc: New test.
* testsuite/23_containers/set/48101_neg.cc: New test.
* testsuite/23_containers/unordered_map/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_map/48101_neg.cc: New test.
* testsuite/23_containers/unordered_multimap/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_multimap/48101_neg.cc: New test.
* testsuite/23_containers/unordered_multiset/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_multiset/48101_neg.cc: New test.
* testsuite/23_containers/unordered_set/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_set/48101_neg.cc: New test.
* testsuite/23_containers/vector/48101-2_neg.cc: New test.
* testsuite/23_containers/vector/48101_neg.cc: New test.
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 52219 bytes --]
commit be65a3f6c9738c646b37fdfe1508b15e15c093f5
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Nov 21 18:36:26 2017 +0000
PR libstdc++/48101 improve errors for invalid container specializations
PR libstdc++/48101
* include/bits/allocator.h (allocator<const _Tp>)
(allocator<volatile _Tp>, allocator<const volatile _Tp>): Add partial
specializations.
* include/bits/forward_list.h (forward_list): Add static assertions.
* include/bits/hashtable.h (__cache_default): Use
__is_nothrow_invocable instead of __is_noexcept_hash.
(_Hashtable): Add static assertions.
* include/bits/hashtable_policy.h (__is_noexcept_hash): Remove.
* include/bits/stl_deque.h (deque): Add static assertions.
* include/bits/stl_function.h (_Identity<const _Tp>): Add partial
specialization.
* include/bits/stl_list.h (list): Add static assertions.
* include/bits/stl_map.h (map): Likewise.
* include/bits/stl_multimap.h (multimap): Likewise.
* include/bits/stl_multiset.h (multiset): Likewise.
* include/bits/stl_set.h (set): Likewise.
* include/bits/stl_tree.h (_Rb_tree): Likewise.
* include/bits/stl_vector.h (vector): Likewise.
* include/bits/unordered_map.h (unordered_map, unordered_multimap):
Use typename instead of class in template-parameter-list and remove
spaces.
* include/bits/unordered_set.h (unordered_set, unordered_multiset):
Likewise.
* testsuite/23_containers/deque/48101-2_neg.cc: New test.
* testsuite/23_containers/deque/48101_neg.cc: New test.
* testsuite/23_containers/forward_list/48101-2_neg.cc: New test.
* testsuite/23_containers/forward_list/48101_neg.cc: New test.
* testsuite/23_containers/list/48101-2_neg.cc: New test.
* testsuite/23_containers/list/48101_neg.cc: New test.
* testsuite/23_containers/map/48101-2_neg.cc: New test.
* testsuite/23_containers/map/48101_neg.cc: New test.
* testsuite/23_containers/map/operations/31440.cc: Fix comparison
object to have const-qualified call operator.
* testsuite/23_containers/multimap/48101-2_neg.cc: New test.
* testsuite/23_containers/multimap/48101_neg.cc: New test.
* testsuite/23_containers/multiset/48101-2_neg.cc: New test.
* testsuite/23_containers/multiset/48101_neg.cc: New test.
* testsuite/23_containers/set/48101-2_neg.cc: New test.
* testsuite/23_containers/set/48101_neg.cc: New test.
* testsuite/23_containers/unordered_map/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_map/48101_neg.cc: New test.
* testsuite/23_containers/unordered_multimap/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_multimap/48101_neg.cc: New test.
* testsuite/23_containers/unordered_multiset/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_multiset/48101_neg.cc: New test.
* testsuite/23_containers/unordered_set/48101-2_neg.cc: New test.
* testsuite/23_containers/unordered_set/48101_neg.cc: New test.
* testsuite/23_containers/unordered_set/instantiation_neg.cc: Adjust
dg-error line number.
* testsuite/23_containers/vector/48101-2_neg.cc: New test.
* testsuite/23_containers/vector/48101_neg.cc: New test.
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
index 20813864c62..b5a2bad07c0 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -105,7 +105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
- class allocator: public __allocator_base<_Tp>
+ class allocator : public __allocator_base<_Tp>
{
public:
typedef size_t size_type;
@@ -165,6 +165,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_USE_NOEXCEPT
{ return false; }
+ // Invalid allocator<cv T> partial specializations.
+ // allocator_traits::rebind_alloc can be used to form a valid allocator type.
+ template<typename _Tp>
+ class allocator<const _Tp>
+ {
+ public:
+ typedef _Tp value_type;
+ template<typename _Up> allocator(const allocator<_Up>&) { }
+ };
+
+ template<typename _Tp>
+ class allocator<volatile _Tp>
+ {
+ public:
+ typedef _Tp value_type;
+ template<typename _Up> allocator(const allocator<_Up>&) { }
+ };
+
+ template<typename _Tp>
+ class allocator<const volatile _Tp>
+ {
+ public:
+ typedef _Tp value_type;
+ template<typename _Up> allocator(const allocator<_Up>&) { }
+ };
+
/// @} group allocator
// Inhibit implicit instantiations for required instantiations,
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 855a72815ae..96494cc20de 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -406,9 +406,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* specialized algorithms %unique to linked lists, such as
* splicing, sorting, and in-place reversal.
*/
- template<typename _Tp, typename _Alloc = allocator<_Tp> >
+ template<typename _Tp, typename _Alloc = allocator<_Tp>>
class forward_list : private _Fwd_list_base<_Tp, _Alloc>
{
+ static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
+ "std::forward_list must have a non-const, non-volatile value_type");
+#ifdef __STRICT_ANSI__
+ static_assert(is_same<typename _Alloc::value_type, _Tp>::value,
+ "std::forward_list must have the same value_type as its allocator");
+#endif
+
private:
typedef _Fwd_list_base<_Tp, _Alloc> _Base;
typedef _Fwd_list_node<_Tp> _Node;
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index e0806dc93a1..a9473c16bde 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -46,7 +46,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= __not_<__and_<// Do not cache for fast hasher.
__is_fast_hash<_Hash>,
// Mandatory to have erase not throwing.
- __detail::__is_noexcept_hash<_Tp, _Hash>>>;
+ __is_nothrow_invocable<const _Hash&, const _Tp&>>>;
/**
* Primary class template _Hashtable.
@@ -186,6 +186,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__detail::_Hash_node<_Value,
_Traits::__hash_cached::value>>>
{
+ static_assert(is_same<typename remove_cv<_Value>::type, _Value>::value,
+ "unordered container must have a non-const, non-volatile value_type");
+#ifdef __STRICT_ANSI__
+ static_assert(is_same<typename _Alloc::value_type, _Value>{},
+ "unordered container must have the same value_type as its allocator");
+#endif
+ static_assert(__is_invocable<const _H1&, const _Key&>{},
+ "hash function must be invocable with an argument of key type");
+ static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
+ "key equality predicate must be invocable with two arguments of "
+ "key type");
+
using __traits_type = _Traits;
using __hash_cached = typename __traits_type::__hash_cached;
using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>;
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index e19f92abd76..4dd0e1717f8 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -79,12 +79,6 @@ namespace __detail
return __distance_fw(__first, __last, _Tag());
}
- // Helper type used to detect whether the hash functor is noexcept.
- template <typename _Key, typename _Hash>
- struct __is_noexcept_hash : std::__bool_constant<
- noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
- { };
-
struct _Identity
{
template<typename _Tp>
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 48b2bc7f5eb..93c82ca8909 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -840,6 +840,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
#endif
+#if __cplusplus >= 201103L
+ static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
+ "std::deque must have a non-const, non-volatile value_type");
+# ifdef __STRICT_ANSI__
+ static_assert(is_same<typename _Alloc::value_type, _Tp>::value,
+ "std::deque must have the same value_type as its allocator");
+# endif
+#endif
+
typedef _Deque_base<_Tp, _Alloc> _Base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
typedef typename _Base::_Alloc_traits _Alloc_traits;
diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h
index 4fbcdb91f56..5cd8e3aeb7c 100644
--- a/libstdc++-v3/include/bits/stl_function.h
+++ b/libstdc++-v3/include/bits/stl_function.h
@@ -867,7 +867,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct _Identity
- : public unary_function<_Tp,_Tp>
+ : public unary_function<_Tp, _Tp>
{
_Tp&
operator()(_Tp& __x) const
@@ -878,6 +878,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __x; }
};
+ // Partial specialization, avoids confusing errors in e.g. std::set<const T>.
+ template<typename _Tp> struct _Identity<const _Tp> : _Identity<_Tp> { };
+
template<typename _Pair>
struct _Select1st
: public unary_function<_Pair, typename _Pair::first_type>
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index be5bb5e5b68..8ed97f7c8b0 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -571,6 +571,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
#endif
+#if __cplusplus >= 201103L
+ static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
+ "std::list must have a non-const, non-volatile value_type");
+# ifdef __STRICT_ANSI__
+ static_assert(is_same<typename _Alloc::value_type, _Tp>::value,
+ "std::list must have the same value_type as its allocator");
+# endif
+#endif
+
typedef _List_base<_Tp, _Alloc> _Base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
typedef typename _Base::_Tp_alloc_traits _Tp_alloc_traits;
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index 8a9e6c9c329..bec6c47c086 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -118,6 +118,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
#endif
+#if __cplusplus >= 201103L && defined(__STRICT_ANSI__)
+ static_assert(is_same<typename _Alloc::value_type, value_type>::value,
+ "std::map must have the same value_type as its allocator");
+#endif
+
public:
class value_compare
: public std::binary_function<value_type, value_type, bool>
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 1a16bf982e3..24ac4a3c186 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -117,6 +117,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
#endif
+#if __cplusplus >= 201103L && defined(__STRICT_ANSI__)
+ static_assert(is_same<typename _Alloc::value_type, value_type>::value,
+ "std::multimap must have the same value_type as its allocator");
+#endif
+
public:
class value_compare
: public std::binary_function<value_type, value_type, bool>
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index d34b6758e18..ff7d3dca586 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -106,6 +106,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
#endif
+#if __cplusplus >= 201103L
+ static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value,
+ "std::multiset must have a non-const, non-volatile value_type");
+# ifdef __STRICT_ANSI__
+ static_assert(is_same<typename _Alloc::value_type, _Key>::value,
+ "std::multiset must have the same value_type as its allocator");
+# endif
+#endif
+
public:
// typedefs:
typedef _Key key_type;
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 3a7992c4dab..e07d78124eb 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -104,6 +104,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
#endif
+#if __cplusplus >= 201103L
+ static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value,
+ "std::set must have a non-const, non-volatile value_type");
+# ifdef __STRICT_ANSI__
+ static_assert(is_same<typename _Alloc::value_type, _Key>::value,
+ "std::set must have the same value_type as its allocator");
+# endif
+#endif
+
public:
// typedefs:
//@{
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index c2417f1f8cc..ff36618bccf 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -448,6 +448,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
+#if __cplusplus >= 201103L
+ static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
+ "comparison object must be invocable with two arguments of key type");
+#endif
+
protected:
typedef _Rb_tree_node_base* _Base_ptr;
typedef const _Rb_tree_node_base* _Const_Base_ptr;
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index c7634216c01..aeeba820020 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -347,6 +347,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
#endif
+#if __cplusplus >= 201103L
+ static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
+ "std::vector must have a non-const, non-volatile value_type");
+# ifdef __STRICT_ANSI__
+ static_assert(is_same<typename _Alloc::value_type, _Tp>::value,
+ "std::vector must have the same value_type as its allocator");
+# endif
+#endif
+
typedef _Vector_base<_Tp, _Alloc> _Base;
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
index 385e4bd4df4..cb5bcb89a16 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -95,10 +95,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Base is _Hashtable, dispatched at compile time via template
* alias __umap_hashtable.
*/
- template<class _Key, class _Tp,
- class _Hash = hash<_Key>,
- class _Pred = std::equal_to<_Key>,
- class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
+ template<typename _Key, typename _Tp,
+ typename _Hash = hash<_Key>,
+ typename _Pred = equal_to<_Key>,
+ typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
class unordered_map
{
typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
@@ -1229,10 +1229,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Base is _Hashtable, dispatched at compile time via template
* alias __ummap_hashtable.
*/
- template<class _Key, class _Tp,
- class _Hash = hash<_Key>,
- class _Pred = std::equal_to<_Key>,
- class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
+ template<typename _Key, typename _Tp,
+ typename _Hash = hash<_Key>,
+ typename _Pred = equal_to<_Key>,
+ typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
class unordered_multimap
{
typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable;
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
index 416dbbcfb96..550548c42db 100644
--- a/libstdc++-v3/include/bits/unordered_set.h
+++ b/libstdc++-v3/include/bits/unordered_set.h
@@ -90,10 +90,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Base is _Hashtable, dispatched at compile time via template
* alias __uset_hashtable.
*/
- template<class _Value,
- class _Hash = hash<_Value>,
- class _Pred = std::equal_to<_Value>,
- class _Alloc = std::allocator<_Value> >
+ template<typename _Value,
+ typename _Hash = hash<_Value>,
+ typename _Pred = equal_to<_Value>,
+ typename _Alloc = allocator<_Value>>
class unordered_set
{
typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
@@ -888,10 +888,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Base is _Hashtable, dispatched at compile time via template
* alias __umset_hashtable.
*/
- template<class _Value,
- class _Hash = hash<_Value>,
- class _Pred = std::equal_to<_Value>,
- class _Alloc = std::allocator<_Value> >
+ template<typename _Value,
+ typename _Hash = hash<_Value>,
+ typename _Pred = equal_to<_Value>,
+ typename _Alloc = allocator<_Value>>
class unordered_multiset
{
typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable;
diff --git a/libstdc++-v3/testsuite/23_containers/deque/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/48101-2_neg.cc
new file mode 100644
index 00000000000..7bb63731ffe
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <deque>
+
+void
+test01()
+{
+ std::deque<int, std::allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/deque/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/48101_neg.cc
new file mode 100644
index 00000000000..57327e085e5
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/48101_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 <deque>
+
+void
+test01()
+{
+ std::deque<const int> c;
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-prune-output "std::allocator<.* has no member named " }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/48101-2_neg.cc
new file mode 100644
index 00000000000..a830d7a15bd
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <forward_list>
+
+void
+test01()
+{
+ std::forward_list<int, std::allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc
new file mode 100644
index 00000000000..268c06d4450
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 <forward_list>
+
+void
+test01()
+{
+ std::forward_list<const int> c;
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-prune-output "std::allocator<.* has no member named " }
diff --git a/libstdc++-v3/testsuite/23_containers/list/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/list/48101-2_neg.cc
new file mode 100644
index 00000000000..bce7e34c76f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <list>
+
+void
+test01()
+{
+ std::list<int, std::allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/list/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/list/48101_neg.cc
new file mode 100644
index 00000000000..9652e072e56
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/48101_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 <list>
+
+void
+test01()
+{
+ std::list<const int> c;
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-prune-output "std::allocator<.* has no member named " }
diff --git a/libstdc++-v3/testsuite/23_containers/map/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/map/48101-2_neg.cc
new file mode 100644
index 00000000000..dcb43356bbe
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <map>
+
+void
+test01()
+{
+ std::map<int, int, std::less<int>, std::allocator<int>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
new file mode 100644
index 00000000000..75821faf6c5
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <map>
+
+void
+test01()
+{
+ std::map<int, int, std::less<int*>> c; // { dg-error "here" }
+ std::map<int, int, std::allocator<int>> c2; // { dg-error "here" }
+}
+
+// { dg-error "comparison object must be invocable" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/map/operations/31440.cc b/libstdc++-v3/testsuite/23_containers/map/operations/31440.cc
index 6401bfe5a31..531c74d7418 100644
--- a/libstdc++-v3/testsuite/23_containers/map/operations/31440.cc
+++ b/libstdc++-v3/testsuite/23_containers/map/operations/31440.cc
@@ -38,7 +38,7 @@ private:
struct MemoTable::dagNodeLt
{
- bool operator()(const DagNode*, const DagNode*);
+ bool operator()(const DagNode*, const DagNode*) const;
};
class MemoTable::MemoMap
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/48101-2_neg.cc
new file mode 100644
index 00000000000..2b8db2cb821
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <map>
+
+void
+test01()
+{
+ std::multimap<int, int, std::less<int>, std::allocator<int>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc
new file mode 100644
index 00000000000..a303c75dec1
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <map>
+
+void
+test01()
+{
+ std::multimap<int, int, std::less<int*>> c; // { dg-error "here" }
+ std::multimap<int, int, std::allocator<int>> c2; // { dg-error "here" }
+}
+
+// { dg-error "comparison object must be invocable" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/48101-2_neg.cc
new file mode 100644
index 00000000000..c9bb1f4b325
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <set>
+
+void
+test01()
+{
+ std::multiset<int, std::less<int>, std::allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc
new file mode 100644
index 00000000000..3697d328982
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 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 <set>
+
+void
+test01()
+{
+ std::multiset<const int> c; // { dg-error "here" }
+ std::multiset<int, std::less<long*>> c2; // { dg-error "here" }
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-error "comparison object must be invocable" "" { target *-*-* } 0 }
+// { dg-prune-output "std::allocator<.* has no member named " }
diff --git a/libstdc++-v3/testsuite/23_containers/set/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/set/48101-2_neg.cc
new file mode 100644
index 00000000000..925d4ad2b2a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <set>
+
+void
+test01()
+{
+ std::set<int, std::less<int>, std::allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc
new file mode 100644
index 00000000000..258fab8dd68
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 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 <set>
+
+void
+test01()
+{
+ std::set<const int> c; // { dg-error "here" }
+ std::set<int, std::less<long*>> c2; // { dg-error "here" }
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-error "comparison object must be invocable" "" { target *-*-* } 0 }
+// { dg-prune-output "std::allocator<.* has no member named " }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/48101-2_neg.cc
new file mode 100644
index 00000000000..847ac8074d4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/48101-2_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <unordered_map>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_map<int, int, hash<int>, equal_to<int>, allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc
new file mode 100644
index 00000000000..6180c2d2210
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 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>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_map<int, int, equal_to<int>, hash<int>> c2; // { dg-error "here" }
+}
+
+// { dg-error "hash function must be invocable" "" { target *-*-* } 0 }
+// { dg-error "key equality predicate must be invocable" "" { target *-*-* } 0 }
+// { dg-prune-output "use of deleted function" }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101-2_neg.cc
new file mode 100644
index 00000000000..6b2660ab924
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101-2_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <unordered_map>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_multimap<int, int, hash<int>, equal_to<int>, allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc
new file mode 100644
index 00000000000..538d1dcfa0e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 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>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_multimap<int, int, equal_to<int>, hash<int>> c2; // { dg-error "here" }
+}
+
+// { dg-error "hash function must be invocable" "" { target *-*-* } 0 }
+// { dg-error "key equality predicate must be invocable" "" { target *-*-* } 0 }
+// { dg-prune-output "use of deleted function" }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101-2_neg.cc
new file mode 100644
index 00000000000..6dccaa7aa84
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101-2_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <unordered_set>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_multiset<int, hash<int>, equal_to<int>, allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc
new file mode 100644
index 00000000000..3ec61dd2b01
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 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_set>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_multiset<const int, hash<int>> c; // { dg-error "here" }
+ unordered_multiset<int, equal_to<int>, hash<int>> c2; // { dg-error "here" }
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-error "hash function must be invocable" "" { target *-*-* } 0 }
+// { dg-error "key equality predicate must be invocable" "" { target *-*-* } 0 }
+// { dg-prune-output "use of deleted function" }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/48101-2_neg.cc
new file mode 100644
index 00000000000..1221b8ad6ae
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/48101-2_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <unordered_set>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_set<int, hash<int>, equal_to<int>, allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc
new file mode 100644
index 00000000000..d74370bd2de
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 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_set>
+
+void
+test01()
+{
+ using namespace std;
+ unordered_set<const int, hash<int>> c; // { dg-error "here" }
+ unordered_set<int, equal_to<int>, hash<int>> c2; // { dg-error "here" }
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-error "hash function must be invocable" "" { target *-*-* } 0 }
+// { dg-error "key equality predicate must be invocable" "" { target *-*-* } 0 }
+// { dg-prune-output "use of deleted function" }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
index ac4477d6d92..60e5b2b7982 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
@@ -18,7 +18,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "with noexcept" "" { target *-*-* } 268 }
+// { dg-error "qualify your functors .* with noexcept" "" { target *-*-* } 0 }
#include <unordered_set>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/48101-2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/48101-2_neg.cc
new file mode 100644
index 00000000000..0a54a489652
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/48101-2_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 }
+// { dg-options "-std=c++11" }
+
+#include <vector>
+
+void
+test01()
+{
+ std::vector<int, std::allocator<long>> c;
+}
+
+// { dg-error "same value_type as its allocator" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/48101_neg.cc
new file mode 100644
index 00000000000..ed701563699
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/48101_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2017 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 <vector>
+
+void
+test01()
+{
+ std::vector<const int> c;
+}
+
+// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
+// { dg-prune-output "std::allocator<.* has no member named " }
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR libstdc++/48101 improve errors for invalid container specializations
2017-11-21 22:47 [PATCH] PR libstdc++/48101 improve errors for invalid container specializations Jonathan Wakely
@ 2017-11-22 10:31 ` Rainer Orth
2017-11-22 11:01 ` Jonathan Wakely
0 siblings, 1 reply; 5+ messages in thread
From: Rainer Orth @ 2017-11-22 10:31 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: libstdc++, gcc-patches, Ian Lance Taylor
Hi Jonathan,
> This uses static_assert to improve the errors when attempting to
> instantiate invalid specializations of containers, e.g. set<const T>,
> or unordered_set<int, equal_to<int>, hash<int>> (which mixes up the
> order of the hasher and equality predicate arguments).
>
> This means instead of more than 100 lines of confusing errors for
> https://wandbox.org/permlink/kL1YVNVOzrAsLPyS we get only this:
>
> In file included from /home/jwakely/gcc/8/include/c++/8.0.0/set:61:0,
> from s.cc:2:
> /home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h: In instantiation of ‘class std::set<const int>’:
> s.cc:8:18: required from here
> /home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h:108:7: error: static assertion failed: std::set must have a non-const, non-volatile value_type
> static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value,
> ^~~~~~~~~~~~~
> In file included from /home/jwakely/gcc/8/include/c++/8.0.0/unordered_set:46:0,
> from s.cc:1:
> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h: In instantiation of ‘class std::_Hashtable<int, int, std::allocator<int>, std::__detail::_Identity, std::hash<int>, std::equal_to<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, true, false> >’:
> /home/jwakely/gcc/8/include/c++/8.0.0/bits/unordered_set.h:898:18: required from ‘class std::unordered_multiset<int, std::equal_to<int>, std::hash<int> >’
> s.cc:10:53: required from here
> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:195:7: error: static assertion failed: hash function must be invocable with an argument of key type
> static_assert(__is_invocable<const _H1&, const _Key&>{},
> ^~~~~~~~~~~~~
> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:197:7: error: static assertion failed: key equality predicate must be invocable with two arguments of key type
> static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
> ^~~~~~~~~~~~~
>
> Tested powerpc64le-linux, committed to trunk.
this broke Go bootstrap, it seems. Seen on i386-pc-solaris2.11 as of
r255048:
In file included from /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
from /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/ast-dump.cc:7:
/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*, std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*> >':
/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17: required from 'class std::set<Import_init*, Import_init_lt>'
/vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required from here
/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7: error: static assertion failed: comparison object must be invocable with two arguments of key type
static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
^~~~~~~~~~~~~
In file included from /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
from /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/escape.cc:7:
/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*, std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*> >':
/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17: required from 'class std::set<Import_init*, Import_init_lt>'
/vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required from here
/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7: error: static assertion failed: comparison object must be invocable with two arguments of key type
static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
^~~~~~~~~~~~~
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR libstdc++/48101 improve errors for invalid container specializations
2017-11-22 10:31 ` Rainer Orth
@ 2017-11-22 11:01 ` Jonathan Wakely
2017-11-22 11:15 ` Jonathan Wakely
0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2017-11-22 11:01 UTC (permalink / raw)
To: Rainer Orth; +Cc: libstdc++, gcc-patches, Ian Lance Taylor
On 22/11/17 11:23 +0100, Rainer Orth wrote:
>Hi Jonathan,
>
>> This uses static_assert to improve the errors when attempting to
>> instantiate invalid specializations of containers, e.g. set<const T>,
>> or unordered_set<int, equal_to<int>, hash<int>> (which mixes up the
>> order of the hasher and equality predicate arguments).
>>
>> This means instead of more than 100 lines of confusing errors for
>> https://wandbox.org/permlink/kL1YVNVOzrAsLPyS we get only this:
>>
>> In file included from /home/jwakely/gcc/8/include/c++/8.0.0/set:61:0,
>> from s.cc:2:
>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h: In instantiation of âclass std::set<const int>â:
>> s.cc:8:18: required from here
>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h:108:7: error: static assertion failed: std::set must have a non-const, non-volatile value_type
>> static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value,
>> ^~~~~~~~~~~~~
>> In file included from /home/jwakely/gcc/8/include/c++/8.0.0/unordered_set:46:0,
>> from s.cc:1:
>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h: In instantiation of âclass std::_Hashtable<int, int, std::allocator<int>, std::__detail::_Identity, std::hash<int>, std::equal_to<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, true, false> >â:
>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/unordered_set.h:898:18: required from âclass std::unordered_multiset<int, std::equal_to<int>, std::hash<int> >â
>> s.cc:10:53: required from here
>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:195:7: error: static assertion failed: hash function must be invocable with an argument of key type
>> static_assert(__is_invocable<const _H1&, const _Key&>{},
>> ^~~~~~~~~~~~~
>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:197:7: error: static assertion failed: key equality predicate must be invocable with two arguments of key type
>> static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
>> ^~~~~~~~~~~~~
>>
>> Tested powerpc64le-linux, committed to trunk.
>
>this broke Go bootstrap, it seems. Seen on i386-pc-solaris2.11 as of
>r255048:
>
>In file included from /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
> from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
> from /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/ast-dump.cc:7:
>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*, std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*> >':
>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17: required from 'class std::set<Import_init*, Import_init_lt>'
>/vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required from here
>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7: error: static assertion failed: comparison object must be invocable with two arguments of key type
> static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
> ^~~~~~~~~~~~~
>In file included from /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
> from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
> from /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/escape.cc:7:
>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*, std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*> >':
>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17: required from 'class std::set<Import_init*, Import_init_lt>'
>/vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required from here
>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7: error: static assertion failed: comparison object must be invocable with two arguments of key type
> static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
> ^~~~~~~~~~~~~
This is PR83102. I'm going to relax the checks, but the Go
frontend still needs to be fixed.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR libstdc++/48101 improve errors for invalid container specializations
2017-11-22 11:01 ` Jonathan Wakely
@ 2017-11-22 11:15 ` Jonathan Wakely
2017-11-22 15:25 ` Ian Lance Taylor
0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2017-11-22 11:15 UTC (permalink / raw)
To: Rainer Orth; +Cc: libstdc++, gcc-patches, Ian Lance Taylor
[-- Attachment #1: Type: text/plain, Size: 4796 bytes --]
On 22/11/17 10:56 +0000, Jonathan Wakely wrote:
>On 22/11/17 11:23 +0100, Rainer Orth wrote:
>>Hi Jonathan,
>>
>>>This uses static_assert to improve the errors when attempting to
>>>instantiate invalid specializations of containers, e.g. set<const T>,
>>>or unordered_set<int, equal_to<int>, hash<int>> (which mixes up the
>>>order of the hasher and equality predicate arguments).
>>>
>>>This means instead of more than 100 lines of confusing errors for
>>>https://wandbox.org/permlink/kL1YVNVOzrAsLPyS we get only this:
>>>
>>>In file included from /home/jwakely/gcc/8/include/c++/8.0.0/set:61:0,
>>> from s.cc:2:
>>>/home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h: In instantiation of âclass std::set<const int>â:
>>>s.cc:8:18: required from here
>>>/home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h:108:7: error: static assertion failed: std::set must have a non-const, non-volatile value_type
>>> static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value,
>>> ^~~~~~~~~~~~~
>>>In file included from /home/jwakely/gcc/8/include/c++/8.0.0/unordered_set:46:0,
>>> from s.cc:1:
>>>/home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h: In instantiation of âclass std::_Hashtable<int, int, std::allocator<int>, std::__detail::_Identity, std::hash<int>, std::equal_to<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, true, false> >â:
>>>/home/jwakely/gcc/8/include/c++/8.0.0/bits/unordered_set.h:898:18: required from âclass std::unordered_multiset<int, std::equal_to<int>, std::hash<int> >â
>>>s.cc:10:53: required from here
>>>/home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:195:7: error: static assertion failed: hash function must be invocable with an argument of key type
>>> static_assert(__is_invocable<const _H1&, const _Key&>{},
>>> ^~~~~~~~~~~~~
>>>/home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:197:7: error: static assertion failed: key equality predicate must be invocable with two arguments of key type
>>> static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
>>> ^~~~~~~~~~~~~
>>>
>>>Tested powerpc64le-linux, committed to trunk.
>>
>>this broke Go bootstrap, it seems. Seen on i386-pc-solaris2.11 as of
>>r255048:
>>
>>In file included from /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
>> from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
>> from /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/ast-dump.cc:7:
>>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*, std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*> >':
>>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17: required from 'class std::set<Import_init*, Import_init_lt>'
>>/vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required from here
>>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7: error: static assertion failed: comparison object must be invocable with two arguments of key type
>> static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
>> ^~~~~~~~~~~~~
>>In file included from /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
>> from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
>> from /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/escape.cc:7:
>>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*, std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*> >':
>>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17: required from 'class std::set<Import_init*, Import_init_lt>'
>>/vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required from here
>>/var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7: error: static assertion failed: comparison object must be invocable with two arguments of key type
>> static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
>> ^~~~~~~~~~~~~
>
>This is PR83102. I'm going to relax the checks, but the Go
>frontend still needs to be fixed.
>
>
This should allow Go to build again (unless you bootstrap with
-std=gnu++17 in the build flags)
[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1334 bytes --]
commit fbf3996895469f1bcd56c6ca3cfac190d956fff9
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Wed Nov 22 10:52:56 2017 +0000
PR go/83102 relax std::set checks for invocable comparison object
PR go/83102
* include/bits/stl_tree.h (_Rb_tree): Relax invocable checks for
comparison object pre-C++17.
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index ff36618bccf..df92a60d4dd 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -449,9 +449,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
#if __cplusplus >= 201103L
- static_assert(__is_invocable<const _Compare&, const _Key&, const _Key&>{},
+ static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
"comparison object must be invocable with two arguments of key type");
-#endif
+# if __cplusplus >= 201703L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2542. Missing const requirements for associative containers
+ static_assert(is_invocable_v<const _Compare&, const _Key&, const _Key&>,
+ "comparison object must be invocable as const");
+# endif // C++17
+#endif // C++11
protected:
typedef _Rb_tree_node_base* _Base_ptr;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] PR libstdc++/48101 improve errors for invalid container specializations
2017-11-22 11:15 ` Jonathan Wakely
@ 2017-11-22 15:25 ` Ian Lance Taylor
0 siblings, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2017-11-22 15:25 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: Rainer Orth, libstdc++, gcc-patches, gofrontend-dev
On Wed, Nov 22, 2017 at 3:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 22/11/17 10:56 +0000, Jonathan Wakely wrote:
>>
>> On 22/11/17 11:23 +0100, Rainer Orth wrote:
>>>
>>> Hi Jonathan,
>>>
>>>> This uses static_assert to improve the errors when attempting to
>>>> instantiate invalid specializations of containers, e.g. set<const T>,
>>>> or unordered_set<int, equal_to<int>, hash<int>> (which mixes up the
>>>> order of the hasher and equality predicate arguments).
>>>>
>>>> This means instead of more than 100 lines of confusing errors for
>>>> https://wandbox.org/permlink/kL1YVNVOzrAsLPyS we get only this:
>>>>
>>>> In file included from /home/jwakely/gcc/8/include/c++/8.0.0/set:61:0,
>>>> from s.cc:2:
>>>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h: In instantiation
>>>> of ‘class std::set<const int>’:
>>>> s.cc:8:18: required from here
>>>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/stl_set.h:108:7: error:
>>>> static assertion failed: std::set must have a non-const, non-volatile
>>>> value_type
>>>> static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value,
>>>> ^~~~~~~~~~~~~
>>>> In file included from
>>>> /home/jwakely/gcc/8/include/c++/8.0.0/unordered_set:46:0,
>>>> from s.cc:1:
>>>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h: In instantiation
>>>> of ‘class std::_Hashtable<int, int, std::allocator<int>,
>>>> std::__detail::_Identity, std::hash<int>, std::equal_to<int>,
>>>> std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash,
>>>> std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true,
>>>> true, false> >’:
>>>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/unordered_set.h:898:18:
>>>> required from ‘class std::unordered_multiset<int, std::equal_to<int>,
>>>> std::hash<int> >’
>>>> s.cc:10:53: required from here
>>>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:195:7: error:
>>>> static assertion failed: hash function must be invocable with an argument of
>>>> key type
>>>> static_assert(__is_invocable<const _H1&, const _Key&>{},
>>>> ^~~~~~~~~~~~~
>>>> /home/jwakely/gcc/8/include/c++/8.0.0/bits/hashtable.h:197:7: error:
>>>> static assertion failed: key equality predicate must be invocable with two
>>>> arguments of key type
>>>> static_assert(__is_invocable<const _Equal&, const _Key&, const
>>>> _Key&>{},
>>>> ^~~~~~~~~~~~~
>>>>
>>>> Tested powerpc64le-linux, committed to trunk.
>>>
>>>
>>> this broke Go bootstrap, it seems. Seen on i386-pc-solaris2.11 as of
>>> r255048:
>>>
>>> In file included from
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
>>> from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
>>> from
>>> /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/ast-dump.cc:7:
>>>
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:
>>> In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*,
>>> std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*>
>>> >':
>>>
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17:
>>> required from 'class std::set<Import_init*, Import_init_lt>'
>>> /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required
>>> from here
>>>
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7:
>>> error: static assertion failed: comparison object must be invocable with two
>>> arguments of key type
>>> static_assert(__is_invocable<const _Compare&, const _Key&, const
>>> _Key&>{},
>>> ^~~~~~~~~~~~~
>>> In file included from
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/map:60,
>>> from /vol/gcc/src/hg/trunk/local/gcc/go/go-system.h:36,
>>> from
>>> /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/escape.cc:7:
>>>
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:
>>> In instantiation of 'class std::_Rb_tree<Import_init*, Import_init*,
>>> std::_Identity<Import_init*>, Import_init_lt, std::allocator<Import_init*>
>>> >':
>>>
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_set.h:133:17:
>>> required from 'class std::set<Import_init*, Import_init_lt>'
>>> /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/gogo.h:127:37: required
>>> from here
>>>
>>> /var/gcc/regression/trunk/11.4-gcc/build/prev-i386-pc-solaris2.11/libstdc++-v3/include/bits/stl_tree.h:452:7:
>>> error: static assertion failed: comparison object must be invocable with two
>>> arguments of key type
>>> static_assert(__is_invocable<const _Compare&, const _Key&, const
>>> _Key&>{},
>>> ^~~~~~~~~~~~~
>>
>>
>> This is PR83102. I'm going to relax the checks, but the Go
>> frontend still needs to be fixed.
>>
>>
>
> This should allow Go to build again (unless you bootstrap with
> -std=gnu++17 in the build flags)
Thanks. Committed.
Ian
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-11-22 15:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-21 22:47 [PATCH] PR libstdc++/48101 improve errors for invalid container specializations Jonathan Wakely
2017-11-22 10:31 ` Rainer Orth
2017-11-22 11:01 ` Jonathan Wakely
2017-11-22 11:15 ` Jonathan Wakely
2017-11-22 15:25 ` Ian Lance Taylor
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).