diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-09 12:38:00 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-09 12:38:00 +0000 |
commit | b06ebed55304d3344917a8b249cab1955a9e7d23 (patch) | |
tree | 02a44fb906ee33f23c3474e42a2d8281b25b50ed | |
parent | 5f35dd0e122d3aa3cccd4a32c912c25f60064ee6 (diff) | |
download | ppe42-gcc-b06ebed55304d3344917a8b249cab1955a9e7d23.tar.gz ppe42-gcc-b06ebed55304d3344917a8b249cab1955a9e7d23.zip |
PR libstdc++/58982
* include/bits/stl_algobase.h (__copy_move::__copy_m): Use assertion
to prevent using memmove() on non-assignable types.
(__copy_move_backward::__copy_move_b): Likewise.
* include/bits/stl_uninitialized.h (uninitialized_copy
uninitialized_copy_n, uninitialized_fill, uninitialized_fill_n,
__uninitialized_default, __uninitialized_default_n): Check for
assignable as well as trivial.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/
58982.cc: New.
* testsuite/20_util/specialized_algorithms/uninitialized_copy_n/
58982.cc: New.
* testsuite/20_util/specialized_algorithms/uninitialized_fill/
58982.cc: New.
* testsuite/20_util/specialized_algorithms/uninitialized_fill_n/
58982.cc: New.
* testsuite/25_algorithms/copy/58982.cc: New.
* testsuite/25_algorithms/copy_n/58982.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204615 138bc75d-0d04-0410-961f-82ee72b054a4
9 files changed, 311 insertions, 6 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 31bffa55022..2244435322d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,24 @@ +2013-11-09 Jonathan Wakely <jwakely.gcc@gmail.com> + + PR libstdc++/58982 + * include/bits/stl_algobase.h (__copy_move::__copy_m): Use assertion + to prevent using memmove() on non-assignable types. + (__copy_move_backward::__copy_move_b): Likewise. + * include/bits/stl_uninitialized.h (uninitialized_copy + uninitialized_copy_n, uninitialized_fill, uninitialized_fill_n, + __uninitialized_default, __uninitialized_default_n): Check for + assignable as well as trivial. + * testsuite/20_util/specialized_algorithms/uninitialized_copy/ + 58982.cc: New. + * testsuite/20_util/specialized_algorithms/uninitialized_copy_n/ + 58982.cc: New. + * testsuite/20_util/specialized_algorithms/uninitialized_fill/ + 58982.cc: New. + * testsuite/20_util/specialized_algorithms/uninitialized_fill_n/ + 58982.cc: New. + * testsuite/25_algorithms/copy/58982.cc: New. + * testsuite/25_algorithms/copy_n/58982.cc: New. + 2013-11-08 François Dumont <fdumont@gcc.gnu.org> * include/debug/safe_iterator.h (_BeforeBeginHelper<>::_S_Is): diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index a7432da150c..5c7db5b8269 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -368,6 +368,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _Tp* __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) { +#if __cplusplus >= 201103L + // trivial types can have deleted assignment + static_assert( is_copy_assignable<_Tp>::value, + "type is not assignable" ); +#endif const ptrdiff_t _Num = __last - __first; if (_Num) __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); @@ -563,6 +568,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _Tp* __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result) { +#if __cplusplus >= 201103L + // trivial types can have deleted assignment + static_assert( is_copy_assignable<_Tp>::value, + "type is not assignable" ); +#endif const ptrdiff_t _Num = __last - __first; if (_Num) __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num); diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 310b16202ec..e45046b4999 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -111,9 +111,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ValueType1; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; +#if __cplusplus < 201103L + const bool __assignable = true; +#else + // trivial types can have deleted assignment + typedef typename iterator_traits<_InputIterator>::reference _RefType; + const bool __assignable = is_assignable<_ValueType1, _RefType>::value; +#endif - return std::__uninitialized_copy<(__is_trivial(_ValueType1) - && __is_trivial(_ValueType2))>:: + return std::__uninitialized_copy<__is_trivial(_ValueType1) + && __is_trivial(_ValueType2) + && __assignable>:: __uninit_copy(__first, __last, __result); } @@ -166,8 +174,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; +#if __cplusplus < 201103L + const bool __assignable = true; +#else + // trivial types can have deleted assignment + const bool __assignable = is_copy_assignable<_ValueType>::value; +#endif - std::__uninitialized_fill<__is_trivial(_ValueType)>:: + std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>:: __uninit_fill(__first, __last, __x); } @@ -219,8 +233,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; +#if __cplusplus < 201103L + const bool __assignable = true; +#else + // trivial types can have deleted assignment + const bool __assignable = is_copy_assignable<_ValueType>::value; +#endif - std::__uninitialized_fill_n<__is_trivial(_ValueType)>:: + std::__uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>:: __uninit_fill_n(__first, __n, __x); } @@ -526,8 +546,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + // trivial types can have deleted assignment + const bool __assignable = is_copy_assignable<_ValueType>::value; - std::__uninitialized_default_1<__is_trivial(_ValueType)>:: + std::__uninitialized_default_1<__is_trivial(_ValueType) + && __assignable>:: __uninit_default(__first, __last); } @@ -539,8 +562,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + // trivial types can have deleted assignment + const bool __assignable = is_copy_assignable<_ValueType>::value; - std::__uninitialized_default_n_1<__is_trivial(_ValueType)>:: + std::__uninitialized_default_n_1<__is_trivial(_ValueType) + && __assignable>:: __uninit_default_n(__first, __n); } diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc new file mode 100644 index 00000000000..7e059a35b9b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2013 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/>. + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <memory> + +// libstdc++/58982 + +// trivial class that is not assignable +struct T +{ + T() = default; + ~T() = default; + + T& operator=(const T&) = delete; +}; + +void +test01(T* result) +{ + T t[1]; + std::uninitialized_copy(t, t+1, result); +} diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc new file mode 100644 index 00000000000..e10b31a70f6 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2013 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/>. + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <memory> + +// libstdc++/58982 + +// trivial class that is not assignable +struct T +{ + T() = default; + ~T() = default; + + T& operator=(const T&) = delete; +}; + +void +test01(T* result) +{ + T t[1]; + std::uninitialized_copy_n(t, 1, result); +} diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc new file mode 100644 index 00000000000..012e2c6c88c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2013 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/>. + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <memory> + +// libstdc++/58982 + +// trivial class that is not assignable +struct T +{ + T() = default; + ~T() = default; + + T& operator=(const T&) = delete; +}; + +void +test01(T* first, T* last) +{ + T t; + std::uninitialized_fill(first, last, t); +} diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc new file mode 100644 index 00000000000..606c63266e3 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2013 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/>. + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <memory> + +// libstdc++/58982 + +// trivial class that is not assignable +struct T +{ + T() = default; + ~T() = default; + + T& operator=(const T&) = delete; +}; + +void +test01(T* first) +{ + T t; + std::uninitialized_fill_n(first, 1, t); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc b/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc new file mode 100644 index 00000000000..58ece1b80f6 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc @@ -0,0 +1,42 @@ +// Copyright (C) 2013 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/>. + +// 25.3.1 copy + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <algorithm> + +// libstdc++/58982 + +// trivial class that is not assignable +struct T +{ + T() = default; + ~T() = default; + + T& operator=(const T&) = delete; +}; + +void +test01(T* result) +{ + T t[1]; + std::copy(t, t+1, result); // { dg-error "here" } +} +// { dg-prune-output "not assignable" } diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc new file mode 100644 index 00000000000..f7dfa599388 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc @@ -0,0 +1,42 @@ +// Copyright (C) 2013 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/>. + +// 25.3.1 copy + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include <algorithm> + +// libstdc++/58982 + +// trivial class that is not assignable +struct T +{ + T() = default; + ~T() = default; + + T& operator=(const T&) = delete; +}; + +void +test01(T* result) +{ + T t[1]; + std::copy_n(t, 1, result); // { dg-error "here" } +} +// { dg-prune-output "not assignable" } |