From 0edf5aadeaf8955cc2f0d97f7e244cf9ab7b6084 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 9 Jan 2015 18:02:47 +0000 Subject: [PATCH] re PR libstdc++/64476 (std::uninitialized_copy tests assignability the wrong way, resulting in performance pessimization) PR libstdc++/64476 * include/bits/stl_uninitialized.h (uninitialized_copy): Fix is_assignable arguments. * testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc: New. From-SVN: r219398 --- libstdc++-v3/ChangeLog | 8 +++ libstdc++-v3/include/bits/stl_uninitialized.h | 5 +- .../uninitialized_copy/64476.cc | 65 +++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 83c1add18a5..c27250d52a9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2015-01-09 Jonathan Wakely + + PR libstdc++/64476 + * include/bits/stl_uninitialized.h (uninitialized_copy): Fix + is_assignable arguments. + * testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc: + New. + 2015-01-09 Andreas Tobler * libsupc++/unwind-cxx.h: Revert previous commit. diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 00659e91270..61a15618f43 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -115,8 +115,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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; + typedef typename iterator_traits<_InputIterator>::reference _RefType1; + typedef typename iterator_traits<_ForwardIterator>::reference _RefType2; + const bool __assignable = is_assignable<_RefType2, _RefType1>::value; #endif return std::__uninitialized_copy<__is_trivial(_ValueType1) diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc new file mode 100644 index 00000000000..6369b17af1e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc @@ -0,0 +1,65 @@ +// Copyright (C) 2015 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include + +struct X +{ + X() = default; + X(X const &) = default; + X& operator=(X const&) = delete; +}; + +static_assert(__is_trivial(X), "X is trivial"); + +int constructed = 0; +int assigned = 0; + +struct Y +{ + Y() = default; + Y(Y const &) = default; + Y& operator=(Y const&) = default; + + Y(const X&) { ++constructed; } + Y& operator=(const X&)& { ++assigned; return *this; } + Y& operator=(const X&)&& = delete; + Y& operator=(X&&) = delete; +}; + +static_assert(__is_trivial(Y), "Y is trivial"); + +void +test01() +{ + X a[100]; + Y b[100]; + + std::uninitialized_copy(a, a+10, b); + + VERIFY(constructed == 0); + VERIFY(assigned == 10); +} + +int +main() +{ + test01(); +} -- 2.30.2