[libcxx] r189114 - Debug mode for string. This commit also marks the first time libc++ debug-mode has found a bug (found one in regex). Had to play with extern templates a bit to get this to work since string is heavily used within libc++.dylib.

Howard Hinnant hhinnant at apple.com
Fri Aug 23 10:37:06 PDT 2013


Author: hhinnant
Date: Fri Aug 23 12:37:05 2013
New Revision: 189114

URL: http://llvm.org/viewvc/llvm-project?rev=189114&view=rev
Log:
Debug mode for string.  This commit also marks the first time libc++ debug-mode has found a bug (found one in regex).  Had to play with extern templates a bit to get this to work since string is heavily used within libc++.dylib.

Added:
    libcxx/trunk/test/strings/basic.string/string.access/db_back.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.access/db_cback.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.access/db_cfront.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.access/db_cindex.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.access/db_front.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.access/db_index.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_2.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_3.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_4.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_5.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_6.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_7.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_8.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp
Modified:
    libcxx/trunk/include/__config
    libcxx/trunk/include/__debug
    libcxx/trunk/include/__locale
    libcxx/trunk/include/algorithm
    libcxx/trunk/include/iterator
    libcxx/trunk/include/locale
    libcxx/trunk/include/regex
    libcxx/trunk/include/string
    libcxx/trunk/src/debug.cpp
    libcxx/trunk/test/strings/basic.string/string.access/back.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.access/front.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.access/index.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp
    libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp

Modified: libcxx/trunk/include/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Fri Aug 23 12:37:05 2013
@@ -525,10 +525,25 @@ template <unsigned> struct __static_asse
 #define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x)
 #endif  // _LIBCPP_HAS_NO_STRONG_ENUMS
 
+#ifdef _LIBCPP_DEBUG2
+#   if _LIBCPP_DEBUG2 == 0
+#       define _LIBCPP_DEBUG_LEVEL 1
+#   elif _LIBCPP_DEBUG2 == 1
+#       define _LIBCPP_DEBUG_LEVEL 2
+#   else
+#       error Supported values for _LIBCPP_DEBUG2 are 0 and 1
+#   endif
+#   define _LIBCPP_EXTERN_TEMPLATE(...)
+#endif
+
 #ifndef _LIBCPP_EXTERN_TEMPLATE
 #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
 #endif
 
+#ifndef _LIBCPP_EXTERN_TEMPLATE2
+#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;
+#endif
+
 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__) || defined(__NetBSD__)
 #define _LIBCPP_LOCALE__L_EXTENSIONS 1
 #endif
@@ -544,16 +559,6 @@ template <unsigned> struct __static_asse
 #define _LIBCPP_WCTYPE_IS_MASK
 #endif
 
-#ifdef _LIBCPP_DEBUG2
-#   if _LIBCPP_DEBUG2 == 0
-#       define _LIBCPP_DEBUG_LEVEL 1
-#   elif _LIBCPP_DEBUG2 == 1
-#       define _LIBCPP_DEBUG_LEVEL 2
-#   else
-#       error Supported values for _LIBCPP_DEBUG2 are 0 and 1
-#   endif
-#endif
-
 #ifndef _LIBCPP_STD_VER
 #  if  __cplusplus <= 201103L
 #    define _LIBCPP_STD_VER 11

Modified: libcxx/trunk/include/__debug
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__debug?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/__debug (original)
+++ libcxx/trunk/include/__debug Fri Aug 23 12:37:05 2013
@@ -11,6 +11,10 @@
 #ifndef _LIBCPP_DEBUG_H
 #define _LIBCPP_DEBUG_H
 
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
 #if _LIBCPP_DEBUG_LEVEL >= 1
 
 #   include <cstdlib>
@@ -24,10 +28,6 @@
 
 #if _LIBCPP_DEBUG_LEVEL >= 2
 
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct _LIBCPP_TYPE_VIS __c_node;
@@ -38,8 +38,15 @@ struct _LIBCPP_TYPE_VIS __i_node
     __i_node* __next_;
     __c_node* __c_;
 
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
     __i_node(const __i_node&) = delete;
     __i_node& operator=(const __i_node&) = delete;
+#else
+private:
+    __i_node(const __i_node&);
+    __i_node& operator=(const __i_node&);
+public:
+#endif
     _LIBCPP_INLINE_VISIBILITY
     __i_node(void* __i, __i_node* __next, __c_node* __c)
         : __i_(__i), __next_(__next), __c_(__c) {}
@@ -54,8 +61,15 @@ struct _LIBCPP_TYPE_VIS __c_node
     __i_node** end_;
     __i_node** cap_;
 
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
     __c_node(const __c_node&) = delete;
     __c_node& operator=(const __c_node&) = delete;
+#else
+private:
+    __c_node(const __c_node&);
+    __c_node& operator=(const __c_node&);
+public:
+#endif
     _LIBCPP_INLINE_VISIBILITY
     __c_node(void* __c, __c_node* __next)
         : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
@@ -134,8 +148,15 @@ class _LIBCPP_TYPE_VIS __libcpp_db
 
     __libcpp_db();
 public:
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
     __libcpp_db(const __libcpp_db&) = delete;
     __libcpp_db& operator=(const __libcpp_db&) = delete;
+#else
+private:
+    __libcpp_db(const __libcpp_db&);
+    __libcpp_db& operator=(const __libcpp_db&);
+public:
+#endif
     ~__libcpp_db();
 
     class __db_c_iterator;

Modified: libcxx/trunk/include/__locale
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__locale?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/__locale (original)
+++ libcxx/trunk/include/__locale Fri Aug 23 12:37:05 2013
@@ -256,8 +256,8 @@ collate<_CharT>::do_hash(const char_type
     return static_cast<long>(__h);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS collate<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS collate<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
 
 // template <class CharT> class collate_byname;
 
@@ -1147,10 +1147,10 @@ codecvt_byname<_InternT, _ExternT, _Stat
 {
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
 
 _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
 

Modified: libcxx/trunk/include/algorithm
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/algorithm?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/algorithm (original)
+++ libcxx/trunk/include/algorithm Fri Aug 23 12:37:05 2013
@@ -1692,6 +1692,8 @@ __unwrap_iter(move_iterator<_Tp*> __i)
     return __i.base();
 }
 
+#if _LIBCPP_DEBUG_LEVEL < 2
+
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
@@ -1704,6 +1706,8 @@ __unwrap_iter(__wrap_iter<_Tp*> __i)
     return __i.base();
 }
 
+#endif  // _LIBCPP_DEBUG_LEVEL < 2
+
 template <class _InputIterator, class _OutputIterator>
 inline _LIBCPP_INLINE_VISIBILITY
 _OutputIterator

Modified: libcxx/trunk/include/iterator
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/iterator?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/iterator (original)
+++ libcxx/trunk/include/iterator Fri Aug 23 12:37:05 2013
@@ -1197,12 +1197,13 @@ public:
     _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;}
 
 private:
-    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
 #if _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x)
     {
         __get_db()->__insert_ic(this, __p);
     }
+#else
+    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
 #endif
 
     template <class _Up> friend class __wrap_iter;

Modified: libcxx/trunk/include/locale
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/locale?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/locale (original)
+++ libcxx/trunk/include/locale Fri Aug 23 12:37:05 2013
@@ -687,8 +687,8 @@ __num_get<_CharT>::__stage2_float_loop(_
     return 0;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(struct _LIBCPP_TYPE_VIS __num_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>)
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 class _LIBCPP_TYPE_VIS_ONLY num_get
@@ -1436,8 +1436,8 @@ num_get<_CharT, _InputIterator>::do_get(
     return __b;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS num_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>)
 
 struct _LIBCPP_TYPE_VIS __num_put_base
 {
@@ -1586,8 +1586,8 @@ __num_put<_CharT>::__widen_and_group_flo
         __op = __ob + (__np - __nb);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(struct _LIBCPP_TYPE_VIS __num_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>)
 
 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
 class _LIBCPP_TYPE_VIS_ONLY num_put
@@ -1770,7 +1770,12 @@ num_put<_CharT, _OutputIterator>::do_put
         return do_put(__s, __iob, __fl, (unsigned long)__v);
     const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc());
     typedef typename numpunct<char_type>::string_type string_type;
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    string_type __tmp(__v ? __np.truename() : __np.falsename());
+    string_type __nm = _VSTD::move(__tmp);
+#else
     string_type __nm = __v ? __np.truename() : __np.falsename();
+#endif
     for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s)
         *__s = *__i;
     return __s;
@@ -2066,8 +2071,8 @@ num_put<_CharT, _OutputIterator>::do_put
     return __pad_and_output(__s, __o, __op, __oe, __iob, __fl);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS num_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS num_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>)
 
 template <class _CharT, class _InputIterator>
 _LIBCPP_HIDDEN
@@ -2733,8 +2738,8 @@ time_get<_CharT, _InputIterator>::do_get
     return __b;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>)
 
 class _LIBCPP_TYPE_VIS __time_get
 {
@@ -2816,8 +2821,8 @@ private:
     virtual const string_type& __X() const      {return this->__X_;}
 };
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_get_byname<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>)
 
 class _LIBCPP_TYPE_VIS __time_put
 {
@@ -2929,8 +2934,8 @@ time_put<_CharT, _OutputIterator>::do_pu
     return _VSTD::copy(__nb, __ne, __s);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>)
 
 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
 class _LIBCPP_TYPE_VIS_ONLY time_put_byname
@@ -2950,8 +2955,8 @@ protected:
     ~time_put_byname() {}
 };
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_put_byname<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>)
 
 // money_base
 
@@ -3017,10 +3022,10 @@ template <class _CharT, bool _Internatio
 const bool
 moneypunct<_CharT, _International>::intl;
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>)
 
 // moneypunct_byname
 
@@ -3074,10 +3079,10 @@ template<> void moneypunct_byname<char,
 template<> void moneypunct_byname<wchar_t, false>::init(const char*);
 template<> void moneypunct_byname<wchar_t, true>::init(const char*);
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>)
 
 // money_get
 
@@ -3133,8 +3138,8 @@ __money_get<_CharT>::__gather_info(bool
     }
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __money_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>)
 
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 class _LIBCPP_TYPE_VIS_ONLY money_get
@@ -3514,8 +3519,8 @@ money_get<_CharT, _InputIterator>::do_ge
     return __b;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS money_get<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>)
 
 // money_put
 
@@ -3689,8 +3694,8 @@ __money_put<_CharT>::__format(char_type*
         __mi = __mb;
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __money_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>)
 
 template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> >
 class _LIBCPP_TYPE_VIS_ONLY money_put
@@ -3846,8 +3851,8 @@ money_put<_CharT, _OutputIterator>::do_p
     return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl);
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS money_put<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>)
 
 // messages
 
@@ -3956,8 +3961,8 @@ messages<_CharT>::do_close(catalog __c)
 #endif // !_WIN32
 }
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS messages<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS messages<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>)
 
 template <class _CharT>
 class _LIBCPP_TYPE_VIS_ONLY messages_byname
@@ -3980,8 +3985,8 @@ protected:
     ~messages_byname() {}
 };
 
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS messages_byname<char>)
-_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>)
+_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>)
 
 template<class _Codecvt, class _Elem = wchar_t,
          class _Wide_alloc = allocator<_Elem>,

Modified: libcxx/trunk/include/regex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/regex?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/regex (original)
+++ libcxx/trunk/include/regex Fri Aug 23 12:37:05 2013
@@ -3785,7 +3785,7 @@ basic_regex<_CharT, _Traits>::__parse_ex
                 }
                 __ml->__add_range(_VSTD::move(__start_range), _VSTD::move(__end_range));
             }
-            else
+            else if (!__start_range.empty())
             {
                 if (__start_range.size() == 1)
                     __ml->__add_char(__start_range[0]);
@@ -3793,7 +3793,7 @@ basic_regex<_CharT, _Traits>::__parse_ex
                     __ml->__add_digraph(__start_range[0], __start_range[1]);
             }
         }
-        else
+        else if (!__start_range.empty())
         {
             if (__start_range.size() == 1)
                 __ml->__add_char(__start_range[0]);

Modified: libcxx/trunk/include/string
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/string?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/include/string (original)
+++ libcxx/trunk/include/string Fri Aug 23 12:37:05 2013
@@ -447,7 +447,7 @@ basic_string<char32_t> operator "" s( co
 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
 #include <cstdint>
 #endif
-#if defined(_LIBCPP_NO_EXCEPTIONS) || defined(_LIBCPP_DEBUG)
+#if defined(_LIBCPP_NO_EXCEPTIONS)
 #include <cassert>
 #endif
 
@@ -605,6 +605,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 _CharT*
 char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     char_type* __r = __s1;
     for (; __n; --__n, ++__s1, ++__s2)
         assign(*__s1, *__s2);
@@ -656,7 +657,10 @@ struct _LIBCPP_TYPE_VIS_ONLY char_traits
         {return (char_type*)memmove(__s1, __s2, __n);}
     _LIBCPP_INLINE_VISIBILITY
     static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
-        {return (char_type*)memcpy(__s1, __s2, __n);}
+        {
+            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            return (char_type*)memcpy(__s1, __s2, __n);
+        }
     _LIBCPP_INLINE_VISIBILITY
     static char_type* assign(char_type* __s, size_t __n, char_type __a)
         {return (char_type*)memset(__s, to_int_type(__a), __n);}
@@ -713,7 +717,10 @@ struct _LIBCPP_TYPE_VIS_ONLY char_traits
         {return (char_type*)wmemmove(__s1, __s2, __n);}
     _LIBCPP_INLINE_VISIBILITY
     static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n)
-        {return (char_type*)wmemcpy(__s1, __s2, __n);}
+        {
+            _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+            return (char_type*)wmemcpy(__s1, __s2, __n);
+        }
     _LIBCPP_INLINE_VISIBILITY
     static char_type* assign(char_type* __s, size_t __n, char_type __a)
         {return (char_type*)wmemset(__s, __a, __n);}
@@ -841,6 +848,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 char16_t*
 char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     char_type* __r = __s1;
     for (; __n; --__n, ++__s1, ++__s2)
         assign(*__s1, *__s2);
@@ -961,6 +969,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 char32_t*
 char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n)
 {
+    _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     char_type* __r = __s1;
     for (; __n; --__n, ++__s1, ++__s2)
         assign(*__s1, *__s2);
@@ -1072,13 +1081,13 @@ public:
     typedef const value_type&                            const_reference;
     typedef typename __alloc_traits::pointer             pointer;
     typedef typename __alloc_traits::const_pointer       const_pointer;
-#ifdef _LIBCPP_DEBUG
-    typedef __debug_iter<basic_string, pointer>          iterator;
-    typedef __debug_iter<basic_string, const_pointer>    const_iterator;
-
-    friend class __debug_iter<basic_string, pointer>;
-    friend class __debug_iter<basic_string, const_pointer>;
-#elif defined(_LIBCPP_RAW_ITERATORS)
+
+    static_assert(is_pod<value_type>::value, "Character type of basic_string must be a POD");
+    static_assert((is_same<_CharT, value_type>::value),
+                  "traits_type::char_type must be the same type as CharT");
+    static_assert((is_same<typename allocator_type::value_type, value_type>::value),
+                  "Allocator::value_type must be same type as value_type");
+#if defined(_LIBCPP_RAW_ITERATORS)
     typedef pointer                                      iterator;
     typedef const_pointer                                const_iterator;
 #else  // defined(_LIBCPP_RAW_ITERATORS)
@@ -1152,9 +1161,9 @@ private:
 
 #endif  // _LIBCPP_ALTERNATE_STRING_LAYOUT
 
-    union __lx{__long __lx; __short __lxx;};
+    union __ulx{__long __lx; __short __lxx;};
 
-    enum {__n_words = sizeof(__lx) / sizeof(size_type)};
+    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
 
     struct __raw
     {
@@ -1173,15 +1182,6 @@ private:
 
     __compressed_pair<__rep, allocator_type> __r_;
 
-#ifdef _LIBCPP_DEBUG
-
-    pair<iterator*, const_iterator*> __iterator_list_;
-
-    _LIBCPP_INLINE_VISIBILITY iterator*&       __get_iterator_list(iterator*)       {return __iterator_list_.first;}
-    _LIBCPP_INLINE_VISIBILITY const_iterator*& __get_iterator_list(const_iterator*) {return __iterator_list_.second;}
-
-#endif  // _LIBCPP_DEBUG
-
 public:
     static const size_type npos = -1;
 
@@ -1239,7 +1239,20 @@ public:
     basic_string& operator=(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());}
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 
-#ifndef _LIBCPP_DEBUG
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_INLINE_VISIBILITY
+    iterator begin() _NOEXCEPT
+        {return iterator(this, __get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator begin() const _NOEXCEPT
+        {return const_iterator(this, __get_pointer());}
+    _LIBCPP_INLINE_VISIBILITY
+    iterator end() _NOEXCEPT
+        {return iterator(this, __get_pointer() + size());}
+    _LIBCPP_INLINE_VISIBILITY
+    const_iterator end() const _NOEXCEPT
+        {return const_iterator(this, __get_pointer() + size());}
+#else
     _LIBCPP_INLINE_VISIBILITY
     iterator begin() _NOEXCEPT
         {return iterator(__get_pointer());}
@@ -1252,12 +1265,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     const_iterator end() const _NOEXCEPT
         {return const_iterator(__get_pointer() + size());}
-#else  // _LIBCPP_DEBUG
-    _LIBCPP_INLINE_VISIBILITY iterator       begin()       {return iterator(this, __get_pointer());}
-    _LIBCPP_INLINE_VISIBILITY const_iterator begin() const {return const_iterator(this, data());}
-    _LIBCPP_INLINE_VISIBILITY iterator       end()         {return iterator(this, __get_pointer() + size());}
-    _LIBCPP_INLINE_VISIBILITY const_iterator end() const   {return const_iterator(this, data() + size());}
-#endif  // _LIBCPP_DEBUG
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_INLINE_VISIBILITY
     reverse_iterator rbegin() _NOEXCEPT
         {return reverse_iterator(end());}
@@ -1520,6 +1528,15 @@ public:
     bool __is_long() const _NOEXCEPT
         {return bool(__r_.first().__s.__size_ & __short_mask);}
 
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 private:
     _LIBCPP_INLINE_VISIBILITY
     allocator_type& __alloc() _NOEXCEPT
@@ -1732,60 +1749,43 @@ private:
 };
 
 template <class _CharT, class _Traits, class _Allocator>
-#ifndef _LIBCPP_DEBUG
 _LIBCPP_INLINE_VISIBILITY inline
-#endif
 void
 basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators()
 {
-#ifdef _LIBCPP_DEBUG
-    iterator::__remove_all(this);
-    const_iterator::__remove_all(this);
-#endif  // _LIBCPP_DEBUG
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__invalidate_all(this);
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
 }
 
 template <class _CharT, class _Traits, class _Allocator>
-#ifndef _LIBCPP_DEBUG
 _LIBCPP_INLINE_VISIBILITY inline
-#endif
 void
 basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type
-#ifdef _LIBCPP_DEBUG
+#if _LIBCPP_DEBUG_LEVEL >= 2
                                                                         __pos
 #endif
                                                                       )
 {
-#ifdef _LIBCPP_DEBUG
-    const_iterator __beg = begin();
-    if (__iterator_list_.first)
-    {
-        for (iterator* __p = __iterator_list_.first; __p;)
-        {
-            if (*__p - __beg > static_cast<difference_type>(__pos))
-            {
-                iterator* __n = __p;
-                __p = __p->__next;
-                __n->__remove_owner();
-            }
-            else
-                __p = __p->__next;
-        }
-    }
-    if (__iterator_list_.second)
-    {
-        for (const_iterator* __p = __iterator_list_.second; __p;)
-        {
-            if (*__p - __beg > static_cast<difference_type>(__pos))
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __c_node* __c = __get_db()->__find_c_and_lock(this);
+    if (__c)
+    {
+        const_pointer __new_last = __get_pointer() + __pos;
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
+        {
+            --__p;
+            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+            if (__i->base() > __new_last)
             {
-                const_iterator* __n = __p;
-                __p = __p->__next;
-                __n->__remove_owner();
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
             }
-            else
-                __p = __p->__next;
         }
+        __get_db()->unlock();
     }
-#endif  // _LIBCPP_DEBUG
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1793,6 +1793,9 @@ _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string()
     _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __zero();
 }
 
@@ -1801,6 +1804,9 @@ _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
     : __r_(__a)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
     __zero();
 }
 
@@ -1856,10 +1862,11 @@ template <class _CharT, class _Traits, c
 _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
     __init(__s, traits_type::length(__s));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1867,20 +1874,22 @@ _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
     : __r_(__a)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
     __init(__s, traits_type::length(__s));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
     __init(__s, __n);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1888,10 +1897,11 @@ _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
     : __r_(__a)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
     __init(__s, __n);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1902,6 +1912,9 @@ basic_string<_CharT, _Traits, _Allocator
         __r_.first().__r = __str.__r_.first().__r;
     else
         __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1912,6 +1925,9 @@ basic_string<_CharT, _Traits, _Allocator
         __r_.first().__r = __str.__r_.first().__r;
     else
         __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1923,8 +1939,10 @@ basic_string<_CharT, _Traits, _Allocator
     : __r_(_VSTD::move(__str.__r_))
 {
     __str.__zero();
-#ifdef _LIBCPP_DEBUG
-    __str.__invalidate_all_iterators();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    if (__is_long())
+        __get_db()->swap(this, &__str);
 #endif
 }
 
@@ -1938,8 +1956,10 @@ basic_string<_CharT, _Traits, _Allocator
     else
         __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
     __str.__zero();
-#ifdef _LIBCPP_DEBUG
-    __str.__invalidate_all_iterators();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+    if (__is_long())
+        __get_db()->swap(this, &__str);
 #endif
 }
 
@@ -1974,6 +1994,9 @@ _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
 {
     __init(__n, __c);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1982,6 +2005,9 @@ basic_string<_CharT, _Traits, _Allocator
     : __r_(__a)
 {
     __init(__n, __c);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -1993,6 +2019,9 @@ basic_string<_CharT, _Traits, _Allocator
     if (__pos > __str_sz)
         this->__throw_out_of_range();
     __init(__str.data() + __pos, _VSTD::min(__n, __str_sz - __pos));
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2060,6 +2089,9 @@ _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last)
 {
     __init(__first, __last);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2070,6 +2102,9 @@ basic_string<_CharT, _Traits, _Allocator
     : __r_(__a)
 {
     __init(__first, __last);
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2079,6 +2114,9 @@ _LIBCPP_INLINE_VISIBILITY inline
 basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
 {
     __init(__il.begin(), __il.end());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2087,6 +2125,9 @@ basic_string<_CharT, _Traits, _Allocator
     : __r_(__a)
 {
     __init(__il.begin(), __il.end());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2094,7 +2135,9 @@ basic_string<_CharT, _Traits, _Allocator
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>::~basic_string()
 {
-    __invalidate_all_iterators();
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    __get_db()->__erase_c(this);
+#endif
     if (__is_long())
         __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap());
 }
@@ -2166,9 +2209,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign recieved nullptr");
     size_type __cap = capacity();
     if (__cap >= __n)
     {
@@ -2342,9 +2383,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::assign recieved nullptr");
     return assign(__s, traits_type::length(__s));
 }
 
@@ -2354,9 +2393,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append recieved nullptr");
     size_type __cap = capacity();
     size_type __sz = size();
     if (__cap - __sz >= __n)
@@ -2493,9 +2530,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::append recieved nullptr");
     return append(__s, traits_type::length(__s));
 }
 
@@ -2505,9 +2540,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert recieved nullptr");
     size_type __sz = size();
     if (__pos > __sz)
         this->__throw_out_of_range();
@@ -2576,13 +2609,22 @@ typename enable_if
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, range) called with an iterator not"
+        " referring to this string");
+#endif
     size_type __old_sz = size();
     difference_type __ip = __pos - begin();
     for (; __first != __last; ++__first)
         push_back(*__first);
     pointer __p = __get_pointer();
     _VSTD::rotate(__p + __ip, __p + __old_sz, __p + size());
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    return iterator(this, __p + __ip);
+#else
     return iterator(__p + __ip);
+#endif
 }
 
 template <class _CharT, class _Traits, class _Allocator>
@@ -2594,6 +2636,11 @@ typename enable_if
 >::type
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, range) called with an iterator not"
+        " referring to this string");
+#endif
     size_type __ip = static_cast<size_type>(__pos - begin());
     size_type __sz = size();
     size_type __cap = capacity();
@@ -2645,9 +2692,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::insert recieved nullptr");
     return insert(__pos, __s, traits_type::length(__s));
 }
 
@@ -2682,6 +2727,11 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::insert(iterator, n, value) called with an iterator not"
+        " referring to this string");
+#endif
     difference_type __p = __pos - begin();
     insert(static_cast<size_type>(__p), __n, __c);
     return begin() + __p;
@@ -2693,9 +2743,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace recieved nullptr");
     size_type __sz = size();
     if (__pos > __sz)
         this->__throw_out_of_range();
@@ -2827,9 +2875,7 @@ template <class _CharT, class _Traits, c
 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::replace recieved nullptr");
     return replace(__pos, __n1, __s, traits_type::length(__s));
 }
 
@@ -2895,6 +2941,13 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this,
+        "string::erase(iterator) called with an iterator not"
+        " referring to this string");
+#endif
+    _LIBCPP_ASSERT(__pos != end(),
+        "string::erase(iterator) called with a non-dereferenceable iterator");
     iterator __b = begin();
     size_type __r = static_cast<size_type>(__pos - __b);
     erase(__r, 1);
@@ -2906,6 +2959,12 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::iterator
 basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+        "string::erase(iterator,  iterator) called with an iterator not"
+        " referring to this string");
+#endif
+    _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range");
     iterator __b = begin();
     size_type __r = static_cast<size_type>(__first - __b);
     erase(__r, static_cast<size_type>(__last - __first));
@@ -2917,9 +2976,7 @@ _LIBCPP_INLINE_VISIBILITY inline
 void
 basic_string<_CharT, _Traits, _Allocator>::pop_back()
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
     size_type __sz;
     if (__is_long())
     {
@@ -3064,9 +3121,7 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const
 {
-#ifdef __LIBCPP_DEBUG
-    assert(__pos <= size());
-#endif
+    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
     return *(data() + __pos);
 }
 
@@ -3075,9 +3130,7 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos)
 {
-#ifdef __LIBCPP_DEBUG
-    assert(__pos < size());
-#endif
+    _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
     return *(__get_pointer() + __pos);
 }
 
@@ -3104,9 +3157,7 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::front()
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
     return *__get_pointer();
 }
 
@@ -3115,9 +3166,7 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::front() const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::front(): string is empty");
     return *data();
 }
 
@@ -3126,9 +3175,7 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::reference
 basic_string<_CharT, _Traits, _Allocator>::back()
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
     return *(__get_pointer() + size() - 1);
 }
 
@@ -3137,9 +3184,7 @@ _LIBCPP_INLINE_VISIBILITY inline
 typename basic_string<_CharT, _Traits, _Allocator>::const_reference
 basic_string<_CharT, _Traits, _Allocator>::back() const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(!empty());
-#endif
+    _LIBCPP_ASSERT(!empty(), "string::back(): string is empty");
     return *(data() + size() - 1);
 }
 
@@ -3170,12 +3215,15 @@ basic_string<_CharT, _Traits, _Allocator
         _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<allocator_type>::value)
 {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+    if (!__is_long())
+        __get_db()->__invalidate_all(this);
+    if (!__str.__is_long())
+        __get_db()->__invalidate_all(&__str);
+    __get_db()->swap(this, &__str);
+#endif
     _VSTD::swap(__r_.first(), __str.__r_.first());
     __swap_alloc(__alloc(), __str.__alloc());
-#ifdef _LIBCPP_DEBUG
-    __invalidate_all_iterators();
-    __str.__invalidate_all_iterators();
-#endif  // _LIBCPP_DEBUG
 }
 
 // find
@@ -3195,9 +3243,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                 size_type __pos,
                                                 size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): recieved nullptr");
     size_type __sz = size();
     if (__pos > __sz || __sz - __pos < __n)
         return npos;
@@ -3226,9 +3272,7 @@ typename basic_string<_CharT, _Traits, _
 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s,
                                                 size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find(): recieved nullptr");
     return find(__s, __pos, traits_type::length(__s));
 }
 
@@ -3255,9 +3299,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                  size_type __pos,
                                                  size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): recieved nullptr");
     size_type __sz = size();
     __pos = _VSTD::min(__pos, __sz);
     if (__n < __sz - __pos)
@@ -3287,9 +3329,7 @@ typename basic_string<_CharT, _Traits, _
 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s,
                                                  size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): recieved nullptr");
     return rfind(__s, __pos, traits_type::length(__s));
 }
 
@@ -3323,9 +3363,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                          size_type __pos,
                                                          size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): recieved nullptr");
     size_type __sz = size();
     if (__pos >= __sz || __n == 0)
         return npos;
@@ -3352,9 +3390,7 @@ typename basic_string<_CharT, _Traits, _
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s,
                                                          size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): recieved nullptr");
     return find_first_of(__s, __pos, traits_type::length(__s));
 }
 
@@ -3375,9 +3411,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                         size_type __pos,
                                                         size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): recieved nullptr");
     if (__n != 0)
     {
         size_type __sz = size();
@@ -3411,9 +3445,7 @@ typename basic_string<_CharT, _Traits, _
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s,
                                                         size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): recieved nullptr");
     return find_last_of(__s, __pos, traits_type::length(__s));
 }
 
@@ -3434,9 +3466,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                              size_type __pos,
                                                              size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): recieved nullptr");
     size_type __sz = size();
     if (__pos < __sz)
     {
@@ -3464,9 +3494,7 @@ typename basic_string<_CharT, _Traits, _
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s,
                                                              size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): recieved nullptr");
     return find_first_not_of(__s, __pos, traits_type::length(__s));
 }
 
@@ -3496,9 +3524,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                             size_type __pos,
                                                             size_type __n) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): recieved nullptr");
     size_type __sz = size();
     if (__pos < __sz)
         ++__pos;
@@ -3526,9 +3552,7 @@ typename basic_string<_CharT, _Traits, _
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s,
                                                             size_type __pos) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): recieved nullptr");
     return find_last_not_of(__s, __pos, traits_type::length(__s));
 }
 
@@ -3599,9 +3623,7 @@ template <class _CharT, class _Traits, c
 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): recieved nullptr");
     return compare(0, npos, __s, traits_type::length(__s));
 }
 
@@ -3611,9 +3633,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                    size_type __n1,
                                                    const value_type* __s) const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__s != nullptr, "string::compare(): recieved nullptr");
     return compare(__pos1, __n1, __s, traits_type::length(__s));
 }
 
@@ -3624,9 +3644,7 @@ basic_string<_CharT, _Traits, _Allocator
                                                    const value_type* __s,
                                                    size_type __n2) const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__s != 0);
-#endif
+    _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): recieved nullptr");
     size_type __sz = size();
     if (__pos1 > __sz || __n2 == npos)
         this->__throw_out_of_range();
@@ -4102,6 +4120,42 @@ getline(basic_istream<_CharT, _Traits>&&
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
+#if _LIBCPP_DEBUG_LEVEL >= 2
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const
+{
+    return this->data() <= _VSTD::__to_raw_pointer(__i->base()) &&
+           _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const
+{
+    return this->data() < _VSTD::__to_raw_pointer(__i->base()) &&
+           _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
+    return this->data() <= __p && __p <= this->data() + this->size();
+}
+
+template<class _CharT, class _Traits, class _Allocator>
+bool
+basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n;
+    return this->data() <= __p && __p < this->data() + this->size();
+}
+
+#endif  // _LIBCPP_DEBUG_LEVEL >= 2
+
 #if _LIBCPP_STD_VER > 11 
 // Literal suffixes for basic_string [basic.string.literals]
 // inline // Deviation from N3690.
@@ -4140,10 +4194,7 @@ namespace literals
 
 _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>)
 _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>)
-
-extern template
-    string
-    operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
+_LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&))
 
 _LIBCPP_END_NAMESPACE_STD
 

Modified: libcxx/trunk/src/debug.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/debug.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/src/debug.cpp (original)
+++ libcxx/trunk/src/debug.cpp Fri Aug 23 12:37:05 2013
@@ -118,20 +118,19 @@ void
 __libcpp_db::__insert_ic(void* __i, const void* __c)
 {
     WLock _(mut());
-    __i_node* i = __insert_iterator(__i);
-    const char* errmsg =
-        "Container constructed in a translation unit with debug mode disabled."
-        " But it is being used in a translation unit with debug mode enabled."
-        " Enable it in the other translation unit with #define _LIBCPP_DEBUG2 1";
-    _LIBCPP_ASSERT(__cbeg_ != __cend_, errmsg);
+    if (__cbeg_ == __cend_)
+        return;
     size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
     __c_node* c = __cbeg_[hc];
-    _LIBCPP_ASSERT(c != nullptr, errmsg);
+    if (c == nullptr)
+        return;
     while (c->__c_ != __c)
     {
         c = c->__next_;
-        _LIBCPP_ASSERT(c != nullptr, errmsg);
+        if (c == nullptr)
+            return;
     }
+    __i_node* i = __insert_iterator(__i);
     c->__add(i);
     i->__c_ = c;
 }
@@ -217,18 +216,23 @@ void
 __libcpp_db::__invalidate_all(void* __c)
 {
     WLock _(mut());
-    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p = __cbeg_[hc];
-    _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all A");
-    while (p->__c_ != __c)
+    if (__cend_ != __cbeg_)
     {
-        p = p->__next_;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all B");
-    }
-    while (p->end_ != p->beg_)
-    {
-        --p->end_;
-        (*p->end_)->__c_ = nullptr;
+        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
+        __c_node* p = __cbeg_[hc];
+        if (p == nullptr)
+            return;
+        while (p->__c_ != __c)
+        {
+            p = p->__next_;
+            if (p == nullptr)
+                return;
+        }
+        while (p->end_ != p->beg_)
+        {
+            --p->end_;
+            (*p->end_)->__c_ = nullptr;
+        }
     }
 }
 
@@ -236,13 +240,26 @@ __c_node*
 __libcpp_db::__find_c_and_lock(void* __c) const
 {
     mut().lock();
+    if (__cend_ == __cbeg_)
+    {
+        mut().unlock();
+        return nullptr;
+    }
     size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
     __c_node* p = __cbeg_[hc];
-    _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock A");
+    if (p == nullptr)
+    {
+        mut().unlock();
+        return nullptr;
+    }
     while (p->__c_ != __c)
     {
         p = p->__next_;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock B");
+        if (p == nullptr)
+        {
+            mut().unlock();
+            return nullptr;
+        }
     }
     return p;
 }
@@ -271,28 +288,35 @@ void
 __libcpp_db::__erase_c(void* __c)
 {
     WLock _(mut());
-    size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
-    __c_node* p = __cbeg_[hc];
-    __c_node* q = nullptr;
-    _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
-    while (p->__c_ != __c)
+    if (__cend_ != __cbeg_)
     {
-        q = p;
-        p = p->__next_;
-        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
+        size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
+        __c_node* p = __cbeg_[hc];
+        if (p == nullptr)
+            return;
+        __c_node* q = nullptr;
+        _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
+        while (p->__c_ != __c)
+        {
+            q = p;
+            p = p->__next_;
+            if (p == nullptr)
+                return;
+            _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
+        }
+        if (q == nullptr)
+            __cbeg_[hc] = p->__next_;
+        else
+            q->__next_ = p->__next_;
+        while (p->end_ != p->beg_)
+        {
+            --p->end_;
+            (*p->end_)->__c_ = nullptr;
+        }
+        free(p->beg_);
+        free(p);
+        --__csz_;
     }
-    if (q == nullptr)
-        __cbeg_[hc] = p->__next_;
-    else
-        q->__next_ = p->__next_;
-    while (p->end_ != p->beg_)
-    {
-        --p->end_;
-        (*p->end_)->__c_ = nullptr;
-    }
-    free(p->beg_);
-    free(p);
-    --__csz_;
 }
 
 void

Modified: libcxx/trunk/test/strings/basic.string/string.access/back.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/back.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/back.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.access/back.pass.cpp Fri Aug 23 12:37:05 2013
@@ -12,6 +12,10 @@
 // const charT& back() const;
 //       charT& back();
 
+#ifdef _LIBCPP_DEBUG2
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <cassert>
 
@@ -42,4 +46,11 @@ int main()
     test(S("1234567890123456789012345678901234567890"));
     }
 #endif
+#ifdef _LIBCPP_DEBUG2
+    {
+        std::string s;
+        char c = s.back();
+        assert(false);
+    }
+#endif
 }

Added: libcxx/trunk/test/strings/basic.string/string.access/db_back.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/db_back.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/db_back.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.access/db_back.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call back() on empty container.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    S s(1, '\0');
+    assert(s.back() == 0);
+    s.clear();
+    assert(s.back() == 0);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S s(1, '\0');
+    assert(s.back() == 0);
+    s.clear();
+    assert(s.back() == 0);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.access/db_cback.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/db_cback.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/db_cback.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.access/db_cback.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call back() on empty const container.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    const S s;
+    assert(s.back() == 0);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    const S s;
+    assert(s.back() == 0);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.access/db_cfront.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/db_cfront.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/db_cfront.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.access/db_cfront.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call front() on empty const container.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    const S s;
+    assert(s.front() == 0);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    const S s;
+    assert(s.front() == 0);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.access/db_cindex.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/db_cindex.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/db_cindex.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.access/db_cindex.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Index const string out of bounds.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    const S s;
+    assert(s[0] == 0);
+    assert(s[1] == 0);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    const S s;
+    assert(s[0] == 0);
+    assert(s[1] == 0);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.access/db_front.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/db_front.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/db_front.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.access/db_front.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call front() on empty container.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    S s(1, '\0');
+    assert(s.front() == 0);
+    s.clear();
+    assert(s.front() == 0);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S s(1, '\0');
+    assert(s.front() == 0);
+    s.clear();
+    assert(s.front() == 0);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.access/db_index.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/db_index.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/db_index.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.access/db_index.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Index string out of bounds.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    S s;
+    assert(s[0] == 0);
+    assert(s[1] == 0);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S s;
+    assert(s[0] == 0);
+    assert(s[1] == 0);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Modified: libcxx/trunk/test/strings/basic.string/string.access/front.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/front.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/front.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.access/front.pass.cpp Fri Aug 23 12:37:05 2013
@@ -12,6 +12,10 @@
 // const charT& front() const;
 //       charT& front();
 
+#ifdef _LIBCPP_DEBUG2
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <cassert>
 
@@ -42,4 +46,11 @@ int main()
     test(S("1234567890123456789012345678901234567890"));
     }
 #endif
+#ifdef _LIBCPP_DEBUG2
+    {
+        std::string s;
+        char c = s.front();
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/strings/basic.string/string.access/index.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.access/index.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.access/index.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.access/index.pass.cpp Fri Aug 23 12:37:05 2013
@@ -12,6 +12,10 @@
 // const_reference operator[](size_type pos) const;
 //       reference operator[](size_type pos);
 
+#ifdef _LIBCPP_DEBUG2
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <cassert>
 
@@ -47,4 +51,13 @@ int main()
     assert(s2[0] == '\0');
     }
 #endif
+#ifdef _LIBCPP_DEBUG2
+    {
+        std::string s;
+        char c = s[0];
+        assert(c == '\0');
+        c = s[1];
+        assert(false);
+    }
+#endif
 }

Added: libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_2.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_2.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_2.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_2.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Compare iterators from different containers with <.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    S s1;
+    S s2;
+    bool b = s1.begin() < s2.begin();
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S s1;
+    S s2;
+    bool b = s1.begin() < s2.begin();
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_3.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_3.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_3.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_3.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Subtract iterators from different containers with <.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string S;
+    S s1;
+    S s2;
+    int i = s1.begin() - s2.begin();
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S s1;
+    S s2;
+    int i = s1.begin() - s2.begin();
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_4.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_4.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_4.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_4.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Index iterator out of bounds.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string C;
+    C c(1, '\0');
+    C::iterator i = c.begin();
+    assert(i[0] == 0);
+    assert(i[1] == 0);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C;
+    C c(1, '\0');
+    C::iterator i = c.begin();
+    assert(i[0] == 0);
+    assert(i[1] == 0);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_5.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_5.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_5.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_5.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Add to iterator out of bounds.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string C;
+    C c(1, '\0');
+    C::iterator i = c.begin();
+    i += 1;
+    assert(i == c.end());
+    i = c.begin();
+    i += 2;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C;
+    C c(1, '\0');
+    C::iterator i = c.begin();
+    i += 1;
+    assert(i == c.end());
+    i = c.begin();
+    i += 2;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_6.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_6.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_6.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_6.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Decrement iterator prior to begin.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string C;
+    C c(1, '\0');
+    C::iterator i = c.end();
+    --i;
+    assert(i == c.begin());
+    --i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C;
+    C c(1, '\0');
+    C::iterator i = c.end();
+    --i;
+    assert(i == c.begin());
+    --i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_7.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_7.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_7.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_7.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Increment iterator past end.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string C;
+    C c(1, '\0');
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C;
+    C c(1, '\0');
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_8.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_8.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_8.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.iterators/db_iterators_8.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../min_allocator.h"
+
+int main()
+{
+    {
+    typedef std::string C;
+    C c(1, '\0');
+    C::iterator i = c.end();
+    char j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> C;
+    C c(1, '\0');
+    C::iterator i = c.end();
+    char j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db1.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator position) with end()
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <cstdlib>
+#include <exception>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    std::string l1("123");
+    std::string::const_iterator i = l1.end();
+    l1.erase(i);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S l1("123");
+    S::const_iterator i = l1.end();
+    l1.erase(i);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_db2.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator position) with iterator from another container
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <cstdlib>
+#include <exception>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    std::string l1("123");
+    std::string l2("123");
+    std::string::const_iterator i = l2.begin();
+    l1.erase(i);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S l1("123");
+    S l2("123");
+    S::const_iterator i = l2.begin();
+    l1.erase(i);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db1.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator first, const_iterator last); with first iterator from another container
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    std::string l1("123");
+    std::string l2("123");
+    std::string::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S l1("123");
+    S l2("123");
+    S::iterator i = l1.erase(l2.cbegin(), l1.cbegin()+1);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db2.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator first, const_iterator last); with second iterator from another container
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    std::string l1("123");
+    std::string l2("123");
+    std::string::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S l1("123");
+    S l2("123");
+    S::iterator i = l1.erase(l1.cbegin(), l2.cbegin()+1);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db3.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator first, const_iterator last); with both iterators from another container
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    std::string l1("123");
+    std::string l2("123");
+    std::string::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1);
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S l1("123");
+    S l2("123");
+    S::iterator i = l1.erase(l2.cbegin(), l2.cbegin()+1);
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp?rev=189114&view=auto
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp (added)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/erase_iter_iter_db4.pass.cpp Fri Aug 23 12:37:05 2013
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <string>
+
+// Call erase(const_iterator first, const_iterator last); with a bad range
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <string>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    std::string l1("123");
+    std::string::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin());
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
+    S l1("123");
+    S::iterator i = l1.erase(l1.cbegin()+1, l1.cbegin());
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_erase/pop_back.pass.cpp Fri Aug 23 12:37:05 2013
@@ -11,6 +11,10 @@
 
 // void pop_back();
 
+#if _LIBCPP_DEBUG2 >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <cassert>
 
@@ -41,4 +45,11 @@ int main()
     test(S("abcdefghijklmnopqrst"), S("abcdefghijklmnopqrs"));
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        std::string s;
+        s.pop_back();
+        assert(false);
+    }
+#endif        
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_char.pass.cpp Fri Aug 23 12:37:05 2013
@@ -11,6 +11,10 @@
 
 // iterator insert(const_iterator p, charT c);
 
+#if _LIBCPP_DEBUG2 >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <stdexcept>
 #include <cassert>
@@ -72,4 +76,13 @@ int main()
     test(s, s.begin()+6, 'C', S("a567ABC1432dcb"));
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        typedef std::string S;
+        S s;
+        S s2;
+        s.insert(s2.begin(), '1');
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_initializer_list.pass.cpp Fri Aug 23 12:37:05 2013
@@ -11,6 +11,10 @@
 
 // iterator insert(const_iterator p, initializer_list<charT> il);
 
+#if _LIBCPP_DEBUG2 >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <cassert>
 
@@ -34,5 +38,13 @@ int main()
         assert(s == "123abc456");
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        std::string s;
+        std::string s2;
+        s.insert(s2.begin(), {'a', 'b', 'c'});
+        assert(false);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp Fri Aug 23 12:37:05 2013
@@ -12,6 +12,10 @@
 // template<class InputIterator>
 //   iterator insert(const_iterator p, InputIterator first, InputIterator last);
 
+#if _LIBCPP_DEBUG2 >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <cassert>
 
@@ -123,4 +127,14 @@ int main()
          S("12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        std::string v;
+        std::string v2;
+        char a[] = "123";
+        const int N = sizeof(a)/sizeof(a[0]);
+        std::string::iterator i = v.insert(v2.cbegin() + 10, a, a+N);
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_insert/iter_size_char.pass.cpp Fri Aug 23 12:37:05 2013
@@ -11,6 +11,10 @@
 
 // iterator insert(const_iterator p, size_type n, charT c);
 
+#if _LIBCPP_DEBUG2 >= 1
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+#endif
+
 #include <string>
 #include <cassert>
 
@@ -166,4 +170,12 @@ int main()
     test(S("abcdefghijklmnopqrst"), 20, 20, '1', S("abcdefghijklmnopqrst11111111111111111111"));
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        std::string s;
+        std::string s2;
+        s.insert(s2.begin(), 1, 'a');
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp Fri Aug 23 12:37:05 2013
@@ -26,10 +26,10 @@ test(S s, typename S::size_type pos1, ty
     typename S::size_type old_size = s.size();
     typename S::const_iterator first = s.begin() + pos1;
     typename S::const_iterator last = s.begin() + pos1 + n1;
+    typename S::size_type xlen = last - first;
     s.replace(first, last, f, l);
     assert(s.__invariants());
     assert(s == expected);
-    typename S::size_type xlen = last - first;
     typename S::size_type rlen = std::distance(f, l);
     assert(s.size() == old_size - xlen + rlen);
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer.pass.cpp Fri Aug 23 12:37:05 2013
@@ -27,10 +27,10 @@ test(S s, typename S::size_type pos1, ty
     typename S::size_type old_size = s.size();
     typename S::const_iterator first = s.begin() + pos1;
     typename S::const_iterator last = s.begin() + pos1 + n1;
+    typename S::size_type xlen = last - first;
     s.replace(first, last, str);
     assert(s.__invariants());
     assert(s == expected);
-    typename S::size_type xlen = last - first;
     typename S::size_type rlen = S::traits_type::length(str);
     assert(s.size() == old_size - xlen + rlen);
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_pointer_size.pass.cpp Fri Aug 23 12:37:05 2013
@@ -28,10 +28,10 @@ test(S s, typename S::size_type pos1, ty
     typename S::size_type old_size = s.size();
     typename S::const_iterator first = s.begin() + pos1;
     typename S::const_iterator last = s.begin() + pos1 + n1;
+    typename S::size_type xlen = last - first;
     s.replace(first, last, str, n2);
     assert(s.__invariants());
     assert(s == expected);
-    typename S::size_type xlen = last - first;
     typename S::size_type rlen = n2;
     assert(s.size() == old_size - xlen + rlen);
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_size_char.pass.cpp Fri Aug 23 12:37:05 2013
@@ -28,10 +28,10 @@ test(S s, typename S::size_type pos1, ty
     typename S::size_type old_size = s.size();
     typename S::const_iterator first = s.begin() + pos1;
     typename S::const_iterator last = s.begin() + pos1 + n1;
+    typename S::size_type xlen = last - first;
     s.replace(first, last, n2, c);
     assert(s.__invariants());
     assert(s == expected);
-    typename S::size_type xlen = last - first;
     typename S::size_type rlen = n2;
     assert(s.size() == old_size - xlen + rlen);
 }

Modified: libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp?rev=189114&r1=189113&r2=189114&view=diff
==============================================================================
--- libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp (original)
+++ libcxx/trunk/test/strings/basic.string/string.modifiers/string_replace/iter_iter_string.pass.cpp Fri Aug 23 12:37:05 2013
@@ -27,10 +27,10 @@ test(S s, typename S::size_type pos1, ty
     typename S::size_type old_size = s.size();
     typename S::const_iterator first = s.begin() + pos1;
     typename S::const_iterator last = s.begin() + pos1 + n1;
+    typename S::size_type xlen = last - first;
     s.replace(first, last, str);
     assert(s.__invariants());
     assert(s == expected);
-    typename S::size_type xlen = last - first;
     typename S::size_type rlen = str.size();
     assert(s.size() == old_size - xlen + rlen);
 }





More information about the cfe-commits mailing list