From patchwork Thu Aug 1 20:00:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Patchwork-Id: 264108 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 34FAD2C007C for ; Fri, 2 Aug 2013 06:00:58 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=pae3WQeoCIJqqrDIS EuHDZVTq4ZytMnm4UVvtM+dMGOb8S8LZOMKwLfauEorHrQcHfwx98TnfUVpo60F8 He3hqlptL4POHBtRf103pyAD7QUbrtAH3Y8qID7c32+632AQJFiajdWPzQxHcdcf FOyTbB4jtayrRxKejiTn/sa37U= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=1kkFK+qypL6pPbwc/mIjPnA RzbM=; b=VizHalMAdxEUx2XNVNNwa+8GfuXrEDguOCkCefmMLkD7Kt/3rfUGRSx irBvp/MaE+wcvdznUsm+Xg6mi/Xwm3fciQK89IyIyDb+qOtBsBfh0dhKCVnYJG3P DH+59ow5pXwVVkHZjfKJ2r6PV0kJ4c+NT5g0LuAwbtkVOmnMU4Aw= Received: (qmail 18767 invoked by alias); 1 Aug 2013 20:00:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 18753 invoked by uid 89); 1 Aug 2013 20:00:51 -0000 X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RDNS_NONE, SPF_PASS autolearn=ham version=3.3.1 X-Spam-User: qpsmtpd, 2 recipients Received: from Unknown (HELO mail-wg0-f49.google.com) (74.125.82.49) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 01 Aug 2013 20:00:49 +0000 Received: by mail-wg0-f49.google.com with SMTP id y10so2015425wgg.4 for ; Thu, 01 Aug 2013 13:00:40 -0700 (PDT) X-Received: by 10.180.21.229 with SMTP id y5mr9025552wie.17.1375387240762; Thu, 01 Aug 2013 13:00:40 -0700 (PDT) Received: from localhost.localdomain (arf62-1-82-237-250-248.fbx.proxad.net. [82.237.250.248]) by mx.google.com with ESMTPSA id b13sm5832645wic.9.2013.08.01.13.00.38 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 01 Aug 2013 13:00:39 -0700 (PDT) Message-ID: <51FABE51.3080203@gmail.com> Date: Thu, 01 Aug 2013 22:00:17 +0200 From: =?ISO-8859-1?Q?Fran=E7ois_Dumont?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120829 Thunderbird/15.0 MIME-Version: 1.0 To: Paolo Carlini CC: Jonathan Wakely , "libstdc++@gcc.gnu.org" , gcc-patches Subject: Re: PR 57779 New debug check References: <51DDC4A0.6020008@gmail.com> <51DEE0A9.9010809@oracle.com> <51DF1291.6040404@gmail.com> <51E45AB2.10000@gmail.com> <775842B8-CCCC-4126-9577-AF34711D5123@oracle.com> <51EEE901.4010107@gmail.com> <51EF9530.3010702@oracle.com> <51F03BF4.6080207@gmail.com> <51F050BC.1060106@oracle.com> <51F96C4C.1080800@gmail.com> <51F986C0.8070800@oracle.com> In-Reply-To: <51F986C0.8070800@oracle.com> X-Virus-Found: No Attached patch applied. Compare to the proposed one I had to: - Disable the new check for __gnu_debug::basic_string<>, it is supported following Standard words. To do so I had to slithly review how _GLIBCXX_DEBUG_PEDANTIC was managed. - Add check on forward_list::insert_after 2013-08-01 François Dumont PR libstdc++/57779 * include/debug/formatter.h (_Debug_msg_id): Add __msg_insert_itself_range entry. * include/debug/functions.h (_Insert_range_from_self_is_safe<>): New, indicate container types supporting self range insertion in GNU implementation. (__foreign_iterator): New, check if an iterator points to a given sequence. * include/debug/macros.h (__glibcxx_check_insert_range): Add check using __foreign_iterator. (__gibcxx_check_insert_range_after): Likewise. * include/debug/string (_Insert_range_from_self_is_safe<>): Partially specialized to mark __gnu_debug::basic_string<> as supporting self range insert. * include/debug/list (_Insert_range_from_self_is_safe<>): Partially specialized to mark std::list as supporting self range insert if _GLIBCXX_DEBUG_PEDANTIC is not defined. * include/debug/forward_list (_Insert_range_from_self_is_safe<>): Likewise. * src/c++11/debug.cc (_S_debug_messages): Add __msg_insert_itself_range_entry message. (_Error_formatter::_Parameter::_M_print_description): Display iterator sequence address rather than sequence address when the parameter type is an iterator. (_Error_formatter::_M_print_word): Enhance behavior when displaying a word with an appended '\n'. * testsuite/util/debug/checks.h (check_insert4<>): New. * testsuite/23_containers/deque/debug/insert5_neg.cc: New. * testsuite/23_containers/vector/debug/insert5_neg.cc: Likewise. * testsuite/23_containers/vector/debug/insert6_neg.cc: Likewise. * testsuite/23_containers/vector/debug/57779_neg.cc: Likewise. * testsuite/23_containers/list/debug/insert5_neg.cc: Likewise. * testsuite/23_containers/forward_list/debug/insert_after4_neg.cc: Likewise. François On 07/31/2013 11:50 PM, Paolo Carlini wrote: > On 07/31/2013 09:58 PM, François Dumont wrote: >> Here is another proposal using std::common_type to find out how to >> instantiate std::less and std::greater_equal. Much easier with C++11 >> features indeed. >> >> Tested under linux x86_64 debug mode. >> >> Ok to commit ? > Ok, thanks! > > Paolo. > Index: include/debug/formatter.h =================================================================== --- include/debug/formatter.h (revision 201413) +++ include/debug/formatter.h (working copy) @@ -114,7 +114,9 @@ // unordered container buckets __msg_bucket_index_oob, __msg_valid_load_factor, - __msg_equal_allocs + // others + __msg_equal_allocs, + __msg_insert_range_from_self }; class _Error_formatter Index: include/debug/functions.h =================================================================== --- include/debug/functions.h (revision 201413) +++ include/debug/functions.h (working copy) @@ -32,7 +32,11 @@ #include #include // for iterator_traits, categories and // _Iter_base -#include // for __is_integer +#include // for __is_integer +#if __cplusplus >= 201103L +# include // for less and greater_equal +# include // for common_type +#endif #include namespace __gnu_debug @@ -40,6 +44,10 @@ template class _Safe_iterator; + template + struct _Insert_range_from_self_is_safe + { enum { __value = 0 }; }; + // An arbitrary iterator pointer is not singular. inline bool __check_singular_aux(const void*) { return false; } @@ -162,6 +170,123 @@ return __first; } +#if __cplusplus >= 201103L + template + inline bool + __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + _PointerType1, _PointerType2) + { + typedef typename std::common_type<_PointerType1, + _PointerType2>::type _PointerType; + std::less<_PointerType> __l; + std::greater_equal<_PointerType> __ge; + + return + __l(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().begin()))) + || __ge(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + 1); + + } + + template + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::true_type) + { + // Only containers with all elements in contiguous memory can have their + // elements passed through pointers. + // Arithmetics is here just to make sure we are not dereferencing + // past-the-end iterator. + if (__it._M_get_sequence()->_M_base().begin() + != __it._M_get_sequence()->_M_base().end()) + if (std::__addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + - std::__addressof(*(__it._M_get_sequence()->_M_base().begin())) + == __it._M_get_sequence()->size() - 1) + return __foreign_iterator_aux4(__it, __other, + std::addressof(*(__it._M_get_sequence()->_M_base().begin())), + std::addressof(*__other)); + return true; + } + + /* Fallback overload for which we can't say, assume it is valid. */ + template + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::false_type) + { return true; } +#endif + + /** Checks that iterators do not belong to the same sequence. */ + template + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + const _Safe_iterator<_OtherIterator, _Sequence>& __other, + std::input_iterator_tag) + { return __it._M_get_sequence() != __other._M_get_sequence(); } + +#if __cplusplus >= 201103L + /* This overload detects when passing pointers to the contained elements rather + than using iterators. + */ + template + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::random_access_iterator_tag) + { + typedef typename _Sequence::const_iterator _ItType; + typedef typename std::iterator_traits<_ItType>::reference _Ref; + return __foreign_iterator_aux3(__it, __other, + std::is_lvalue_reference<_Ref>()); + } +#endif + + /* Fallback overload for which we can't say, assume it is valid. */ + template + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>&, + _InputIterator, + std::input_iterator_tag) + { return true; } + + template + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, + _Integral __other, + std::__true_type) + { return true; } + + template + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::__false_type) + { + return + _Insert_range_from_self_is_safe<_Sequence>::__value + || __foreign_iterator_aux2(__it, __other, + std::__iterator_category(__it)); + } + + template + inline bool + __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return __foreign_iterator_aux(__it, __other, _Integral()); + } + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ template inline const _CharT* Index: include/debug/forward_list =================================================================== --- include/debug/forward_list (revision 201413) +++ include/debug/forward_list (working copy) @@ -796,6 +796,13 @@ _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) { return _S_Is(__it, __seq); } }; + +#ifndef _GLIBCXX_DEBUG_PEDANTIC + template + struct _Insert_range_from_self_is_safe< + std::__debug::forward_list<_Tp, _Alloc> > + { enum { __value = 1 }; }; +#endif } #endif Index: include/debug/string =================================================================== --- include/debug/string (revision 201413) +++ include/debug/string (working copy) @@ -1156,6 +1156,11 @@ typedef basic_string wstring; #endif + template + struct _Insert_range_from_self_is_safe< + __gnu_debug::basic_string<_CharT, _Traits, _Allocator> > + { enum { __value = 1 }; }; + } // namespace __gnu_debug #endif Index: include/debug/macros.h =================================================================== --- include/debug/macros.h (revision 201413) +++ include/debug/macros.h (working copy) @@ -72,11 +72,11 @@ */ #define __glibcxx_check_insert(_Position) \ _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ - _M_message(__gnu_debug::__msg_insert_singular) \ + _M_message(__gnu_debug::__msg_insert_singular) \ ._M_sequence(*this, "this") \ ._M_iterator(_Position, #_Position)); \ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ - _M_message(__gnu_debug::__msg_insert_different) \ + _M_message(__gnu_debug::__msg_insert_different) \ ._M_sequence(*this, "this") \ ._M_iterator(_Position, #_Position)) @@ -101,15 +101,16 @@ * that it reference the sequence we are inserting into, and that the * iterator range [_First, Last) is a valid (possibly empty) * range. Note that this macro is only valid when the container is a - * _Safe_sequence and the iterator is a _Safe_iterator. - * - * @todo We would like to be able to check for noninterference of - * _Position and the range [_First, _Last), but that can't (in - * general) be done. + * _Safe_sequence and the _Position iterator is a _Safe_iterator. */ #define __glibcxx_check_insert_range(_Position,_First,_Last) \ __glibcxx_check_valid_range(_First,_Last); \ -__glibcxx_check_insert(_Position) +__glibcxx_check_insert(_Position); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First),\ + _M_message(__gnu_debug::__msg_insert_range_from_self)\ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_sequence(*this, "this")) /** Verify that we can insert the values in the iterator range * [_First, _Last) into *this after the iterator _Position. Insertion @@ -126,7 +127,12 @@ */ #define __glibcxx_check_insert_range_after(_Position,_First,_Last) \ __glibcxx_check_valid_range(_First,_Last); \ -__glibcxx_check_insert_after(_Position) +__glibcxx_check_insert_after(_Position); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First),\ + _M_message(__gnu_debug::__msg_insert_range_from_self)\ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_sequence(*this, "this")) /** Verify that we can erase the element referenced by the iterator * _Position. We can erase the element if the _Position iterator is @@ -332,7 +338,7 @@ _M_message(__gnu_debug::__msg_valid_load_factor) \ ._M_sequence(*this, "this")) -#define __glibcxx_check_equal_allocs(_Other) \ +#define __glibcxx_check_equal_allocs(_Other) \ _GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \ _M_message(__gnu_debug::__msg_equal_allocs) \ ._M_sequence(*this, "this")) Index: include/debug/list =================================================================== --- include/debug/list (revision 201413) +++ include/debug/list (working copy) @@ -791,4 +791,13 @@ } // namespace __debug } // namespace std +#ifndef _GLIBCXX_DEBUG_PEDANTIC +namespace __gnu_debug +{ + template + struct _Insert_range_from_self_is_safe > + { enum { __value = 1 }; }; +} #endif + +#endif Index: testsuite/util/debug/checks.h =================================================================== --- testsuite/util/debug/checks.h (revision 201413) +++ testsuite/util/debug/checks.h (working copy) @@ -129,7 +129,7 @@ c2.assign(last, first); // Expected failure } - // Check that invalid range of debug !random debug iterators is detected + // Check that invalid range of debug not random iterators is detected template void check_assign3() @@ -377,6 +377,34 @@ } template + void + check_insert4() + { + bool test __attribute__((unused)) = true; + + typedef _Tp cont_type; + typedef typename cont_type::value_type cont_val_type; + typedef typename CopyableValueType::value_type val_type; + typedef std::list list_type; + + generate_unique gu; + + list_type l; + for (int i = 0; i != 5; ++i) + l.push_back(gu.build()); + VERIFY(l.size() == 5); + + typename list_type::iterator first = l.begin(); ++first; + typename list_type::iterator last = first; ++last; ++last; + + cont_type c1; + InsertRangeHelper::Insert(c1, l.begin(), l.end()); + VERIFY(c1.size() == 5); + + c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure. + } + + template void use_invalid_iterator() { bool test __attribute__((unused)) = true; Index: testsuite/23_containers/vector/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,33 @@ +// Copyright (C) 2013 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-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_insert4 >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/vector/debug/insert6_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/insert6_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/insert6_neg.cc (revision 0) @@ -0,0 +1,48 @@ +// Copyright (C) 2013 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 { xfail *-*-* } } + +#include +#include +#include + +void test01() +{ + std::vector v; + __gnu_debug::vector dv; + for (int i = 0; i != 10; ++i) + { + v.push_back((i % 2) != 0); + dv.push_back((i % 2) == 0); + } + + dv.insert(dv.begin(), v.begin(), v.begin() + 5); + VERIFY( dv.size() == 15 ); +} + +void test02() +{ + __gnu_test::check_insert4<__gnu_debug::vector >(); +} + +int main() +{ + test01(); + test02(); + return 0; +} Index: testsuite/23_containers/vector/debug/57779_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/57779_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/57779_neg.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2013 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" } +// { dg-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + std::vector v; + for (int i = 0; i != 10; ++i) + v.push_back(i); + + v.insert(v.begin(), v.data() + 1, v.data() + 5); // Expected failure +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/deque/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/deque/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/deque/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,33 @@ +// Copyright (C) 2013 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-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_insert4 >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/list/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/list/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/list/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,34 @@ +// Copyright (C) 2013 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-require-debug-mode "" } +// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + __gnu_test::check_insert4 >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/forward_list/debug/insert_after4_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/insert_after4_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/insert_after4_neg.cc (revision 0) @@ -0,0 +1,35 @@ +// Copyright (C) 2013 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-require-debug-mode "" } +// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG_PEDANTIC" } +// { dg-do run { xfail *-*-* } } + +#include +#include + +void test01() +{ + std::forward_list fl{ 1, 2, 3 }; + fl.insert_after(fl.before_begin(), fl.begin(), std::next(fl.begin(), 2)); +} + +int main() +{ + test01(); + return 0; +} Index: src/c++11/debug.cc =================================================================== --- src/c++11/debug.cc (revision 201413) +++ src/c++11/debug.cc (working copy) @@ -181,7 +181,8 @@ "attempt to access container with out-of-bounds bucket index %2;," " container only holds %3; buckets", "load factor shall be positive", - "allocators must be equal" + "allocators must be equal", + "attempt to insert with an iterator range [%1.name;, %2.name;) from this container" }; void @@ -695,7 +696,7 @@ } __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n", - _M_variant._M_sequence._M_address); + _M_variant._M_iterator._M_sequence); __formatter->_M_print_word(__buf); } __formatter->_M_print_word("}\n"); @@ -808,8 +809,11 @@ if (__length == 0) return; - if ((_M_column + __length < _M_max_length) - || (__length >= _M_max_length && _M_column == 1)) + size_t __visual_length + = __word[__length - 1] == '\n' ? __length - 1 : __length; + if (__visual_length == 0 + || (_M_column + __visual_length < _M_max_length) + || (__visual_length >= _M_max_length && _M_column == 1)) { // If this isn't the first line, indent if (_M_column == 1 && !_M_first_line) @@ -823,17 +827,17 @@ } fprintf(stderr, "%s", __word); - _M_column += __length; if (__word[__length - 1] == '\n') { _M_first_line = false; _M_column = 1; } + else + _M_column += __length; } else { - _M_column = 1; _M_print_word("\n"); _M_print_word(__word); }