From patchwork Tue Nov 15 23:32:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v3] libstdc++/51142 X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 125897 Message-Id: <4EC2F693.9060408@oracle.com> To: "gcc-patches@gcc.gnu.org" Cc: libstdc++ Date: Wed, 16 Nov 2011 00:32:35 +0100 From: Paolo Carlini List-Id: Hi, this fixes the problem submitter noticed by implementing LWG 2059, which seems a good thing to do anyway, instead of just fixing the specific erase calls in the debug-mode code. The patch seems big, but actually is straightforward and limited to C++11, thus I mean to apply it to the branch too pretty soon. Tested x86_64-linux, normal-mode and debug-mode. Thanks, Paolo. //////////////////////// 2011-11-15 Paolo Carlini PR libstdc++/51142 * include/debug/unordered_map (unordered_map<>::erase(iterator), unordered_multimap<>::erase(iterator)): Add, consistently with LWG 2059. * include/debug/unordered_set (unordered_set<>::erase(iterator), unordered_multiset<>::erase(iterator)): Likewise. * include/debug/map.h (map<>::erase(iterator)): Likewise. * include/debug/multimap.h (multimap<>::erase(iterator)): Likewise. * include/profile/map.h (map<>::erase(iterator)): Likewise. * include/profile/multimap.h (multimap<>::erase(iterator)): Likewise. * include/bits/hashtable.h (_Hashtable<>::erase(iterator)): Likewise. * include/bits/stl_map.h (map<>::erase(iterator)): Likewise. * include/bits/stl_multimap.h (multimap<>::erase(iterator)): Likewise. * include/bits/stl_tree.h (_Rb_tree<>::erase(iterator)): Likewise. * testsuite/23_containers/unordered_map/erase/51142.cc: New. * testsuite/23_containers/multimap/modifiers/erase/51142.cc: Likewise. * testsuite/23_containers/set/modifiers/erase/51142.cc: Likewise. * testsuite/23_containers/unordered_multimap/erase/51142.cc: Likewise. * testsuite/23_containers/unordered_set/erase/51142.cc: Likewise. * testsuite/23_containers/multiset/modifiers/erase/51142.cc: Likewise. * testsuite/23_containers/unordered_multiset/erase/51142.cc: Likewise. * testsuite/23_containers/map/modifiers/erase/51142.cc: Likewise. Index: include/debug/unordered_map =================================================================== --- include/debug/unordered_map (revision 181385) +++ include/debug/unordered_map (working copy) @@ -334,6 +334,10 @@ } iterator + erase(iterator __it) + { return erase(const_iterator(__it)); } + + iterator erase(const_iterator __first, const_iterator __last) { __glibcxx_check_erase_range(__first, __last); @@ -709,6 +713,10 @@ } iterator + erase(iterator __it) + { return erase(const_iterator(__it)); } + + iterator erase(const_iterator __first, const_iterator __last) { __glibcxx_check_erase_range(__first, __last); Index: include/debug/unordered_set =================================================================== --- include/debug/unordered_set (revision 181385) +++ include/debug/unordered_set (working copy) @@ -330,6 +330,10 @@ } iterator + erase(iterator __it) + { return erase(const_iterator(__it)); } + + iterator erase(const_iterator __first, const_iterator __last) { __glibcxx_check_erase_range(__first, __last); @@ -696,6 +700,10 @@ } iterator + erase(iterator __it) + { return erase(const_iterator(__it)); } + + iterator erase(const_iterator __first, const_iterator __last) { __glibcxx_check_erase_range(__first, __last); Index: include/debug/map.h =================================================================== --- include/debug/map.h (revision 181385) +++ include/debug/map.h (working copy) @@ -271,6 +271,10 @@ this->_M_invalidate_if(_Equal(__position.base())); return iterator(_Base::erase(__position.base()), this); } + + iterator + erase(iterator __position) + { return erase(const_iterator(__position)); } #else void erase(iterator __position) Index: include/debug/multimap.h =================================================================== --- include/debug/multimap.h (revision 181385) +++ include/debug/multimap.h (working copy) @@ -254,6 +254,10 @@ this->_M_invalidate_if(_Equal(__position.base())); return iterator(_Base::erase(__position.base()), this); } + + iterator + erase(iterator __position) + { return erase(const_iterator(__position)); } #else void erase(iterator __position) Index: include/profile/map.h =================================================================== --- include/profile/map.h (revision 181385) +++ include/profile/map.h (working copy) @@ -327,6 +327,10 @@ __profcxx_map_to_unordered_map_erase(this, size(), 1); return __i; } + + iterator + erase(iterator __position) + { return erase(const_iterator(__position)); } #else void erase(iterator __position) Index: include/profile/multimap.h =================================================================== --- include/profile/multimap.h (revision 181385) +++ include/profile/multimap.h (working copy) @@ -226,6 +226,10 @@ iterator erase(const_iterator __position) { return iterator(_Base::erase(__position)); } + + iterator + erase(iterator __position) + { return iterator(_Base::erase(__position)); } #else void erase(iterator __position) Index: include/bits/hashtable.h =================================================================== --- include/bits/hashtable.h (revision 181359) +++ include/bits/hashtable.h (working copy) @@ -432,6 +432,11 @@ iterator erase(const_iterator); + // LWG 2059. + iterator + erase(iterator __it) + { return erase(const_iterator(__it)); } + size_type erase(const key_type&); Index: include/bits/stl_map.h =================================================================== --- include/bits/stl_map.h (revision 181359) +++ include/bits/stl_map.h (working copy) @@ -617,6 +617,11 @@ iterator erase(const_iterator __position) { return _M_t.erase(__position); } + + // LWG 2059. + iterator + erase(iterator __position) + { return _M_t.erase(__position); } #else /** * @brief Erases an element from a %map. Index: include/bits/stl_multimap.h =================================================================== --- include/bits/stl_multimap.h (revision 181359) +++ include/bits/stl_multimap.h (working copy) @@ -536,6 +536,11 @@ iterator erase(const_iterator __position) { return _M_t.erase(__position); } + + // LWG 2059. + iterator + erase(iterator __position) + { return _M_t.erase(__position); } #else /** * @brief Erases an element from a %multimap. Index: include/bits/stl_tree.h =================================================================== --- include/bits/stl_tree.h (revision 181359) +++ include/bits/stl_tree.h (working copy) @@ -767,6 +767,16 @@ _M_erase_aux(__position); return __result._M_const_cast(); } + + // LWG 2059. + iterator + erase(iterator __position) + { + iterator __result = __position; + ++__result; + _M_erase_aux(__position); + return __result; + } #else void erase(iterator __position) Index: testsuite/23_containers/unordered_map/erase/51142.cc =================================================================== --- testsuite/23_containers/unordered_map/erase/51142.cc (revision 0) +++ testsuite/23_containers/unordered_map/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator==(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::unordered_map& s, X x) +{ + std::unordered_map::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +} Index: testsuite/23_containers/multimap/modifiers/erase/51142.cc =================================================================== --- testsuite/23_containers/multimap/modifiers/erase/51142.cc (revision 0) +++ testsuite/23_containers/multimap/modifiers/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator<(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::multimap& s, X x) +{ + std::multimap::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +} Index: testsuite/23_containers/set/modifiers/erase/51142.cc =================================================================== --- testsuite/23_containers/set/modifiers/erase/51142.cc (revision 0) +++ testsuite/23_containers/set/modifiers/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator<(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::set& s, X x) +{ + std::set::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +} Index: testsuite/23_containers/unordered_multimap/erase/51142.cc =================================================================== --- testsuite/23_containers/unordered_multimap/erase/51142.cc (revision 0) +++ testsuite/23_containers/unordered_multimap/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator==(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::unordered_multimap& s, X x) +{ + std::unordered_multimap::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +} Index: testsuite/23_containers/unordered_set/erase/51142.cc =================================================================== --- testsuite/23_containers/unordered_set/erase/51142.cc (revision 0) +++ testsuite/23_containers/unordered_set/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator==(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::unordered_set& s, X x) +{ + std::unordered_set::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +} Index: testsuite/23_containers/multiset/modifiers/erase/51142.cc =================================================================== --- testsuite/23_containers/multiset/modifiers/erase/51142.cc (revision 0) +++ testsuite/23_containers/multiset/modifiers/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator<(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::multiset& s, X x) +{ + std::multiset::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +} Index: testsuite/23_containers/unordered_multiset/erase/51142.cc =================================================================== --- testsuite/23_containers/unordered_multiset/erase/51142.cc (revision 0) +++ testsuite/23_containers/unordered_multiset/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator==(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::unordered_multiset& s, X x) +{ + std::unordered_multiset::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +} Index: testsuite/23_containers/map/modifiers/erase/51142.cc =================================================================== --- testsuite/23_containers/map/modifiers/erase/51142.cc (revision 0) +++ testsuite/23_containers/map/modifiers/erase/51142.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2011 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 compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct X +{ + template + X(T&) {} +}; + +bool operator<(const X&, const X&) { return false; } + +// LWG 2059. +void erasor(std::map& s, X x) +{ + std::map::iterator it = s.find(x); + if (it != s.end()) + s.erase(it); +}