From d2763ab5f180a4e22cc7d05c84a3728e89ced2b1 Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Fri, 27 May 2005 15:01:45 +0000 Subject: re PR libstdc++/20534 (Erroneous #include of ) 2005-05-27 Benjamin Kosnik PR libstdc++/20534 * include/debug/debug.h: Forwarding header, that pulls in details only if in debug mode. * include/debug/macros.h: ...transfer all the internal macros here. * include/debug/functions.h: ...transfer all the functions here. * include/debug/safe_iterator.h: Add functions.h, macros.h includes. * include/debug/safe_sequence.h: Same. * include/debug/vector: Tweak. * include/Makefile.am (debug_headers): Add new includes. * include/Makefile.in: Regenerate. * testsuite/17_intro/no_assert_neg.cc: Add. * include/ext/hash_set: Add debug mode include. * include/ext/hash_map: Same. * include/debug/hash_map: Fix included files to match actual files. * include/debug/hash_set: Same. From-SVN: r100255 --- libstdc++-v3/ChangeLog | 19 + libstdc++-v3/include/Makefile.am | 2 + libstdc++-v3/include/Makefile.in | 2 + libstdc++-v3/include/debug/debug.h | 454 +---------------------- libstdc++-v3/include/debug/functions.h | 286 ++++++++++++++ libstdc++-v3/include/debug/hash_map | 8 +- libstdc++-v3/include/debug/hash_set | 8 +- libstdc++-v3/include/debug/macros.h | 219 +++++++++++ libstdc++-v3/include/debug/safe_iterator.h | 7 +- libstdc++-v3/include/debug/safe_sequence.h | 4 +- libstdc++-v3/include/debug/vector | 4 +- libstdc++-v3/include/ext/hash_map | 7 +- libstdc++-v3/include/ext/hash_set | 7 +- libstdc++-v3/testsuite/17_intro/no_assert_neg.cc | 89 +++++ 14 files changed, 657 insertions(+), 459 deletions(-) create mode 100644 libstdc++-v3/include/debug/functions.h create mode 100644 libstdc++-v3/include/debug/macros.h create mode 100644 libstdc++-v3/testsuite/17_intro/no_assert_neg.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6314115..8260302 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2005-05-27 Benjamin Kosnik + + PR libstdc++/20534 + * include/debug/debug.h: Forwarding header, that pulls in details + only if in debug mode. + * include/debug/macros.h: ...transfer all the internal macros here. + * include/debug/functions.h: ...transfer all the functions here. + * include/debug/safe_iterator.h: Add functions.h, macros.h includes. + * include/debug/safe_sequence.h: Same. + * include/debug/vector: Tweak. + * include/Makefile.am (debug_headers): Add new includes. + * include/Makefile.in: Regenerate. + * testsuite/17_intro/no_assert_neg.cc: Add. + + * include/ext/hash_set: Add debug mode include. + * include/ext/hash_map: Same. + * include/debug/hash_map: Fix included files to match actual files. + * include/debug/hash_set: Same. + 2005-05-26 Paolo Carlini PR libstdc++/13943 diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index abd9abf..797afb6 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -321,6 +321,7 @@ debug_headers = \ ${debug_srcdir}/debug.h \ ${debug_srcdir}/deque \ ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/functions.h \ ${debug_srcdir}/hash_map \ ${debug_srcdir}/hash_map.h \ ${debug_srcdir}/hash_multimap.h \ @@ -329,6 +330,7 @@ debug_headers = \ ${debug_srcdir}/hash_set.h \ ${debug_srcdir}/list \ ${debug_srcdir}/map \ + ${debug_srcdir}/macros.h \ ${debug_srcdir}/map.h \ ${debug_srcdir}/multimap.h \ ${debug_srcdir}/multiset.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 60bf72b..253c898 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -538,6 +538,7 @@ debug_headers = \ ${debug_srcdir}/debug.h \ ${debug_srcdir}/deque \ ${debug_srcdir}/formatter.h \ + ${debug_srcdir}/functions.h \ ${debug_srcdir}/hash_map \ ${debug_srcdir}/hash_map.h \ ${debug_srcdir}/hash_multimap.h \ @@ -546,6 +547,7 @@ debug_headers = \ ${debug_srcdir}/hash_set.h \ ${debug_srcdir}/list \ ${debug_srcdir}/map \ + ${debug_srcdir}/macros.h \ ${debug_srcdir}/map.h \ ${debug_srcdir}/multimap.h \ ${debug_srcdir}/multiset.h \ diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h index f371a6a..b4ffb6f 100644 --- a/libstdc++-v3/include/debug/debug.h +++ b/libstdc++-v3/include/debug/debug.h @@ -31,191 +31,6 @@ #ifndef _GLIBCXX_DEBUG_DEBUG_H #define _GLIBCXX_DEBUG_DEBUG_H 1 -/** - * Macros used by the implementation to verify certain - * properties. These macros may only be used directly by the debug - * wrappers. Note that these are macros (instead of the more obviously - * "correct" choice of making them functions) because we need line and - * file information at the call site, to minimize the distance between - * the user error and where the error is reported. - * - */ -#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ - do { \ - if (! (_Condition)) \ - ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ - ._ErrorMessage._M_error(); \ - } while (false) - -// Verify that [_First, _Last) forms a valid iterator range. -#define __glibcxx_check_valid_range(_First,_Last) \ -_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \ - _M_message(::__gnu_debug::__msg_valid_range) \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last)) - -/** Verify that we can insert into *this with the iterator _Position. - * Insertion into a container at a specific position requires that - * the iterator be nonsingular (i.e., either dereferenceable or - * past-the-end) and that it reference the sequence we are inserting - * into. Note that this macro is only valid when the container is a - * _Safe_sequence and the iterator is a _Safe_iterator. -*/ -#define __glibcxx_check_insert(_Position) \ -_GLIBCXX_DEBUG_VERIFY(!_Position._M_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_sequence(*this, "this") \ - ._M_iterator(_Position, #_Position)) - -/** Verify that we can insert the values in the iterator range - * [_First, _Last) into *this with the iterator _Position. Insertion - * into a container at a specific position requires that the iterator - * be nonsingular (i.e., either dereferenceable or past-the-end), - * 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. - * - * @tbd 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. -*/ -#define __glibcxx_check_insert_range(_Position,_First,_Last) \ -__glibcxx_check_valid_range(_First,_Last); \ -_GLIBCXX_DEBUG_VERIFY(!_Position._M_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_sequence(*this, "this") \ - ._M_iterator(_Position, #_Position)) - -/** Verify that we can erase the element referenced by the iterator - * _Position. We can erase the element if the _Position iterator is - * dereferenceable and references this sequence. -*/ -#define __glibcxx_check_erase(_Position) \ -_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ - _M_message(::__gnu_debug::__msg_erase_bad) \ - ._M_sequence(*this, "this") \ - ._M_iterator(_Position, #_Position)); \ -_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ - _M_message(::__gnu_debug::__msg_erase_different) \ - ._M_sequence(*this, "this") \ - ._M_iterator(_Position, #_Position)) - -/** Verify that we can erase the elements in the iterator range - * [_First, _Last). We can erase the elements if [_First, _Last) is a - * valid iterator range within this sequence. -*/ -#define __glibcxx_check_erase_range(_First,_Last) \ -__glibcxx_check_valid_range(_First,_Last); \ -_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ - _M_message(::__gnu_debug::__msg_erase_different) \ - ._M_sequence(*this, "this") \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last)) - -// Verify that the subscript _N is less than the container's size. -#define __glibcxx_check_subscript(_N) \ -_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ - _M_message(::__gnu_debug::__msg_subscript_oob) \ - ._M_sequence(*this, "this") \ - ._M_integer(_N, #_N) \ - ._M_integer(this->size(), "size")) - -// Verify that the container is nonempty -#define __glibcxx_check_nonempty() \ -_GLIBCXX_DEBUG_VERIFY(! this->empty(), \ - _M_message(::__gnu_debug::__msg_empty) \ - ._M_sequence(*this, "this")) - -// Verify that the < operator for elements in the sequence is a -// StrictWeakOrdering by checking that it is irreflexive. -#define __glibcxx_check_strict_weak_ordering(_First,_Last) \ -_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) - -// Verify that the predicate is StrictWeakOrdering by checking that it -// is irreflexive. -#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ -_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) - - -// Verify that the iterator range [_First, _Last) is sorted -#define __glibcxx_check_sorted(_First,_Last) \ -__glibcxx_check_valid_range(_First,_Last); \ -__glibcxx_check_strict_weak_ordering(_First,_Last); \ -_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \ - _M_message(::__gnu_debug::__msg_unsorted) \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last)) - -/** Verify that the iterator range [_First, _Last) is sorted by the - predicate _Pred. */ -#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ -__glibcxx_check_valid_range(_First,_Last); \ -__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ -_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \ - _M_message(::__gnu_debug::__msg_unsorted_pred) \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last) \ - ._M_string(#_Pred)) - -/** Verify that the iterator range [_First, _Last) is partitioned - w.r.t. the value _Value. */ -#define __glibcxx_check_partitioned(_First,_Last,_Value) \ -__glibcxx_check_valid_range(_First,_Last); \ -_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ - _Value), \ - _M_message(::__gnu_debug::__msg_unpartitioned) \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last) \ - ._M_string(#_Value)) - -/** Verify that the iterator range [_First, _Last) is partitioned - w.r.t. the value _Value and predicate _Pred. */ -#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ -__glibcxx_check_valid_range(_First,_Last); \ -_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ - _Value, _Pred), \ - _M_message(::__gnu_debug::__msg_unpartitioned_pred) \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last) \ - ._M_string(#_Pred) \ - ._M_string(#_Value)) - -// Verify that the iterator range [_First, _Last) is a heap -#define __glibcxx_check_heap(_First,_Last) \ -__glibcxx_check_valid_range(_First,_Last); \ -_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \ - _M_message(::__gnu_debug::__msg_not_heap) \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last)) - -/** Verify that the iterator range [_First, _Last) is a heap - w.r.t. the predicate _Pred. */ -#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ -__glibcxx_check_valid_range(_First,_Last); \ -_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ - _M_message(::__gnu_debug::__msg_not_heap_pred) \ - ._M_iterator(_First, #_First) \ - ._M_iterator(_Last, #_Last) \ - ._M_string(#_Pred)) - -#ifdef _GLIBCXX_DEBUG_PEDANTIC -# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) -# define __glibcxx_check_string_len(_String,_Len) \ - _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) -#else -# define __glibcxx_check_string(_String) -# define __glibcxx_check_string_len(_String,_Len) -#endif - /** Macros used by the implementation outside of debug wrappers to * verify certain properties. The __glibcxx_requires_xxx macros are * merely wrappers around the __glibcxx_check_xxx wrappers when we @@ -223,7 +38,14 @@ _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ * release mode so that there is no checking performed in, e.g., the * standard library algorithms. */ + #ifdef _GLIBCXX_DEBUG +# include + +// The debug mode requires assert functionality, but keep this include +// conditionalized, so that non-debug use doesn't mandate exposure to the +// assert macro. +# include # define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition) # ifdef _GLIBCXX_DEBUG_PEDANTIC @@ -252,6 +74,9 @@ _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ # define __glibcxx_requires_string_len(_String,_Len) \ __glibcxx_check_string_len(_String,_Len) # define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N) + +# include +# include #else # define _GLIBCXX_DEBUG_ASSERT(_Condition) # define _GLIBCXX_DEBUG_PEDASSERT(_Condition) @@ -269,263 +94,4 @@ _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ # define __glibcxx_requires_subscript(_N) #endif -#include // TBD: temporary - -#include // for ptrdiff_t -#include // for iterator_traits, categories -#include // for __is_integer - -namespace __gnu_debug -{ - template - class _Safe_iterator; - - // An arbitrary iterator pointer is not singular. - inline bool - __check_singular_aux(const void*) { return false; } - - // We may have an iterator that derives from _Safe_iterator_base but isn't - // a _Safe_iterator. - template - inline bool - __check_singular(_Iterator& __x) - { return __gnu_debug::__check_singular_aux(&__x); } - - /** Non-NULL pointers are nonsingular. */ - template - inline bool - __check_singular(const _Tp* __ptr) - { return __ptr == 0; } - - /** Safe iterators know if they are singular. */ - template - inline bool - __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) - { return __x._M_singular(); } - - /** Assume that some arbitrary iterator is dereferenceable, because we - can't prove that it isn't. */ - template - inline bool - __check_dereferenceable(_Iterator&) - { return true; } - - /** Non-NULL pointers are dereferenceable. */ - template - inline bool - __check_dereferenceable(const _Tp* __ptr) - { return __ptr; } - - /** Safe iterators know if they are singular. */ - template - inline bool - __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) - { return __x._M_dereferenceable(); } - - /** If the distance between two random access iterators is - * nonnegative, assume the range is valid. - */ - template - inline bool - __valid_range_aux2(const _RandomAccessIterator& __first, - const _RandomAccessIterator& __last, - std::random_access_iterator_tag) - { return __last - __first >= 0; } - - /** Can't test for a valid range with input iterators, because - * iteration may be destructive. So we just assume that the range - * is valid. - */ - template - inline bool - __valid_range_aux2(const _InputIterator&, const _InputIterator&, - std::input_iterator_tag) - { return true; } - - /** We say that integral types for a valid range, and defer to other - * routines to realize what to do with integral types instead of - * iterators. - */ - template - inline bool - __valid_range_aux(const _Integral&, const _Integral&, __true_type) - { return true; } - - /** We have iterators, so figure out what kind of iterators that are - * to see if we can check the range ahead of time. - */ - template - inline bool - __valid_range_aux(const _InputIterator& __first, - const _InputIterator& __last, __false_type) - { - typedef typename std::iterator_traits<_InputIterator>::iterator_category - _Category; - return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); - } - - /** Don't know what these iterators are, or if they are even - * iterators (we may get an integral type for InputIterator), so - * see if they are integral and pass them on to the next phase - * otherwise. - */ - template - inline bool - __valid_range(const _InputIterator& __first, const _InputIterator& __last) - { - typedef typename std::__is_integer<_InputIterator>::__type _Integral; - return __gnu_debug::__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); } - - /* 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. - */ - template - inline _InputIterator - __check_valid_range(const _InputIterator& __first, - const _InputIterator& __last) - { - _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last)); - return __first; - } - - /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ - template - inline const _CharT* - __check_string(const _CharT* __s, const _Integer& __n) - { -#ifdef _GLIBCXX_DEBUG_PEDANTIC - _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); -#endif - return __s; - } - - /** Checks that __s is non-NULL and then returns __s. */ - template - inline const _CharT* - __check_string(const _CharT* __s) - { -#ifdef _GLIBCXX_DEBUG_PEDANTIC - _GLIBCXX_DEBUG_ASSERT(__s != 0); -#endif - return __s; - } - - // Can't check if an input iterator sequence is sorted, because we - // can't step through the sequence. - template - inline bool - __check_sorted_aux(const _InputIterator&, const _InputIterator&, - std::input_iterator_tag) - { return true; } - - // Can verify if a forward iterator sequence is in fact sorted using - // std::__is_sorted - template - inline bool - __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, - std::forward_iterator_tag) - { - if (__first == __last) - return true; - - _ForwardIterator __next = __first; - for (++__next; __next != __last; __first = __next, ++__next) { - if (*__next < *__first) - return false; - } - - return true; - } - - // Can't check if an input iterator sequence is sorted, because we can't step - // through the sequence. - template - inline bool - __check_sorted_aux(const _InputIterator&, const _InputIterator&, - _Predicate, std::input_iterator_tag) - { return true; } - - // Can verify if a forward iterator sequence is in fact sorted using - // std::__is_sorted - template - inline bool - __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, - _Predicate __pred, std::forward_iterator_tag) - { - if (__first == __last) - return true; - - _ForwardIterator __next = __first; - for (++__next; __next != __last; __first = __next, ++__next) { - if (__pred(*__next, *__first)) - return false; - } - - return true; - } - - // Determine if a sequence is sorted. - template - inline bool - __check_sorted(const _InputIterator& __first, const _InputIterator& __last) - { - typedef typename std::iterator_traits<_InputIterator>::iterator_category - _Category; - return __gnu_debug::__check_sorted_aux(__first, __last, _Category()); - } - - template - inline bool - __check_sorted(const _InputIterator& __first, const _InputIterator& __last, - _Predicate __pred) - { - typedef typename std::iterator_traits<_InputIterator>::iterator_category - _Category; - return __gnu_debug::__check_sorted_aux(__first, __last, __pred, - _Category()); - } - - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 270. Binary search requirements overly strict - // Determine if a sequence is partitioned w.r.t. this element. - template - inline bool - __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, - const _Tp& __value) - { - while (__first != __last && *__first < __value) - ++__first; - while (__first != __last && !(*__first < __value)) - ++__first; - return __first == __last; - } - - // Determine if a sequence is partitioned w.r.t. this element. - template - inline bool - __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, - const _Tp& __value, _Pred __pred) - { - while (__first != __last && __pred(*__first, __value)) - ++__first; - while (__first != __last && !__pred(*__first, __value)) - ++__first; - return __first == __last; - } -} // namespace __gnu_debug - -#ifdef _GLIBCXX_DEBUG -// We need the error formatter -# include -#endif - #endif diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h new file mode 100644 index 0000000..28834d4 --- /dev/null +++ b/libstdc++-v3/include/debug/functions.h @@ -0,0 +1,286 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003, 2005 +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_FUNCTIONS_H +#define _GLIBCXX_DEBUG_FUNCTIONS_H 1 + +#include // for ptrdiff_t +#include // for iterator_traits, categories +#include // for __is_integer + +namespace __gnu_debug +{ + template + class _Safe_iterator; + + // An arbitrary iterator pointer is not singular. + inline bool + __check_singular_aux(const void*) { return false; } + + // We may have an iterator that derives from _Safe_iterator_base but isn't + // a _Safe_iterator. + template + inline bool + __check_singular(_Iterator& __x) + { return __gnu_debug::__check_singular_aux(&__x); } + + /** Non-NULL pointers are nonsingular. */ + template + inline bool + __check_singular(const _Tp* __ptr) + { return __ptr == 0; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_singular(); } + + /** Assume that some arbitrary iterator is dereferenceable, because we + can't prove that it isn't. */ + template + inline bool + __check_dereferenceable(_Iterator&) + { return true; } + + /** Non-NULL pointers are dereferenceable. */ + template + inline bool + __check_dereferenceable(const _Tp* __ptr) + { return __ptr; } + + /** Safe iterators know if they are singular. */ + template + inline bool + __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) + { return __x._M_dereferenceable(); } + + /** If the distance between two random access iterators is + * nonnegative, assume the range is valid. + */ + template + inline bool + __valid_range_aux2(const _RandomAccessIterator& __first, + const _RandomAccessIterator& __last, + std::random_access_iterator_tag) + { return __last - __first >= 0; } + + /** Can't test for a valid range with input iterators, because + * iteration may be destructive. So we just assume that the range + * is valid. + */ + template + inline bool + __valid_range_aux2(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + /** We say that integral types for a valid range, and defer to other + * routines to realize what to do with integral types instead of + * iterators. + */ + template + inline bool + __valid_range_aux(const _Integral&, const _Integral&, __true_type) + { return true; } + + /** We have iterators, so figure out what kind of iterators that are + * to see if we can check the range ahead of time. + */ + template + inline bool + __valid_range_aux(const _InputIterator& __first, + const _InputIterator& __last, __false_type) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__valid_range_aux2(__first, __last, _Category()); + } + + /** Don't know what these iterators are, or if they are even + * iterators (we may get an integral type for InputIterator), so + * see if they are integral and pass them on to the next phase + * otherwise. + */ + template + inline bool + __valid_range(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return __gnu_debug::__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); } + + /* 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. + */ + template + inline _InputIterator + __check_valid_range(const _InputIterator& __first, + const _InputIterator& __last) + { + _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last)); + return __first; + } + + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s, const _Integer& __n) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0); +#endif + return __s; + } + + /** Checks that __s is non-NULL and then returns __s. */ + template + inline const _CharT* + __check_string(const _CharT* __s) + { +#ifdef _GLIBCXX_DEBUG_PEDANTIC + _GLIBCXX_DEBUG_ASSERT(__s != 0); +#endif + return __s; + } + + // Can't check if an input iterator sequence is sorted, because we + // can't step through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) + return false; + } + + return true; + } + + // Can't check if an input iterator sequence is sorted, because we can't step + // through the sequence. + template + inline bool + __check_sorted_aux(const _InputIterator&, const _InputIterator&, + _Predicate, std::input_iterator_tag) + { return true; } + + // Can verify if a forward iterator sequence is in fact sorted using + // std::__is_sorted + template + inline bool + __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred, std::forward_iterator_tag) + { + if (__first == __last) + return true; + + _ForwardIterator __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__pred(*__next, *__first)) + return false; + } + + return true; + } + + // Determine if a sequence is sorted. + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, _Category()); + } + + template + inline bool + __check_sorted(const _InputIterator& __first, const _InputIterator& __last, + _Predicate __pred) + { + typedef typename std::iterator_traits<_InputIterator>::iterator_category + _Category; + return __gnu_debug::__check_sorted_aux(__first, __last, __pred, + _Category()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 270. Binary search requirements overly strict + // Determine if a sequence is partitioned w.r.t. this element. + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value) + { + while (__first != __last && *__first < __value) + ++__first; + while (__first != __last && !(*__first < __value)) + ++__first; + return __first == __last; + } + + // Determine if a sequence is partitioned w.r.t. this element. + template + inline bool + __check_partitioned(_ForwardIterator __first, _ForwardIterator __last, + const _Tp& __value, _Pred __pred) + { + while (__first != __last && __pred(*__first, __value)) + ++__first; + while (__first != __last && !__pred(*__first, __value)) + ++__first; + return __first == __last; + } +} // namespace __gnu_debug + +#endif diff --git a/libstdc++-v3/include/debug/hash_map b/libstdc++-v3/include/debug/hash_map index 570a9af..d4d1497 100644 --- a/libstdc++-v3/include/debug/hash_map +++ b/libstdc++-v3/include/debug/hash_map @@ -1,6 +1,6 @@ // Debugging hash_map/hash_multimap implementation -*- C++ -*- -// Copyright (C) 2003 +// Copyright (C) 2003, 2005 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -31,8 +31,8 @@ #ifndef _GLIBCXX_DEBUG_HASH_MAP #define _GLIBCXX_DEBUG_HASH_MAP 1 -#include -#include -#include +#include +#include +#include #endif diff --git a/libstdc++-v3/include/debug/hash_set b/libstdc++-v3/include/debug/hash_set index 282cba2..c600f07 100644 --- a/libstdc++-v3/include/debug/hash_set +++ b/libstdc++-v3/include/debug/hash_set @@ -1,6 +1,6 @@ // Debugging hash_set/hash_multiset implementation -*- C++ -*- -// Copyright (C) 2003 +// Copyright (C) 2003, 2005 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -31,8 +31,8 @@ #ifndef _GLIBCXX_DEBUG_HASH_SET #define _GLIBCXX_DEBUG_HASH_SET 1 -#include -#include -#include +#include +#include +#include #endif diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h new file mode 100644 index 0000000..c89ff9e --- /dev/null +++ b/libstdc++-v3/include/debug/macros.h @@ -0,0 +1,219 @@ +// Debugging support implementation -*- C++ -*- + +// Copyright (C) 2003, 2005 +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#ifndef _GLIBCXX_DEBUG_MACROS_H +#define _GLIBCXX_DEBUG_MACROS_H 1 + +/** + * Macros used by the implementation to verify certain + * properties. These macros may only be used directly by the debug + * wrappers. Note that these are macros (instead of the more obviously + * "correct" choice of making them functions) because we need line and + * file information at the call site, to minimize the distance between + * the user error and where the error is reported. + * + */ +#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \ + do { \ + if (! (_Condition)) \ + ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \ + ._ErrorMessage._M_error(); \ + } while (false) + +// Verify that [_First, _Last) forms a valid iterator range. +#define __glibcxx_check_valid_range(_First,_Last) \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \ + _M_message(::__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that we can insert into *this with the iterator _Position. + * Insertion into a container at a specific position requires that + * the iterator be nonsingular (i.e., either dereferenceable or + * past-the-end) and that it reference the sequence we are inserting + * into. Note that this macro is only valid when the container is a + * _Safe_sequence and the iterator is a _Safe_iterator. +*/ +#define __glibcxx_check_insert(_Position) \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_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_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can insert the values in the iterator range + * [_First, _Last) into *this with the iterator _Position. Insertion + * into a container at a specific position requires that the iterator + * be nonsingular (i.e., either dereferenceable or past-the-end), + * 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. + * + * @tbd 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. +*/ +#define __glibcxx_check_insert_range(_Position,_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(!_Position._M_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_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the element referenced by the iterator + * _Position. We can erase the element if the _Position iterator is + * dereferenceable and references this sequence. +*/ +#define __glibcxx_check_erase(_Position) \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \ + _M_message(::__gnu_debug::__msg_erase_bad) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)); \ +_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_Position, #_Position)) + +/** Verify that we can erase the elements in the iterator range + * [_First, _Last). We can erase the elements if [_First, _Last) is a + * valid iterator range within this sequence. +*/ +#define __glibcxx_check_erase_range(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ + _M_message(::__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +// Verify that the subscript _N is less than the container's size. +#define __glibcxx_check_subscript(_N) \ +_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \ + _M_message(::__gnu_debug::__msg_subscript_oob) \ + ._M_sequence(*this, "this") \ + ._M_integer(_N, #_N) \ + ._M_integer(this->size(), "size")) + +// Verify that the container is nonempty +#define __glibcxx_check_nonempty() \ +_GLIBCXX_DEBUG_VERIFY(! this->empty(), \ + _M_message(::__gnu_debug::__msg_empty) \ + ._M_sequence(*this, "this")) + +// Verify that the < operator for elements in the sequence is a +// StrictWeakOrdering by checking that it is irreflexive. +#define __glibcxx_check_strict_weak_ordering(_First,_Last) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First)) + +// Verify that the predicate is StrictWeakOrdering by checking that it +// is irreflexive. +#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \ +_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First)) + + +// Verify that the iterator range [_First, _Last) is sorted +#define __glibcxx_check_sorted(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \ + _M_message(::__gnu_debug::__msg_unsorted) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is sorted by the + predicate _Pred. */ +#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_unsorted_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value. */ +#define __glibcxx_check_partitioned(_First,_Last,_Value) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value), \ + _M_message(::__gnu_debug::__msg_unpartitioned) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Value)) + +/** Verify that the iterator range [_First, _Last) is partitioned + w.r.t. the value _Value and predicate _Pred. */ +#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \ + _Value, _Pred), \ + _M_message(::__gnu_debug::__msg_unpartitioned_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred) \ + ._M_string(#_Value)) + +// Verify that the iterator range [_First, _Last) is a heap +#define __glibcxx_check_heap(_First,_Last) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \ + _M_message(::__gnu_debug::__msg_not_heap) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)) + +/** Verify that the iterator range [_First, _Last) is a heap + w.r.t. the predicate _Pred. */ +#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \ +__glibcxx_check_valid_range(_First,_Last); \ +_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \ + _M_message(::__gnu_debug::__msg_not_heap_pred) \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_string(#_Pred)) + +#ifdef _GLIBCXX_DEBUG_PEDANTIC +# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0) +# define __glibcxx_check_string_len(_String,_Len) \ + _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0) +#else +# define __glibcxx_check_string(_String) +# define __glibcxx_check_string_len(_String,_Len) +#endif + +#endif diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 1f5b0f6..8d96f39 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -31,10 +31,12 @@ #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1 -#include #include +#include +#include #include #include +#include #include namespace __gnu_debug @@ -46,7 +48,8 @@ namespace __gnu_debug * _Safe_iterators can be determined singular or non-singular via * _Safe_iterator_base. */ - inline bool __check_singular_aux(const _Safe_iterator_base* __x) + inline bool + __check_singular_aux(const _Safe_iterator_base* __x) { return __x->_M_singular(); } /** \brief Safe iterator wrapper. diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h index f050530..a1577b4b 100644 --- a/libstdc++-v3/include/debug/safe_sequence.h +++ b/libstdc++-v3/include/debug/safe_sequence.h @@ -1,6 +1,6 @@ // Safe sequence implementation -*- C++ -*- -// Copyright (C) 2003, 2004 +// Copyright (C) 2003, 2004, 2005 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -32,6 +32,8 @@ #define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1 #include +#include +#include #include namespace __gnu_debug diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index 0cc2997..45a423d 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -1,6 +1,6 @@ // Debugging vector implementation -*- C++ -*- -// Copyright (C) 2003, 2004 +// Copyright (C) 2003, 2004, 2005 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -32,9 +32,9 @@ #define _GLIBCXX_DEBUG_VECTOR 1 #include +#include #include #include -#include namespace __gnu_debug_def { diff --git a/libstdc++-v3/include/ext/hash_map b/libstdc++-v3/include/ext/hash_map index eff10e0..20eebeb 100644 --- a/libstdc++-v3/include/ext/hash_map +++ b/libstdc++-v3/include/ext/hash_map @@ -1,6 +1,6 @@ // Hashing map implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004, 2005 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 @@ -617,4 +617,9 @@ namespace std { return *this; } }; } // namespace std + +#ifdef _GLIBCXX_DEBUG +# include +#endif + #endif diff --git a/libstdc++-v3/include/ext/hash_set b/libstdc++-v3/include/ext/hash_set index f6e791a..120bfc5 100644 --- a/libstdc++-v3/include/ext/hash_set +++ b/libstdc++-v3/include/ext/hash_set @@ -1,6 +1,6 @@ // Hashing set implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004, 2005 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 @@ -583,4 +583,9 @@ namespace std operator++(int) { return *this; } }; } // namespace std + +#ifdef _GLIBCXX_DEBUG +# include +#endif + #endif diff --git a/libstdc++-v3/testsuite/17_intro/no_assert_neg.cc b/libstdc++-v3/testsuite/17_intro/no_assert_neg.cc new file mode 100644 index 0000000..f3ffa4a --- /dev/null +++ b/libstdc++-v3/testsuite/17_intro/no_assert_neg.cc @@ -0,0 +1,89 @@ +// { dg-do compile } +// { dg-options "-D__GLIBCXX__=99999999" } +// NB: This is done to force any generated and possibly included PCH +// to be invalid. + +// 2005-05-24 bkoz + +// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 17.4.1.2 Headers + +// This file tests that assert is not included in any of the standard +// includes by accident. + +// C++ headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// C headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void foo() +{ + assert(true); +} + +// { dg-error "not declared" "" { target *-*-* } 84 } + + -- cgit v1.1