This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [v3 PATCH] PR libstdc++/78389
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: Ville Voutilainen <ville dot voutilainen at gmail dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, libstdc++ <libstdc++ at gcc dot gnu dot org>, Tim Song <t dot canens dot cpp at gmail dot com>
- Date: Fri, 13 Jan 2017 14:41:23 +0000
- Subject: Re: [v3 PATCH] PR libstdc++/78389
- Authentication-results: sourceware.org; auth=none
- References: <CAFk2RUYjjXW2MGuEaLRPHV87R7YB-PTYhSk7QnxzJUBdHS4nkA@mail.gmail.com>
On 13/01/17 16:26 +0200, Ville Voutilainen wrote:
Update patch with splices for __carry added. Hopefully this resolves
the remaining concerns that we had.
OK for trunk after fixing the ADL issue noted below.
There are also two stylistic comments ...
diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc
index c4f397f..9ba403c 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -380,26 +380,36 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// 300. list::merge() specification incomplete
if (this != std::__addressof(__x))
{
- _M_check_equal_allocators(__x);
+ _M_check_equal_allocators(__x);
iterator __first1 = begin();
iterator __last1 = end();
iterator __first2 = __x.begin();
iterator __last2 = __x.end();
- while (__first1 != __last1 && __first2 != __last2)
- if (*__first2 < *__first1)
- {
- iterator __next = __first2;
- _M_transfer(__first1, __first2, ++__next);
- __first2 = __next;
- }
- else
- ++__first1;
- if (__first2 != __last2)
- _M_transfer(__last1, __first2, __last2);
+ size_t __orig_size = __x.size();
This could be const, just to ensure we don't accidentally modify it.
+ __try {
+ while (__first1 != __last1 && __first2 != __last2)
+ if (*__first2 < *__first1)
+ {
+ iterator __next = __first2;
+ _M_transfer(__first1, __first2, ++__next);
+ __first2 = __next;
+ }
+ else
+ ++__first1;
+ if (__first2 != __last2)
+ _M_transfer(__last1, __first2, __last2);
- this->_M_inc_size(__x._M_get_size());
- __x._M_set_size(0);
+ this->_M_inc_size(__x._M_get_size());
+ __x._M_set_size(0);
+ }
+ __catch(...)
+ {
+ size_t __dist = distance(__first2, __last2);
This must be std::distance, so we don't find an overload in a
namespace associated with our value_type or allocator_type.
Same comments for the second merge function as well.
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/78389.cc b/libstdc++-v3/testsuite/23_containers/list/operations/78389.cc
new file mode 100644
index 0000000..fded09d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/78389.cc
@@ -0,0 +1,85 @@
+// { dg-do run { target c++11 } }
+
+// Copyright (C) 2017 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
+// <http://www.gnu.org/licenses/>.
+
+// 23.2.2.4 list operations [lib.list.ops]
+
+#include <testsuite_hooks.h>
+
+#include <list>
+
+struct ThrowingComparator
+{
+ unsigned int throw_after = 0;
+ unsigned int count = 0;
+ bool operator()(int, int) {
+ if (++count >= throw_after) {
+ throw 666;
+ }
+ return true;
+ }
+};
+
+struct X
+{
+ X() = default;
+ X(int) {}
+};
The indentation in this test keeps changing from 2 spaces to 4 spaces
:-)