[libcxx-commits] [libcxx] r356417 - Remove exception throwing debug mode handler support.

Eric Fiselier via libcxx-commits libcxx-commits at lists.llvm.org
Mon Mar 18 14:50:12 PDT 2019


Author: ericwf
Date: Mon Mar 18 14:50:12 2019
New Revision: 356417

URL: http://llvm.org/viewvc/llvm-project?rev=356417&view=rev
Log:
Remove exception throwing debug mode handler support.

Summary:
The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
I thought that if a debug violation aborted, we could only test one violation per file. This made
it impossible to test debug mode. Which throwing behavior we could test more!

However, the throwing approach didn't work either, since there are debug violations underneath noexcept
functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
mode was off.

Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
changing the behavior of their program.

  This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
  death tests.

Reviewers: mclow.lists, ldionne, thomasanderson

Reviewed By: ldionne

Subscribers: christof, arphaman, libcxx-commits, #libc

Differential Revision: https://reviews.llvm.org/D59166

Added:
    libcxx/trunk/test/libcxx/debug/debug_helper_test.pass.cpp
    libcxx/trunk/test/libcxx/debug/debug_register.pass.cpp
      - copied, changed from r356416, libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp
    libcxx/trunk/test/support/container_debug_tests.hpp
Removed:
    libcxx/trunk/test/libcxx/debug/debug_throw.pass.cpp
    libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp
Modified:
    libcxx/trunk/include/__config
    libcxx/trunk/include/__debug
    libcxx/trunk/include/__hash_table
    libcxx/trunk/include/iterator
    libcxx/trunk/include/list
    libcxx/trunk/include/string
    libcxx/trunk/include/vector
    libcxx/trunk/lib/abi/CHANGELOG.TXT
    libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist
    libcxx/trunk/lib/abi/x86_64-apple-darwin.v2.abilist
    libcxx/trunk/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
    libcxx/trunk/src/debug.cpp
    libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_back.pass.cpp
    libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_front.pass.cpp
    libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_indexing.pass.cpp
    libcxx/trunk/test/libcxx/debug/containers/db_associative_container_tests.pass.cpp
    libcxx/trunk/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp
    libcxx/trunk/test/libcxx/debug/containers/db_string.pass.cpp
    libcxx/trunk/test/libcxx/debug/containers/db_unord_container_tests.pass.cpp
    libcxx/trunk/test/libcxx/input.output/filesystems/class.path/path.itr/iterator_db.pass.cpp
    libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp
    libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
    libcxx/trunk/test/support/debug_mode_helper.h

Modified: libcxx/trunk/include/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Mon Mar 18 14:50:12 2019
@@ -850,22 +850,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_
 #  define _NOEXCEPT_(x)
 #endif
 
-#if defined(_LIBCPP_DEBUG_USE_EXCEPTIONS)
-#  if !defined(_LIBCPP_DEBUG)
-#    error cannot use _LIBCPP_DEBUG_USE_EXCEPTIONS unless _LIBCPP_DEBUG is defined
-#  endif
-#  ifdef _LIBCPP_HAS_NO_NOEXCEPT
-#    define _NOEXCEPT_DEBUG
-#    define _NOEXCEPT_DEBUG_(x)
-#  else
-#    define _NOEXCEPT_DEBUG noexcept(false)
-#    define _NOEXCEPT_DEBUG_(x) noexcept(false)
-#  endif
-#else
-#  define _NOEXCEPT_DEBUG _NOEXCEPT
-#  define _NOEXCEPT_DEBUG_(x) _NOEXCEPT_(x)
-#endif
-
 #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS
 typedef unsigned short char16_t;
 typedef unsigned int   char32_t;

Modified: libcxx/trunk/include/__debug
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__debug?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/include/__debug (original)
+++ libcxx/trunk/include/__debug Mon Mar 18 14:50:12 2019
@@ -11,6 +11,7 @@
 #define _LIBCPP_DEBUG_H
 
 #include <__config>
+#include <iosfwd>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -24,7 +25,6 @@
 #   include <cstdlib>
 #   include <cstdio>
 #   include <cstddef>
-#   include <exception>
 #endif
 
 #if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_ASSERT)
@@ -49,10 +49,6 @@
 #define _LIBCPP_DEBUG_MODE(...) ((void)0)
 #endif
 
-#if _LIBCPP_DEBUG_LEVEL < 1
-class _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception;
-#endif
-
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info {
@@ -62,6 +58,9 @@ struct _LIBCPP_TEMPLATE_VIS __libcpp_deb
   _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
   __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m)
     : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {}
+
+  _LIBCPP_FUNC_VIS std::string what() const;
+
   const char* __file_;
   int __line_;
   const char* __pred_;
@@ -79,38 +78,11 @@ extern _LIBCPP_EXPORTED_FROM_ABI __libcp
 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS
 void __libcpp_abort_debug_function(__libcpp_debug_info const&);
 
-/// __libcpp_throw_debug_function - A debug handler that throws
-///   an instance of __libcpp_debug_exception when called.
- _LIBCPP_NORETURN _LIBCPP_FUNC_VIS
-void __libcpp_throw_debug_function(__libcpp_debug_info const&);
-
 /// __libcpp_set_debug_function - Set the debug handler to the specified
 ///    function.
 _LIBCPP_FUNC_VIS
 bool __libcpp_set_debug_function(__libcpp_debug_function_type __func);
 
-// Setup the throwing debug handler during dynamic initialization.
-#if _LIBCPP_DEBUG_LEVEL >= 1 && defined(_LIBCPP_DEBUG_USE_EXCEPTIONS)
-# if defined(_LIBCPP_NO_EXCEPTIONS)
-#   error _LIBCPP_DEBUG_USE_EXCEPTIONS cannot be used when exceptions are disabled.
-# endif
-static bool __init_dummy = __libcpp_set_debug_function(__libcpp_throw_debug_function);
-#endif
-
-#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY)
-class _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception : public exception {
-public:
-  __libcpp_debug_exception() _NOEXCEPT;
-  explicit __libcpp_debug_exception(__libcpp_debug_info const& __i);
-  __libcpp_debug_exception(__libcpp_debug_exception const&);
-  ~__libcpp_debug_exception() _NOEXCEPT;
-  const char* what() const _NOEXCEPT;
-private:
-  struct __libcpp_debug_exception_imp;
-  __libcpp_debug_exception_imp *__imp_;
-};
-#endif
-
 #if _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY)
 
 struct _LIBCPP_TYPE_VIS __c_node;

Modified: libcxx/trunk/include/__hash_table
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__hash_table?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/include/__hash_table (original)
+++ libcxx/trunk/include/__hash_table Mon Mar 18 14:50:12 2019
@@ -1260,7 +1260,7 @@ public:
 
     void swap(__hash_table& __u)
 #if _LIBCPP_STD_VER <= 11
-        _NOEXCEPT_DEBUG_(
+        _NOEXCEPT_(
             __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
             && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
                   || __is_nothrow_swappable<__pointer_allocator>::value)
@@ -1268,7 +1268,7 @@ public:
                   || __is_nothrow_swappable<__node_allocator>::value)
             );
 #else
-     _NOEXCEPT_DEBUG_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
+     _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
 #endif
 
     _LIBCPP_INLINE_VISIBILITY
@@ -2807,7 +2807,7 @@ template <class _Tp, class _Hash, class
 void
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
 #if _LIBCPP_STD_VER <= 11
-    _NOEXCEPT_DEBUG_(
+    _NOEXCEPT_(
         __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
         && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
               || __is_nothrow_swappable<__pointer_allocator>::value)
@@ -2815,7 +2815,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>
               || __is_nothrow_swappable<__node_allocator>::value)
             )
 #else
-  _NOEXCEPT_DEBUG_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
+  _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
 #endif
 {
     _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value ||

Modified: libcxx/trunk/include/iterator
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/iterator?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/include/iterator (original)
+++ libcxx/trunk/include/iterator Mon Mar 18 14:50:12 2019
@@ -1241,50 +1241,50 @@ template <class _Iter> class __wrap_iter
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 auto
-operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 -> decltype(__x.base() - __y.base());
 #else
 template <class _Iter1, class _Iter2>
 _LIBCPP_INLINE_VISIBILITY
 typename __wrap_iter<_Iter1>::difference_type
-operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 #endif
 
 template <class _Iter>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 __wrap_iter<_Iter>
-operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT_DEBUG;
+operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT;
 
 template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op);
 template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2);
@@ -1328,7 +1328,7 @@ public:
 private:
     iterator_type __i;
 public:
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter() _NOEXCEPT
 #if _LIBCPP_STD_VER > 11
                 : __i{}
 #endif
@@ -1339,7 +1339,7 @@ public:
     }
     template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
         __wrap_iter(const __wrap_iter<_Up>& __u,
-            typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT_DEBUG
+            typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT
             : __i(__u.base())
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1369,7 +1369,7 @@ public:
         __get_db()->__erase_i(this);
     }
 #endif
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference operator*() const _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
@@ -1377,7 +1377,7 @@ public:
 #endif
         return *__i;
     }
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer  operator->() const _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG pointer  operator->() const _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
@@ -1385,7 +1385,7 @@ public:
 #endif
         return (pointer)_VSTD::addressof(*__i);
     }
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator++() _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
@@ -1394,10 +1394,10 @@ public:
         ++__i;
         return *this;
     }
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator++(int) _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator++(int) _NOEXCEPT
         {__wrap_iter __tmp(*this); ++(*this); return __tmp;}
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator--() _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         _LIBCPP_ASSERT(__get_const_db()->__decrementable(this),
@@ -1406,11 +1406,11 @@ public:
         --__i;
         return *this;
     }
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator--(int) _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator--(int) _NOEXCEPT
         {__wrap_iter __tmp(*this); --(*this); return __tmp;}
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator+ (difference_type __n) const _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator+ (difference_type __n) const _NOEXCEPT
         {__wrap_iter __w(*this); __w += __n; return __w;}
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator+=(difference_type __n) _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n),
@@ -1419,11 +1419,11 @@ public:
         __i += __n;
         return *this;
     }
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator- (difference_type __n) const _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter  operator- (difference_type __n) const _NOEXCEPT
         {return *this + (-__n);}
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter& operator-=(difference_type __n) _NOEXCEPT
         {*this += -__n; return *this;}
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference    operator[](difference_type __n) const _NOEXCEPT_DEBUG
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG reference    operator[](difference_type __n) const _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n),
@@ -1432,7 +1432,7 @@ public:
         return __i[__n];
     }
 
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT_DEBUG {return __i;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG iterator_type base() const _NOEXCEPT {return __i;}
 
 private:
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1441,7 +1441,7 @@ private:
         __get_db()->__insert_ic(this, __p);
     }
 #else
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {}
 #endif
 
     template <class _Up> friend class __wrap_iter;
@@ -1452,50 +1452,50 @@ private:
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     bool
-    operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+    operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     bool
-    operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+    operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     bool
-    operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+    operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     bool
-    operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+    operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     bool
-    operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+    operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     bool
-    operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+    operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 
 #ifndef _LIBCPP_CXX03_LANG
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     auto
-    operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+    operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
     -> decltype(__x.base() - __y.base());
 #else
     template <class _Iter1, class _Iter2>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     typename __wrap_iter<_Iter1>::difference_type
-    operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG;
+    operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT;
 #endif
 
     template <class _Iter1>
     _LIBCPP_CONSTEXPR_IF_NODEBUG friend
     __wrap_iter<_Iter1>
-    operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT_DEBUG;
+    operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT;
 
     template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op);
     template <class _B1, class _B2> friend _B2 copy_backward(_B1, _B1, _B2);
@@ -1526,7 +1526,7 @@ private:
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
     return __x.base() == __y.base();
 }
@@ -1534,7 +1534,7 @@ operator==(const __wrap_iter<_Iter1>& __
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
@@ -1546,7 +1546,7 @@ operator<(const __wrap_iter<_Iter1>& __x
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
     return !(__x == __y);
 }
@@ -1554,7 +1554,7 @@ operator!=(const __wrap_iter<_Iter1>& __
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
     return __y < __x;
 }
@@ -1562,7 +1562,7 @@ operator>(const __wrap_iter<_Iter1>& __x
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
     return !(__x < __y);
 }
@@ -1570,7 +1570,7 @@ operator>=(const __wrap_iter<_Iter1>& __
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
     return !(__y < __x);
 }
@@ -1578,7 +1578,7 @@ operator<=(const __wrap_iter<_Iter1>& __
 template <class _Iter1>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
+operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
 {
     return !(__x == __y);
 }
@@ -1586,7 +1586,7 @@ operator!=(const __wrap_iter<_Iter1>& __
 template <class _Iter1>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
+operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
 {
     return __y < __x;
 }
@@ -1594,7 +1594,7 @@ operator>(const __wrap_iter<_Iter1>& __x
 template <class _Iter1>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
+operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
 {
     return !(__x < __y);
 }
@@ -1602,7 +1602,7 @@ operator>=(const __wrap_iter<_Iter1>& __
 template <class _Iter1>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 bool
-operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG
+operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT
 {
     return !(__y < __x);
 }
@@ -1611,7 +1611,7 @@ operator<=(const __wrap_iter<_Iter1>& __
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 auto
-operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 -> decltype(__x.base() - __y.base())
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1624,7 +1624,7 @@ operator-(const __wrap_iter<_Iter1>& __x
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 typename __wrap_iter<_Iter1>::difference_type
-operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG
+operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
     _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y),
@@ -1638,7 +1638,7 @@ template <class _Iter>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG
 __wrap_iter<_Iter>
 operator+(typename __wrap_iter<_Iter>::difference_type __n,
-          __wrap_iter<_Iter> __x) _NOEXCEPT_DEBUG
+          __wrap_iter<_Iter> __x) _NOEXCEPT
 {
     __x += __n;
     return __x;

Modified: libcxx/trunk/include/list
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/list?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/include/list (original)
+++ libcxx/trunk/include/list Mon Mar 18 14:50:12 2019
@@ -647,9 +647,9 @@ protected:
 
     void swap(__list_imp& __c)
 #if _LIBCPP_STD_VER >= 14
-        _NOEXCEPT_DEBUG;
+        _NOEXCEPT;
 #else
-        _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                     __is_nothrow_swappable<allocator_type>::value);
 #endif
 
@@ -769,9 +769,9 @@ template <class _Tp, class _Alloc>
 void
 __list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
 #if _LIBCPP_STD_VER >= 14
-        _NOEXCEPT_DEBUG
+        _NOEXCEPT
 #else
-        _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                     __is_nothrow_swappable<allocator_type>::value)
 #endif
 {
@@ -1038,9 +1038,9 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void swap(list& __c)
 #if _LIBCPP_STD_VER >= 14
-        _NOEXCEPT_DEBUG
+        _NOEXCEPT
 #else
-        _NOEXCEPT_DEBUG_(!__node_alloc_traits::propagate_on_container_swap::value ||
+        _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<__node_allocator>::value)
 #endif
         {base::swap(__c);}

Modified: libcxx/trunk/include/string
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/string?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/include/string (original)
+++ libcxx/trunk/include/string Mon Mar 18 14:50:12 2019
@@ -1236,9 +1236,9 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     void swap(basic_string& __str)
 #if _LIBCPP_STD_VER >= 14
-        _NOEXCEPT_DEBUG;
+        _NOEXCEPT;
 #else
-        _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                     __is_nothrow_swappable<allocator_type>::value);
 #endif
 
@@ -3295,9 +3295,9 @@ inline
 void
 basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
 #if _LIBCPP_STD_VER >= 14
-        _NOEXCEPT_DEBUG
+        _NOEXCEPT
 #else
-        _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                     __is_nothrow_swappable<allocator_type>::value)
 #endif
 {

Modified: libcxx/trunk/include/vector
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/vector?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/include/vector (original)
+++ libcxx/trunk/include/vector Mon Mar 18 14:50:12 2019
@@ -779,9 +779,9 @@ public:
 
     void swap(vector&)
 #if _LIBCPP_STD_VER >= 14
-        _NOEXCEPT_DEBUG;
+        _NOEXCEPT;
 #else
-        _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
+        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                     __is_nothrow_swappable<allocator_type>::value);
 #endif
 
@@ -2064,9 +2064,9 @@ template <class _Tp, class _Allocator>
 void
 vector<_Tp, _Allocator>::swap(vector& __x)
 #if _LIBCPP_STD_VER >= 14
-    _NOEXCEPT_DEBUG
+    _NOEXCEPT
 #else
-    _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
+    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                 __is_nothrow_swappable<allocator_type>::value)
 #endif
 {

Modified: libcxx/trunk/lib/abi/CHANGELOG.TXT
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/CHANGELOG.TXT?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/CHANGELOG.TXT (original)
+++ libcxx/trunk/lib/abi/CHANGELOG.TXT Mon Mar 18 14:50:12 2019
@@ -16,6 +16,47 @@ New entries should be added directly bel
 Version 9.0
 -----------
 
+* rTBD - Remove exception throwing debug mode handler support.
+
+  The reason libc++ implemented a throwing debug mode handler was for ease of testing. Specifically,
+  I thought that if a debug violation aborted, we could only test one violation per file. This made
+  it impossible to test debug mode. Which throwing behavior we could test more!
+
+  However, the throwing approach didn't work either, since there are debug violations underneath noexcept
+  functions. This lead to the introduction of `_NOEXCEPT_DEBUG`, which was only noexcept when debug
+  mode was off.
+
+  Having thought more and having grown wiser, `_NOEXCEPT_DEBUG` was a horrible decision. It was
+  viral, it didn't cover all the cases it needed to, and it was observable to the user -- at worst
+  changing the behavior of their program.
+
+  This patch removes the throwing debug handler, and rewrites the debug tests using 'fork-ing' style
+  death tests.
+
+  All Platforms (ignoring versioning namespaces)
+  ----------------------------------------------
+  Symbol added: _ZNKSt3__119__libcpp_debug_info4whatEv
+  Symbol removed: _ZNKSt3__124__libcpp_debug_exception4whatEv
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionC1ERKNS_19__libcpp_debug_infoE
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionC1ERKS0_
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionC1Ev
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionC2ERKNS_19__libcpp_debug_infoE
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionC2ERKS0_
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionC2Ev
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionD0Ev
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionD1Ev
+  Symbol removed: _ZNSt3__124__libcpp_debug_exceptionD2Ev
+  Symbol removed: _ZNSt3__129__libcpp_throw_debug_functionERKNS_19__libcpp_debug_infoE
+  Symbol removed: _ZTINSt3__124__libcpp_debug_exceptionE
+  Symbol removed: _ZTSNSt3__124__libcpp_debug_exceptionE
+  Symbol removed: _ZTVNSt3__124__libcpp_debug_exceptionE
+
+
+    x86_64-apple-apple-darwin
+    -------------------------
+    Symbol added: __ZNSt3__111__libcpp_db10__insert_cEPvPFPNS_8__c_nodeES1_S1_S3_E
+    Symbol removed: __ZNSt3__111__libcpp_db10__insert_cEPv
+
 * r355367 - Fix -fsanitize=vptr badness in <__debug>
 
   This patch fixes a lifetime bug when inserting a new container into the debug database. It is

Modified: libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist (original)
+++ libcxx/trunk/lib/abi/x86_64-apple-darwin.v1.abilist Mon Mar 18 14:50:12 2019
@@ -219,6 +219,7 @@
 {'is_defined': True, 'name': '__ZNKSt3__117moneypunct_bynameIwLb1EE16do_thousands_sepEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__119__libcpp_debug_info4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__120__codecvt_utf8_utf16IDiE10do_unshiftER11__mbstate_tPcS4_RS4_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__120__codecvt_utf8_utf16IDiE11do_encodingEv', 'type': 'FUNC'}
@@ -261,7 +262,6 @@
 {'is_defined': True, 'name': '__ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNKSt3__124__libcpp_debug_exception4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__15ctypeIcE10do_tolowerEPcPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__15ctypeIcE10do_tolowerEc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__15ctypeIcE10do_toupperEPcPKc', 'type': 'FUNC'}
@@ -1201,15 +1201,6 @@
 {'is_defined': True, 'name': '__ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__121undeclare_no_pointersEPcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__123__libcpp_debug_functionE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionC1ERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionC1ERKS0_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionC1Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionC2ERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionC2ERKS0_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionC2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionD0Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionD1Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__124__libcpp_debug_exceptionD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
@@ -1228,7 +1219,6 @@
 {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIyyEEPyEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__127__libcpp_set_debug_functionEPFvRKNS_19__libcpp_debug_infoEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__129__libcpp_abort_debug_functionERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__129__libcpp_throw_debug_functionERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__13cinE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__14cerrE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__14clogE', 'size': 0, 'type': 'OBJECT'}
@@ -1654,7 +1644,6 @@
 {'is_defined': True, 'name': '__ZTINSt3__120__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__120__time_get_c_storageIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__120__time_get_c_storageIwEE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZTINSt3__124__libcpp_debug_exceptionE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__16locale5facetE', 'size': 0, 'type': 'OBJECT'}
@@ -2182,7 +2171,6 @@
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZTVNSt3__124__libcpp_debug_exceptionE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__15ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__15ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__16locale5facetE', 'size': 0, 'type': 'OBJECT'}

Modified: libcxx/trunk/lib/abi/x86_64-apple-darwin.v2.abilist
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/x86_64-apple-darwin.v2.abilist?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/x86_64-apple-darwin.v2.abilist (original)
+++ libcxx/trunk/lib/abi/x86_64-apple-darwin.v2.abilist Mon Mar 18 14:50:12 2019
@@ -218,6 +218,7 @@
 {'is_defined': True, 'name': '__ZNKSt3__217moneypunct_bynameIwLb1EE16do_thousands_sepEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__218__time_get_storageIcE15__do_date_orderEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__218__time_get_storageIwE15__do_date_orderEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNKSt3__219__libcpp_debug_info4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__219__shared_weak_count13__get_deleterERKSt9type_info', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__220__codecvt_utf8_utf16IDiE10do_unshiftER11__mbstate_tPcS4_RS4_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__220__codecvt_utf8_utf16IDiE11do_encodingEv', 'type': 'FUNC'}
@@ -260,7 +261,6 @@
 {'is_defined': True, 'name': '__ZNKSt3__221__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__223__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__223__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNKSt3__224__libcpp_debug_exception4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__25ctypeIcE10do_tolowerEPcPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__25ctypeIcE10do_tolowerEc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNKSt3__25ctypeIcE10do_toupperEPcPKc', 'type': 'FUNC'}
@@ -1123,15 +1123,6 @@
 {'is_defined': True, 'name': '__ZNSt3__221recursive_timed_mutexD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__221undeclare_no_pointersEPcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__223__libcpp_debug_functionE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionC1ERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionC1ERKS0_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionC1Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionC2ERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionC2ERKS0_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionC2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionD0Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionD1Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__224__libcpp_debug_exceptionD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__225notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__227__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__227__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
@@ -1150,7 +1141,6 @@
 {'is_defined': True, 'name': '__ZNSt3__227__insertion_sort_incompleteIRNS_6__lessIyyEEPyEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__227__libcpp_set_debug_functionEPFvRKNS_19__libcpp_debug_infoEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__229__libcpp_abort_debug_functionERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt3__229__libcpp_throw_debug_functionERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '__ZNSt3__23cinE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__24cerrE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZNSt3__24clogE', 'size': 0, 'type': 'OBJECT'}
@@ -1577,7 +1567,6 @@
 {'is_defined': True, 'name': '__ZTINSt3__220__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__220__time_get_c_storageIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__220__time_get_c_storageIwEE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZTINSt3__224__libcpp_debug_exceptionE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__25ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__25ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTINSt3__26locale5facetE', 'size': 0, 'type': 'OBJECT'}
@@ -1867,7 +1856,6 @@
 {'is_defined': True, 'name': '__ZTSNSt3__220__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__220__time_get_c_storageIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__220__time_get_c_storageIwEE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZTSNSt3__224__libcpp_debug_exceptionE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__25ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__25ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTSNSt3__26locale5facetE', 'size': 0, 'type': 'OBJECT'}
@@ -2143,7 +2131,6 @@
 {'is_defined': True, 'name': '__ZTVNSt3__220__codecvt_utf8_utf16IDiEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__220__codecvt_utf8_utf16IDsEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__220__codecvt_utf8_utf16IwEE', 'size': 0, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '__ZTVNSt3__224__libcpp_debug_exceptionE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__25ctypeIcEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__25ctypeIwEE', 'size': 0, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '__ZTVNSt3__26locale5facetE', 'size': 0, 'type': 'OBJECT'}

Modified: libcxx/trunk/lib/abi/x86_64-unknown-linux-gnu.v1.abilist
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/lib/abi/x86_64-unknown-linux-gnu.v1.abilist?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/lib/abi/x86_64-unknown-linux-gnu.v1.abilist (original)
+++ libcxx/trunk/lib/abi/x86_64-unknown-linux-gnu.v1.abilist Mon Mar 18 14:50:12 2019
@@ -211,6 +211,7 @@
 {'is_defined': True, 'name': '_ZNKSt3__117moneypunct_bynameIwLb1EE16do_thousands_sepEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIcE15__do_date_orderEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__118__time_get_storageIwE15__do_date_orderEv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNKSt3__119__libcpp_debug_info4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__120__codecvt_utf8_utf16IDiE10do_unshiftER11__mbstate_tPcS4_RS4_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__120__codecvt_utf8_utf16IDiE11do_encodingEv', 'type': 'FUNC'}
@@ -253,7 +254,6 @@
 {'is_defined': True, 'name': '_ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNKSt3__124__libcpp_debug_exception4whatEv', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__15ctypeIcE10do_tolowerEPcPKc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__15ctypeIcE10do_tolowerEc', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNKSt3__15ctypeIcE10do_toupperEPcPKc', 'type': 'FUNC'}
@@ -1114,15 +1114,6 @@
 {'is_defined': True, 'name': '_ZNSt3__121recursive_timed_mutexD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__121undeclare_no_pointersEPcm', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__123__libcpp_debug_functionE', 'size': 8, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionC1ERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionC1ERKS0_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionC1Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionC2ERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionC2ERKS0_', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionC2Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionD0Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionD1Ev', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__124__libcpp_debug_exceptionD2Ev', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIaaEEPaEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIccEEPcEEbT0_S5_T_', 'type': 'FUNC'}
@@ -1141,7 +1132,6 @@
 {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIyyEEPyEEbT0_S5_T_', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__127__libcpp_set_debug_functionEPFvRKNS_19__libcpp_debug_infoEE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__129__libcpp_abort_debug_functionERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt3__129__libcpp_throw_debug_functionERKNS_19__libcpp_debug_infoE', 'type': 'FUNC'}
 {'is_defined': True, 'name': '_ZNSt3__13cinE', 'size': 168, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__14cerrE', 'size': 160, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZNSt3__14clogE', 'size': 160, 'type': 'OBJECT'}
@@ -1524,7 +1514,6 @@
 {'is_defined': True, 'name': '_ZTINSt3__120__codecvt_utf8_utf16IwEE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIcEE', 'size': 16, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__120__time_get_c_storageIwEE', 'size': 16, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZTINSt3__124__libcpp_debug_exceptionE', 'size': 24, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__15ctypeIcEE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__15ctypeIwEE', 'size': 56, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTINSt3__16locale5facetE', 'size': 24, 'type': 'OBJECT'}
@@ -1650,7 +1639,6 @@
 {'is_defined': True, 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IwEE', 'size': 34, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIcEE', 'size': 34, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__120__time_get_c_storageIwEE', 'size': 34, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZTSNSt3__124__libcpp_debug_exceptionE', 'size': 35, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__15ctypeIcEE', 'size': 18, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__15ctypeIwEE', 'size': 18, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTSNSt3__16locale5facetE', 'size': 22, 'type': 'OBJECT'}
@@ -1762,7 +1750,6 @@
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 96, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 96, 'type': 'OBJECT'}
-{'is_defined': True, 'name': '_ZTVNSt3__124__libcpp_debug_exceptionE', 'size': 40, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__15ctypeIcEE', 'size': 104, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__15ctypeIwEE', 'size': 136, 'type': 'OBJECT'}
 {'is_defined': True, 'name': '_ZTVNSt3__16locale5facetE', 'size': 40, 'type': 'OBJECT'}

Modified: libcxx/trunk/src/debug.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/debug.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/src/debug.cpp (original)
+++ libcxx/trunk/src/debug.cpp Mon Mar 18 14:50:12 2019
@@ -17,14 +17,18 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-static std::string make_what_str(__libcpp_debug_info const& info) {
-  string msg = info.__file_;
-  msg += ":" + to_string(info.__line_) + ": _LIBCPP_ASSERT '";
-  msg += info.__pred_;
+std::string __libcpp_debug_info::what() const {
+  string msg = __file_;
+  msg += ":" + to_string(__line_) + ": _LIBCPP_ASSERT '";
+  msg += __pred_;
   msg += "' failed. ";
-  msg += info.__msg_;
+  msg += __msg_;
   return msg;
 }
+_LIBCPP_NORETURN void __libcpp_abort_debug_function(__libcpp_debug_info const& info) {
+    std::fprintf(stderr, "%s\n", info.what().c_str());
+    std::abort();
+}
 
 _LIBCPP_SAFE_STATIC __libcpp_debug_function_type
     __libcpp_debug_function = __libcpp_abort_debug_function;
@@ -34,51 +38,6 @@ bool __libcpp_set_debug_function(__libcp
   return true;
 }
 
-_LIBCPP_NORETURN void __libcpp_abort_debug_function(__libcpp_debug_info const& info) {
-  std::fprintf(stderr, "%s\n", make_what_str(info).c_str());
-  std::abort();
-}
-
-_LIBCPP_NORETURN void __libcpp_throw_debug_function(__libcpp_debug_info const& info) {
-#ifndef _LIBCPP_NO_EXCEPTIONS
-  throw __libcpp_debug_exception(info);
-#else
-  __libcpp_abort_debug_function(info);
-#endif
-}
-
-struct __libcpp_debug_exception::__libcpp_debug_exception_imp {
-  __libcpp_debug_info __info_;
-  std::string __what_str_;
-};
-
-__libcpp_debug_exception::__libcpp_debug_exception() _NOEXCEPT
-    : __imp_(nullptr) {
-}
-
-__libcpp_debug_exception::__libcpp_debug_exception(
-    __libcpp_debug_info const& info) : __imp_(new __libcpp_debug_exception_imp)
-{
-  __imp_->__info_ = info;
-  __imp_->__what_str_ = make_what_str(info);
-}
-__libcpp_debug_exception::__libcpp_debug_exception(
-    __libcpp_debug_exception const& other) : __imp_(nullptr) {
-  if (other.__imp_)
-    __imp_ = new __libcpp_debug_exception_imp(*other.__imp_);
-}
-
-__libcpp_debug_exception::~__libcpp_debug_exception() _NOEXCEPT {
-  if (__imp_)
-    delete __imp_;
-}
-
-const char* __libcpp_debug_exception::what() const _NOEXCEPT {
-  if (__imp_)
-    return __imp_->__what_str_.c_str();
-  return "__libcpp_debug_exception";
-}
-
 _LIBCPP_FUNC_VIS
 __libcpp_db*
 __get_db()

Modified: libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_back.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_back.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_back.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_back.pass.cpp Mon Mar 18 14:50:12 2019
@@ -5,29 +5,18 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
 
-// UNSUPPORTED: libcpp-no-exceptions
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
 
-// test array<T, 0>::front() throws a debug exception.
+// test array<T, 0>::front() raises a debug error.
 
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 #include <array>
-
-template <class Array>
-inline bool CheckDebugThrows(Array& Arr) {
-  try {
-    Arr.back();
-  } catch (std::__libcpp_debug_exception const&) {
-    return true;
-  }
-  return false;
-}
+#include "debug_mode_helper.h"
 
 int main(int, char**)
 {
@@ -35,15 +24,15 @@ int main(int, char**)
     typedef std::array<int, 0> C;
     C c = {};
     C const& cc = c;
-    assert(CheckDebugThrows(c));
-    assert(CheckDebugThrows(cc));
+    EXPECT_DEATH( c.back() );
+    EXPECT_DEATH( cc.back() );
   }
   {
     typedef std::array<const int, 0> C;
     C c = {{}};
     C const& cc = c;
-    assert(CheckDebugThrows(c));
-    assert(CheckDebugThrows(cc));
+    EXPECT_DEATH( c.back() );
+    EXPECT_DEATH( cc.back() );
   }
 
   return 0;

Modified: libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_front.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_front.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_front.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_front.pass.cpp Mon Mar 18 14:50:12 2019
@@ -5,29 +5,18 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
 
-// UNSUPPORTED: libcpp-no-exceptions
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
 
-// test array<T, 0>::front() throws a debug exception.
+// test array<T, 0>::front() raises a debug error.
 
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 #include <array>
-
-template <class Array>
-inline bool CheckDebugThrows(Array& Arr) {
-  try {
-    Arr.front();
-  } catch (std::__libcpp_debug_exception const&) {
-    return true;
-  }
-  return false;
-}
+#include "debug_mode_helper.h"
 
 int main(int, char**)
 {
@@ -35,15 +24,15 @@ int main(int, char**)
     typedef std::array<int, 0> C;
     C c = {};
     C const& cc = c;
-    assert(CheckDebugThrows(c));
-    assert(CheckDebugThrows(cc));
+    EXPECT_DEATH(c.front());
+    EXPECT_DEATH(cc.front());
   }
   {
     typedef std::array<const int, 0> C;
     C c = {{}};
     C const& cc = c;
-    assert(CheckDebugThrows(c));
-    assert(CheckDebugThrows(cc));
+    EXPECT_DEATH(c.front());
+    EXPECT_DEATH(cc.front());
   }
 
   return 0;

Modified: libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_indexing.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_indexing.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_indexing.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/containers/sequences/array/array.zero/db_indexing.pass.cpp Mon Mar 18 14:50:12 2019
@@ -5,29 +5,18 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-// XFAIL:*
-// UNSUPPORTED: libcpp-no-exceptions
+// UNSUPPORTED: c++98, c++03
+
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
 
-// test array<T, 0>::operator[] throws a debug exception.
+// test array<T, 0>::operator[] raises a debug error.
 
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 #include <array>
-
-template <class Array>
-inline bool CheckDebugThrows(Array& Arr, size_t Index) {
-  try {
-    Arr[Index];
-  } catch (std::__libcpp_debug_exception const&) {
-    return true;
-  }
-  return false;
-}
+#include "debug_mode_helper.h"
 
 int main(int, char**)
 {
@@ -35,19 +24,19 @@ int main(int, char**)
     typedef std::array<int, 0> C;
     C c = {};
     C const& cc = c;
-    assert(CheckDebugThrows(c, 0));
-    assert(CheckDebugThrows(c, 1));
-    assert(CheckDebugThrows(cc, 0));
-    assert(CheckDebugThrows(cc, 1));
+    EXPECT_DEATH( c[0] );
+    EXPECT_DEATH( c[1] );
+    EXPECT_DEATH( cc[0] );
+    EXPECT_DEATH( cc[1] );
   }
   {
     typedef std::array<const int, 0> C;
     C c = {{}};
     C const& cc = c;
-    assert(CheckDebugThrows(c, 0));
-    assert(CheckDebugThrows(c, 1));
-    assert(CheckDebugThrows(cc, 0));
-    assert(CheckDebugThrows(cc, 1));
+    EXPECT_DEATH( c[0] );
+    EXPECT_DEATH( c[1] );
+    EXPECT_DEATH( cc[0] );
+    EXPECT_DEATH( cc[1] );
   }
 
   return 0;

Modified: libcxx/trunk/test/libcxx/debug/containers/db_associative_container_tests.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/containers/db_associative_container_tests.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/debug/containers/db_associative_container_tests.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/debug/containers/db_associative_container_tests.pass.cpp Mon Mar 18 14:50:12 2019
@@ -7,9 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++98, c++03, c++11, c++14
-// UNSUPPORTED: libcpp-no-exceptions, libcpp-no-if-constexpr
+// UNSUPPORTED: libcpp-no-if-constexpr
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
@@ -17,12 +16,12 @@
 // test container debugging
 
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 #include <map>
 #include <set>
 #include <utility>
 #include <cassert>
+#include "container_debug_tests.hpp"
 #include "debug_mode_helper.h"
 
 using namespace IteratorDebugChecks;
@@ -40,11 +39,6 @@ struct AssociativeContainerChecks : Basi
 public:
   static void run() {
     Base::run();
-    try {
-     // FIXME Add tests
-    } catch (...) {
-      assert(false && "uncaught debug exception");
-    }
   }
 
 private:

Modified: libcxx/trunk/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/debug/containers/db_sequence_container_iterators.pass.cpp Mon Mar 18 14:50:12 2019
@@ -6,11 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-// XFAIL: *
 // UNSUPPORTED: c++98, c++03, c++11, c++14
-// UNSUPPORTED: libcpp-no-exceptions, libcpp-no-if-constexpr
+// UNSUPPORTED: libcpp-no-if-constexpr
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
@@ -18,11 +16,12 @@
 // test container debugging
 
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
+
 #include <forward_list>
 #include <list>
 #include <vector>
 #include <deque>
+#include "container_debug_tests.hpp"
 #include "debug_mode_helper.h"
 
 using namespace IteratorDebugChecks;
@@ -40,11 +39,10 @@ struct SequenceContainerChecks : BasicCo
 public:
   static void run() {
     Base::run();
-    try {
-      SanityTest();
-      FrontOnEmptyContainer();
+    SanityTest();
+    FrontOnEmptyContainer();
 
-      if constexpr (CT != CT_ForwardList) {
+    if constexpr(CT != CT_ForwardList) {
         AssignInvalidates();
         BackOnEmptyContainer();
         InsertIterValue();
@@ -52,24 +50,22 @@ public:
         InsertIterIterIter();
         EmplaceIterValue();
         EraseIterIter();
-      } else {
-        SpliceFirstElemAfter();
-      }
-      if constexpr (CT == CT_Vector || CT == CT_Deque || CT == CT_List) {
-        PopBack();
-      }
-      if constexpr (CT == CT_List || CT == CT_Deque) {
-        PopFront(); // FIXME: Run with forward list as well
-      }
-      if constexpr (CT == CT_List || CT == CT_ForwardList) {
-        RemoveFirstElem();
-      }
-      if constexpr (CT == CT_List) {
-        SpliceFirstElem();
-        SpliceSameContainer();
       }
-    } catch (...) {
-      assert(false && "uncaught debug exception");
+    else {
+      SpliceFirstElemAfter();
+    }
+    if constexpr (CT == CT_Vector || CT == CT_Deque || CT == CT_List) {
+      PopBack();
+    }
+    if constexpr (CT == CT_List || CT == CT_Deque) {
+      PopFront(); // FIXME: Run with forward list as well
+    }
+    if constexpr (CT == CT_List || CT == CT_ForwardList) {
+      RemoveFirstElem();
+    }
+    if constexpr (CT == CT_List) {
+      SpliceFirstElem();
+      SpliceSameContainer();
     }
   }
 
@@ -144,9 +140,9 @@ private:
       it3 = C.end();
     };
     auto check = [&]() {
-      CHECK_DEBUG_THROWS( C.erase(it1) );
-      CHECK_DEBUG_THROWS( C.erase(it2) );
-      CHECK_DEBUG_THROWS( C.erase(it3, C.end()) );
+      EXPECT_DEATH( C.erase(it1) );
+      EXPECT_DEATH( C.erase(it2) );
+      EXPECT_DEATH( C.erase(it3, C.end()) );
     };
     reset();
     C.assign(2, makeValueType(4));
@@ -173,8 +169,8 @@ private:
     (void)C.back();
     (void)CC.back();
     C.clear();
-    CHECK_DEBUG_THROWS( C.back() );
-    CHECK_DEBUG_THROWS( CC.back() );
+    EXPECT_DEATH( C.back() );
+    EXPECT_DEATH( CC.back() );
   }
 
   static void FrontOnEmptyContainer() {
@@ -184,8 +180,8 @@ private:
     (void)C.front();
     (void)CC.front();
     C.clear();
-    CHECK_DEBUG_THROWS( C.front() );
-    CHECK_DEBUG_THROWS( CC.front() );
+    EXPECT_DEATH( C.front() );
+    EXPECT_DEATH( CC.front() );
   }
 
   static void EraseIterIter() {
@@ -198,15 +194,15 @@ private:
     iterator it1_back = --C1.end();
     assert(it1_next != it1_back);
     if (CT == CT_Vector) {
-      CHECK_DEBUG_THROWS( C1.erase(it1_next, it1) ); // bad range
+      EXPECT_DEATH( C1.erase(it1_next, it1) ); // bad range
     }
     C1.erase(it1, it1_after_next);
-    CHECK_DEBUG_THROWS( C1.erase(it1) );
-    CHECK_DEBUG_THROWS( C1.erase(it1_next) );
+    EXPECT_DEATH( C1.erase(it1) );
+    EXPECT_DEATH( C1.erase(it1_next) );
     if (CT == CT_List) {
       C1.erase(it1_back);
     } else {
-      CHECK_DEBUG_THROWS( C1.erase(it1_back) );
+      EXPECT_DEATH( C1.erase(it1_back) );
     }
   }
 
@@ -216,10 +212,10 @@ private:
     iterator it1 = C1.end();
     --it1;
     C1.pop_back();
-    CHECK_DEBUG_THROWS( C1.erase(it1) );
+    EXPECT_DEATH( C1.erase(it1) );
     C1.erase(C1.begin());
     assert(C1.size() == 0);
-    CHECK_DEBUG_THROWS( C1.pop_back() );
+    EXPECT_DEATH( C1.pop_back() );
   }
 
   static void PopFront() {
@@ -227,10 +223,10 @@ private:
     Container C1 = makeContainer(2);
     iterator it1 = C1.begin();
     C1.pop_front();
-    CHECK_DEBUG_THROWS( C1.erase(it1) );
+    EXPECT_DEATH( C1.erase(it1) );
     C1.erase(C1.begin());
     assert(C1.size() == 0);
-    CHECK_DEBUG_THROWS( C1.pop_front() );
+    EXPECT_DEATH( C1.pop_front() );
   }
 
   static void InsertIterValue() {
@@ -242,8 +238,8 @@ private:
     Container C2 = C1;
     const value_type value = makeValueType(3);
     value_type rvalue = makeValueType(3);
-    CHECK_DEBUG_THROWS( C2.insert(it1, value) ); // wrong container
-    CHECK_DEBUG_THROWS( C2.insert(it1, std::move(rvalue)) ); // wrong container
+    EXPECT_DEATH( C2.insert(it1, value) ); // wrong container
+    EXPECT_DEATH( C2.insert(it1, std::move(rvalue)) ); // wrong container
     C1.insert(it1_next, value);
     if  (CT == CT_List) {
       C1.insert(it1_next, value);
@@ -251,10 +247,10 @@ private:
       C1.insert(it1_next, std::move(rvalue));
       C1.insert(it1, std::move(rvalue));
     } else {
-      CHECK_DEBUG_THROWS( C1.insert(it1_next, value) ); // invalidated iterator
-      CHECK_DEBUG_THROWS( C1.insert(it1, value) ); // invalidated iterator
-      CHECK_DEBUG_THROWS( C1.insert(it1_next, std::move(rvalue)) ); // invalidated iterator
-      CHECK_DEBUG_THROWS( C1.insert(it1, std::move(rvalue)) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1_next, value) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1, value) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1_next, std::move(rvalue)) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1, std::move(rvalue)) ); // invalidated iterator
     }
   }
 
@@ -266,15 +262,15 @@ private:
     ++it1_next;
     Container C2 = C1;
     const value_type value = makeValueType(3);
-    CHECK_DEBUG_THROWS( C2.emplace(it1, value) ); // wrong container
-    CHECK_DEBUG_THROWS( C2.emplace(it1, makeValueType(4)) ); // wrong container
+    EXPECT_DEATH( C2.emplace(it1, value) ); // wrong container
+    EXPECT_DEATH( C2.emplace(it1, makeValueType(4)) ); // wrong container
     C1.emplace(it1_next, value);
     if  (CT == CT_List) {
       C1.emplace(it1_next, value);
       C1.emplace(it1, value);
     } else {
-      CHECK_DEBUG_THROWS( C1.emplace(it1_next, value) ); // invalidated iterator
-      CHECK_DEBUG_THROWS( C1.emplace(it1, value) ); // invalidated iterator
+      EXPECT_DEATH( C1.emplace(it1_next, value) ); // invalidated iterator
+      EXPECT_DEATH( C1.emplace(it1, value) ); // invalidated iterator
     }
   }
 
@@ -286,14 +282,14 @@ private:
     ++it1_next;
     Container C2 = C1;
     const value_type value = makeValueType(3);
-    CHECK_DEBUG_THROWS( C2.insert(it1, 1, value) ); // wrong container
+    EXPECT_DEATH( C2.insert(it1, 1, value) ); // wrong container
     C1.insert(it1_next, 2, value);
     if  (CT == CT_List) {
       C1.insert(it1_next, 3, value);
       C1.insert(it1, 1, value);
     } else {
-      CHECK_DEBUG_THROWS( C1.insert(it1_next, 1, value) ); // invalidated iterator
-      CHECK_DEBUG_THROWS( C1.insert(it1, 1, value) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1_next, 1, value) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1, 1, value) ); // invalidated iterator
     }
   }
 
@@ -309,14 +305,14 @@ private:
         makeValueType(2),
         makeValueType(3)
     };
-    CHECK_DEBUG_THROWS( C2.insert(it1, V.begin(), V.end()) ); // wrong container
+    EXPECT_DEATH( C2.insert(it1, V.begin(), V.end()) ); // wrong container
     C1.insert(it1_next, V.begin(), V.end());
     if  (CT == CT_List) {
       C1.insert(it1_next, V.begin(), V.end());
       C1.insert(it1, V.begin(), V.end());
     } else {
-      CHECK_DEBUG_THROWS( C1.insert(it1_next, V.begin(), V.end()) ); // invalidated iterator
-      CHECK_DEBUG_THROWS( C1.insert(it1, V.begin(), V.end()) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1_next, V.begin(), V.end()) ); // invalidated iterator
+      EXPECT_DEATH( C1.insert(it1, V.begin(), V.end()) ); // invalidated iterator
     }
   }
 };

Modified: libcxx/trunk/test/libcxx/debug/containers/db_string.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/containers/db_string.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/debug/containers/db_string.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/debug/containers/db_string.pass.cpp Mon Mar 18 14:50:12 2019
@@ -7,9 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++98, c++03, c++11, c++14
-// UNSUPPORTED: libcpp-no-exceptions, libcpp-no-if-constexpr
+// UNSUPPORTED: libcpp-no-if-constexpr
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
@@ -17,11 +16,11 @@
 // test container debugging
 
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 #include <string>
 #include <vector>
 
 #include "test_macros.h"
+#include "container_debug_tests.hpp"
 #include "debug_mode_helper.h"
 
 using namespace IteratorDebugChecks;
@@ -43,14 +42,11 @@ public:
   static void run() {
     Base::run_iterator_tests();
     Base::run_allocator_aware_tests();
-    try {
-      for (int N : {3, 128}) {
-        FrontOnEmptyContainer(N);
-        BackOnEmptyContainer(N);
-        PopBack(N);
-      }
-    } catch (...) {
-      assert(false && "uncaught debug exception");
+
+    for (int N : {3, 128}) {
+      FrontOnEmptyContainer(N);
+      BackOnEmptyContainer(N);
+      PopBack(N);
     }
   }
 
@@ -63,10 +59,10 @@ private:
     (void)C.back();
     (void)CC.back();
     C.pop_back();
-    CHECK_DEBUG_THROWS( C.erase(it) );
+    EXPECT_DEATH( C.erase(it) );
     C.clear();
-    CHECK_DEBUG_THROWS( C.back() );
-    CHECK_DEBUG_THROWS( CC.back() );
+    EXPECT_DEATH( C.back() );
+    EXPECT_DEATH( CC.back() );
   }
 
   static void FrontOnEmptyContainer(int N) {
@@ -76,8 +72,8 @@ private:
     (void)C.front();
     (void)CC.front();
     C.clear();
-    CHECK_DEBUG_THROWS( C.front() );
-    CHECK_DEBUG_THROWS( CC.front() );
+    EXPECT_DEATH( C.front() );
+    EXPECT_DEATH( CC.front() );
   }
 
   static void PopBack(int N) {
@@ -86,10 +82,10 @@ private:
     iterator it1 = C1.end();
     --it1;
     C1.pop_back();
-    CHECK_DEBUG_THROWS( C1.erase(it1) );
+    EXPECT_DEATH( C1.erase(it1) );
     C1.erase(C1.begin(), C1.end());
     assert(C1.size() == 0);
-    CHECK_DEBUG_THROWS( C1.pop_back() );
+    EXPECT_DEATH_MATCHES(DebugInfoMatcher("string::pop_back(): string is already empty"), C1.pop_back() );
   }
 };
 

Modified: libcxx/trunk/test/libcxx/debug/containers/db_unord_container_tests.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/containers/db_unord_container_tests.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/debug/containers/db_unord_container_tests.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/debug/containers/db_unord_container_tests.pass.cpp Mon Mar 18 14:50:12 2019
@@ -7,9 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++98, c++03, c++11, c++14
-// UNSUPPORTED: libcpp-no-exceptions, libcpp-no-if-constexpr
+// UNSUPPORTED: libcpp-no-if-constexpr
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
@@ -17,11 +16,11 @@
 // test container debugging
 
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
 #include <cassert>
+#include "container_debug_tests.hpp"
 #include "debug_mode_helper.h"
 
 using namespace IteratorDebugChecks;
@@ -39,11 +38,6 @@ struct UnorderedContainerChecks : BasicC
 public:
   static void run() {
     Base::run();
-    try {
-     // FIXME
-    } catch (...) {
-      assert(false && "uncaught debug exception");
-    }
   }
 private:
 

Added: libcxx/trunk/test/libcxx/debug/debug_helper_test.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/debug_helper_test.pass.cpp?rev=356417&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/debug/debug_helper_test.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/debug/debug_helper_test.pass.cpp Mon Mar 18 14:50:12 2019
@@ -0,0 +1,70 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// Can't test the system lib because this test enables debug mode
+// UNSUPPORTED: with_system_cxx_lib
+
+// MODULES_DEFINES: _LIBCPP_DEBUG=1
+
+#define _LIBCPP_DEBUG 1
+
+#include <__debug>
+#include "debug_mode_helper.h"
+
+
+template <class Func>
+inline bool TestDeathTest(const char* stmt, Func&& func, DeathTest::ResultKind ExpectResult, DebugInfoMatcher Matcher = AnyMatcher) {
+  DeathTest DT(Matcher);
+  DeathTest::ResultKind RK = DT.Run(func);
+  auto OnFailure = [&](std::string msg) {
+    std::cerr << "EXPECT_DEATH( " << stmt << " ) failed! (" << msg << ")\n\n";
+    if (!DT.getChildStdErr().empty()) {
+      std::cerr << "---------- standard err ----------\n";
+      std::cerr << DT.getChildStdErr() << "\n";
+    }
+    if (!DT.getChildStdOut().empty()) {
+      std::cerr << "---------- standard out ----------\n";
+      std::cerr << DT.getChildStdOut() << "\n";
+    }
+    return false;
+  };
+  if (RK != ExpectResult)
+    return OnFailure(std::string("expected result did not occur: expected ") + DeathTest::ResultKindToString(ExpectResult) + " got: " + DeathTest::ResultKindToString(RK));
+  return true;
+}
+#define TEST_DEATH_TEST(RK, ...) assert((TestDeathTest(#__VA_ARGS__, [&]() { __VA_ARGS__; }, RK, AnyMatcher )))
+
+#define TEST_DEATH_TEST_MATCHES(RK, Matcher, ...) assert((TestDeathTest(#__VA_ARGS__, [&]() { __VA_ARGS__; }, RK, Matcher)))
+
+void my_libcpp_assert() {
+  _LIBCPP_ASSERT(false, "other");
+}
+
+void test_no_match_found() {
+  DebugInfoMatcher ExpectMatch("my message");
+  TEST_DEATH_TEST_MATCHES(DeathTest::RK_MatchFailure, ExpectMatch, my_libcpp_assert());
+}
+
+void test_did_not_die() {
+  TEST_DEATH_TEST(DeathTest::RK_DidNotDie, ((void)0));
+}
+
+void test_unknown() {
+  TEST_DEATH_TEST(DeathTest::RK_Unknown, std::exit(13));
+}
+
+int main(int, char**)
+{
+  test_no_match_found();
+  test_did_not_die();
+  test_unknown();
+  return 0;
+}

Copied: libcxx/trunk/test/libcxx/debug/debug_register.pass.cpp (from r356416, libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp)
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/debug_register.pass.cpp?p2=libcxx/trunk/test/libcxx/debug/debug_register.pass.cpp&p1=libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp&r1=356416&r2=356417&rev=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/debug/debug_register.pass.cpp Mon Mar 18 14:50:12 2019
@@ -7,31 +7,27 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: libcpp-no-exceptions
 // MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 // Can't test the system lib because this test enables debug mode
 // UNSUPPORTED: with_system_cxx_lib
 
-// Test that defining _LIBCPP_DEBUG_USE_EXCEPTIONS causes _LIBCPP_ASSERT
-// to throw on failure.
-
 #define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 
 #include <cstdlib>
-#include <exception>
+#include <string>
 #include <type_traits>
 #include <__debug>
 #include <cassert>
 
+void my_debug_function(std::__libcpp_debug_info const& info) {
+  assert(info.__msg_ == std::string("foo"));
+  std::exit(0);
+}
+
 int main(int, char**)
 {
-  try {
-    _LIBCPP_ASSERT(false, "foo");
-    assert(false);
-  } catch (...) {}
-
-  return 0;
+  std::__libcpp_set_debug_function(&my_debug_function);
+  _LIBCPP_ASSERT(false, "foo");
+  return 1;
 }

Removed: libcxx/trunk/test/libcxx/debug/debug_throw.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/debug_throw.pass.cpp?rev=356416&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/debug/debug_throw.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/debug/debug_throw.pass.cpp (removed)
@@ -1,42 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: libcpp-no-exceptions
-// MODULES_DEFINES: _LIBCPP_DEBUG=0
-
-// Can't test the system lib because this test enables debug mode
-// UNSUPPORTED: with_system_cxx_lib
-
-// Test that the default debug handler can be overridden and test the
-// throwing debug handler.
-
-#define _LIBCPP_DEBUG 0
-
-#include <cstdlib>
-#include <exception>
-#include <type_traits>
-#include <__debug>
-
-int main(int, char**)
-{
-  {
-    std::__libcpp_debug_function = std::__libcpp_throw_debug_function;
-    try {
-      _LIBCPP_ASSERT(false, "foo");
-    } catch (std::__libcpp_debug_exception const&) {}
-  }
-  {
-    // test that the libc++ exception type derives from std::exception
-    static_assert((std::is_base_of<std::exception,
-                                  std::__libcpp_debug_exception
-                  >::value), "must be an exception");
-  }
-
-  return 0;
-}

Removed: libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp?rev=356416&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/debug/debug_throw_register.pass.cpp (removed)
@@ -1,37 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: libcpp-no-exceptions
-// MODULES_DEFINES: _LIBCPP_DEBUG=1
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
-
-// Can't test the system lib because this test enables debug mode
-// UNSUPPORTED: with_system_cxx_lib
-
-// Test that defining _LIBCPP_DEBUG_USE_EXCEPTIONS causes _LIBCPP_ASSERT
-// to throw on failure.
-
-#define _LIBCPP_DEBUG 1
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
-
-#include <cstdlib>
-#include <exception>
-#include <type_traits>
-#include <__debug>
-#include <cassert>
-
-int main(int, char**)
-{
-  try {
-    _LIBCPP_ASSERT(false, "foo");
-    assert(false);
-  } catch (...) {}
-
-  return 0;
-}

Modified: libcxx/trunk/test/libcxx/input.output/filesystems/class.path/path.itr/iterator_db.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/input.output/filesystems/class.path/path.itr/iterator_db.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/input.output/filesystems/class.path/path.itr/iterator_db.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/input.output/filesystems/class.path/path.itr/iterator_db.pass.cpp Mon Mar 18 14:50:12 2019
@@ -7,9 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++98, c++03
-// UNSUPPORTED: libcpp-no-exceptions
 
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 // MODULES_DEFINES: _LIBCPP_DEBUG=0
 
 // <filesystem>
@@ -17,7 +15,6 @@
 // class path
 
 #define _LIBCPP_DEBUG 0
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 #include "filesystem_include.hpp"
 #include <iterator>
 #include <type_traits>
@@ -25,51 +22,32 @@
 
 #include "test_macros.h"
 #include "filesystem_test_helper.hpp"
+#include "debug_mode_helper.h"
 
 int main(int, char**) {
   using namespace fs;
-  using ExType = std::__libcpp_debug_exception;
   // Test incrementing/decrementing a singular iterator
   {
     path::iterator singular;
-    try {
-      ++singular;
-      assert(false);
-    } catch (ExType const&) {}
-    try {
-      --singular;
-      assert(false);
-    } catch (ExType const&) {}
+    EXPECT_DEATH( ++singular );
+    EXPECT_DEATH( --singular );
   }
   // Test decrementing the begin iterator
   {
     path p("foo/bar");
     auto it = p.begin();
-    try {
-      --it;
-      assert(false);
-    } catch (ExType const&) {}
     ++it;
     ++it;
-    try {
-      ++it;
-      assert(false);
-    } catch (ExType const&) {}
+    EXPECT_DEATH( ++it );
   }
   // Test incrementing the end iterator
   {
     path p("foo/bar");
     auto it = p.end();
-    try {
-      ++it;
-      assert(false);
-    } catch (ExType const&) {}
+    EXPECT_DEATH( ++it );
     --it;
     --it;
-    try {
-      --it;
-      assert(false);
-    } catch (ExType const&) {}
+    EXPECT_DEATH( --it );
   }
 
   return 0;

Modified: libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception.pass.cpp Mon Mar 18 14:50:12 2019
@@ -6,11 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: libcpp-no-exceptions
 // UNSUPPORTED: libcpp-has-no-threads
 // UNSUPPORTED: c++98, c++03
 
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 // MODULES_DEFINES: _LIBCPP_DEBUG=0
 
 // Can't test the system lib because this test enables debug mode
@@ -24,33 +22,28 @@
 // Test that a null exception_ptr is diagnosed.
 
 #define _LIBCPP_DEBUG 0
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
+
 #include <future>
 #include <exception>
 #include <cstdlib>
 #include <cassert>
 
 
+#include "debug_mode_helper.h"
+
 int main(int, char**)
 {
-    typedef std::__libcpp_debug_exception ExType;
     {
         typedef int T;
         std::promise<T> p;
-        try {
-            p.set_exception(std::exception_ptr());
-            assert(false);
-        } catch (ExType const&) {
-        }
+
+        EXPECT_DEATH( p.set_exception(std::exception_ptr()) );
     }
     {
         typedef int& T;
         std::promise<T> p;
-        try {
-            p.set_exception(std::exception_ptr());
-            assert(false);
-        } catch (ExType const&) {
-        }
+
+        EXPECT_DEATH( p.set_exception(std::exception_ptr()) );
     }
 
   return 0;

Modified: libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp (original)
+++ libcxx/trunk/test/libcxx/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp Mon Mar 18 14:50:12 2019
@@ -10,7 +10,6 @@
 // UNSUPPORTED: libcpp-has-no-threads
 // UNSUPPORTED: c++98, c++03
 
-// MODULES_DEFINES: _LIBCPP_DEBUG_USE_EXCEPTIONS
 // MODULES_DEFINES: _LIBCPP_DEBUG=0
 
 // Can't test the system lib because this test enables debug mode
@@ -24,33 +23,27 @@
 // Test that a null exception_ptr is diagnosed.
 
 #define _LIBCPP_DEBUG 0
-#define _LIBCPP_DEBUG_USE_EXCEPTIONS
 #include <future>
 #include <exception>
 #include <cstdlib>
 #include <cassert>
+#include "debug_mode_helper.h"
 
 
 int main(int, char**)
 {
-    typedef std::__libcpp_debug_exception ExType;
     {
         typedef int T;
         std::promise<T> p;
-        try {
-            p.set_exception_at_thread_exit(std::exception_ptr());
-            assert(false);
-        } catch (ExType const& value) {
-        }
+
+        EXPECT_DEATH( p.set_exception_at_thread_exit(std::exception_ptr()) );
+
     }
     {
         typedef int& T;
         std::promise<T> p;
-        try {
-            p.set_exception_at_thread_exit(std::exception_ptr());
-            assert(false);
-        } catch (ExType const& value) {
-        }
+
+        EXPECT_DEATH( p.set_exception_at_thread_exit(std::exception_ptr()) );
     }
 
   return 0;

Added: libcxx/trunk/test/support/container_debug_tests.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/container_debug_tests.hpp?rev=356417&view=auto
==============================================================================
--- libcxx/trunk/test/support/container_debug_tests.hpp (added)
+++ libcxx/trunk/test/support/container_debug_tests.hpp Mon Mar 18 14:50:12 2019
@@ -0,0 +1,371 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_SUPPORT_CONTAINER_DEBUG_TESTS_H
+#define TEST_SUPPORT_CONTAINER_DEBUG_TESTS_H
+
+#include <ciso646>
+#ifndef _LIBCPP_VERSION
+#error This header may only be used for libc++ tests"
+#endif
+
+#ifndef _LIBCPP_DEBUG
+#error _LIBCPP_DEBUG must be defined before including this header
+#endif
+
+#include <__debug>
+#include <utility>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <string>
+#include <sstream>
+#include <iostream>
+
+#include "test_macros.h"
+#include "debug_mode_helper.h"
+#include "assert_checkpoint.h"
+#include "test_allocator.h"
+
+// These test make use of 'if constexpr'.
+#if TEST_STD_VER <= 14
+#error This header may only be used in C++17 and greater
+#endif
+
+#ifndef __cpp_if_constexpr
+#error These tests require if constexpr
+#endif
+
+
+namespace IteratorDebugChecks {
+
+enum ContainerType {
+  CT_None,
+  CT_String,
+  CT_Vector,
+  CT_VectorBool,
+  CT_List,
+  CT_Deque,
+  CT_ForwardList,
+  CT_Map,
+  CT_Set,
+  CT_MultiMap,
+  CT_MultiSet,
+  CT_UnorderedMap,
+  CT_UnorderedSet,
+  CT_UnorderedMultiMap,
+  CT_UnorderedMultiSet
+};
+
+constexpr bool isSequential(ContainerType CT) {
+  return CT_Vector >= CT && CT_ForwardList <= CT;
+}
+
+constexpr bool isAssociative(ContainerType CT) {
+  return CT_Map >= CT && CT_MultiSet <= CT;
+}
+
+constexpr bool isUnordered(ContainerType CT) {
+  return CT_UnorderedMap >= CT && CT_UnorderedMultiSet <= CT;
+}
+
+constexpr bool isSet(ContainerType CT) {
+  return CT == CT_Set
+      || CT == CT_MultiSet
+      || CT == CT_UnorderedSet
+      || CT == CT_UnorderedMultiSet;
+}
+
+constexpr bool isMap(ContainerType CT) {
+  return CT == CT_Map
+      || CT == CT_MultiMap
+      || CT == CT_UnorderedMap
+      || CT == CT_UnorderedMultiMap;
+}
+
+constexpr bool isMulti(ContainerType CT) {
+  return CT == CT_MultiMap
+      || CT == CT_MultiSet
+      || CT == CT_UnorderedMultiMap
+      || CT == CT_UnorderedMultiSet;
+}
+
+template <class Container, class ValueType = typename Container::value_type>
+struct ContainerDebugHelper {
+  static_assert(std::is_constructible<ValueType, int>::value,
+                "must be constructible from int");
+
+  static ValueType makeValueType(int val = 0, int = 0) {
+    return ValueType(val);
+  }
+};
+
+template <class Container>
+struct ContainerDebugHelper<Container, char> {
+  static char makeValueType(int = 0, int = 0) {
+    return 'A';
+  }
+};
+
+template <class Container, class Key, class Value>
+struct ContainerDebugHelper<Container, std::pair<const Key, Value> > {
+  using ValueType = std::pair<const Key, Value>;
+  static_assert(std::is_constructible<Key, int>::value,
+                "must be constructible from int");
+  static_assert(std::is_constructible<Value, int>::value,
+                "must be constructible from int");
+
+  static ValueType makeValueType(int key = 0, int val = 0) {
+    return ValueType(key, val);
+  }
+};
+
+template <class Container, ContainerType CT,
+    class Helper = ContainerDebugHelper<Container> >
+struct BasicContainerChecks {
+  using value_type = typename Container::value_type;
+  using iterator = typename Container::iterator;
+  using const_iterator = typename Container::const_iterator;
+  using allocator_type = typename Container::allocator_type;
+  using traits = std::iterator_traits<iterator>;
+  using category = typename traits::iterator_category;
+
+  static_assert(std::is_same<test_allocator<value_type>, allocator_type>::value,
+                "the container must use a test allocator");
+
+  static constexpr bool IsBiDir =
+      std::is_convertible<category, std::bidirectional_iterator_tag>::value;
+
+ public:
+  static void run() {
+    run_iterator_tests();
+    run_container_tests();
+    run_allocator_aware_tests();
+  }
+
+  static void run_iterator_tests() {
+    try {
+      TestNullIterators<iterator>();
+      TestNullIterators<const_iterator>();
+      if constexpr (IsBiDir) { DecrementBegin(); }
+      IncrementEnd();
+      DerefEndIterator();
+    } catch (...) {
+      assert(false && "uncaught debug exception");
+    }
+  }
+
+  static void run_container_tests() {
+    try {
+      CopyInvalidatesIterators();
+      MoveInvalidatesIterators();
+      if constexpr (CT != CT_ForwardList) {
+        EraseIter();
+        EraseIterIter();
+      }
+    } catch (...) {
+      assert(false && "uncaught debug exception");
+    }
+  }
+
+  static void run_allocator_aware_tests() {
+    try {
+      SwapNonEqualAllocators();
+      if constexpr (CT != CT_ForwardList ) {
+        // FIXME: This should work for both forward_list and string
+        SwapInvalidatesIterators();
+      }
+    } catch (...) {
+      assert(false && "uncaught debug exception");
+    }
+  }
+
+  static Container makeContainer(int size, allocator_type A = allocator_type()) {
+    Container C(A);
+    if constexpr (CT == CT_ForwardList) {
+      for (int i = 0; i < size; ++i)
+        C.insert_after(C.before_begin(), Helper::makeValueType(i));
+    } else {
+      for (int i = 0; i < size; ++i)
+        C.insert(C.end(), Helper::makeValueType(i));
+      assert(C.size() == static_cast<std::size_t>(size));
+    }
+    return C;
+  }
+
+  static value_type makeValueType(int value) {
+    return Helper::makeValueType(value);
+  }
+
+ private:
+  // Iterator tests
+  template <class Iter>
+  static void TestNullIterators() {
+    CHECKPOINT("testing null iterator");
+    Iter it;
+    EXPECT_DEATH( ++it );
+    EXPECT_DEATH( it++ );
+    EXPECT_DEATH( *it );
+    if constexpr (CT != CT_VectorBool) {
+      EXPECT_DEATH( it.operator->() );
+    }
+    if constexpr (IsBiDir) {
+      EXPECT_DEATH( --it );
+      EXPECT_DEATH( it-- );
+    }
+  }
+
+  static void DecrementBegin() {
+    CHECKPOINT("testing decrement on begin");
+    Container C = makeContainer(1);
+    iterator i = C.end();
+    const_iterator ci = C.cend();
+    --i;
+    --ci;
+    assert(i == C.begin());
+    EXPECT_DEATH( --i );
+    EXPECT_DEATH( i-- );
+    EXPECT_DEATH( --ci );
+    EXPECT_DEATH( ci-- );
+  }
+
+  static void IncrementEnd() {
+    CHECKPOINT("testing increment on end");
+    Container C = makeContainer(1);
+    iterator i = C.begin();
+    const_iterator ci = C.begin();
+    ++i;
+    ++ci;
+    assert(i == C.end());
+    EXPECT_DEATH( ++i );
+    EXPECT_DEATH( i++ );
+    EXPECT_DEATH( ++ci );
+    EXPECT_DEATH( ci++ );
+  }
+
+  static void DerefEndIterator() {
+    CHECKPOINT("testing deref end iterator");
+    Container C = makeContainer(1);
+    iterator i = C.begin();
+    const_iterator ci = C.cbegin();
+    (void)*i; (void)*ci;
+    if constexpr (CT != CT_VectorBool) {
+      i.operator->();
+      ci.operator->();
+    }
+    ++i; ++ci;
+    assert(i == C.end());
+    EXPECT_DEATH( *i );
+    EXPECT_DEATH( *ci );
+    if constexpr (CT != CT_VectorBool) {
+      EXPECT_DEATH( i.operator->() );
+      EXPECT_DEATH( ci.operator->() );
+    }
+  }
+
+  // Container tests
+  static void CopyInvalidatesIterators() {
+    CHECKPOINT("copy invalidates iterators");
+    Container C1 = makeContainer(3);
+    iterator i = C1.begin();
+    Container C2 = C1;
+    if constexpr (CT == CT_ForwardList) {
+      iterator i_next = i;
+      ++i_next;
+      (void)*i_next;
+      EXPECT_DEATH( C2.erase_after(i) );
+      C1.erase_after(i);
+      EXPECT_DEATH( *i_next );
+    } else {
+      EXPECT_DEATH( C2.erase(i) );
+      (void)*i;
+      C1.erase(i);
+      EXPECT_DEATH( *i );
+    }
+  }
+
+  static void MoveInvalidatesIterators() {
+    CHECKPOINT("copy move invalidates iterators");
+    Container C1 = makeContainer(3);
+    iterator i = C1.begin();
+    Container C2 = std::move(C1);
+    (void) *i;
+    if constexpr (CT == CT_ForwardList) {
+      EXPECT_DEATH( C1.erase_after(i) );
+      C2.erase_after(i);
+    } else {
+      EXPECT_DEATH( C1.erase(i) );
+      C2.erase(i);
+      EXPECT_DEATH(*i);
+    }
+  }
+
+  static void EraseIter() {
+    CHECKPOINT("testing erase invalidation");
+    Container C1 = makeContainer(2);
+    iterator it1 = C1.begin();
+    iterator it1_next = it1;
+    ++it1_next;
+    Container C2 = C1;
+    EXPECT_DEATH( C2.erase(it1) ); // wrong container
+    EXPECT_DEATH( C2.erase(C2.end()) ); // erase with end
+    C1.erase(it1_next);
+    EXPECT_DEATH( C1.erase(it1_next) ); // invalidated iterator
+    C1.erase(it1);
+    EXPECT_DEATH( C1.erase(it1) ); // invalidated iterator
+  }
+
+  static void EraseIterIter() {
+    CHECKPOINT("testing erase iter iter invalidation");
+    Container C1 = makeContainer(2);
+    iterator it1 = C1.begin();
+    iterator it1_next = it1;
+    ++it1_next;
+    Container C2 = C1;
+    iterator it2 = C2.begin();
+    iterator it2_next = it2;
+    ++it2_next;
+    EXPECT_DEATH( C2.erase(it1, it1_next) ); // begin from wrong container
+    EXPECT_DEATH( C2.erase(it1, it2_next) ); // end   from wrong container
+    EXPECT_DEATH( C2.erase(it2, it1_next) ); // both  from wrong container
+    C2.erase(it2, it2_next);
+  }
+
+  // Allocator aware tests
+  static void SwapInvalidatesIterators() {
+    CHECKPOINT("testing swap invalidates iterators");
+    Container C1 = makeContainer(3);
+    Container C2 = makeContainer(3);
+    iterator it1 = C1.begin();
+    iterator it2 = C2.begin();
+    swap(C1, C2);
+    EXPECT_DEATH( C1.erase(it1) );
+    if (CT == CT_String) {
+      EXPECT_DEATH(C1.erase(it2));
+    } else
+      C1.erase(it2);
+    //C2.erase(it1);
+    EXPECT_DEATH( C1.erase(it1) );
+  }
+
+  static void SwapNonEqualAllocators() {
+    CHECKPOINT("testing swap with non-equal allocators");
+    Container C1 = makeContainer(3, allocator_type(1));
+    Container C2 = makeContainer(1, allocator_type(2));
+    Container C3 = makeContainer(2, allocator_type(2));
+    swap(C2, C3);
+    EXPECT_DEATH( swap(C1, C2) );
+  }
+
+ private:
+  BasicContainerChecks() = delete;
+};
+
+} // namespace IteratorDebugChecks
+
+#endif // TEST_SUPPORT_CONTAINER_DEBUG_TESTS_H

Modified: libcxx/trunk/test/support/debug_mode_helper.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/debug_mode_helper.h?rev=356417&r1=356416&r2=356417&view=diff
==============================================================================
--- libcxx/trunk/test/support/debug_mode_helper.h (original)
+++ libcxx/trunk/test/support/debug_mode_helper.h Mon Mar 18 14:50:12 2019
@@ -12,9 +12,6 @@
 #ifndef _LIBCPP_DEBUG
 #error _LIBCPP_DEBUG must be defined before including this header
 #endif
-#ifndef _LIBCPP_DEBUG_USE_EXCEPTIONS
-#error _LIBCPP_DEBUG_USE_EXCEPTIONS must be defined before including this header
-#endif
 
 #include <ciso646>
 #ifndef _LIBCPP_VERSION
@@ -26,360 +23,280 @@
 #include <cstddef>
 #include <cstdlib>
 #include <cassert>
+#include <string_view>
+#include <sstream>
+#include <iostream>
 
+#include <unistd.h>
+#include <sys/wait.h>
 #include "test_macros.h"
 #include "assert_checkpoint.h"
 #include "test_allocator.h"
 
-// These test make use of 'if constexpr'.
-#if TEST_STD_VER <= 14
-#error This header may only be used in C++17 and greater
-#endif
-#ifdef TEST_HAS_NO_EXCEPTIONS
-#error These tests require exceptions
-#endif
-
-#ifndef __cpp_if_constexpr
-#error These tests require if constexpr
+#if TEST_STD_VER < 11
+# error "C++11 or greater is required to use this header"
 #endif
 
-/// Assert that the specified expression throws a libc++ debug exception.
-#define CHECK_DEBUG_THROWS(...) assert((CheckDebugThrows( [&]() { __VA_ARGS__; } )))
+struct DebugInfoMatcher {
+  static const int any_line = -1;
+  static constexpr const char* any_file = "*";
+  static constexpr const char* any_msg = "*";
+
+  constexpr DebugInfoMatcher() : is_empty(true), msg(any_msg), file(any_file), line(any_line) { }
+  constexpr DebugInfoMatcher(const char* msg, const char* file = any_file, int line = any_line)
+    : is_empty(false), msg(msg), file(file), line(line) {}
+
+  bool Matches(std::__libcpp_debug_info const& got) const {
+    assert(!empty() && "empty matcher");
+
+    if (CheckLineMatches(got.__line_) && CheckFileMatches(got.__file_) &&
+        CheckMessageMatches(got.__msg_))
+        return true;
+    // Write to stdout because that's the file descriptor captured by the parent
+    // process.
+    std::cout << "Failed to match debug info!\n"
+              << ToString() << "\n"
+              << "VS\n"
+              << got.what() << "\n";
+      return false;
+    }
 
-template <class Func>
-inline bool CheckDebugThrows(Func&& func) {
-  try {
-    func();
-  } catch (std::__libcpp_debug_exception const&) {
-    return true;
+  std::string ToString() const {
+    std::stringstream ss;
+    ss << "msg = \"" << msg << "\"\n"
+       << "line = " << (line == any_line ? "'*'" : std::to_string(line)) << "\n"
+       << "file = " << (file == any_file ? "'*'" : any_file) << "";
+    return ss.str();
   }
-  return false;
-}
 
-namespace IteratorDebugChecks {
+  bool empty() const { return is_empty; }
+private:
+  bool CheckLineMatches(int got_line) const {
+    if (line == any_line)
+      return true;
+    return got_line == line;
+  }
+
+  bool CheckFileMatches(std::string_view got_file) const {
+    assert(!empty() && "empty matcher");
+    if (file == any_file)
+      return true;
+    std::size_t found_at = got_file.find(file);
+    if (found_at == std::string_view::npos)
+      return false;
+    // require the match start at the beginning of the file or immediately after
+    // a directory separator.
+    if (found_at != 0) {
+      char last_char = got_file[found_at - 1];
+      if (last_char != '/' && last_char != '\\')
+        return false;
+    }
+    // require the match goes until the end of the string.
+    return got_file.substr(found_at) == file;
+  }
 
-enum ContainerType {
-  CT_None,
-  CT_String,
-  CT_Vector,
-  CT_VectorBool,
-  CT_List,
-  CT_Deque,
-  CT_ForwardList,
-  CT_Map,
-  CT_Set,
-  CT_MultiMap,
-  CT_MultiSet,
-  CT_UnorderedMap,
-  CT_UnorderedSet,
-  CT_UnorderedMultiMap,
-  CT_UnorderedMultiSet
+  bool CheckMessageMatches(std::string_view got_msg) const {
+    assert(!empty() && "empty matcher");
+    if (msg == any_msg)
+      return true;
+    std::size_t found_at = got_msg.find(msg);
+    if (found_at == std::string_view::npos)
+      return false;
+    // Allow any match
+    return true;
+  }
+private:
+  bool is_empty;
+  std::string_view msg;
+  std::string_view file;
+  int line;
 };
 
-constexpr bool isSequential(ContainerType CT) {
-  return CT_Vector >= CT && CT_ForwardList <= CT;
-}
-
-constexpr bool isAssociative(ContainerType CT) {
-  return CT_Map >= CT && CT_MultiSet <= CT;
-}
-
-constexpr bool isUnordered(ContainerType CT) {
-  return CT_UnorderedMap >= CT && CT_UnorderedMultiSet <= CT;
-}
-
-constexpr bool isSet(ContainerType CT) {
-  return CT == CT_Set
-      || CT == CT_MultiSet
-      || CT == CT_UnorderedSet
-      || CT == CT_UnorderedMultiSet;
-}
-
-constexpr bool isMap(ContainerType CT) {
-  return CT == CT_Map
-      || CT == CT_MultiMap
-      || CT == CT_UnorderedMap
-      || CT == CT_UnorderedMultiMap;
-}
+static constexpr DebugInfoMatcher AnyMatcher(DebugInfoMatcher::any_msg);
 
-constexpr bool isMulti(ContainerType CT) {
-  return CT == CT_MultiMap
-      || CT == CT_MultiSet
-      || CT == CT_UnorderedMultiMap
-      || CT == CT_UnorderedMultiSet;
+inline DebugInfoMatcher& GlobalMatcher() {
+  static DebugInfoMatcher GMatch;
+  return GMatch;
 }
 
-template <class Container, class ValueType = typename Container::value_type>
-struct ContainerDebugHelper {
-  static_assert(std::is_constructible<ValueType, int>::value,
-                "must be constructible from int");
+struct DeathTest {
+  enum ResultKind {
+    RK_DidNotDie, RK_MatchFound, RK_MatchFailure, RK_SetupFailure, RK_Unknown
+  };
+
+  static const char* ResultKindToString(ResultKind RK) {
+#define CASE(K) case K: return #K
+    switch (RK) {
+    CASE(RK_MatchFailure);
+    CASE(RK_DidNotDie);
+    CASE(RK_SetupFailure);
+    CASE(RK_MatchFound);
+    CASE(RK_Unknown);
+    }
+    return "not a result kind";
+  }
 
-  static ValueType makeValueType(int val = 0, int = 0) {
-    return ValueType(val);
+  static bool IsValidResultKind(int val) {
+    return val >= RK_DidNotDie && val <= RK_Unknown;
   }
-};
 
-template <class Container>
-struct ContainerDebugHelper<Container, char> {
-  static char makeValueType(int = 0, int = 0) {
-    return 'A';
+  TEST_NORETURN static void DeathTestDebugHandler(std::__libcpp_debug_info const& info) {
+    assert(!GlobalMatcher().empty());
+    if (GlobalMatcher().Matches(info)) {
+      std::exit(RK_MatchFound);
+    }
+    std::exit(RK_MatchFailure);
   }
-};
 
-template <class Container, class Key, class Value>
-struct ContainerDebugHelper<Container, std::pair<const Key, Value> > {
-  using ValueType = std::pair<const Key, Value>;
-  static_assert(std::is_constructible<Key, int>::value,
-                "must be constructible from int");
-  static_assert(std::is_constructible<Value, int>::value,
-                "must be constructible from int");
 
-  static ValueType makeValueType(int key = 0, int val = 0) {
-    return ValueType(key, val);
-  }
-};
+  DeathTest(DebugInfoMatcher const& Matcher) : matcher_(Matcher) {}
 
-template <class Container, ContainerType CT,
-    class Helper = ContainerDebugHelper<Container> >
-struct BasicContainerChecks {
-  using value_type = typename Container::value_type;
-  using iterator = typename Container::iterator;
-  using const_iterator = typename Container::const_iterator;
-  using allocator_type = typename Container::allocator_type;
-  using traits = std::iterator_traits<iterator>;
-  using category = typename traits::iterator_category;
-
-  static_assert(std::is_same<test_allocator<value_type>, allocator_type>::value,
-                "the container must use a test allocator");
-
-  static constexpr bool IsBiDir =
-      std::is_convertible<category, std::bidirectional_iterator_tag>::value;
-
-public:
-  static void run() {
-    run_iterator_tests();
-    run_container_tests();
-    run_allocator_aware_tests();
-  }
-
-  static void run_iterator_tests() {
-    try {
-      TestNullIterators<iterator>();
-      TestNullIterators<const_iterator>();
-      if constexpr (IsBiDir) { DecrementBegin(); }
-      IncrementEnd();
-      DerefEndIterator();
-    } catch (...) {
-      assert(false && "uncaught debug exception");
+  template <class Func>
+  ResultKind Run(Func&& f) {
+    int pipe_res = pipe(stdout_pipe_fd_);
+    assert(pipe_res != -1 && "failed to create pipe");
+    pipe_res = pipe(stderr_pipe_fd_);
+    assert(pipe_res != -1 && "failed to create pipe");
+    pid_t child_pid = fork();
+    assert(child_pid != -1 &&
+        "failed to fork a process to perform a death test");
+    child_pid_ = child_pid;
+    if (child_pid_ == 0) {
+      RunForChild(std::forward<Func>(f));
+      assert(false && "unreachable");
     }
+    return RunForParent();
   }
 
-  static void run_container_tests() {
-    try {
-      CopyInvalidatesIterators();
-      MoveInvalidatesIterators();
-      if constexpr (CT != CT_ForwardList) {
-          EraseIter();
-          EraseIterIter();
+  int getChildExitCode() const { return exit_code_; }
+  std::string const& getChildStdOut() const { return stdout_from_child_; }
+  std::string const& getChildStdErr() const { return stderr_from_child_; }
+private:
+  template <class Func>
+  TEST_NORETURN void RunForChild(Func&& f) {
+    close(GetStdOutReadFD()); // don't need to read from the pipe in the child.
+    close(GetStdErrReadFD());
+    auto DupFD = [](int DestFD, int TargetFD) {
+      int dup_result = dup2(DestFD, TargetFD);
+      if (dup_result == -1)
+        std::exit(RK_SetupFailure);
+    };
+    DupFD(GetStdOutWriteFD(), STDOUT_FILENO);
+    DupFD(GetStdErrWriteFD(), STDERR_FILENO);
+
+    GlobalMatcher() = matcher_;
+    std::__libcpp_set_debug_function(&DeathTestDebugHandler);
+    f();
+    std::exit(RK_DidNotDie);
+  }
+
+  static std::string ReadChildIOUntilEnd(int FD) {
+    std::string error_msg;
+    char buffer[256];
+    int num_read;
+    do {
+      while ((num_read = read(FD, buffer, 255)) > 0) {
+        buffer[num_read] = '\0';
+        error_msg += buffer;
       }
-    } catch (...) {
-      assert(false && "uncaught debug exception");
-    }
+    } while (num_read == -1 && errno == EINTR);
+    return error_msg;
   }
 
-  static void run_allocator_aware_tests() {
-    try {
-      SwapNonEqualAllocators();
-      if constexpr (CT != CT_ForwardList ) {
-          // FIXME: This should work for both forward_list and string
-          SwapInvalidatesIterators();
-      }
-    } catch (...) {
-      assert(false && "uncaught debug exception");
+  void CaptureIOFromChild() {
+    close(GetStdOutWriteFD()); // no need to write from the parent process
+    close(GetStdErrWriteFD());
+    stdout_from_child_ = ReadChildIOUntilEnd(GetStdOutReadFD());
+    stderr_from_child_ = ReadChildIOUntilEnd(GetStdErrReadFD());
+    close(GetStdOutReadFD());
+    close(GetStdErrReadFD());
+  }
+
+  ResultKind RunForParent() {
+    CaptureIOFromChild();
+
+    int status_value;
+    pid_t result = waitpid(child_pid_, &status_value, 0);
+    assert(result != -1 && "there is no child process to wait for");
+
+    if (WIFEXITED(status_value)) {
+      exit_code_ = WEXITSTATUS(status_value);
+      if (!IsValidResultKind(exit_code_))
+        return RK_Unknown;
+      return static_cast<ResultKind>(exit_code_);
     }
+    return RK_Unknown;
   }
 
-  static Container makeContainer(int size, allocator_type A = allocator_type()) {
-    Container C(A);
-    if constexpr (CT == CT_ForwardList) {
-      for (int i = 0; i < size; ++i)
-        C.insert_after(C.before_begin(), Helper::makeValueType(i));
-    } else {
-      for (int i = 0; i < size; ++i)
-        C.insert(C.end(), Helper::makeValueType(i));
-      assert(C.size() == static_cast<std::size_t>(size));
-    }
-    return C;
-  }
+  DeathTest(DeathTest const&) = delete;
+  DeathTest& operator=(DeathTest const&) = delete;
 
-  static value_type makeValueType(int value) {
-    return Helper::makeValueType(value);
+  int GetStdOutReadFD() const {
+    return stdout_pipe_fd_[0];
   }
 
-private:
-  // Iterator tests
-  template <class Iter>
-  static void TestNullIterators() {
-    CHECKPOINT("testing null iterator");
-    Iter it;
-    CHECK_DEBUG_THROWS( ++it );
-    CHECK_DEBUG_THROWS( it++ );
-    CHECK_DEBUG_THROWS( *it );
-    if constexpr (CT != CT_VectorBool) {
-      CHECK_DEBUG_THROWS( it.operator->() );
-    }
-    if constexpr (IsBiDir) {
-      CHECK_DEBUG_THROWS( --it );
-      CHECK_DEBUG_THROWS( it-- );
-    }
+  int GetStdOutWriteFD() const {
+    return stdout_pipe_fd_[1];
   }
 
-  static void DecrementBegin() {
-    CHECKPOINT("testing decrement on begin");
-    Container C = makeContainer(1);
-    iterator i = C.end();
-    const_iterator ci = C.cend();
-    --i;
-    --ci;
-    assert(i == C.begin());
-    CHECK_DEBUG_THROWS( --i );
-    CHECK_DEBUG_THROWS( i-- );
-    CHECK_DEBUG_THROWS( --ci );
-    CHECK_DEBUG_THROWS( ci-- );
-  }
-
-  static void IncrementEnd() {
-    CHECKPOINT("testing increment on end");
-    Container C = makeContainer(1);
-    iterator i = C.begin();
-    const_iterator ci = C.begin();
-    ++i;
-    ++ci;
-    assert(i == C.end());
-    CHECK_DEBUG_THROWS( ++i );
-    CHECK_DEBUG_THROWS( i++ );
-    CHECK_DEBUG_THROWS( ++ci );
-    CHECK_DEBUG_THROWS( ci++ );
-  }
-
-  static void DerefEndIterator() {
-    CHECKPOINT("testing deref end iterator");
-    Container C = makeContainer(1);
-    iterator i = C.begin();
-    const_iterator ci = C.cbegin();
-    (void)*i; (void)*ci;
-    if constexpr (CT != CT_VectorBool) {
-      i.operator->();
-      ci.operator->();
-    }
-    ++i; ++ci;
-    assert(i == C.end());
-    CHECK_DEBUG_THROWS( *i );
-    CHECK_DEBUG_THROWS( *ci );
-    if constexpr (CT != CT_VectorBool) {
-      CHECK_DEBUG_THROWS( i.operator->() );
-      CHECK_DEBUG_THROWS( ci.operator->() );
-    }
+  int GetStdErrReadFD() const {
+    return stderr_pipe_fd_[0];
   }
 
-  // Container tests
-  static void CopyInvalidatesIterators() {
-    CHECKPOINT("copy invalidates iterators");
-    Container C1 = makeContainer(3);
-    iterator i = C1.begin();
-    Container C2 = C1;
-    if constexpr (CT == CT_ForwardList) {
-      iterator i_next = i;
-      ++i_next;
-      (void)*i_next;
-      CHECK_DEBUG_THROWS( C2.erase_after(i) );
-      C1.erase_after(i);
-      CHECK_DEBUG_THROWS( *i_next );
-    } else {
-      CHECK_DEBUG_THROWS( C2.erase(i) );
-      (void)*i;
-      C1.erase(i);
-      CHECK_DEBUG_THROWS( *i );
-    }
+  int GetStdErrWriteFD() const {
+    return stderr_pipe_fd_[1];
   }
+private:
+  DebugInfoMatcher matcher_;
+  pid_t child_pid_ = -1;
+  int exit_code_ = -1;
+  int stdout_pipe_fd_[2];
+  int stderr_pipe_fd_[2];
+  std::string stdout_from_child_;
+  std::string stderr_from_child_;
+};
 
-  static void MoveInvalidatesIterators() {
-    CHECKPOINT("copy move invalidates iterators");
-    Container C1 = makeContainer(3);
-    iterator i = C1.begin();
-    Container C2 = std::move(C1);
-    (void) *i;
-    if constexpr (CT == CT_ForwardList) {
-      CHECK_DEBUG_THROWS( C1.erase_after(i) );
-      C2.erase_after(i);
-    } else {
-      CHECK_DEBUG_THROWS( C1.erase(i) );
-      C2.erase(i);
-      CHECK_DEBUG_THROWS(*i);
+template <class Func>
+inline bool ExpectDeath(const char* stmt, Func&& func, DebugInfoMatcher Matcher) {
+  DeathTest DT(Matcher);
+  DeathTest::ResultKind RK = DT.Run(func);
+  auto OnFailure = [&](const char* msg) {
+    std::cerr << "EXPECT_DEATH( " << stmt << " ) failed! (" << msg << ")\n\n";
+    if (RK != DeathTest::RK_Unknown) {
+      std::cerr << "child exit code: " << DT.getChildExitCode() << "\n";
+    }
+    if (!DT.getChildStdErr().empty()) {
+      std::cerr << "---------- standard err ----------\n";
+      std::cerr << DT.getChildStdErr() << "\n";
     }
+    if (!DT.getChildStdOut().empty()) {
+      std::cerr << "---------- standard out ----------\n";
+      std::cerr << DT.getChildStdOut() << "\n";
+    }
+    return false;
+  };
+  switch (RK) {
+  case DeathTest::RK_MatchFound:
+    return true;
+  case DeathTest::RK_SetupFailure:
+    return OnFailure("child failed to setup test environment");
+  case DeathTest::RK_Unknown:
+      return OnFailure("reason unknown");
+  case DeathTest::RK_DidNotDie:
+      return OnFailure("child did not die");
+  case DeathTest::RK_MatchFailure:
+      return OnFailure("matcher failed");
   }
+}
 
-  static void EraseIter() {
-    CHECKPOINT("testing erase invalidation");
-    Container C1 = makeContainer(2);
-    iterator it1 = C1.begin();
-    iterator it1_next = it1;
-    ++it1_next;
-    Container C2 = C1;
-    CHECK_DEBUG_THROWS( C2.erase(it1) ); // wrong container
-    CHECK_DEBUG_THROWS( C2.erase(C2.end()) ); // erase with end
-    C1.erase(it1_next);
-    CHECK_DEBUG_THROWS( C1.erase(it1_next) ); // invalidated iterator
-    C1.erase(it1);
-    CHECK_DEBUG_THROWS( C1.erase(it1) ); // invalidated iterator
-  }
-
-  static void EraseIterIter() {
-    CHECKPOINT("testing erase iter iter invalidation");
-    Container C1 = makeContainer(2);
-    iterator it1 = C1.begin();
-    iterator it1_next = it1;
-    ++it1_next;
-    Container C2 = C1;
-    iterator it2 = C2.begin();
-    iterator it2_next = it2;
-    ++it2_next;
-    CHECK_DEBUG_THROWS( C2.erase(it1, it1_next) ); // begin from wrong container
-    CHECK_DEBUG_THROWS( C2.erase(it1, it2_next) ); // end   from wrong container
-    CHECK_DEBUG_THROWS( C2.erase(it2, it1_next) ); // both  from wrong container
-    C2.erase(it2, it2_next);
-  }
-
-  // Allocator aware tests
-  static void SwapInvalidatesIterators() {
-    CHECKPOINT("testing swap invalidates iterators");
-    Container C1 = makeContainer(3);
-    Container C2 = makeContainer(3);
-    iterator it1 = C1.begin();
-    iterator it2 = C2.begin();
-    swap(C1, C2);
-    CHECK_DEBUG_THROWS( C1.erase(it1) );
-    if (CT == CT_String) {
-      CHECK_DEBUG_THROWS(C1.erase(it2));
-    } else
-      C1.erase(it2);
-    //C2.erase(it1);
-    CHECK_DEBUG_THROWS( C1.erase(it1) );
-  }
-
-  static void SwapNonEqualAllocators() {
-    CHECKPOINT("testing swap with non-equal allocators");
-    Container C1 = makeContainer(3, allocator_type(1));
-    Container C2 = makeContainer(1, allocator_type(2));
-    Container C3 = makeContainer(2, allocator_type(2));
-    swap(C2, C3);
-    CHECK_DEBUG_THROWS( swap(C1, C2) );
-  }
+template <class Func>
+inline bool ExpectDeath(const char* stmt, Func&& func) {
+  return ExpectDeath(stmt, func, AnyMatcher);
+}
 
-private:
-  BasicContainerChecks() = delete;
-};
+/// Assert that the specified expression throws a libc++ debug exception.
+#define EXPECT_DEATH(...) assert((ExpectDeath(#__VA_ARGS__, [&]() { __VA_ARGS__; } )))
 
-} // namespace IteratorDebugChecks
+#define EXPECT_DEATH_MATCHES(Matcher, ...) assert((ExpectDeath(#__VA_ARGS__, [&]() { __VA_ARGS__; }, Matcher)))
 
 #endif // TEST_SUPPORT_DEBUG_MODE_HELPER_H




More information about the libcxx-commits mailing list