Complete tests on _GLIBCXX_DEBUG checks in include/debug/safe_local_iterator.h.
Fix several tests not testing the container corresponding to their location in the
testsuite directory.
libstdc++-v3/ChangeLog:
* testsuite/util/debug/unordered_checks.h (fill_container): New helper method.
(use_erased_local_iterator, invalid_local_iterator_pre_increment)
(invalid_local_iterator_post_increment, invalid_local_iterator_compare)
(invalid_local_iterator_range): Use latter.
(fill_and_get_local_iterator): New, use fill_container.
(use_invalid_local_iterator): Use latter.
(invalid_local_iterator_arrow_operator): New test function.
(invalid_local_iterator_copy_instantiation): New test function.
(invalid_local_iterator_move_instantiation): New test function.
(invalid_local_iterator_copy_assignment): New test function.
(invalid_local_iterator_move_assignment): New test function.
(invalid_local_iterator_const_conversion): New test function.
* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_arrow_operator_neg.cc:
New test case.
* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_const_conversion_neg.cc:
New test case.
* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_copy_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_copy_construction_neg.cc:
New test case.
* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_move_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_map/debug/invalid_local_iterator_move_construction_neg.cc:
New test case.
* testsuite/23_containers/unordered_map/debug/max_load_factor_neg.cc: Test unordered_map.
* testsuite/23_containers/unordered_multimap/debug/begin2_neg.cc: Test unordered_multimap.
* testsuite/23_containers/unordered_multimap/debug/bucket_size_neg.cc: Likewise.
* testsuite/23_containers/unordered_multimap/debug/cbegin_neg.cc: Likewise.
* testsuite/23_containers/unordered_multimap/debug/cend_neg.cc: Likewise.
* testsuite/23_containers/unordered_multimap/debug/end1_neg.cc: Likewise.
* testsuite/23_containers/unordered_multimap/debug/end2_neg.cc: Likewise.
* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_arrow_operator_neg.cc:
New test case.
* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_const_conversion_neg.cc:
New test case.
* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_copy_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_copy_construction_neg.cc:
New test case.
* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_move_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_multimap/debug/invalid_local_iterator_move_construction_neg.cc:
New test case.
* testsuite/23_containers/unordered_multimap/debug/max_load_factor_neg.cc:
Test unordered_multimap.
* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_arrow_operator_neg.cc:
New test case.
* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_const_conversion_neg.cc:
New test case.
* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_copy_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_copy_construction_neg.cc:
New test case.
* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_move_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_multiset/debug/invalid_local_iterator_move_construction_neg.cc:
New test case.
* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_arrow_operator_neg.cc:
New test case.
* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_const_conversion_neg.cc:
New test case.
* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_copy_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_copy_construction_neg.cc:
New test case.
* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_move_assignment_neg.cc:
New test case.
* testsuite/23_containers/unordered_set/debug/invalid_local_iterator_move_construction_neg.cc:
New test case.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_arrow_operator
+ <std::unordered_map<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_const_conversion
+ <std::unordered_map<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_assignment
+ <std::unordered_map<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_construction
+ <std::unordered_map<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_assignment
+ <std::unordered_map<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_construction
+ <std::unordered_map<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
void test01()
{
- std::unordered_multimap<int, int> um;
+ std::unordered_map<int, int> um;
um.max_load_factor(-1.0f);
}
void test01()
{
- std::unordered_map<int, int> um;
- const std::unordered_map<int, int>& cum = um;
+ std::unordered_multimap<int, int> um;
+ const std::unordered_multimap<int, int>& cum = um;
cum.begin(um.bucket_count());
}
void test01()
{
- std::unordered_map<int, int> um;
+ std::unordered_multimap<int, int> um;
um.bucket_size(um.bucket_count());
}
void test01()
{
- std::unordered_map<int, int> um;
+ std::unordered_multimap<int, int> um;
um.cbegin(um.bucket_count());
}
void test01()
{
- std::unordered_map<int, int> um;
+ std::unordered_multimap<int, int> um;
um.cend(um.bucket_count());
}
void test01()
{
- std::unordered_map<int, int> um;
+ std::unordered_multimap<int, int> um;
um.end(um.bucket_count());
}
void test01()
{
- std::unordered_map<int, int> um;
- const std::unordered_map<int, int>& cum = um;
+ std::unordered_multimap<int, int> um;
+ const std::unordered_multimap<int, int>& cum = um;
cum.end(um.bucket_count());
}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_arrow_operator
+ <std::unordered_multimap<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_const_conversion
+ <std::unordered_multimap<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_assignment
+ <std::unordered_multimap<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_construction
+ <std::unordered_multimap<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_assignment
+ <std::unordered_multimap<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_map>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_construction
+ <std::unordered_multimap<int, int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
void test01()
{
- std::unordered_map<int, int> um;
+ std::unordered_multimap<int, int> um;
um.max_load_factor(-1.0f);
}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_arrow_operator
+ <std::unordered_multiset<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_const_conversion
+ <std::unordered_multiset<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_assignment
+ <std::unordered_multiset<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_construction
+ <std::unordered_multiset<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_assignment
+ <std::unordered_multiset<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_construction
+ <std::unordered_multiset<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_arrow_operator
+ <std::unordered_set<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_const_conversion
+ <std::unordered_set<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_assignment
+ <std::unordered_set<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_copy_construction
+ <std::unordered_set<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_assignment
+ <std::unordered_set<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-do run { target c++11 xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <debug/unordered_checks.h>
+
+void test01()
+{
+ __gnu_test::invalid_local_iterator_move_construction
+ <std::unordered_set<int>>();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
template<typename _Tp>
struct KeyExtractor
{
- static _Tp get_key(const _Tp& val)
+ static const _Tp& get_key(const _Tp& val)
{ return val; }
};
template<typename _Tp1, typename _Tp2>
- struct KeyExtractor<std::pair<const _Tp1, _Tp2>>
+ struct KeyExtractor<std::pair<_Tp1, _Tp2>>
{
- static _Tp1 get_key(const std::pair<const _Tp1, _Tp2>& val)
+ static const _Tp1& get_key(const std::pair<_Tp1, _Tp2>& val)
{ return val.first; }
};
template<typename _Tp>
- void use_erased_local_iterator()
+ void fill_container(_Tp& c)
{
typedef _Tp cont_type;
typedef typename cont_type::value_type cont_val_type;
typedef typename CopyableValueType<cont_val_type>::value_type val_type;
generate_unique<val_type> gu;
- cont_type c;
for (size_t i = 0; i != 5; ++i)
c.insert(gu.build());
+ }
+
+ template<typename _Tp>
+ void use_erased_local_iterator()
+ {
+ typedef _Tp cont_type;
+ typedef typename cont_type::value_type cont_val_type;
+ cont_type c;
+ fill_container(c);
typename cont_type::local_iterator it, end;
for (size_t i = 0; i != c.bucket_count(); ++i)
if (it != end)
break;
}
- typename cont_type::key_type key = KeyExtractor<cont_val_type>::get_key(*it);
+
+ const auto& key = KeyExtractor<cont_val_type>::get_key(*it);
c.erase(key);
VERIFY( it != end );
}
template<typename _Tp>
- void use_invalid_local_iterator()
+ typename _Tp::local_iterator
+ fill_and_get_local_iterator(_Tp& c)
{
typedef _Tp cont_type;
- typedef typename cont_type::value_type cont_val_type;
- typedef typename CopyableValueType<cont_val_type>::value_type val_type;
- generate_unique<val_type> gu;
-
- cont_type c;
- for (size_t i = 0; i != 5; ++i)
- c.insert(gu.build());
+ fill_container(c);
typename cont_type::local_iterator it;
for (size_t i = 0; i != c.bucket_count(); ++i)
if (it != c.end(i))
break;
}
- cont_val_type val = *it;
+
+ return it;
+ }
+
+ template<typename _Tp>
+ void use_invalid_local_iterator()
+ {
+ typedef _Tp cont_type;
+ cont_type c;
+ auto it = fill_and_get_local_iterator(c);
+
+ const auto& val = *it;
c.clear();
VERIFY( *it == val );
}
template<typename _Tp>
- void invalid_local_iterator_pre_increment()
+ void invalid_local_iterator_arrow_operator()
{
typedef _Tp cont_type;
- typedef typename cont_type::value_type cont_val_type;
- typedef typename CopyableValueType<cont_val_type>::value_type val_type;
- generate_unique<val_type> gu;
+ cont_type c;
+ auto it = fill_and_get_local_iterator(c);
+
+ const auto& val = *it;
+ c.clear();
+ VERIFY( *it.operator->() == val );
+ }
+ template<typename _Tp>
+ void invalid_local_iterator_copy_construction()
+ {
+ typedef _Tp cont_type;
cont_type c;
- for (size_t i = 0; i != 5; ++i)
- c.insert(gu.build());
+ auto it = fill_and_get_local_iterator(c);
+
+ const auto& val = *it;
+ c.clear();
+ typename cont_type::local_iterator lit(it);
+ VERIFY( *lit == val );
+ }
+
+ template<typename _Tp>
+ void invalid_local_iterator_move_construction()
+ {
+ typedef _Tp cont_type;
+ cont_type c;
+ auto it = fill_and_get_local_iterator(c);
+
+ const auto& val = *it;
+ c.clear();
+ typename cont_type::local_iterator lit(std::move(it));
+ VERIFY( *lit == val );
+ }
+
+ template<typename _Tp>
+ void invalid_local_iterator_copy_assignment()
+ {
+ typedef _Tp cont_type;
+ cont_type c;
+ auto it = fill_and_get_local_iterator(c);
+
+ const auto& val = *it;
+ c.clear();
+ typename cont_type::local_iterator lit;
+ lit = it;
+ VERIFY( *lit == val );
+ }
+
+ template<typename _Tp>
+ void invalid_local_iterator_move_assignment()
+ {
+ typedef _Tp cont_type;
+ cont_type c;
+ auto it = fill_and_get_local_iterator(c);
+
+ const auto& val = *it;
+ c.clear();
+ typename cont_type::local_iterator lit;
+ lit = std::move(it);
+ VERIFY( *lit == val );
+ }
+
+ template<typename _Tp>
+ void invalid_local_iterator_const_conversion()
+ {
+ typedef _Tp cont_type;
+ cont_type c;
+ auto it = fill_and_get_local_iterator(c);
+
+ const auto& val = *it;
+ c.clear();
+ typename cont_type::const_local_iterator clit(it);
+ VERIFY( *clit == val );
+ }
+
+ template<typename _Tp>
+ void invalid_local_iterator_pre_increment()
+ {
+ typedef _Tp cont_type;
+ cont_type c;
+ fill_container(c);
auto lit = c.begin(0);
for (size_t i = 0; i != 6; ++i)
void invalid_local_iterator_post_increment()
{
typedef _Tp cont_type;
- typedef typename cont_type::value_type cont_val_type;
- typedef typename CopyableValueType<cont_val_type>::value_type val_type;
- generate_unique<val_type> gu;
-
cont_type c;
- for (size_t i = 0; i != 5; ++i)
- c.insert(gu.build());
+ fill_container(c);
auto lit = c.begin(0);
for (size_t i = 0; i != 6; ++i)
void invalid_local_iterator_compare()
{
typedef _Tp cont_type;
- typedef typename cont_type::value_type cont_val_type;
- typedef typename CopyableValueType<cont_val_type>::value_type val_type;
- generate_unique<val_type> gu;
-
cont_type c;
- for (size_t i = 0; i != 5; ++i)
- c.insert(gu.build());
+ fill_container(c);
typename cont_type::local_iterator it1, it2;
size_t i;
void invalid_local_iterator_range()
{
typedef _Tp cont_type;
- typedef typename cont_type::value_type cont_val_type;
- typedef typename CopyableValueType<cont_val_type>::value_type val_type;
- generate_unique<val_type> gu;
-
cont_type c;
- for (size_t i = 0; i != 5; ++i)
- c.insert(gu.build());
+ fill_container(c);
typename cont_type::local_iterator it, end;
for (size_t i = 0; i != c.bucket_count(); ++i)