From patchwork Mon May 25 13:31:04 2015 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: 476210 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B3DDE1402AD for ; Mon, 25 May 2015 23:31:30 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=lp8LPghO; dkim-atps=neutral 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:subject:content-type; q= dns; s=default; b=H+AYjRwUFy4/xx5cqaVHVudij0yI9uNI01o7mkiLFCKwy1 Lq4QJbkMPSFdWmOLF1QyfP3AVt/JBZCdUHSaS3oQJVYRIGtEKGstLGAKSkGWL7IL z2j6Q0WHqNUDrUzezEA+PaZfslq2EcSJHV28UnwsnH7zzGcR1KvosBulurt/w= 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:subject:content-type; s= default; bh=BXA4CYjiTZg+btVCtCHCEa6AoRQ=; b=lp8LPghOXP2u5JJVPhzk 1gwP6BKJIJb/P8kINtcwEOlQrmu5sIVDXA2W2z763apJBtDbhHUbpSEhqLRPWNXh 8uYwBHF/hQUmZN6bMJ2ShYOSVJu1jPzqNxQqkijJWg14hEN9lLExlllCUJNSCyI4 e9Hfp5Pkcxc6/pOl0uwytAA= Received: (qmail 31264 invoked by alias); 25 May 2015 13:31:21 -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 31245 invoked by uid 89); 25 May 2015 13:31:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.8 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-wg0-f52.google.com Received: from mail-wg0-f52.google.com (HELO mail-wg0-f52.google.com) (74.125.82.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 25 May 2015 13:31:10 +0000 Received: by wgbgq6 with SMTP id gq6so73210652wgb.3; Mon, 25 May 2015 06:31:07 -0700 (PDT) X-Received: by 10.194.122.105 with SMTP id lr9mr40522650wjb.153.1432560667233; Mon, 25 May 2015 06:31:07 -0700 (PDT) Received: from [192.168.0.22] (arf62-1-82-237-250-248.fbx.proxad.net. [82.237.250.248]) by mx.google.com with ESMTPSA id nb9sm11940117wic.10.2015.05.25.06.31.05 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 May 2015 06:31:05 -0700 (PDT) Message-ID: <55632418.6000007@gmail.com> Date: Mon, 25 May 2015 15:31:04 +0200 From: =?UTF-8?B?RnJhbsOnb2lzIER1bW9udA==?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: "libstdc++@gcc.gnu.org" , gcc-patches Subject: debug mode maintenance patch Hi This is a patch to clean the debug mode code. I have introduced a new debug header, assertions.h, so that headers that only need _GLIBCXX_DEBUG_ASSERT do not have to include the big debug.h. I also introduce functions.tcc to isolate implementation of __foreign_iterator which require a number of other headers. I reorganized _Error_formatter. Nested _Parameter is now public like several format methods so that I am able to move some code to debug.cc. I would have needed to export new symbols otherwise. I introduced 2 new type of debug parameters, __instance for any functor, __iterator_value_type to report iterator value_type. I will use those in new debug checks to come. Note that I try to regenerate include/Makefile.in with autoreconf 2.64 but it was producing a lot of modifications in all Makefile.in. Can someone check if those files are up to date ? 2015-02-19 François Dumont * include/debug/debug.h ([_GLIBCXX_DEBUG_ASSERT, _GLIBCXX_DEBUG_PEDASSERT, _GLIBCXX_DEBUG_ONLY]): Move definition... * include/debug/assertions.h: ...here, new. * include/debug/formatter.h (struct _Error_formatter::_Is_iterator_value_type): New. (struct _Error_formatter::_Is_instance): New. (struct _Error_formatter::_Parameter): Make public and not friend anymore. (_Error_formatter::_Parameter::__instance): New _M_kind enum entry. (_Error_formatter::_Parameter::__iterator_value_type): New _M_kind enum entry. (struct _Error_formatter::_Parameter::_Type): New. (struct _Error_formatter::_Parameter::_Instance): New, inherit from latter. (union _Error_formatter::_Parameter::_M_variant): Reorganize. (_Parameter(_Iterator const&, const char*, _Is_iterator)): Make all overloads take iterator through a const reference. (_Parameter(const _Iterator&, const char*, _Is_iterator_value_type)): New. (_Parameter(const _Type&, const char*, _Is_instance)): New. (_Error_formatter::_M_print_type): Delete. (_Error_formatter::_M_iterator_value_type): New. (_Error_formatter::_M_instance): New. * include/debug/functions.h (__foreign_iterator): Move definition... * include/debug/functions.tcc: ...here, new. * include/Makefile.am: Add new above debug files. * include/Makefile.in: Regenerate. * include/debug/safe_iterator.h: Replace debug.h include with assertions.h. (__check_dereferenceable, __valid_range): Move here overload for _Safe_iterator. (struct __is_safe_random_iterator): Move here partial specialization for _Safe_iterator. (__check_singular_aux): Move... * include/debug/safe_base.h (__check_singular_aux): ... here. * include/debug/safe_local_iterator.h (__check_dereferenceable) (__valid_range): Move here overload for _Safe_local_iterator. * include/debug/safe_sequence.h: Replace debug.h with assertions.h. Remove _Safe_iterator declaration. * include/debug/safe_unordered_container.h: Replace debug.h with assertions.h. * include/debug/array: Replace safe_sequence.h include with formatter.h and macros.h. * include/debug/deque: Include functions.tcc. * include/debug/forward_list: Likewise. * include/debug/list: Likewise. * include/debug/string: Likewise. * include/debug/vector: Likewise. * include/bits/unique_ptr.h: Replace debug.h include with new assertions.h. * include/bits/stl_iterator_base_funcs.h: Likewise. * testsuite/23_containers/array/tuple_interface/get_debug_neg.cc: Adjust dg-error line number. * testsuite/23_containers/array/tuple_interface/ tuple_element_debug_neg.cc: Likewise. * src/c++11/debug.cc: Adapt. Tested under Linux x86_64 debug mode. Will commit in a couple of days if no complain. François Index: include/Makefile.am =================================================================== --- include/Makefile.am (revision 223630) +++ include/Makefile.am (working copy) @@ -759,6 +759,7 @@ debug_builddir = ./debug debug_headers = \ ${debug_srcdir}/array \ + ${debug_srcdir}/assertions.h \ ${debug_srcdir}/bitset \ ${debug_srcdir}/debug.h \ ${debug_srcdir}/deque \ @@ -765,6 +766,7 @@ ${debug_srcdir}/formatter.h \ ${debug_srcdir}/forward_list \ ${debug_srcdir}/functions.h \ + ${debug_srcdir}/functions.tcc \ ${debug_srcdir}/list \ ${debug_srcdir}/map \ ${debug_srcdir}/macros.h \ Index: include/Makefile.in =================================================================== --- include/Makefile.in (revision 223630) +++ include/Makefile.in (working copy) @@ -1040,6 +1040,7 @@ debug_builddir = ./debug debug_headers = \ ${debug_srcdir}/array \ + ${debug_srcdir}/assertions.h \ ${debug_srcdir}/bitset \ ${debug_srcdir}/debug.h \ ${debug_srcdir}/deque \ @@ -1046,6 +1047,7 @@ ${debug_srcdir}/formatter.h \ ${debug_srcdir}/forward_list \ ${debug_srcdir}/functions.h \ + ${debug_srcdir}/functions.tcc \ ${debug_srcdir}/list \ ${debug_srcdir}/map \ ${debug_srcdir}/macros.h \ Index: include/bits/stl_iterator_base_funcs.h =================================================================== --- include/bits/stl_iterator_base_funcs.h (revision 223630) +++ include/bits/stl_iterator_base_funcs.h (working copy) @@ -62,7 +62,7 @@ #pragma GCC system_header #include -#include +#include namespace std _GLIBCXX_VISIBILITY(default) { Index: include/bits/unique_ptr.h =================================================================== --- include/bits/unique_ptr.h (revision 223630) +++ include/bits/unique_ptr.h (working copy) @@ -31,7 +31,7 @@ #define _UNIQUE_PTR_H 1 #include -#include +#include #include #include #include Index: include/debug/array =================================================================== --- include/debug/array (revision 223630) +++ include/debug/array (working copy) @@ -31,7 +31,8 @@ #pragma GCC system_header -#include +#include +#include namespace std _GLIBCXX_VISIBILITY(default) { Index: include/debug/assertions.h =================================================================== --- include/debug/assertions.h (revision 0) +++ include/debug/assertions.h (working copy) @@ -0,0 +1,52 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2015 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file debug/assertions.h + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_ASSERTIONS_H +#define _GLIBCXX_DEBUG_ASSERTIONS_H 1 + +#ifndef _GLIBCXX_DEBUG + +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +# define _GLIBCXX_DEBUG_ONLY(_Statement) ; + +#else + +#define _GLIBCXX_DEBUG_ASSERT(_Condition) __glibcxx_assert(_Condition) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition) +#else +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +#endif + +# define _GLIBCXX_DEBUG_ONLY(_Statement) _Statement + +#endif + +#endif // _GLIBCXX_DEBUG_ASSERTIONS Index: include/debug/debug.h =================================================================== --- include/debug/debug.h (revision 223630) +++ include/debug/debug.h (working copy) @@ -37,6 +37,8 @@ * the standard library algorithms. */ +#include + // Debug mode namespaces. /** @@ -58,9 +60,6 @@ #ifndef _GLIBCXX_DEBUG -# define _GLIBCXX_DEBUG_ASSERT(_Condition) -# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) -# define _GLIBCXX_DEBUG_ONLY(_Statement) ; # define __glibcxx_requires_cond(_Cond,_Msg) # define __glibcxx_requires_valid_range(_First,_Last) # define __glibcxx_requires_non_empty_range(_First,_Last) @@ -83,16 +82,6 @@ # include -#define _GLIBCXX_DEBUG_ASSERT(_Condition) __glibcxx_assert(_Condition) - -#ifdef _GLIBCXX_DEBUG_PEDANTIC -# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition) -#else -# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) -#endif - -# define _GLIBCXX_DEBUG_ONLY(_Statement) _Statement - # define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) # define __glibcxx_requires_valid_range(_First,_Last) \ __glibcxx_check_valid_range(_First,_Last) Index: include/debug/deque =================================================================== --- include/debug/deque (revision 223630) +++ include/debug/deque (working copy) @@ -636,4 +636,6 @@ } // namespace __debug } // namespace std +#include + #endif Index: include/debug/formatter.h =================================================================== --- include/debug/formatter.h (revision 223630) +++ include/debug/formatter.h (working copy) @@ -154,8 +154,11 @@ // Tags denoting the type of parameter for construction struct _Is_iterator { }; + struct _Is_iterator_value_type { }; struct _Is_sequence { }; + struct _Is_instance { }; + public: // A parameter that may be referenced by an error message struct _Parameter { @@ -165,17 +168,27 @@ __iterator, __sequence, __integer, - __string + __string, + __instance, + __iterator_value_type } _M_kind; + struct _Type + { + const char* _M_name; + const type_info* _M_type; + }; + + struct _Instance : _Type + { + const void* _M_address; + }; + union { // When _M_kind == __iterator - struct + struct : _Instance { - const char* _M_name; - const void* _M_address; - const type_info* _M_type; _Constness _M_constness; _Iterator_state _M_state; const void* _M_sequence; @@ -183,12 +196,7 @@ } _M_iterator; // When _M_kind == __sequence - struct - { - const char* _M_name; - const void* _M_address; - const type_info* _M_type; - } _M_sequence; + _Instance _M_sequence; // When _M_kind == __integer struct @@ -203,6 +211,12 @@ const char* _M_name; const char* _M_value; } _M_string; + + // When _M_kind == __instance + _Instance _M_instance; + + // When _M_kind == __iterator_value_type + _Type _M_iterator_value_type; } _M_variant; _Parameter() : _M_kind(__unused_param), _M_variant() { } @@ -222,7 +236,7 @@ } template - _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it, + _Parameter(_Safe_iterator<_Iterator, _Sequence> const& __it, const char* __name, _Is_iterator) : _M_kind(__iterator), _M_variant() { @@ -252,7 +266,7 @@ } template - _Parameter(const _Safe_local_iterator<_Iterator, _Sequence>& __it, + _Parameter(_Safe_local_iterator<_Iterator, _Sequence> const& __it, const char* __name, _Is_iterator) : _M_kind(__iterator), _M_variant() { @@ -280,33 +294,33 @@ } template - _Parameter(const _Type*& __it, const char* __name, _Is_iterator) + _Parameter(const _Type* const& __it, const char* __name, _Is_iterator) : _M_kind(__iterator), _M_variant() { _M_variant._M_iterator._M_name = __name; _M_variant._M_iterator._M_address = &__it; _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it); - _M_variant._M_iterator._M_constness = __mutable_iterator; - _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_constness = __const_iterator; + _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular; _M_variant._M_iterator._M_sequence = 0; _M_variant._M_iterator._M_seq_type = 0; } template - _Parameter(_Type*& __it, const char* __name, _Is_iterator) + _Parameter(_Type* const& __it, const char* __name, _Is_iterator) : _M_kind(__iterator), _M_variant() { _M_variant._M_iterator._M_name = __name; _M_variant._M_iterator._M_address = &__it; _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it); - _M_variant._M_iterator._M_constness = __const_iterator; - _M_variant._M_iterator._M_state = __it? __unknown_state : __singular; + _M_variant._M_iterator._M_constness = __mutable_iterator; + _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular; _M_variant._M_iterator._M_sequence = 0; _M_variant._M_iterator._M_seq_type = 0; } template - _Parameter(const _Iterator& __it, const char* __name, _Is_iterator) + _Parameter(_Iterator const& __it, const char* __name, _Is_iterator) : _M_kind(__iterator), _M_variant() { _M_variant._M_iterator._M_name = __name; @@ -314,7 +328,7 @@ _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it); _M_variant._M_iterator._M_constness = __unknown_constness; _M_variant._M_iterator._M_state = - __gnu_debug::__check_singular(__it)? __singular : __unknown_state; + __gnu_debug::__check_singular(__it) ? __singular : __unknown_state; _M_variant._M_iterator._M_sequence = 0; _M_variant._M_iterator._M_seq_type = 0; } @@ -339,6 +353,25 @@ _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence); } + template + _Parameter(const _Iterator& __it, const char* __name, + _Is_iterator_value_type) + : _M_kind(__iterator_value_type), _M_variant() + { + _M_variant._M_iterator_value_type._M_name = __name; + _M_variant._M_iterator_value_type._M_type = + _GLIBCXX_TYPEID(typename std::iterator_traits<_Iterator>::value_type); + } + + template + _Parameter(const _Type& __inst, const char* __name, _Is_instance) + : _M_kind(__instance), _M_variant() + { + _M_variant._M_instance._M_name = __name; + _M_variant._M_instance._M_address = &__inst; + _M_variant._M_instance._M_type = _GLIBCXX_TYPEID(_Type); + } + void _M_print_field(const _Error_formatter* __formatter, const char* __name) const; @@ -347,9 +380,6 @@ _M_print_description(const _Error_formatter* __formatter) const; }; - friend struct _Parameter; - - public: template const _Error_formatter& _M_iterator(const _Iterator& __it, const char* __name = 0) const @@ -360,6 +390,17 @@ return *this; } + template + const _Error_formatter& + _M_iterator_value_type(const _Iterator& __it, + const char* __name = 0) const + { + if (_M_num_parameters < std::size_t(__max_parameters)) + _M_parameters[_M_num_parameters++] = + _Parameter(__it, __name, _Is_iterator_value_type()); + return *this; + } + const _Error_formatter& _M_integer(long __value, const char* __name = 0) const { @@ -386,6 +427,16 @@ return *this; } + template + const _Error_formatter& + _M_instance(const _Type& __inst, const char* __name = 0) const + { + if (_M_num_parameters < std::size_t(__max_parameters)) + _M_parameters[_M_num_parameters++] = _Parameter(__inst, __name, + _Is_instance()); + return *this; + } + const _Error_formatter& _M_message(const char* __text) const { _M_text = __text; return *this; } @@ -396,12 +447,6 @@ _GLIBCXX_NORETURN void _M_error() const; - private: - _Error_formatter(const char* __file, std::size_t __line) - : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), - _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) - { _M_get_max_length(); } - template void _M_format_word(char*, int, const char*, _Tp) const throw (); @@ -412,9 +457,11 @@ void _M_print_string(const char* __string) const; - void - _M_print_type(const type_info* __info, - const char* __unknown_name) const; + private: + _Error_formatter(const char* __file, std::size_t __line) + : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0), + _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false) + { _M_get_max_length(); } void _M_get_max_length() const throw (); Index: include/debug/forward_list =================================================================== --- include/debug/forward_list (revision 223630) +++ include/debug/forward_list (working copy) @@ -824,4 +824,6 @@ #endif } +#include + #endif Index: include/debug/functions.h =================================================================== --- include/debug/functions.h (revision 223630) +++ include/debug/functions.h (working copy) @@ -33,11 +33,7 @@ #include // for iterator_traits, categories and // _Iter_base #include // for __is_integer -#include // for __addressof and addressof -#include // for less -#if __cplusplus >= 201103L -# include // for is_lvalue_reference and __and_ -#endif + #include namespace __gnu_debug @@ -45,9 +41,6 @@ template class _Safe_iterator; - template - class _Safe_local_iterator; - template struct _Insert_range_from_self_is_safe { enum { __value = 0 }; }; @@ -85,19 +78,6 @@ __check_dereferenceable(const _Tp* __ptr) { return __ptr; } - /** Safe iterators know if they are dereferenceable. */ - template - inline bool - __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) - { return __x._M_dereferenceable(); } - - /** Safe local iterators know if they are dereferenceable. */ - template - inline bool - __check_dereferenceable(const _Safe_local_iterator<_Iterator, - _Sequence>& __x) - { return __x._M_dereferenceable(); } - /** If the distance between two random access iterators is * nonnegative, assume the range is valid. */ @@ -150,20 +130,6 @@ return __valid_range_aux(__first, __last, _Integral()); } - /** Safe iterators know how to check if they form a valid range. */ - template - inline bool - __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, - const _Safe_iterator<_Iterator, _Sequence>& __last) - { return __first._M_valid_range(__last); } - - /** Safe local iterators know how to check if they form a valid range. */ - template - inline bool - __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first, - const _Safe_local_iterator<_Iterator, _Sequence>& __last) - { return __first._M_valid_range(__last); } - /* Checks that [first, last) is a valid range, and then returns * __first. This routine is useful when we can't use a separate * assertion statement because, e.g., we are in a constructor. @@ -178,121 +144,11 @@ return __first; } - /* Handle the case where __other is a pointer to _Sequence::value_type. */ - template - inline bool - __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it, - const typename _Sequence::value_type* __other) - { - typedef const typename _Sequence::value_type* _PointerType; - typedef std::less<_PointerType> _Less; -#if __cplusplus >= 201103L - constexpr _Less __l{}; -#else - const _Less __l = _Less(); -#endif - const _Sequence* __seq = __it._M_get_sequence(); - const _PointerType __begin = std::__addressof(*__seq->_M_base().begin()); - const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1)); - - // Check whether __other points within the contiguous storage. - return __l(__other, __begin) || __l(__end, __other); - } - - /* Fallback overload for when we can't tell, assume it is valid. */ - template - inline bool - __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&, ...) - { return true; } - - /* Handle sequences with contiguous storage */ - template - inline bool - __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, - const _InputIterator& __other, - const _InputIterator& __other_end, - std::__true_type) - { - if (__other == __other_end) - return true; // inserting nothing is safe even if not foreign iters - if (__it._M_get_sequence()->begin() == __it._M_get_sequence()->end()) - return true; // can't be self-inserting if self is empty - return __foreign_iterator_aux4(__it, std::__addressof(*__other)); - } - - /* Handle non-contiguous containers, assume it is valid. */ - template - inline bool - __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>&, - const _InputIterator&, const _InputIterator&, - std::__false_type) - { return true; } - - /** Handle debug iterators from the same type of container. */ - template - inline bool - __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, - const _Safe_iterator<_OtherIterator, _Sequence>& __other, - const _Safe_iterator<_OtherIterator, _Sequence>&) - { return __it._M_get_sequence() != __other._M_get_sequence(); } - - /** Handle debug iterators from different types of container. */ - template - inline bool - __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, - const _Safe_iterator<_OtherIterator, _OtherSequence>&, - const _Safe_iterator<_OtherIterator, _OtherSequence>&) - { return true; } - - /* Handle non-debug iterators. */ - template - inline bool - __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, - const _InputIterator& __other, - const _InputIterator& __other_end) - { -#if __cplusplus < 201103L - typedef _Is_contiguous_sequence<_Sequence> __tag; -#else - using __lvalref = std::is_lvalue_reference< - typename std::iterator_traits<_InputIterator>::reference>; - using __contiguous = _Is_contiguous_sequence<_Sequence>; - using __tag = typename std::conditional<__lvalref::value, __contiguous, - std::__false_type>::type; -#endif - return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); - } - - /* Handle the case where we aren't really inserting a range after all */ - template - inline bool - __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>&, - _Integral, _Integral, - std::__true_type) - { return true; } - - /* Handle all iterators. */ template - inline bool - __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, - _InputIterator __other, _InputIterator __other_end, - std::__false_type) - { - return _Insert_range_from_self_is_safe<_Sequence>::__value - || __foreign_iterator_aux2(__it, __other, __other_end); - } - - template - inline bool + bool __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it, - _InputIterator __other, _InputIterator __other_end) - { - typedef typename std::__is_integer<_InputIterator>::__type _Integral; - return __foreign_iterator_aux(__it, __other, __other_end, _Integral()); - } + _InputIterator __other, _InputIterator __other_end); /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ template @@ -535,13 +391,6 @@ typedef std::__false_type __type; }; - template - struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> > - : std::__are_same:: - iterator_category> - { }; - template struct _Siter_base : std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value> Index: include/debug/functions.tcc =================================================================== --- include/debug/functions.tcc (revision 0) +++ include/debug/functions.tcc (working copy) @@ -0,0 +1,159 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2015 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file debug/functions.tcc + * This file is a GNU debug extension to the Standard C++ Library. + */ + +#ifndef _GLIBCXX_DEBUG_FUNCTIONS_TCC +#define _GLIBCXX_DEBUG_FUNCTIONS_TCC 1 + +#include // for __addressof and addressof +#include // for less +#if __cplusplus >= 201103L +# include // for is_lvalue_reference + // conditional. +#endif + +namespace __gnu_debug +{ + /* Handle the case where __other is a pointer to _Sequence::value_type. */ + template + inline bool + __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it, + const typename _Sequence::value_type* __other) + { + typedef const typename _Sequence::value_type* _PointerType; + typedef std::less<_PointerType> _Less; +#if __cplusplus >= 201103L + constexpr _Less __l{}; +#else + const _Less __l = _Less(); +#endif + const _Sequence* __seq = __it._M_get_sequence(); + const _PointerType __begin = std::__addressof(*__seq->_M_base().begin()); + const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1)); + + // Check whether __other points within the contiguous storage. + return __l(__other, __begin) || __l(__end, __other); + } + + /* Fallback overload for when we can't tell, assume it is valid. */ + template + inline bool + __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&, ...) + { return true; } + + /* Handle sequences with contiguous storage */ + template + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, + const _InputIterator& __other, + const _InputIterator& __other_end, + std::__true_type) + { + if (__other == __other_end) + return true; // inserting nothing is safe even if not foreign iters + if (__it._M_get_sequence()->begin() == __it._M_get_sequence()->end()) + return true; // can't be self-inserting if self is empty + return __foreign_iterator_aux4(__it, std::__addressof(*__other)); + } + + /* Handle non-contiguous containers, assume it is valid. */ + template + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>&, + const _InputIterator&, const _InputIterator&, + std::__false_type) + { return true; } + + /** Handle debug iterators from the same type of container. */ + template + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + const _Safe_iterator<_OtherIterator, _Sequence>& __other, + const _Safe_iterator<_OtherIterator, _Sequence>&) + { return __it._M_get_sequence() != __other._M_get_sequence(); } + + /** Handle debug iterators from different types of container. */ + template + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + const _Safe_iterator<_OtherIterator, _OtherSequence>&, + const _Safe_iterator<_OtherIterator, _OtherSequence>&) + { return true; } + + /* Handle non-debug iterators. */ + template + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + const _InputIterator& __other, + const _InputIterator& __other_end) + { +#if __cplusplus < 201103L + typedef _Is_contiguous_sequence<_Sequence> __tag; +#else + using __lvalref = std::is_lvalue_reference< + typename std::iterator_traits<_InputIterator>::reference>; + using __contiguous = _Is_contiguous_sequence<_Sequence>; + using __tag = typename std::conditional<__lvalref::value, __contiguous, + std::__false_type>::type; +#endif + return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); + } + + /* Handle the case where we aren't really inserting a range after all */ + template + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>&, + _Integral, _Integral, + std::__true_type) + { return true; } + + /* Handle all iterators. */ + template + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, _InputIterator __other_end, + std::__false_type) + { + return _Insert_range_from_self_is_safe<_Sequence>::__value + || __foreign_iterator_aux2(__it, __other, __other_end); + } + + template + inline bool + __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, _InputIterator __other_end) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return __foreign_iterator_aux(__it, __other, __other_end, _Integral()); + } + +} // namespace __gnu_debug + +#endif Index: include/debug/list =================================================================== --- include/debug/list (revision 223630) +++ include/debug/list (working copy) @@ -797,4 +797,6 @@ } #endif +#include + #endif Index: include/debug/safe_base.h =================================================================== --- include/debug/safe_base.h (revision 223630) +++ include/debug/safe_base.h (working copy) @@ -159,6 +159,13 @@ } }; + /** Iterators that derive from _Safe_iterator_base can be determined singular + * or non-singular. + **/ + inline bool + __check_singular_aux(const _Safe_iterator_base* __x) + { return __x->_M_singular(); } + /** * @brief Base class that supports tracking of iterators that * reference a sequence. Index: include/debug/safe_iterator.h =================================================================== --- include/debug/safe_iterator.h (revision 223630) +++ include/debug/safe_iterator.h (working copy) @@ -29,7 +29,7 @@ #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 -#include +#include #include #include #include @@ -55,13 +55,6 @@ { return __it.base() == __it._M_get_sequence()->_M_base().begin(); } }; - /** Iterators that derive from _Safe_iterator_base can be determined singular - * or non-singular. - **/ - inline bool - __check_singular_aux(const _Safe_iterator_base* __x) - { return __x->_M_singular(); } - /** The precision to which we can calculate the distance between * two iterators. */ @@ -93,11 +86,7 @@ inline std::pair::difference_type, _Distance_precision> __get_distance(const _Iterator& __lhs, const _Iterator& __rhs) - { - typedef typename std::iterator_traits<_Iterator>::iterator_category - _Category; - return __get_distance(__lhs, __rhs, _Category()); - } + { return __get_distance(__lhs, __rhs, std::__iterator_category(__lhs)); } /** \brief Safe iterator wrapper. * @@ -768,6 +757,27 @@ operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n, const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT { return __i + __n; } + + /** Safe iterators know if they are dereferenceable. */ + template + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** Safe iterators know how to check if they form a valid range. */ + template + inline bool + __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, + const _Safe_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } + + template + struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> > + : std::__are_same:: + iterator_category> + { }; + } // namespace __gnu_debug #include Index: include/debug/safe_local_iterator.h =================================================================== --- include/debug/safe_local_iterator.h (revision 223630) +++ include/debug/safe_local_iterator.h (working copy) @@ -29,11 +29,7 @@ #ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H #define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 1 -#include -#include -#include #include -#include namespace __gnu_debug { @@ -432,6 +428,20 @@ ._M_iterator(__rhs, "rhs")); return __lhs.base() != __rhs.base(); } + + /** Safe local iterators know if they are dereferenceable. */ + template + inline bool + __check_dereferenceable(const _Safe_local_iterator<_Iterator, + _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** Safe local iterators know how to check if they form a valid range. */ + template + inline bool + __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first, + const _Safe_local_iterator<_Iterator, _Sequence>& __last) + { return __first._M_valid_range(__last); } } // namespace __gnu_debug #include Index: include/debug/safe_sequence.h =================================================================== --- include/debug/safe_sequence.h (revision 223630) +++ include/debug/safe_sequence.h (working copy) @@ -29,7 +29,7 @@ #ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_H #define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 -#include +#include #include #include #include @@ -36,9 +36,6 @@ namespace __gnu_debug { - template - class _Safe_iterator; - /** A simple function object that returns true if the passed-in * value is not equal to the stored value. It saves typing over * using both bind1st and not_equal. Index: include/debug/safe_unordered_container.h =================================================================== --- include/debug/safe_unordered_container.h (revision 223630) +++ include/debug/safe_unordered_container.h (working copy) @@ -29,7 +29,7 @@ #ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H #define _GLIBCXX_DEBUG_SAFE_UNORDERED_CONTAINER_H 1 -#include +#include #include #include #include Index: include/debug/string =================================================================== --- include/debug/string (revision 223630) +++ include/debug/string (working copy) @@ -1158,4 +1158,6 @@ } // namespace __gnu_debug +#include + #endif Index: include/debug/vector =================================================================== --- include/debug/vector (revision 223630) +++ include/debug/vector (working copy) @@ -742,8 +742,7 @@ { size_t operator()(const __debug::vector& __b) const noexcept - { return std::hash<_GLIBCXX_STD_C::vector>() - (__b._M_base()); } + { return std::hash<_GLIBCXX_STD_C::vector>()(__b); } }; #endif @@ -762,4 +761,6 @@ { }; } +#include + #endif Index: src/c++11/debug.cc =================================================================== --- src/c++11/debug.cc (revision 223630) +++ src/c++11/debug.cc (working copy) @@ -519,8 +519,123 @@ if (_M_local_iterators == __it) _M_local_iterators = __it->_M_next; } +} +namespace +{ void + print_type(const __gnu_debug::_Error_formatter* __formatter, + const type_info* __info, + const char* __unknown_name) + { + if (!__info) + __formatter->_M_print_word(__unknown_name); + else + { + int __status; + char* __demangled_name = + __cxxabiv1::__cxa_demangle(__info->name(), NULL, NULL, &__status); + __formatter->_M_print_word(__status == 0 + ? __demangled_name : __info->name()); + free(__demangled_name); + } + } + + bool + print_field( + const __gnu_debug::_Error_formatter* __formatter, + const char* __name, + const __gnu_debug::_Error_formatter::_Parameter::_Type& __variant) + { + if (strcmp(__name, "name") == 0) + { + assert(__variant._M_name); + __formatter->_M_print_word(__variant._M_name); + } + else if (strcmp(__name, "type") == 0) + print_type(__formatter, __variant._M_type, ""); + else + return false; + + return true; + } + + bool + print_field( + const __gnu_debug::_Error_formatter* __formatter, + const char* __name, + const __gnu_debug::_Error_formatter::_Parameter::_Instance& __variant) + { + const __gnu_debug::_Error_formatter::_Parameter::_Type& __type = __variant; + if (print_field(__formatter, __name, __type)) + { } + else if (strcmp(__name, "address") == 0) + { + const int __bufsize = 64; + char __buf[__bufsize]; + __formatter->_M_format_word(__buf, __bufsize, "%p", + __variant._M_address); + __formatter->_M_print_word(__buf); + } + else + return false; + + return true; + } + + void + print_description( + const __gnu_debug::_Error_formatter* __formatter, + const __gnu_debug::_Error_formatter::_Parameter::_Type& __variant) + { + if (__variant._M_name) + { + const int __bufsize = 64; + char __buf[__bufsize]; + __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", + __variant._M_name); + __formatter->_M_print_word(__buf); + } + + if (__variant._M_type) + { + __formatter->_M_print_word(" type = "); + print_type(__formatter, __variant._M_type, ""); + __formatter->_M_print_word(";\n"); + } + } + + + void + print_description( + const __gnu_debug::_Error_formatter* __formatter, + const __gnu_debug::_Error_formatter::_Parameter::_Instance& __variant) + { + const int __bufsize = 64; + char __buf[__bufsize]; + + if (__variant._M_name) + { + __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", + __variant._M_name); + __formatter->_M_print_word(__buf); + } + + __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", + __variant._M_address); + __formatter->_M_print_word(__buf); + + if (__variant._M_type) + { + __formatter->_M_print_word(" type = "); + print_type(__formatter, __variant._M_type, ""); + } + } +} + +namespace __gnu_debug +{ + void _Error_formatter::_Parameter:: _M_print_field(const _Error_formatter* __formatter, const char* __name) const { @@ -531,20 +646,8 @@ switch (_M_kind) { case __iterator: - if (strcmp(__name, "name") == 0) - { - assert(_M_variant._M_iterator._M_name); - __formatter->_M_print_word(_M_variant._M_iterator._M_name); - } - else if (strcmp(__name, "address") == 0) - { - __formatter->_M_format_word(__buf, __bufsize, "%p", - _M_variant._M_iterator._M_address); - __formatter->_M_print_word(__buf); - } - else if (strcmp(__name, "type") == 0) - __formatter->_M_print_type(_M_variant._M_iterator._M_type, - ""); + if (print_field(__formatter, __name, _M_variant._M_iterator)) + { } else if (strcmp(__name, "constness") == 0) { static const char* __constness_names[__last_constness] = @@ -579,28 +682,13 @@ __formatter->_M_print_word(__buf); } else if (strcmp(__name, "seq_type") == 0) - __formatter->_M_print_type(_M_variant._M_iterator._M_seq_type, - ""); + print_type(__formatter, _M_variant._M_iterator._M_seq_type, + ""); else assert(false); break; case __sequence: - if (strcmp(__name, "name") == 0) - { - assert(_M_variant._M_sequence._M_name); - __formatter->_M_print_word(_M_variant._M_sequence._M_name); - } - else if (strcmp(__name, "address") == 0) - { - assert(_M_variant._M_sequence._M_address); - __formatter->_M_format_word(__buf, __bufsize, "%p", - _M_variant._M_sequence._M_address); - __formatter->_M_print_word(__buf); - } - else if (strcmp(__name, "type") == 0) - __formatter->_M_print_type(_M_variant._M_sequence._M_type, - ""); - else + if (!print_field(__formatter, __name, _M_variant._M_sequence)) assert(false); break; case __integer: @@ -621,6 +709,14 @@ else assert(false); break; + case __instance: + if (!print_field(__formatter, __name, _M_variant._M_instance)) + assert(false); + break; + case __iterator_value_type: + if (!print_field(__formatter, __name, _M_variant._M_iterator_value_type)) + assert(false); + break; default: assert(false); break; @@ -638,21 +734,10 @@ { case __iterator: __formatter->_M_print_word("iterator "); - if (_M_variant._M_iterator._M_name) - { - __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", - _M_variant._M_iterator._M_name); - __formatter->_M_print_word(__buf); - } + print_description(__formatter, _M_variant._M_iterator); - __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", - _M_variant._M_iterator._M_address); - __formatter->_M_print_word(__buf); if (_M_variant._M_iterator._M_type) { - __formatter->_M_print_word("type = "); - _M_print_field(__formatter, "type"); - if (_M_variant._M_iterator._M_constness != __unknown_constness) { __formatter->_M_print_word(" ("); @@ -687,25 +772,25 @@ break; case __sequence: __formatter->_M_print_word("sequence "); - if (_M_variant._M_sequence._M_name) - { - __formatter->_M_format_word(__buf, __bufsize, "\"%s\" ", - _M_variant._M_sequence._M_name); - __formatter->_M_print_word(__buf); - } + print_description(__formatter, _M_variant._M_sequence); - __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p {\n", - _M_variant._M_sequence._M_address); - __formatter->_M_print_word(__buf); + if (_M_variant._M_sequence._M_type) + __formatter->_M_print_word(";\n"); - if (_M_variant._M_sequence._M_type) - { - __formatter->_M_print_word(" type = "); - _M_print_field(__formatter, "type"); - __formatter->_M_print_word(";\n"); - } __formatter->_M_print_word("}\n"); break; + case __instance: + __formatter->_M_print_word("instance "); + print_description(__formatter, _M_variant._M_instance); + + if (_M_variant._M_instance._M_type) + __formatter->_M_print_word(";\n"); + + break; + case __iterator_value_type: + __formatter->_M_print_word("iterator::value_type "); + print_description(__formatter, _M_variant._M_iterator_value_type); + break; default: break; } @@ -756,6 +841,8 @@ { case _Parameter::__iterator: case _Parameter::__sequence: + case _Parameter::__instance: + case _Parameter::__iterator_value_type: if (!__has_noninteger_parameters) { _M_first_line = true; @@ -879,9 +966,9 @@ // Get the parameter number assert(*__start >= '1' && *__start <= '9'); - size_t __param = *__start - '0'; - --__param; - assert(__param < _M_num_parameters); + size_t __param_index = *__start - '0' - 1; + assert(__param_index < _M_num_parameters); + const auto& __param = _M_parameters[__param_index]; // '.' separates the parameter number from the field // name, if there is one. @@ -891,14 +978,14 @@ assert(*__start == ';'); ++__start; __buf[0] = '\0'; - if (_M_parameters[__param]._M_kind == _Parameter::__integer) + if (__param._M_kind == _Parameter::__integer) { _M_format_word(__buf, __bufsize, "%ld", - _M_parameters[__param]._M_variant._M_integer._M_value); + __param._M_variant._M_integer._M_value); _M_print_word(__buf); } - else if (_M_parameters[__param]._M_kind == _Parameter::__string) - _M_print_string(_M_parameters[__param]._M_variant._M_string._M_value); + else if (__param._M_kind == _Parameter::__string) + _M_print_string(__param._M_variant._M_string._M_value); continue; } @@ -916,27 +1003,11 @@ ++__start; __field[__field_idx] = 0; - _M_parameters[__param]._M_print_field(this, __field); + __param._M_print_field(this, __field); } } void - _Error_formatter::_M_print_type(const type_info* __info, - const char* __unknown_name) const - { - if (!__info) - _M_print_word(__unknown_name); - else - { - int __status; - char* __demangled_name = - __cxxabiv1::__cxa_demangle(__info->name(), NULL, NULL, &__status); - _M_print_word(__status == 0 ? __demangled_name : __info->name()); - free(__demangled_name); - } - } - - void _Error_formatter::_M_get_max_length() const throw () { const char* __nptr = std::getenv("GLIBCXX_DEBUG_MESSAGE_LENGTH"); Index: testsuite/23_containers/array/tuple_interface/get_debug_neg.cc =================================================================== --- testsuite/23_containers/array/tuple_interface/get_debug_neg.cc (revision 223630) +++ testsuite/23_containers/array/tuple_interface/get_debug_neg.cc (working copy) @@ -28,6 +28,6 @@ int n2 = std::get<1>(std::move(a)); int n3 = std::get<1>(ca); -// { dg-error "static assertion failed" "" { target *-*-* } 271 } -// { dg-error "static assertion failed" "" { target *-*-* } 280 } -// { dg-error "static assertion failed" "" { target *-*-* } 288 } +// { dg-error "static assertion failed" "" { target *-*-* } 272 } +// { dg-error "static assertion failed" "" { target *-*-* } 281 } +// { dg-error "static assertion failed" "" { target *-*-* } 289 } Index: testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc =================================================================== --- testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc (revision 223630) +++ testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc (working copy) @@ -23,4 +23,4 @@ typedef std::tuple_element<1, std::array>::type type; -// { dg-error "static assertion failed" "" { target *-*-* } 305 } +// { dg-error "static assertion failed" "" { target *-*-* } 306 }