+2019-03-26 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/85965
+ * include/bits/hashtable.h (_Hashtable): Move static assertions to
+ destructor so they are not evaluated until the _Key type is complete.
+ * include/bits/stl_tree.h (_Rb_tree): Likewise.
+ * testsuite/23_containers/set/85965.cc: New test.
+ * testsuite/23_containers/unordered_set/85965.cc: New test.
+ * testsuite/23_containers/map/48101_neg.cc: Replace "here" errors
+ with regexp matching the corresponding _Rb_tree specialization.
+ * testsuite/23_containers/multimap/48101_neg.cc: Likewise.
+ * testsuite/23_containers/multiset/48101_neg.cc: Remove "here" error.
+ * testsuite/23_containers/set/48101_neg.cc: Likewise.
+ * testsuite/23_containers/unordered_map/48101_neg.cc: Likewise.
+ * testsuite/23_containers/unordered_multimap/48101_neg.cc: Likewise.
+ * testsuite/23_containers/unordered_multiset/48101_neg.cc: Likewise.
+ * testsuite/23_containers/unordered_set/48101_neg.cc: Likewise.
+
2019-03-26 Ville Voutilainen <ville.voutilainen@gmail.com>
PR libstdc++/89825
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;
{
clear();
_M_deallocate_buckets();
+
+ 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");
}
template<typename _Key, typename _Value,
typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
-#if __cplusplus >= 201103L
- static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
- "comparison object must be invocable with two arguments of key type");
-# 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;
typedef const _Rb_tree_node_base* _Const_Base_ptr;
#endif
~_Rb_tree() _GLIBCXX_NOEXCEPT
- { _M_erase(_M_begin()); }
+ {
+ _M_erase(_M_begin());
+
+#if __cplusplus >= 201103L
+ static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
+ "comparison object must be invocable "
+ "with two arguments of key type");
+# 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
+ }
_Rb_tree&
operator=(const _Rb_tree& __x);
void
test01()
{
- std::map<int, int, std::less<int*>> c; // { dg-error "here" }
- std::map<int, int, std::allocator<int>> c2; // { dg-error "here" }
+ std::map<int, int, std::less<int*>> c;
+ std::map<int, int, std::allocator<int>> c2;
}
+// { dg-error "_Compare = std::less<int.>" "" { target *-*-* } 0 }
+// { dg-error "_Compare = std::allocator<int>" "" { target *-*-* } 0 }
// { dg-error "comparison object must be invocable" "" { target *-*-* } 0 }
void
test01()
{
- std::multimap<int, int, std::less<int*>> c; // { dg-error "here" }
- std::multimap<int, int, std::allocator<int>> c2; // { dg-error "here" }
+ std::multimap<int, int, std::less<int*>> c;
+ std::multimap<int, int, std::allocator<int>> c2;
}
+// { dg-error "_Compare = std::less<int.>" "" { target *-*-* } 0 }
+// { dg-error "_Compare = std::allocator<int>" "" { target *-*-* } 0 }
// { dg-error "comparison object must be invocable" "" { target *-*-* } 0 }
test01()
{
std::multiset<const int> c; // { dg-error "here" }
- std::multiset<int, std::less<long*>> c2; // { dg-error "here" }
+ std::multiset<int, std::less<long*>> c2;
}
// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
test01()
{
std::set<const int> c; // { dg-error "here" }
- std::set<int, std::less<long*>> c2; // { dg-error "here" }
+ std::set<int, std::less<long*>> c2;
}
// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
--- /dev/null
+// Copyright (C) 2019 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>
+
+struct Base { };
+struct Derived; // derives from Base, but incomplete at this point
+
+struct Foo
+{
+ // PR libstdc++/85965
+ std::set<Derived*, std::less<Base*>> s;
+};
test01()
{
using namespace std;
- unordered_map<int, int, equal_to<int>, hash<int>> c2; // { dg-error "here" }
+ unordered_map<int, int, equal_to<int>, hash<int>> c2;
}
// { dg-error "hash function must be invocable" "" { target *-*-* } 0 }
test01()
{
using namespace std;
- unordered_multimap<int, int, equal_to<int>, hash<int>> c2; // { dg-error "here" }
+ unordered_multimap<int, int, equal_to<int>, hash<int>> c2;
}
// { dg-error "hash function must be invocable" "" { target *-*-* } 0 }
{
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" }
+ unordered_multiset<int, equal_to<int>, hash<int>> c2;
}
// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
{
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" }
+ unordered_set<int, equal_to<int>, hash<int>> c2;
}
// { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 }
--- /dev/null
+// Copyright (C) 2019 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>
+
+struct Base { };
+struct Derived; // derives from Base, but incomplete at this point
+
+struct Foo
+{
+ // PR libstdc++/85965
+ std::unordered_set<Derived*, std::equal_to<Base*>, std::hash<Base*>> u;
+};