Commit 77e0bf4e by François Dumont Committed by François Dumont

safe_unordered_base.h, [...]: New, support for unordered sequence safe local iterators.

2011-07-19  François Dumont  <francois.cppdevs@free.fr>

        * include/debug/safe_unordered_base.h, safe_unordered_sequence.h,
        safe_unordered_sequence.tcc, safe_local_iterator.h,
        safe_local_iterator.tcc: New, support for unordered sequence safe
        local iterators.
        * include/Makefile.am: Add previous files.
        * include/Makefile.in: Regenerate.
        * include/debug/unordered_map, unordered_set: Implement
        _Safe_unordered_sequence and expose _Safe_local_iterator.
        * include/debug/safe_iterator.h, safe_iterator.tcc: Refactor
        _Safe_iterator::_M_get_distance static method to expose it as
        __get_distance function and use it in _Safe_local_iterator type.
        * include/debug/formatter.h: Add __msg_local_iter_compare_bad
        _Debug_msg_id enum entry to notify invalid comparison between local
        iterators from different buckets. Add _Parameter constructor from
        _Safe_local_iterator.
        * include/debug/functions.h: Add __valid_range overload for
        _Safe_local_iterator.
        * src/debug.cc: Add _Safe_unordered_sequence_base and
        _Safe_local_iterator_base methods implementations.
        * config/abi/pre/gnu.ver: Add export of some
        _Safe_unordered_sequence_base and _Safe_local_iterator_base methods.
        * testsuite/util/debug/checks.h: Add use_invalid_iterator function to
        simulate use of a singular iterator.
        * testsuite/util/debug/unordered_checks.h: New, several functions
        to simulate classic invalid usage of unordered sequence local
        iterators.
        * testsuite/23_containers/unordered_map/debug/
        use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
        use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
        invalid_local_iterator_compare_neg.cc: New.
        * testsuite/23_containers/unordered_multimap/debug/
        use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
        use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
        invalid_local_iterator_compare_neg.cc: New.
        * testsuite/23_containers/unordered_set/debug/
        use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
        use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
        invalid_local_iterator_compare_neg.cc: New.
        * testsuite/23_containers/unordered_multiset/debug/
        use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
        use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
        invalid_local_iterator_compare_neg.cc: New.

From-SVN: r176487
parent 78767fd9
2011-07-19 François Dumont <francois.cppdevs@free.fr>
* include/debug/safe_unordered_base.h, safe_unordered_sequence.h,
safe_unordered_sequence.tcc, safe_local_iterator.h,
safe_local_iterator.tcc: New, support for unordered sequence safe
local iterators.
* include/Makefile.am: Add previous files.
* include/Makefile.in: Regenerate.
* include/debug/unordered_map, unordered_set: Implement
_Safe_unordered_sequence and expose _Safe_local_iterator.
* include/debug/safe_iterator.h, safe_iterator.tcc: Refactor
_Safe_iterator::_M_get_distance static method to expose it as
__get_distance function and use it in _Safe_local_iterator type.
* include/debug/formatter.h: Add __msg_local_iter_compare_bad
_Debug_msg_id enum entry to notify invalid comparison between local
iterators from different buckets. Add _Parameter constructor from
_Safe_local_iterator.
* include/debug/functions.h: Add __valid_range overload for
_Safe_local_iterator.
* src/debug.cc: Add _Safe_unordered_sequence_base and
_Safe_local_iterator_base methods implementations.
* config/abi/pre/gnu.ver: Add export of some
_Safe_unordered_sequence_base and _Safe_local_iterator_base methods.
* testsuite/util/debug/checks.h: Add use_invalid_iterator function to
simulate use of a singular iterator.
* testsuite/util/debug/unordered_checks.h: New, several functions
to simulate classic invalid usage of unordered sequence local
iterators.
* testsuite/23_containers/unordered_map/debug/
use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
invalid_local_iterator_compare_neg.cc: New.
* testsuite/23_containers/unordered_multimap/debug/
use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
invalid_local_iterator_compare_neg.cc: New.
* testsuite/23_containers/unordered_set/debug/
use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
invalid_local_iterator_compare_neg.cc: New.
* testsuite/23_containers/unordered_multiset/debug/
use_erased_local_iterator_neg.cc, invalid_local_iterator_range_neg.cc,
use_invalid_local_iterator_neg.cc, use_invalid_iterator_neg.cc,
invalid_local_iterator_compare_neg.cc: New.
2011-07-18 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/48430
......
......@@ -1284,6 +1284,11 @@ GLIBCXX_3.4.17 {
# std::thread::hardware_concurrency
_ZNSt6thread20hardware_concurrencyEv;
# __gnu_debug::_Safe_unordered_sequence_base and _Safe_local_iterator_base
_ZN11__gnu_debug29_Safe_unordered_sequence_base7_M_swapERS0_;
_ZN11__gnu_debug29_Safe_unordered_sequence_base13_M_detach_allEv;
_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb;
_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv;
} GLIBCXX_3.4.16;
# Symbols in the support library (libsupc++) have their own tag.
......
......@@ -701,8 +701,13 @@ debug_headers = \
${debug_srcdir}/safe_base.h \
${debug_srcdir}/safe_iterator.h \
${debug_srcdir}/safe_iterator.tcc \
${debug_srcdir}/safe_local_iterator.h \
${debug_srcdir}/safe_local_iterator.tcc \
${debug_srcdir}/safe_sequence.h \
${debug_srcdir}/safe_sequence.tcc \
${debug_srcdir}/safe_unordered_base.h \
${debug_srcdir}/safe_unordered_sequence.h \
${debug_srcdir}/safe_unordered_sequence.tcc \
${debug_srcdir}/set \
${debug_srcdir}/set.h \
${debug_srcdir}/string \
......
......@@ -946,8 +946,13 @@ debug_headers = \
${debug_srcdir}/safe_base.h \
${debug_srcdir}/safe_iterator.h \
${debug_srcdir}/safe_iterator.tcc \
${debug_srcdir}/safe_local_iterator.h \
${debug_srcdir}/safe_local_iterator.tcc \
${debug_srcdir}/safe_sequence.h \
${debug_srcdir}/safe_sequence.tcc \
${debug_srcdir}/safe_unordered_base.h \
${debug_srcdir}/safe_unordered_sequence.h \
${debug_srcdir}/safe_unordered_sequence.tcc \
${debug_srcdir}/set \
${debug_srcdir}/set.h \
${debug_srcdir}/string \
......
// Debug-mode error formatting implementation -*- C++ -*-
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
......@@ -46,6 +46,9 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
class _Safe_iterator;
template<typename _Iterator, typename _Sequence>
class _Safe_local_iterator;
template<typename _Sequence>
class _Safe_sequence;
......@@ -103,7 +106,9 @@ namespace __gnu_debug
// forward_list
__msg_insert_after_end,
__msg_erase_after_bad,
__msg_valid_range2
__msg_valid_range2,
// unordered sequence local iterators
__msg_local_iter_compare_bad
};
class _Error_formatter
......@@ -236,6 +241,42 @@ namespace __gnu_debug
}
}
template<typename _Iterator, typename _Sequence>
_Parameter(const _Safe_local_iterator<_Iterator, _Sequence>& __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;
#ifdef __GXX_RTTI
_M_variant._M_iterator._M_type = &typeid(__it);
#else
_M_variant._M_iterator._M_type = 0;
#endif
_M_variant._M_iterator._M_constness =
std::__are_same<_Safe_local_iterator<_Iterator, _Sequence>,
typename _Sequence::local_iterator>::
__value ? __mutable_iterator : __const_iterator;
_M_variant._M_iterator._M_sequence = __it._M_get_sequence();
#ifdef __GXX_RTTI
_M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
#else
_M_variant._M_iterator._M_seq_type = 0;
#endif
if (__it._M_singular())
_M_variant._M_iterator._M_state = __singular;
else
{
if (__it._M_is_end())
_M_variant._M_iterator._M_state = __end;
else if (__it._M_is_begin())
_M_variant._M_iterator._M_state = __begin;
else
_M_variant._M_iterator._M_state = __middle;
}
}
template<typename _Type>
_Parameter(const _Type*& __it, const char* __name, _Is_iterator)
: _M_kind(__iterator), _M_variant()
......
// Debugging support implementation -*- C++ -*-
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
......@@ -144,6 +144,13 @@ namespace __gnu_debug
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<typename _Iterator, typename _Sequence>
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.
......
......@@ -62,6 +62,43 @@ namespace __gnu_debug
__check_singular_aux(const _Safe_iterator_base* __x)
{ return __x->_M_singular(); }
/** The precision to which we can calculate the distance between
* two iterators.
*/
enum _Distance_precision
{
__dp_equality, //< Can compare iterator equality, only
__dp_sign, //< Can determine equality and ordering
__dp_exact //< Can determine distance precisely
};
/** Determine the distance between two iterators with some known
* precision.
*/
template<typename _Iterator1, typename _Iterator2>
inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
_Distance_precision>
__get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
std::random_access_iterator_tag)
{ return std::make_pair(__rhs - __lhs, __dp_exact); }
template<typename _Iterator1, typename _Iterator2>
inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
_Distance_precision>
__get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
std::forward_iterator_tag)
{ return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
template<typename _Iterator1, typename _Iterator2>
inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
_Distance_precision>
__get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
{
typedef typename std::iterator_traits<_Iterator1>::iterator_category
_Category;
return __get_distance(__lhs, __rhs, _Category());
}
/** \brief Safe iterator wrapper.
*
* The class template %_Safe_iterator is a wrapper around an
......@@ -78,16 +115,6 @@ namespace __gnu_debug
{
typedef _Safe_iterator _Self;
/** The precision to which we can calculate the distance between
* two iterators.
*/
enum _Distance_precision
{
__dp_equality, //< Can compare iterator equality, only
__dp_sign, //< Can determine equality and ordering
__dp_exact //< Can determine distance precisely
};
/// The underlying iterator
_Iterator _M_current;
......@@ -380,30 +407,6 @@ namespace __gnu_debug
_M_get_sequence() const
{ return static_cast<const _Sequence*>(_M_sequence); }
/** Determine the distance between two iterators with some known
* precision.
*/
template<typename _Iterator1, typename _Iterator2>
static std::pair<difference_type, _Distance_precision>
_M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
{
typedef typename std::iterator_traits<_Iterator1>::iterator_category
_Category;
return _M_get_distance(__lhs, __rhs, _Category());
}
template<typename _Iterator1, typename _Iterator2>
static std::pair<difference_type, _Distance_precision>
_M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
std::random_access_iterator_tag)
{ return std::make_pair(__rhs - __lhs, __dp_exact); }
template<typename _Iterator1, typename _Iterator2>
static std::pair<difference_type, _Distance_precision>
_M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
std::forward_iterator_tag)
{ return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
/// Is this iterator equal to the sequence's begin() iterator?
bool _M_is_begin() const
{ return base() == _M_get_sequence()->_M_base().begin(); }
......
// Debugging iterator implementation (out of line) -*- C++ -*-
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
......@@ -48,7 +48,7 @@ namespace __gnu_debug
{
const_iterator __begin = _M_get_sequence()->_M_base().begin();
std::pair<difference_type, _Distance_precision> __dist =
this->_M_get_distance(__begin, base());
__get_distance(__begin, base());
bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n)
|| (__dist.second != __dp_exact && __dist.first > 0));
return __ok;
......@@ -57,7 +57,7 @@ namespace __gnu_debug
{
const_iterator __end = _M_get_sequence()->_M_base().end();
std::pair<difference_type, _Distance_precision> __dist =
this->_M_get_distance(base(), __end);
__get_distance(base(), __end);
bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n)
|| (__dist.second != __dp_exact && __dist.first > 0));
return __ok;
......@@ -76,7 +76,7 @@ namespace __gnu_debug
/* Determine if we can order the iterators without the help of
the container */
std::pair<difference_type, _Distance_precision> __dist =
this->_M_get_distance(base(), __rhs.base());
__get_distance(base(), __rhs.base());
switch (__dist.second) {
case __dp_equality:
if (__dist.first == 0)
......
// Debugging iterator implementation (out of line) -*- C++ -*-
// Copyright (C) 2011 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
// <http://www.gnu.org/licenses/>.
/** @file debug/safe_locale_iterator.tcc
* This file is a GNU debug extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_TCC
#define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_TCC 1
namespace __gnu_debug
{
template<typename _Iterator, typename _Sequence>
template<typename _Other>
bool
_Safe_local_iterator<_Iterator, _Sequence>::
_M_valid_range(const _Safe_local_iterator<_Other, _Sequence>& __rhs) const
{
if (!_M_can_compare(__rhs))
return false;
if (_M_bucket != __rhs._M_bucket)
return false;
/* Determine if we can order the iterators without the help of
the container */
std::pair<difference_type, _Distance_precision> __dist =
__get_distance(base(), __rhs.base());
switch (__dist.second)
{
case __dp_equality:
if (__dist.first == 0)
return true;
break;
case __dp_sign:
case __dp_exact:
return __dist.first >= 0;
}
/* We can only test for equality, but check if one of the
iterators is at an extreme. */
/* Optim for classic [begin, it) or [it, end) ranges, limit checks
* when code is valid. */
if (_M_is_begin() || __rhs._M_is_end())
return true;
if (_M_is_end() || __rhs._M_is_begin())
return false;
// Assume that this is a valid range; we can't check anything else
return true;
}
} // namespace __gnu_debug
#endif
// Safe sequence/iterator base implementation -*- C++ -*-
// Copyright (C) 2011 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
// <http://www.gnu.org/licenses/>.
/** @file debug/safe_unordered_base.h
* This file is a GNU debug extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_BASE_H
#define _GLIBCXX_DEBUG_SAFE_UNORDERED_BASE_H 1
#include <debug/safe_base.h>
namespace __gnu_debug
{
class _Safe_unordered_sequence_base;
/** \brief Basic functionality for a @a safe iterator.
*
* The %_Safe_local_iterator_base base class implements the functionality
* of a safe local iterator that is not specific to a particular iterator
* type. It contains a pointer back to the sequence it references
* along with iterator version information and pointers to form a
* doubly-linked list of local iterators referenced by the container.
*
* This class must not perform any operations that can throw an
* exception, or the exception guarantees of derived iterators will
* be broken.
*/
class _Safe_local_iterator_base : public _Safe_iterator_base
{
protected:
/** Initializes the iterator and makes it singular. */
_Safe_local_iterator_base()
{ }
/** Initialize the iterator to reference the sequence pointed to
* by @p__seq. @p __constant is true when we are initializing a
* constant local iterator, and false if it is a mutable local iterator.
* Note that @p __seq may be NULL, in which case the iterator will be
* singular. Otherwise, the iterator will reference @p __seq and
* be nonsingular.
*/
_Safe_local_iterator_base(const _Safe_sequence_base* __seq, bool __constant)
{ this->_M_attach(const_cast<_Safe_sequence_base*>(__seq), __constant); }
/** Initializes the iterator to reference the same sequence that
@p __x does. @p __constant is true if this is a constant
iterator, and false if it is mutable. */
_Safe_local_iterator_base(const _Safe_local_iterator_base& __x,
bool __constant)
{ this->_M_attach(__x._M_sequence, __constant); }
_Safe_local_iterator_base&
operator=(const _Safe_local_iterator_base&);
explicit
_Safe_local_iterator_base(const _Safe_local_iterator_base&);
~_Safe_local_iterator_base() { this->_M_detach(); }
_Safe_unordered_sequence_base*
_M_get_sequence() const _GLIBCXX_NOEXCEPT;
public:
/** Attaches this iterator to the given sequence, detaching it
* from whatever sequence it was attached to originally. If the
* new sequence is the NULL pointer, the iterator is left
* unattached.
*/
void _M_attach(_Safe_sequence_base* __seq, bool __constant);
/** Likewise, but not thread-safe. */
void _M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ();
/** Detach the iterator for whatever sequence it is attached to,
* if any.
*/
void _M_detach();
/** Likewise, but not thread-safe. */
void _M_detach_single() throw ();
};
/**
* @brief Base class that supports tracking of local iterators that
* reference an unordered sequence.
*
* The %_Safe_unordered_sequence_base class provides basic support for
* tracking iterators into an unordered sequence. Sequences that track
* iterators must derived from %_Safe_sequence_base publicly, so
* that safe iterators (which inherit _Safe_iterator_base) can
* attach to them. This class contains four linked lists of
* iterators, one for constant iterators, one for mutable
* iterators, one for constant local iterators, one for mutable local
* iterator and a version number that allows very fast
* invalidation of all iterators that reference the container.
*
* This class must ensure that no operation on it may throw an
* exception, otherwise @a safe sequences may fail to provide the
* exception-safety guarantees required by the C++ standard.
*/
class _Safe_unordered_sequence_base : public _Safe_sequence_base
{
typedef _Safe_sequence_base _Base;
public:
/// The list of mutable local iterators that reference this container
_Safe_iterator_base* _M_local_iterators;
/// The list of constant local iterators that reference this container
_Safe_iterator_base* _M_const_local_iterators;
protected:
// Initialize with a version number of 1 and no iterators
_Safe_unordered_sequence_base()
: _M_local_iterators(0), _M_const_local_iterators(0)
{ }
/** Notify all iterators that reference this sequence that the
sequence is being destroyed. */
~_Safe_unordered_sequence_base()
{ this->_M_detach_all(); }
/** Detach all iterators, leaving them singular. */
void
_M_detach_all();
/** Swap this sequence with the given sequence. This operation
* also swaps ownership of the iterators, so that when the
* operation is complete all iterators that originally referenced
* one container now reference the other container.
*/
void
_M_swap(_Safe_unordered_sequence_base& __x);
public:
/** Attach an iterator to this sequence. */
void
_M_attach_local(_Safe_iterator_base* __it, bool __constant);
/** Likewise but not thread safe. */
void
_M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ();
/** Detach an iterator from this sequence */
void
_M_detach_local(_Safe_iterator_base* __it);
/** Likewise but not thread safe. */
void
_M_detach_local_single(_Safe_iterator_base* __it) throw ();
};
} // namespace __gnu_debug
#endif
// Safe sequence implementation -*- C++ -*-
// Copyright (C) 2011 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
// <http://www.gnu.org/licenses/>.
/** @file debug/safe_unordered_sequence.h
* This file is a GNU debug extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_SEQUENCE_H
#define _GLIBCXX_DEBUG_SAFE_UNORDERED_SEQUENCE_H 1
#include <debug/debug.h>
#include <debug/macros.h>
#include <debug/functions.h>
#include <debug/safe_unordered_base.h>
namespace __gnu_debug
{
/**
* @brief Base class for constructing a @a safe unordered sequence type
* that tracks iterators that reference it.
*
* The class template %_Safe_unordered_sequence simplifies the
* construction of @a safe unordered sequences that track the iterators
* that reference the sequence, so that the iterators are notified of
* changes in the sequence that may affect their operation, e.g., if
* the container invalidates its iterators or is destructed. This class
* template may only be used by deriving from it and passing the name
* of the derived class as its template parameter via the curiously
* recurring template pattern. The derived class must have @c
* iterator and @const_iterator types that are instantiations of
* class template _Safe_iterator for this sequence. Iterators will
* then be tracked automatically.
*/
template<typename _Sequence>
class _Safe_unordered_sequence : public _Safe_unordered_sequence_base
{
public:
/** Invalidates all iterators @c x that reference this sequence,
are not singular, and for which @c pred(x) returns @c
true. @c pred will be invoked with the normal iterators nested
in the safe ones. */
template<typename _Predicate>
void
_M_invalidate_if(_Predicate __pred);
template<typename _Predicate>
void
_M_invalidate_local_if(_Predicate __pred);
};
} // namespace __gnu_debug
#include <debug/safe_unordered_sequence.tcc>
#endif
// Safe sequence implementation -*- C++ -*-
// Copyright (C) 2011 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
// <http://www.gnu.org/licenses/>.
/** @file debug/safe_unordered_sequence.tcc
* This file is a GNU debug extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_DEBUG_SAFE_UNORDERED_SEQUENCE_TCC
#define _GLIBCXX_DEBUG_SAFE_UNORDERED_SEQUENCE_TCC 1
namespace __gnu_debug
{
template<typename _Sequence>
template<typename _Predicate>
void
_Safe_unordered_sequence<_Sequence>::
_M_invalidate_if(_Predicate __pred)
{
typedef typename _Sequence::iterator iterator;
typedef typename _Sequence::const_iterator const_iterator;
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
{
iterator* __victim = static_cast<iterator*>(__iter);
__iter = __iter->_M_next;
if (!__victim->_M_singular() && __pred(__victim->base()))
{
__victim->_M_invalidate();
}
}
for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
{
const_iterator* __victim = static_cast<const_iterator*>(__iter2);
__iter2 = __iter2->_M_next;
if (!__victim->_M_singular() && __pred(__victim->base()))
{
__victim->_M_invalidate();
}
}
}
template<typename _Sequence>
template<typename _Predicate>
void
_Safe_unordered_sequence<_Sequence>::
_M_invalidate_local_if(_Predicate __pred)
{
typedef typename _Sequence::local_iterator local_iterator;
typedef typename _Sequence::const_local_iterator const_local_iterator;
__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
for (_Safe_iterator_base* __iter = _M_local_iterators; __iter;)
{
local_iterator* __victim = static_cast<local_iterator*>(__iter);
__iter = __iter->_M_next;
if (!__victim->_M_singular() && __pred(__victim->base()))
{
__victim->_M_invalidate();
}
}
for (_Safe_iterator_base* __iter2 = _M_const_local_iterators; __iter2;)
{
const_local_iterator* __victim =
static_cast<const_local_iterator*>(__iter2);
__iter2 = __iter2->_M_next;
if (!__victim->_M_singular() && __pred(__victim->base()))
{
__victim->_M_invalidate();
}
}
}
} // namespace __gnu_debug
#endif
// Debugging mode support code -*- C++ -*-
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
// Free Software Foundation, Inc.
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
// 2011 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
......@@ -25,7 +25,9 @@
#include <debug/debug.h>
#include <debug/safe_sequence.h>
#include <debug/safe_unordered_sequence.h>
#include <debug/safe_iterator.h>
#include <debug/safe_local_iterator.h>
#include <algorithm>
#include <cassert>
#include <cstring>
......@@ -51,28 +53,58 @@ namespace
}
void
swap_seq(__gnu_debug::_Safe_sequence_base& __lhs,
__gnu_debug::_Safe_sequence_base& __rhs)
swap_its(__gnu_debug::_Safe_sequence_base& __lhs,
__gnu_debug::_Safe_iterator_base*& __lhs_its,
__gnu_debug::_Safe_sequence_base& __rhs,
__gnu_debug::_Safe_iterator_base*& __rhs_its)
{
swap(__lhs._M_iterators, __rhs._M_iterators);
swap(__lhs._M_const_iterators, __rhs._M_const_iterators);
swap(__lhs._M_version, __rhs._M_version);
swap(__lhs_its, __rhs_its);
__gnu_debug::_Safe_iterator_base* __iter;
for (__iter = __rhs._M_iterators; __iter; __iter = __iter->_M_next)
__iter->_M_sequence = &__rhs;
for (__iter = __lhs._M_iterators; __iter; __iter = __iter->_M_next)
__iter->_M_sequence = &__lhs;
for (__iter = __rhs._M_const_iterators; __iter; __iter = __iter->_M_next)
for (__iter = __rhs_its; __iter; __iter = __iter->_M_next)
__iter->_M_sequence = &__rhs;
for (__iter = __lhs._M_const_iterators; __iter; __iter = __iter->_M_next)
for (__iter = __lhs_its; __iter; __iter = __iter->_M_next)
__iter->_M_sequence = &__lhs;
}
void
swap_seq(__gnu_debug::_Safe_sequence_base& __lhs,
__gnu_debug::_Safe_sequence_base& __rhs)
{
swap(__lhs._M_version, __rhs._M_version);
swap_its(__lhs, __lhs._M_iterators,
__rhs, __rhs._M_iterators);
swap_its(__lhs, __lhs._M_const_iterators,
__rhs, __rhs._M_const_iterators);
}
void
swap_useq(__gnu_debug::_Safe_unordered_sequence_base& __lhs,
__gnu_debug::_Safe_unordered_sequence_base& __rhs)
{
swap_seq(__lhs, __rhs);
swap_its(__lhs, __lhs._M_local_iterators,
__rhs, __rhs._M_local_iterators);
swap_its(__lhs, __lhs._M_const_local_iterators,
__rhs, __rhs._M_const_local_iterators);
}
void
detach_all(__gnu_debug::_Safe_iterator_base* __iter)
{
for (; __iter;)
{
__gnu_debug::_Safe_iterator_base* __old = __iter;
__iter = __iter->_M_next;
__old->_M_reset();
}
}
} // anonymous namespace
namespace __gnu_debug
{
const char* _S_debug_messages[] =
{
// General Checks
"function requires a valid iterator range [%1.name;, %2.name;)",
"attempt to insert into container with a singular iterator",
"attempt to insert into container with an iterator"
......@@ -93,15 +125,18 @@ namespace __gnu_debug
"elements in iterator range [%1.name;, %2.name;) do not form a heap",
"elements in iterator range [%1.name;, %2.name;)"
" do not form a heap with respect to the predicate %3;",
// std::bitset checks
"attempt to write through a singular bitset reference",
"attempt to read from a singular bitset reference",
"attempt to flip a singular bitset reference",
// std::list checks
"attempt to splice a list into itself",
"attempt to splice lists with inequal allocators",
"attempt to splice elements referenced by a %1.state; iterator",
"attempt to splice an iterator from a different container",
"splice destination %1.name;"
" occurs within source range [%2.name;, %3.name;)",
// iterator checks
"attempt to initialize an iterator that will immediately become singular",
"attempt to copy-construct an iterator from a singular iterator",
"attempt to construct a constant iterator"
......@@ -124,17 +159,24 @@ namespace __gnu_debug
" iterator to a %2.state; iterator",
"attempt to compute the different between two iterators"
" from different sequences",
// istream_iterator
"attempt to dereference an end-of-stream istream_iterator",
"attempt to increment an end-of-stream istream_iterator",
// ostream_iterator
"attempt to output via an ostream_iterator with no associated stream",
// istreambuf_iterator
"attempt to dereference an end-of-stream istreambuf_iterator"
" (this is a GNU extension)",
"attempt to increment an end-of-stream istreambuf_iterator",
// std::forward_list
"attempt to insert into container after an end iterator",
"attempt to erase from container after a %2.state; iterator not followed"
" by a dereferenceable one",
"function requires a valid iterator range (%2.name;, %3.name;)"
", \"%2.name;\" shall be before and not equal to \"%3.name;\""
", \"%2.name;\" shall be before and not equal to \"%3.name;\"",
// std::unordered_sequence::local_iterator
"attempt to compare local iterators from different unordered sequence"
" buckets"
};
void
......@@ -142,20 +184,10 @@ namespace __gnu_debug
_M_detach_all()
{
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
{
_Safe_iterator_base* __old = __iter;
__iter = __iter->_M_next;
__old->_M_reset();
}
detach_all(_M_iterators);
_M_iterators = 0;
for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
{
_Safe_iterator_base* __old = __iter2;
__iter2 = __iter2->_M_next;
__old->_M_reset();
}
detach_all(_M_const_iterators);
_M_const_iterators = 0;
}
......@@ -299,9 +331,7 @@ namespace __gnu_debug
_M_detach()
{
if (_M_sequence)
{
_M_sequence->_M_detach(this);
}
_M_reset();
}
......@@ -311,9 +341,7 @@ namespace __gnu_debug
_M_detach_single() throw ()
{
if (_M_sequence)
{
_M_sequence->_M_detach_single(this);
}
_M_reset();
}
......@@ -346,6 +374,143 @@ namespace __gnu_debug
_M_get_mutex() throw ()
{ return get_safe_base_mutex(_M_sequence); }
_Safe_unordered_sequence_base*
_Safe_local_iterator_base::
_M_get_sequence() const _GLIBCXX_NOEXCEPT
{ return static_cast<_Safe_unordered_sequence_base*>(_M_sequence); }
void
_Safe_local_iterator_base::
_M_attach(_Safe_sequence_base* __seq, bool __constant)
{
_M_detach();
// Attach to the new sequence (if there is one)
if (__seq)
{
_M_sequence = __seq;
_M_version = _M_sequence->_M_version;
_M_get_sequence()->_M_attach_local(this, __constant);
}
}
void
_Safe_local_iterator_base::
_M_attach_single(_Safe_sequence_base* __seq, bool __constant) throw ()
{
_M_detach_single();
// Attach to the new sequence (if there is one)
if (__seq)
{
_M_sequence = __seq;
_M_version = _M_sequence->_M_version;
_M_get_sequence()->_M_attach_local_single(this, __constant);
}
}
void
_Safe_local_iterator_base::
_M_detach()
{
if (_M_sequence)
_M_get_sequence()->_M_detach_local(this);
_M_reset();
}
void
_Safe_local_iterator_base::
_M_detach_single() throw ()
{
if (_M_sequence)
_M_get_sequence()->_M_detach_local_single(this);
_M_reset();
}
void
_Safe_unordered_sequence_base::
_M_detach_all()
{
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
detach_all(_M_iterators);
_M_iterators = 0;
detach_all(_M_const_iterators);
_M_const_iterators = 0;
detach_all(_M_local_iterators);
_M_local_iterators = 0;
detach_all(_M_const_local_iterators);
_M_const_local_iterators = 0;
}
void
_Safe_unordered_sequence_base::
_M_swap(_Safe_unordered_sequence_base& __x)
{
// We need to lock both sequences to swap
using namespace __gnu_cxx;
__mutex *__this_mutex = &_M_get_mutex();
__mutex *__x_mutex = &__x._M_get_mutex();
if (__this_mutex == __x_mutex)
{
__scoped_lock __lock(*__this_mutex);
swap_useq(*this, __x);
}
else
{
__scoped_lock __l1(__this_mutex < __x_mutex
? *__this_mutex : *__x_mutex);
__scoped_lock __l2(__this_mutex < __x_mutex
? *__x_mutex : *__this_mutex);
swap_useq(*this, __x);
}
}
void
_Safe_unordered_sequence_base::
_M_attach_local(_Safe_iterator_base* __it, bool __constant)
{
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
_M_attach_local_single(__it, __constant);
}
void
_Safe_unordered_sequence_base::
_M_attach_local_single(_Safe_iterator_base* __it, bool __constant) throw ()
{
_Safe_iterator_base*& __its =
__constant ? _M_const_local_iterators : _M_local_iterators;
__it->_M_next = __its;
if (__it->_M_next)
__it->_M_next->_M_prior = __it;
__its = __it;
}
void
_Safe_unordered_sequence_base::
_M_detach_local(_Safe_iterator_base* __it)
{
// Remove __it from this sequence's list
__gnu_cxx::__scoped_lock sentry(_M_get_mutex());
_M_detach_local_single(__it);
}
void
_Safe_unordered_sequence_base::
_M_detach_local_single(_Safe_iterator_base* __it) throw ()
{
// Remove __it from this sequence's list
__it->_M_unlink();
if (_M_const_local_iterators == __it)
_M_const_local_iterators = __it->_M_next;
if (_M_local_iterators == __it)
_M_local_iterators = __it->_M_next;
}
void
_Error_formatter::_Parameter::
_M_print_field(const _Error_formatter* __formatter, const char* __name) const
......
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::invalid_local_iterator_compare<std::unordered_map<int, int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::invalid_local_iterator_range<std::unordered_map<int, int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::use_erased_local_iterator<std::unordered_map<int, int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/checks.h>
void test01()
{
__gnu_test::use_invalid_iterator<std::unordered_map<int, int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::use_invalid_local_iterator<std::unordered_map<int, int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
typedef std::unordered_multimap<int, int> cont_type;
__gnu_test::invalid_local_iterator_compare<cont_type>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
typedef std::unordered_multimap<int, int> cont_type;
__gnu_test::invalid_local_iterator_range<cont_type>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
typedef std::unordered_multimap<int, int> cont_type;
__gnu_test::use_erased_local_iterator<cont_type>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/checks.h>
void test01()
{
typedef std::unordered_multimap<int, int> cont_type;
__gnu_test::use_invalid_iterator<cont_type>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_map>
#include <debug/unordered_checks.h>
void test01()
{
typedef std::unordered_multimap<int, int> cont_type;
__gnu_test::use_invalid_local_iterator<cont_type>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::invalid_local_iterator_compare<std::unordered_multiset<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::invalid_local_iterator_range<std::unordered_multiset<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::use_erased_local_iterator<std::unordered_multiset<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/checks.h>
void test01()
{
__gnu_test::use_invalid_iterator<std::unordered_multiset<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::use_invalid_local_iterator<std::unordered_multiset<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::invalid_local_iterator_compare<std::unordered_set<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::invalid_local_iterator_range<std::unordered_set<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::use_erased_local_iterator<std::unordered_set<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/checks.h>
void test01()
{
__gnu_test::use_invalid_iterator<std::unordered_set<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// { dg-require-debug-mode "" }
// { dg-options "-std=gnu++0x" }
// { dg-do run { xfail *-*-* } }
#include <unordered_set>
#include <debug/unordered_checks.h>
void test01()
{
__gnu_test::use_invalid_local_iterator<std::unordered_set<int>>();
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2010 Free Software Foundation, Inc.
// Copyright (C) 2010, 2011 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
......@@ -45,7 +45,7 @@ namespace __gnu_test
{
typedef _Tp value_type;
operator value_type()
value_type build()
{
static value_type _S_;
++_S_;
......@@ -60,7 +60,7 @@ namespace __gnu_test
typedef _Tp2 second_type;
typedef std::pair<_Tp1, _Tp2> pair_type;
operator pair_type()
pair_type build()
{
static first_type _S_1;
static second_type _S_2;
......@@ -86,7 +86,7 @@ namespace __gnu_test
vector_type v;
for (int i = 0; i != 5; ++i)
v.push_back(gu);
v.push_back(gu.build());
VERIFY(v.size() == 5);
const val_type* first = &v.front() + 1;
......@@ -116,7 +116,7 @@ namespace __gnu_test
vector_type v;
for (int i = 0; i != 5; ++i)
v.push_back(gu);
v.push_back(gu.build());
VERIFY(v.size() == 5);
typename vector_type::iterator first = v.begin() + 1;
......@@ -145,7 +145,7 @@ namespace __gnu_test
list_type l;
for (int i = 0; i != 5; ++i)
l.push_back(gu);
l.push_back(gu.build());
VERIFY(l.size() == 5);
typename list_type::iterator first = l.begin(); ++first;
......@@ -174,7 +174,7 @@ namespace __gnu_test
vector_type v;
for (int i = 0; i != 5; ++i)
v.push_back(gu);
v.push_back(gu.build());
VERIFY(v.size() == 5);
val_type *first = &v.front() + 1;
......@@ -201,7 +201,7 @@ namespace __gnu_test
vector_type v;
for (int i = 0; i != 5; ++i)
v.push_back(gu);
v.push_back(gu.build());
VERIFY(v.size() == 5);
typename vector_type::iterator first = v.begin() + 1;
......@@ -228,7 +228,7 @@ namespace __gnu_test
list_type l;
for (int i = 0; i != 5; ++i)
l.push_back(gu);
l.push_back(gu.build());
VERIFY(l.size() == 5);
typename list_type::iterator first = l.begin(); ++first;
......@@ -304,7 +304,7 @@ namespace __gnu_test
vector_type v;
for (int i = 0; i != 5; ++i)
v.push_back(gu);
v.push_back(gu.build());
VERIFY(v.size() == 5);
const val_type* first = &v.front() + 1;
......@@ -333,7 +333,7 @@ namespace __gnu_test
vector_type v;
for (int i = 0; i != 5; ++i)
v.push_back(gu);
v.push_back(gu.build());
VERIFY(v.size() == 5);
typename vector_type::iterator first = v.begin() + 1;
......@@ -362,7 +362,7 @@ namespace __gnu_test
list_type l;
for (int i = 0; i != 5; ++i)
l.push_back(gu);
l.push_back(gu.build());
VERIFY(l.size() == 5);
typename list_type::iterator first = l.begin(); ++first;
......@@ -375,5 +375,25 @@ namespace __gnu_test
cont_type c2;
InsertRangeHelper<cont_type>::Insert(c2, last, first); // Expected failure
}
template<typename _Tp>
void use_invalid_iterator()
{
bool test __attribute__((unused)) = true;
typedef _Tp cont_type;
typedef typename cont_type::value_type cont_val_type;
typedef typename CopyableValueType<cont_val_type>::value_type val_type;
generate_unique<val_type> gu;
cont_type c;
for (size_t i = 0; i != 5; ++i)
c.insert(gu.build());
typename cont_type::iterator it = c.begin();
cont_val_type val = *it;
c.clear();
VERIFY( *it == val );
}
}
// Copyright (C) 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
#include <testsuite_hooks.h>
namespace __gnu_test
{
template<typename _Tp>
struct CopyableValueType
{
typedef _Tp value_type;
};
template<typename _Tp1, typename _Tp2>
struct CopyableValueType<std::pair<const _Tp1, _Tp2> >
{
typedef std::pair<_Tp1, _Tp2> value_type;
};
template<typename _Tp>
struct generate_unique
{
typedef _Tp value_type;
value_type build()
{
static value_type _S_;
++_S_;
return _S_;
}
};
template<typename _Tp1, typename _Tp2>
struct generate_unique<std::pair<_Tp1, _Tp2> >
{
typedef _Tp1 first_type;
typedef _Tp2 second_type;
typedef std::pair<_Tp1, _Tp2> pair_type;
pair_type build()
{
static first_type _S_1;
static second_type _S_2;
++_S_1;
++_S_2;
return pair_type(_S_1, _S_2);
}
};
template<typename _Tp>
struct KeyExtractor
{
static _Tp get_key(const _Tp& val)
{ return val; }
};
template<typename _Tp1, typename _Tp2>
struct KeyExtractor<std::pair<const _Tp1, _Tp2>>
{
static _Tp1 get_key(const std::pair<const _Tp1, _Tp2>& val)
{ return val.first; }
};
template<typename _Tp>
void use_erased_local_iterator()
{
bool test __attribute__((unused)) = true;
typedef _Tp cont_type;
typedef typename cont_type::value_type cont_val_type;
typedef typename CopyableValueType<cont_val_type>::value_type val_type;
generate_unique<val_type> gu;
cont_type c;
for (size_t i = 0; i != 5; ++i)
c.insert(gu.build());
typename cont_type::local_iterator it, end;
for (size_t i = 0; i != c.bucket_count(); ++i)
{
it = c.begin(i);
end = c.end(i);
if (it != end)
break;
}
typename cont_type::key_type key = KeyExtractor<cont_val_type>::get_key(*it);
c.erase(key);
VERIFY( it != end );
}
template<typename _Tp>
void use_invalid_local_iterator()
{
bool test __attribute__((unused)) = true;
typedef _Tp cont_type;
typedef typename cont_type::value_type cont_val_type;
typedef typename CopyableValueType<cont_val_type>::value_type val_type;
generate_unique<val_type> gu;
cont_type c;
for (size_t i = 0; i != 5; ++i)
c.insert(gu.build());
typename cont_type::local_iterator it;
for (size_t i = 0; i != c.bucket_count(); ++i)
{
it = c.begin(i);
if (it != c.end(i))
break;
}
cont_val_type val = *it;
c.clear();
VERIFY( *it == val );
}
template<typename _Tp>
void invalid_local_iterator_compare()
{
bool test __attribute__((unused)) = true;
typedef _Tp cont_type;
typedef typename cont_type::value_type cont_val_type;
typedef typename CopyableValueType<cont_val_type>::value_type val_type;
generate_unique<val_type> gu;
cont_type c;
for (size_t i = 0; i != 5; ++i)
c.insert(gu.build());
typename cont_type::local_iterator it1, it2;
size_t i;
for (i = 0; i != c.bucket_count(); ++i)
{
it1 = c.begin(i);
if (it1 != c.end(i))
break;
}
VERIFY( i != c.bucket_count() );
for (++i; i != c.bucket_count(); ++i)
{
it2 = c.begin(i);
if (it2 != c.end(i))
break;
}
VERIFY( it1 != it2 );
}
template<typename _Tp>
void invalid_local_iterator_range()
{
bool test __attribute__((unused)) = true;
typedef _Tp cont_type;
typedef typename cont_type::value_type cont_val_type;
typedef typename CopyableValueType<cont_val_type>::value_type val_type;
generate_unique<val_type> gu;
cont_type c;
for (size_t i = 0; i != 5; ++i)
c.insert(gu.build());
typename cont_type::local_iterator it, end;
for (size_t i = 0; i != c.bucket_count(); ++i)
{
it = c.begin(i);
end = c.end(i);
if (it != end)
break;
}
c.insert(end, it);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment