From 5dce73dd6e4d6b6eb522e813558b2d8a350e50f1 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Tue, 19 May 2015 15:01:48 +0000 Subject: [PATCH] Implement LWG2433: uninitialized_copy()/etc. should tolerate overloaded operator& git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@237699 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/memory | 14 +++++------ .../uninitialized_copy.pass.cpp | 24 ++++++++++++++++++ .../uninitialized_copy_n.pass.cpp | 23 +++++++++++++++++ .../uninitialized_fill_n.pass.cpp | 25 +++++++++++++++++++ .../uninitialized_fill.pass.cpp | 22 ++++++++++++++++ www/cxx1z_status.html | 2 +- 6 files changed, 102 insertions(+), 8 deletions(-) diff --git a/include/memory b/include/memory index eb4a30f1..4af72c3d 100644 --- a/include/memory +++ b/include/memory @@ -3527,8 +3527,8 @@ uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) try { #endif - for (; __f != __l; ++__f, ++__r) - ::new(&*__r) value_type(*__f); + for (; __f != __l; ++__f, (void) ++__r) + ::new (static_cast(_VSTD::addressof(*__r))) value_type(*__f); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -3551,8 +3551,8 @@ uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) try { #endif - for (; __n > 0; ++__f, ++__r, --__n) - ::new(&*__r) value_type(*__f); + for (; __n > 0; ++__f, (void) ++__r, (void) --__n) + ::new (static_cast(_VSTD::addressof(*__r))) value_type(*__f); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -3576,7 +3576,7 @@ uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x) { #endif for (; __f != __l; ++__f) - ::new(&*__f) value_type(__x); + ::new (static_cast(_VSTD::addressof(*__f))) value_type(__x); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -3598,8 +3598,8 @@ uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) try { #endif - for (; __n > 0; ++__f, --__n) - ::new(&*__f) value_type(__x); + for (; __n > 0; ++__f, (void) --__n) + ::new (static_cast(_VSTD::addressof(*__f))) value_type(__x); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp index 7de7eccc..f431335d 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp @@ -28,8 +28,19 @@ struct B int B::count_ = 0; +struct Nasty +{ + Nasty() : i_ ( counter_++ ) {} + Nasty * operator &() const { return NULL; } + int i_; + static int counter_; +}; + +int Nasty::counter_ = 0; + int main() { + { const int N = 5; char pool[sizeof(B)*N] = {0}; B* bp = (B*)pool; @@ -48,4 +59,17 @@ int main() std::uninitialized_copy(b, b+2, bp); for (int i = 0; i < 2; ++i) assert(bp[i].data_ == 1); + } + { + const int N = 5; + char pool[sizeof(Nasty)*N] = {0}; + Nasty * p = (Nasty *) pool; + Nasty arr[N]; + std::uninitialized_copy(arr, arr+N, p); + for (int i = 0; i < N; ++i) { + assert(arr[i].i_ == i); + assert( p[i].i_ == i); + } + } + } diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp index 79afa4f8..3b2007b9 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp @@ -28,8 +28,19 @@ struct B int B::count_ = 0; +struct Nasty +{ + Nasty() : i_ ( counter_++ ) {} + Nasty * operator &() const { return NULL; } + int i_; + static int counter_; +}; + +int Nasty::counter_ = 0; + int main() { + { const int N = 5; char pool[sizeof(B)*N] = {0}; B* bp = (B*)pool; @@ -48,4 +59,16 @@ int main() std::uninitialized_copy_n(b, 2, bp); for (int i = 0; i < 2; ++i) assert(bp[i].data_ == 1); + } + { + const int N = 5; + char pool[sizeof(Nasty)*N] = {0}; + Nasty * p = (Nasty *) pool; + Nasty arr[N]; + std::uninitialized_copy_n(arr, N, p); + for (int i = 0; i < N; ++i) { + assert(arr[i].i_ == i); + assert( p[i].i_ == i); + } + } } diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp index 8fc6b819..d2b1dfa2 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp @@ -27,8 +27,19 @@ struct B int B::count_ = 0; +struct Nasty +{ + Nasty() : i_ ( counter_++ ) {} + Nasty * operator &() const { return NULL; } + int i_; + static int counter_; +}; + +int Nasty::counter_ = 0; + int main() { + { const int N = 5; char pool[sizeof(B)*N] = {0}; B* bp = (B*)pool; @@ -47,4 +58,18 @@ int main() assert(r == bp + 2); for (int i = 0; i < 2; ++i) assert(bp[i].data_ == 1); + } + { + { + const int N = 5; + char pool[N*sizeof(Nasty)] = {0}; + Nasty* bp = (Nasty*)pool; + + Nasty::counter_ = 23; + std::uninitialized_fill_n(bp, N, Nasty()); + for (int i = 0; i < N; ++i) + assert(bp[i].i_ == 23); + } + + } } diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp index c34fdc7a..47cabdfa 100644 --- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp +++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp @@ -28,8 +28,19 @@ struct B int B::count_ = 0; +struct Nasty +{ + Nasty() : i_ ( counter_++ ) {} + Nasty * operator &() const { return NULL; } + int i_; + static int counter_; +}; + +int Nasty::counter_ = 0; + int main() { + { const int N = 5; char pool[sizeof(B)*N] = {0}; B* bp = (B*)pool; @@ -47,4 +58,15 @@ int main() std::uninitialized_fill(bp, bp+2, B()); for (int i = 0; i < 2; ++i) assert(bp[i].data_ == 1); + } + { + const int N = 5; + char pool[N*sizeof(Nasty)] = {0}; + Nasty* bp = (Nasty*)pool; + + Nasty::counter_ = 23; + std::uninitialized_fill(bp, bp+N, Nasty()); + for (int i = 0; i < N; ++i) + assert(bp[i].i_ == 23); + } } diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html index 43678c65..28a723f4 100644 --- a/www/cxx1z_status.html +++ b/www/cxx1z_status.html @@ -120,7 +120,7 @@ 2425operator delete(void*, size_t) doesn't invalidate pointers sufficientlyLenexaComplete 2427Container adaptors as sequence containers, reduxLenexaComplete 2428"External declaration" used without being definedLenexaComplete - 2433uninitialized_copy()/etc. should tolerate overloaded operator&Lenexa + 2433uninitialized_copy()/etc. should tolerate overloaded operator&LenexaComplete 2434shared_ptr::use_count() is efficientLenexaComplete 2437iterator_traits::reference can and can't be voidLenexaComplete 2438std::iterator inheritance shouldn't be mandatedLenexaComplete