From 5275f3e54604ae1e7143cd32d2cd45eae53b5d19 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Sat, 9 Nov 2013 12:38:00 +0000 Subject: [PATCH] re PR libstdc++/58982 (std::vector> vai(10); does not compile anymore) 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. From-SVN: r204615 --- libstdc++-v3/ChangeLog | 21 +++++++++++ libstdc++-v3/include/bits/stl_algobase.h | 10 ++++++ libstdc++-v3/include/bits/stl_uninitialized.h | 38 ++++++++++++++++---- .../uninitialized_copy/58982.cc | 41 +++++++++++++++++++++ .../uninitialized_copy_n/58982.cc | 41 +++++++++++++++++++++ .../uninitialized_fill/58982.cc | 41 +++++++++++++++++++++ .../uninitialized_fill_n/58982.cc | 41 +++++++++++++++++++++ libstdc++-v3/testsuite/25_algorithms/copy/58982.cc | 42 ++++++++++++++++++++++ .../testsuite/25_algorithms/copy_n/58982.cc | 42 ++++++++++++++++++++++ 9 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc create mode 100644 libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc create mode 100644 libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc create mode 100644 libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy/58982.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 31bffa5..2244435 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,24 @@ +2013-11-09 Jonathan Wakely + + 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 * 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 a7432da..5c7db5b 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 310b162..e45046b 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 0000000..7e059a3 --- /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 +// . + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include + +// 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 0000000..e10b31a --- /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 +// . + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include + +// 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 0000000..012e2c6 --- /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 +// . + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include + +// 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 0000000..606c632 --- /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 +// . + +// 20.7.12 specialized algorithms + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include + +// 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 0000000..58ece1b --- /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 +// . + +// 25.3.1 copy + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include + +// 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 0000000..f7dfa59 --- /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 +// . + +// 25.3.1 copy + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include + +// 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" } -- 2.7.4