diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2e595b3eca8..b15d12d3d8c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,21 @@ +2019-03-26 Jonathan Wakely + + 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 PR libstdc++/89825 diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index 4737247994a..da78c68434f 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -192,11 +192,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(is_same{}, "unordered container must have the same value_type as its allocator"); #endif - static_assert(__is_invocable{}, - "hash function must be invocable with an argument of key type"); - static_assert(__is_invocable{}, - "key equality predicate must be invocable with two arguments of " - "key type"); using __traits_type = _Traits; using __hash_cached = typename __traits_type::__hash_cached; @@ -1356,6 +1351,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { clear(); _M_deallocate_buckets(); + + static_assert(__is_invocable{}, + "hash function must be invocable with an argument of key type"); + static_assert(__is_invocable{}, + "key equality predicate must be invocable with two arguments of " + "key type"); } template _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, - "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; @@ -985,7 +974,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #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, + "comparison object must be invocable as const"); +# endif // C++17 +#endif // C++11 + } _Rb_tree& operator=(const _Rb_tree& __x); diff --git a/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc index 066702d9d64..355222058ff 100644 --- a/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/48101_neg.cc @@ -23,8 +23,10 @@ void test01() { - std::map> c; // { dg-error "here" } - std::map> c2; // { dg-error "here" } + std::map> c; + std::map> c2; } +// { dg-error "_Compare = std::less" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::allocator" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc index d46c4641433..5f53ccee168 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/48101_neg.cc @@ -23,8 +23,10 @@ void test01() { - std::multimap> c; // { dg-error "here" } - std::multimap> c2; // { dg-error "here" } + std::multimap> c; + std::multimap> c2; } +// { dg-error "_Compare = std::less" "" { target *-*-* } 0 } +// { dg-error "_Compare = std::allocator" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc index 4aeac6e96d2..71b90e80951 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc @@ -23,7 +23,7 @@ void test01() { std::multiset c; // { dg-error "here" } - std::multiset> c2; // { dg-error "here" } + std::multiset> c2; } // { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc index e9797dec5d1..e58c0627eb8 100644 --- a/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc @@ -23,7 +23,7 @@ void test01() { std::set c; // { dg-error "here" } - std::set> c2; // { dg-error "here" } + std::set> c2; } // { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/set/85965.cc b/libstdc++-v3/testsuite/23_containers/set/85965.cc new file mode 100644 index 00000000000..54d501f6c4f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/85965.cc @@ -0,0 +1,29 @@ +// 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 +// . + +// { dg-do compile { target c++11 } } + +#include + +struct Base { }; +struct Derived; // derives from Base, but incomplete at this point + +struct Foo +{ + // PR libstdc++/85965 + std::set> s; +}; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc index 62be2eb29ee..6c3092554f3 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/48101_neg.cc @@ -23,7 +23,7 @@ void test01() { using namespace std; - unordered_map, hash> c2; // { dg-error "here" } + unordered_map, hash> c2; } // { dg-error "hash function must be invocable" "" { 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 index 54f380b82e3..f5de313a8f1 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/48101_neg.cc @@ -23,7 +23,7 @@ void test01() { using namespace std; - unordered_multimap, hash> c2; // { dg-error "here" } + unordered_multimap, hash> c2; } // { dg-error "hash function must be invocable" "" { 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 index 9149b386bd7..d4e479aaf97 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/48101_neg.cc @@ -24,7 +24,7 @@ test01() { using namespace std; unordered_multiset> c; // { dg-error "here" } - unordered_multiset, hash> c2; // { dg-error "here" } + unordered_multiset, hash> c2; } // { dg-error "non-const, non-volatile value_type" "" { 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 index e357eee6d11..c7e27c53690 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/48101_neg.cc @@ -24,7 +24,7 @@ test01() { using namespace std; unordered_set> c; // { dg-error "here" } - unordered_set, hash> c2; // { dg-error "here" } + unordered_set, hash> c2; } // { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc new file mode 100644 index 00000000000..8b90b369901 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/85965.cc @@ -0,0 +1,29 @@ +// 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 +// . + +// { dg-do compile { target c++11 } } + +#include + +struct Base { }; +struct Derived; // derives from Base, but incomplete at this point + +struct Foo +{ + // PR libstdc++/85965 + std::unordered_set, std::hash> u; +};