[v3 PATCH] PR libstdc++/78389

Jonathan Wakely jwakely@redhat.com
Fri Jan 13 14:41:00 GMT 2017


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
:-)



More information about the Libstdc++ mailing list