From 6af8819be1e09fa2035248eba7fb320350ec14ab Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Tue, 7 Jan 2020 21:01:37 +0000 Subject: [PATCH] PR libstdc++/92124 fix incorrect container move assignment * include/bits/stl_tree.h (_Rb_tree<>::_M_move_assign(_Rb_tree&, false_type)): Replace std::move_if_noexcept by std::move. * testsuite/23_containers/map/92124.cc: New. * testsuite/23_containers/set/92124.cc: New. From-SVN: r279967 --- libstdc++-v3/ChangeLog | 9 +++ libstdc++-v3/include/bits/stl_tree.h | 2 +- .../testsuite/23_containers/map/92124.cc | 58 +++++++++++++++ .../testsuite/23_containers/set/92124.cc | 73 +++++++++++++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/23_containers/map/92124.cc create mode 100644 libstdc++-v3/testsuite/23_containers/set/92124.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1e46178c999..4aae9facabd 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2020-01-07 François Dumont + + PR libstdc++/92124 + * include/bits/stl_tree.h + (_Rb_tree<>::_M_move_assign(_Rb_tree&, false_type)): Replace + std::move_if_noexcept by std::move. + * testsuite/23_containers/map/92124.cc: New. + * testsuite/23_containers/set/92124.cc: New. + 2020-01-06 Jonathan Wakely * include/std/stop_token (stop_token): Remove operator!= (LWG 3254). diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 12ba3181dd9..9339011e872 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1695,7 +1695,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [&__roan](const value_type& __cval) { auto& __val = const_cast(__cval); - return __roan(std::move_if_noexcept(__val)); + return __roan(std::move(__val)); }; _M_root() = _M_copy(__x, __lbd); __x.clear(); diff --git a/libstdc++-v3/testsuite/23_containers/map/92124.cc b/libstdc++-v3/testsuite/23_containers/map/92124.cc new file mode 100644 index 00000000000..177c9d7abe9 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/92124.cc @@ -0,0 +1,58 @@ +// Copyright (C) 2020 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-do run { target c++11 } } + +#include +#include + +struct X +{ + X() = default; + X(const X&) + { if (Throw) throw 1; } + + // Move constructor might throw + X(X&&) noexcept(false) {} + + // Tracking calls to assignment functions + X& operator=(const X&) { throw 1; } + + X& operator=(X&&) noexcept(false) { return *this; } + + static bool Throw; +}; + +bool X::Throw = false; + +void +test01() +{ + using A = __gnu_test::propagating_allocator, false>; + A a1(1), a2(2); + std::map, A> + m1({ { 1, X() } }, a1), + m2({ { 2, X() } }, a2); + X::Throw = true; + m1 = std::move(m2); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/set/92124.cc b/libstdc++-v3/testsuite/23_containers/set/92124.cc new file mode 100644 index 00000000000..95a2e9ce518 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/92124.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2020 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-do run { target c++11 } } + +#include +#include + +struct X +{ + X(int i) noexcept(true) : _i(i) { } + X(const X& x) noexcept(false) + { + if (Throw) throw 0; + _i = x._i; + } + + // Move constructor might throw + X(X&& x) noexcept(false) + { + _i = x._i; + x._i = -x._i; + } + + // Tracking calls to assignment functions + X& operator=(const X&) { throw 1; } + + X& operator=(X&& x) noexcept(false) + { + _i = x._i; + x._i = -x._i; + return *this; + } + + bool + operator < (const X& x) const + { return _i < x._i; } + + int _i; + static bool Throw; +}; + +bool X::Throw = false; + +void +test01() +{ + using A = __gnu_test::propagating_allocator; + A a1(1), a2(2); + std::set, A> s1({ X(1) }, a1), s2({ X(2) }, a2); + X::Throw = true; + s1 = std::move(s2); +} + +int +main() +{ + test01(); +} -- 2.30.2