Index: libcxx/docs/DesignDocs/DebugMode.rst =================================================================== --- libcxx/docs/DesignDocs/DebugMode.rst +++ libcxx/docs/DesignDocs/DebugMode.rst @@ -56,6 +56,25 @@ // control flow doesn't return } +The above example overrides the bug handler at run-time, but it is also +possible to override it at compile time using the +``_LIBCPP_DEBUG_FUNCTION_INVOCATION`` macro. This macro takes 2 arguments: the +expression ``x`` to trigger the assertion, and an error message ``m``. The +default invocation uses these arguments to construct the +``std::__libcpp_debug_info`` argument, but you can do whatever you like with +them (including nothing): + +.. code-block:: cpp + + #define _LIBCPP_DEBUG_FUNCTION_INVOCATION(x, m) abort() + #include + int main(int, char**) { + std::string::iterator bad_it; + std::string str("hello world"); + str.insert(bad_it, '!'); // causes debug assertion + // control flow doesn't return + } + Debug Mode Checks ================= @@ -66,11 +85,11 @@ Basic Checks ============ -These checks are enabled when ``_LIBCPP_DEBUG`` is defined to either 0 or 1. - -The following checks are enabled by ``_LIBCPP_DEBUG``: +These checks are enabled when ``_LIBCPP_DEBUG`` is defined to either 0 or 1: - * FIXME: Update this list + * Bounds checks in containers (e.g ``operator[]``) + * Validity of dereferencing (e.g. ``operator*``, ``operator->``) + * Invariants and preconditions (e.g. ``has_value`` for ``std::optional``) Iterator Debugging Checks ========================= @@ -82,10 +101,11 @@ * ``std::string`` * ``std::vector`` (``T != bool``) * ``std::list`` + * ``std::locale`` * ``std::unordered_map`` * ``std::unordered_multimap`` * ``std::unordered_set`` * ``std::unordered_multiset`` -The remaining containers do not currently support iterator debugging. -Patches welcome. +The remaining includes do not currently support iterator debugging. Patches +welcome. Index: libcxx/include/__debug =================================================================== --- libcxx/include/__debug +++ libcxx/include/__debug @@ -27,15 +27,19 @@ # include #endif +#if !defined(_LIBCPP_DEBUG_FUNCTION_INVOCATION) +# define _LIBCPP_DEBUG_FUNCTION_INVOCATION(x, m) _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m)) +#endif + #if _LIBCPP_DEBUG_LEVEL == 0 # define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) # define _LIBCPP_ASSERT_IMPL(x, m) ((void)0) #elif _LIBCPP_DEBUG_LEVEL == 1 # define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) -# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) +# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _LIBCPP_DEBUG_FUNCTION_INVOCATION((x), m)) #elif _LIBCPP_DEBUG_LEVEL == 2 # define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) -# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) +# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _LIBCPP_DEBUG_FUNCTION_INVOCATION((x), m)) #else # error _LIBCPP_DEBUG_LEVEL must be one of 0, 1, 2 #endif