diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2017-10-27 00:50:40 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2017-10-27 00:50:40 +0100 |
commit | d67be4437a94b3f261ee22515b9508da59c691ef (patch) | |
tree | 102e630a448b23221458eabdc5ea069db19503fc /libstdc++-v3/testsuite | |
parent | e1b76fde8ffaa74dffc895c2e2e625e30428b435 (diff) | |
download | gcc-d67be4437a94b3f261ee22515b9508da59c691ef.zip gcc-d67be4437a94b3f261ee22515b9508da59c691ef.tar.gz gcc-d67be4437a94b3f261ee22515b9508da59c691ef.tar.bz2 |
Protect more algorithms from overloaded comma operators
* include/bits/stl_algo.h (__find_if_not_n, generate_n): Cast to void
to ensure overloaded comma not used.
* include/bits/stl_algobase.h (__fill_n_a, equal): Likewise.
* include/bits/stl_uninitialized.h (__uninitialized_fill_n)
(__uninitialized_fill_n_a, __uninitialized_default_n_1)
(__uninitialized_default_n_a, __uninitialized_copy_n)
(__uninitialized_copy_n_pair): Likewise
* testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc:
Use test iterator wrappers with overloaded comma operator.
* testsuite/25_algorithms/fill_n/1.cc: Likewise.
* testsuite/25_algorithms/generate_n/1.cc: New test.
* testsuite/25_algorithms/stable_partition/1.cc: New test.
* testsuite/util/testsuite_iterators.h (operator,): Add deleted
non-member comma operator with iterator wrappers as right operand.
From-SVN: r254128
Diffstat (limited to 'libstdc++-v3/testsuite')
5 files changed, 130 insertions, 35 deletions
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc index 39d3e76..d118dd1 100644 --- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc @@ -19,8 +19,8 @@ #include <memory> #include <testsuite_hooks.h> +#include <testsuite_iterators.h> #include <string> -#include <array> #include <vector> #include <sstream> @@ -56,36 +56,42 @@ struct ThrowAfterN DelCount dc; }; +template<typename T> + using FwdIteratorRange + = __gnu_test::test_container<T, __gnu_test::forward_iterator_wrapper>; + void test01() { char test_data[] = "123456"; - std::uninitialized_default_construct(std::begin(test_data), - std::end(test_data)); + FwdIteratorRange<char> r(test_data); + std::uninitialized_default_construct(std::begin(r), std::end(r)); VERIFY(std::string(test_data) == "123456"); } void test02() { char test_data[] = "123456"; - std::uninitialized_value_construct(std::begin(test_data), - std::end(test_data)); + FwdIteratorRange<char> r(test_data); + std::uninitialized_value_construct(std::begin(r), std::end(r)); VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0\0", 6)); } void test03() { char test_data[] = "123456"; - auto end = std::uninitialized_default_construct_n(std::begin(test_data), 6); + FwdIteratorRange<char> r(test_data); + auto end = std::uninitialized_default_construct_n(std::begin(r), 6); VERIFY(std::string(test_data) == "123456"); - VERIFY( end == test_data + 6 ); + VERIFY( end == std::next(r.begin(), 6) ); } void test04() { char test_data[] = "123456"; - auto end = std::uninitialized_value_construct_n(std::begin(test_data), 5); + FwdIteratorRange<char> r(test_data); + auto end = std::uninitialized_value_construct_n(std::begin(r), 5); VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0" "6", 6)); - VERIFY( end == test_data + 5 ); + VERIFY( end == std::next(r.begin(), 5) ); } void test05() @@ -122,33 +128,43 @@ void test07() free(x); } +struct MoveOnly +{ + MoveOnly() : val(-1) { } + MoveOnly(MoveOnly&& m) : val(m.val) { m.val = -1; } + int val; +}; + void test08() { - std::vector<std::unique_ptr<int>> source; - for (int i = 0; i < 10; ++i) source.push_back(std::make_unique<int>(i)); - std::unique_ptr<int>* target = - (std::unique_ptr<int>*)malloc(sizeof(std::unique_ptr<int>)*10); - std::uninitialized_move(source.begin(), source.end(), target); - for (const auto& x : source) VERIFY(!x); - for (int i = 0; i < 10; ++i) VERIFY(bool(*(target+i))); - auto end = std::destroy_n(target, 10); - VERIFY( end == target + 10 ); + MoveOnly source[10]; + for (int i = 0; i < 10; ++i) source[i].val = i; + FwdIteratorRange<MoveOnly> src(source); + MoveOnly* target = (MoveOnly*)malloc(sizeof(MoveOnly)*10); + FwdIteratorRange<MoveOnly> tgt(target, target+10); + auto end = std::uninitialized_move(src.begin(), src.end(), tgt.begin()); + VERIFY( end == std::next(tgt.begin(), 10) ); + for (const auto& x : source) VERIFY( x.val == -1 ); + for (int i = 0; i < 10; ++i) VERIFY( target[i].val == i ); + auto end2 = std::destroy_n(tgt.begin(), 10); + VERIFY( end2 == std::next(tgt.begin(), 10) ); free(target); } void test09() { - std::vector<std::unique_ptr<int>> source; - for (int i = 0; i < 10; ++i) source.push_back(std::make_unique<int>(i)); - std::unique_ptr<int>* target = - (std::unique_ptr<int>*)malloc(sizeof(std::unique_ptr<int>)*10); - auto end = std::uninitialized_move_n(source.begin(), 10, target); - VERIFY( end.first == source.begin() + 10 ); - VERIFY( end.second == target + 10 ); - for (const auto& x : source) VERIFY(!x); - for (int i = 0; i < 10; ++i) VERIFY(bool(*(target+i))); - auto end2 = std::destroy_n(target, 10); - VERIFY( end2 == target + 10 ); + MoveOnly source[10]; + for (int i = 0; i < 10; ++i) source[i].val = i; + FwdIteratorRange<MoveOnly> src(source); + MoveOnly* target = (MoveOnly*)malloc(sizeof(MoveOnly)*10); + FwdIteratorRange<MoveOnly> tgt(target, target+10); + auto end = std::uninitialized_move_n(src.begin(), 10, tgt.begin()); + VERIFY( end.first == std::next(src.begin(), 10) ); + VERIFY( end.second == std::next(tgt.begin(), 10) ); + for (const auto& x : source) VERIFY( x.val == -1 ); + for (int i = 0; i < 10; ++i) VERIFY( target[i].val == i ); + auto end2 = std::destroy_n(tgt.begin(), 10); + VERIFY( end2 == std::next(tgt.begin(), 10) ); free(target); } @@ -156,7 +172,8 @@ void test10() { char* x = (char*)malloc(sizeof(char)*10); for (int i = 0; i < 10; ++i) new (x+i) char; - std::destroy(x, x+10); + FwdIteratorRange<char> r(x, x+10); + std::destroy(r.begin(), r.end()); free(x); } @@ -164,8 +181,9 @@ void test11() { char* x = (char*)malloc(sizeof(char)*10); for (int i = 0; i < 10; ++i) new (x+i) char; - auto end = std::destroy_n(x, 10); - VERIFY( end == x + 10 ); + FwdIteratorRange<char> r(x, x+10); + auto end = std::destroy_n(r.begin(), 10); + VERIFY( end == std::next(r.begin(), 10) ); free(x); } diff --git a/libstdc++-v3/testsuite/25_algorithms/fill_n/1.cc b/libstdc++-v3/testsuite/25_algorithms/fill_n/1.cc index d446e7a..4d27f0b 100644 --- a/libstdc++-v3/testsuite/25_algorithms/fill_n/1.cc +++ b/libstdc++-v3/testsuite/25_algorithms/fill_n/1.cc @@ -22,21 +22,36 @@ #include <algorithm> #include <vector> #include <testsuite_hooks.h> +#include <testsuite_iterators.h> + +// Non-scalar type to exercise partial specialization of fill_n implementation. +struct Value +{ + Value(int n) : n(n) { } + + operator int() const { return n; } + +private: + int n; +}; void test01() { using namespace std; + using __gnu_test::test_container; + using __gnu_test::output_iterator_wrapper; const int A1[] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; const int N1 = sizeof(A1) / sizeof(int); int i1[N1]; - fill_n(i1, N1, 3); + test_container<int, output_iterator_wrapper> c1(i1, i1 + N1); + fill_n(c1.begin(), N1, 3); VERIFY( equal(i1, i1 + N1, A1) ); vector<int> v1(N1); - fill_n(v1.begin(), N1, 3); + fill_n(v1.begin(), N1, Value(3)); VERIFY( equal(v1.begin(), v1.end(), A1) ); const char A2[] = {'\3', '\3', '\3', '\3', '\3', diff --git a/libstdc++-v3/testsuite/25_algorithms/generate_n/1.cc b/libstdc++-v3/testsuite/25_algorithms/generate_n/1.cc new file mode 100644 index 0000000..dc3cb9f --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/generate_n/1.cc @@ -0,0 +1,47 @@ +// 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/>. + +#include <algorithm> +#include <testsuite_hooks.h> +#include <testsuite_iterators.h> + +struct Inc +{ + int operator()() { return ++i; } + + int i; +}; + +void +test01() +{ + const int N = 3; + int array[N]; + + using __gnu_test::test_container; + using __gnu_test::output_iterator_wrapper; + test_container<int, output_iterator_wrapper> c(array, array + N); + std::generate_n(c.begin(), N, Inc()); + VERIFY(array[0] == 1); + VERIFY(array[1] == 2); + VERIFY(array[2] == 3); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc b/libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc index 7585157..f29d817 100644 --- a/libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc +++ b/libstdc++-v3/testsuite/25_algorithms/stable_partition/1.cc @@ -21,6 +21,7 @@ #include <functional> #include <testsuite_new_operators.h> #include <testsuite_hooks.h> +#include <testsuite_iterators.h> const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; const int B[] = {2, 4, 6, 8, 10, 12, 14, 16, 1, 3, 5, 7, 9, 11, 13, 15, 17}; @@ -41,11 +42,16 @@ void test01() { using std::stable_partition; + using __gnu_test::test_container; + using __gnu_test::forward_iterator_wrapper; int s1[N]; std::copy(A, A + N, s1); - VERIFY( stable_partition(s1, s1 + N, Pred()) == s1 + M ); + test_container<int, forward_iterator_wrapper> c(s1, s1+N); + forward_iterator_wrapper<int> expected = c.begin(); + std::advance(expected, M); + VERIFY( stable_partition(c.begin(), c.end(), Pred()) == expected); VERIFY( std::equal(s1, s1 + N, B) ); } diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h index d61b216..d6b550d 100644 --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -180,6 +180,11 @@ namespace __gnu_test #endif }; +#if __cplusplus >= 201103L + template<typename T, typename U> + void operator,(const T&, const output_iterator_wrapper<U>&) = delete; +#endif + /** * @brief input_iterator wrapper for pointer * @@ -270,6 +275,10 @@ namespace __gnu_test #endif }; +#if __cplusplus >= 201103L + template<typename T, typename U> + void operator,(const T&, const input_iterator_wrapper<U>&) = delete; +#endif /** * @brief forward_iterator wrapper for pointer |