gcc version 4.9.0 20131011 (experimental) [trunk revision 203426] (GCC) ok gcc version 4.9.0 20131102 (experimental) [trunk revision 204320] (GCC) cat vatom.cc #include<vector> #include<atomic> int main() { std::vector<std::atomic<int>> vai(10); for( auto & a : vai) a=0; return vai[0]; } c++ -Ofast -std=c++11 vatom.cc In file included from /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/vector:60:0, from vatom.cc:1: /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_algobase.h: In instantiation of 'typename __gnu_cxx::__enable_if<(! std::__is_scalar<_Tp>::__value), _OutputIterator>::__type std::__fill_n_a(_OutputIterator, _Size, const _Tp&) [with _OutputIterator = std::atomic<int>*; _Size = long unsigned int; _Tp = std::atomic<int>; typename __gnu_cxx::__enable_if<(! std::__is_scalar<_Tp>::__value), _OutputIterator>::__type = std::atomic<int>*]': /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_algobase.h:787:74: required from '_OI std::fill_n(_OI, _Size, const _Tp&) [with _OI = std::atomic<int>*; _Size = long unsigned int; _Tp = std::atomic<int>]' /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_uninitialized.h:515:42: required from 'static void std::__uninitialized_default_n_1<true>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = std::atomic<int>*; _Size = long unsigned int]' /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_uninitialized.h:544:33: required from 'void std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = std::atomic<int>*; _Size = long unsigned int]' /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_uninitialized.h:605:50: required from 'void std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = std::atomic<int>*; _Size = long unsigned int; _Tp = std::atomic<int>]' /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_vector.h:1290:28: required from 'void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::atomic<int>; _Alloc = std::allocator<std::atomic<int> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int]' /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_vector.h:265:34: required from 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = std::atomic<int>; _Alloc = std::allocator<std::atomic<int> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::atomic<int> >]' vatom.cc:8:39: required from here /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/bits/stl_algobase.h:740:11: error: use of deleted function 'std::atomic<int>& std::atomic<int>::operator=(const std::atomic<int>&)' *__first = __value; ^ In file included from vatom.cc:2:0: /afs/cern.ch/user/i/innocent/w4/include/c++/4.9.0/atomic:606:15: note: declared here atomic& operator=(const atomic&) = delete; ^
Jon are you willing to help with this? I'm in the middle of too many things. First blush, I suspect stl_uninitialized.h needs updating in the light of Jason's r203985: those __is_trivial for dispatching look very suspect!
I think at least something like this for this specific bug, but the whole file needs auditing: Index: stl_uninitialized.h =================================================================== --- stl_uninitialized.h (revision 204342) +++ stl_uninitialized.h (working copy) @@ -527,7 +527,8 @@ typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - std::__uninitialized_default_1<__is_trivial(_ValueType)>:: + std::__uninitialized_default_1 + <std::is_copy_constructible<_ValueType>::value>:: __uninit_default(__first, __last); } @@ -540,7 +541,8 @@ typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - std::__uninitialized_default_n_1<__is_trivial(_ValueType)>:: + std::__uninitialized_default_n_1 + <std::is_copy_constructible<_ValueType>::value>:: __uninit_default_n(__first, __n); }
Well, something closer to a correct minimal fix would be is_trivial && is_copy_assignable. Jon, I think that in general in this file minimal fixes would involve && with the existing is_trivial.
(In reply to Paolo Carlini from comment #2) > I think at least something like this for this specific bug, but the whole > file needs auditing: Not only that file, but stl_algobase.h too, we compile this without complaint and then do a memmove() on atomic objects! std::atomic<int> a[1]; std::atomic<int> b[1]; std::uninitialized_copy(a,a+1, b);
And this, which is more obviously wrong: std::atomic<int> a[1]; std::atomic<int> b[1]; std::copy(a,a+1, b);
At some point we replaced a weak (not using front-end intrinsics) version of is_pod with __is_trivial, in algos & uninitialized. At that time was safe, ins't anymore in 4.9. In principle we could minimally go back to std::is_pod. Or add to __is_trivial the required additional constraints on copy & move operations. Which seems much better.
Yes, it's not too hard to fix properly, so I'm working on that.
Thanks!
Author: redi Date: Sat Nov 9 12:38:00 2013 New Revision: 204615 URL: http://gcc.gnu.org/viewcvs?rev=204615&root=gcc&view=rev Log: 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. Added: trunk/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/58982.cc trunk/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/58982.cc trunk/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/58982.cc trunk/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/58982.cc trunk/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc trunk/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/bits/stl_algobase.h trunk/libstdc++-v3/include/bits/stl_uninitialized.h
Fixed