diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -82,7 +82,10 @@ include(HandleCompilerRT) # Basic options --------------------------------------------------------------- -option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." OFF) +option(LIBCXX_ENABLE_ASSERTIONS + "Enable assertions inside the compiled library, and at the same time make it the + default when compiling user code. Note that assertions can be enabled or disabled + by users in their own code regardless of this option." OFF) option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON) option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON) @@ -694,7 +697,6 @@ endif() # Assertion flags ============================================================= -define_if(LIBCXX_ENABLE_ASSERTIONS -D_LIBCPP_DEBUG=0) define_if(LIBCXX_DEBUG_BUILD -D_DEBUG) if (LIBCXX_ENABLE_ASSERTIONS AND NOT LIBCXX_DEBUG_BUILD) # MSVC doesn't like _DEBUG on release builds. See PR 4379. @@ -896,6 +898,11 @@ config_define_if_not(LIBCXX_ENABLE_UNICODE _LIBCPP_HAS_NO_UNICODE) config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTERS) config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +if (LIBCXX_ENABLE_ASSERTIONS) + config_define(1 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT) +else() + config_define(0 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT) +endif() # Incomplete features get their own specific disabling flags. This makes it # easier to grep for target specific flags once the feature is complete. config_define_if_not(LIBCXX_ENABLE_INCOMPLETE_FEATURES _LIBCPP_HAS_NO_INCOMPLETE_FORMAT) diff --git a/libcxx/cmake/caches/Generic-assertions.cmake b/libcxx/cmake/caches/Generic-assertions.cmake --- a/libcxx/cmake/caches/Generic-assertions.cmake +++ b/libcxx/cmake/caches/Generic-assertions.cmake @@ -1 +1,3 @@ set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "") +set(LIBCXX_TEST_PARAMS "enable_assertions=True" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "enable_assertions=True" CACHE STRING "") diff --git a/libcxx/docs/BuildingLibcxx.rst b/libcxx/docs/BuildingLibcxx.rst --- a/libcxx/docs/BuildingLibcxx.rst +++ b/libcxx/docs/BuildingLibcxx.rst @@ -216,7 +216,10 @@ **Default**: ``OFF`` - Build libc++ with assertions enabled. + Build libc++ with assertions enabled in the compiled library, and enable assertions + by default when building user code as well. Assertions can be turned off by users + by defining ``_LIBCPP_ENABLE_ASSERTIONS=0``. For details, see + :ref:`the documentation `. .. option:: LIBCXX_ENABLE_SHARED:BOOL diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -46,6 +46,12 @@ "heapsort with bounce" to reduce the number of comparisons, and rearranges elements using move-assignment instead of `swap`. + - Libc++ now supports a variety of assertions that can be turned on to help catch + undefined behavior in user code. This new support is now separate from the old + (and incomplete) Debug Mode. Vendors can select whether the library they ship + should include assertions or not by default. For details, see + :ref:`the documentation ` about this new feature. + API Changes ----------- @@ -74,6 +80,10 @@ - The C++14 function ``std::quoted(const char*)`` is no longer supported in C++03 or C++11 modes. +- Setting a custom debug handler with ``std::__libcpp_debug_function`` is not + supported anymore. Please migrate to using the new support for + :ref:`assertions ` instead. + ABI Changes ----------- diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -121,6 +121,92 @@ +.. _assertions-mode: + +Enabling the "safe libc++" mode +=============================== + +Libc++ contains a number of assertions whose goal is to catch undefined behavior in the +library, usually caused by precondition violations. Those assertions do not aim to be +exhaustive -- instead they aim to provide a good balance between safety and performance. +In particular, these assertions do not change the complexity of algorithms. However, they +might, in some cases, interfere with compiler optimizations. + +By default, these assertions are turned off. Vendors can decide to turn them on while building +the compiled library by defining ``LIBCXX_ENABLE_ASSERTIONS=ON`` at CMake configuration time. +When ``LIBCXX_ENABLE_ASSERTIONS`` is used, the compiled library will be built with assertions +enabled, **and** user code will be built with assertions enabled by default. If +``LIBCXX_ENABLE_ASSERTIONS=OFF`` at CMake configure time, the compiled library will not contain +assertions and the default when building user code will be to have assertions disabled. +As a user, you can consult your vendor to know whether assertions are enabled by default. + +Furthermore, independently of any vendor-selected default, users can always control whether +assertions are enabled in their code by defining ``_LIBCPP_ENABLE_ASSERTIONS=0|1`` before +including any libc++ header (we recommend passing ``-D_LIBCPP_ENABLE_ASSERTIONS=X`` to the +compiler). Note that if the compiled library was built by the vendor without assertions, +functions compiled inside the static or shared library won't have assertions enabled even +if the user defines ``_LIBCPP_ENABLE_ASSERTIONS=1`` (the same is true for the inverse case +where the static or shared library was compiled **with** assertions but the user tries to +disable them). However, most of the code in libc++ is in the headers, so the user-selected +value for ``_LIBCPP_ENABLE_ASSERTIONS`` (if any) will usually be respected. + +When an assertion fails, an assertion handler function is called. The library provides a default +assertion handler that prints an error message and calls ``std::abort()``. Note that this assertion +handler is provided by the static or shared library, so it is only available when deploying to a +platform where the compiled library is sufficiently recent. However, users can also override that +assertion handler with their own, which can be useful to provide custom behavior, or when deploying +to older platforms where the default assertion handler isn't available. + +Replacing the default assertion handler is done by defining the following function: + +.. code-block:: cpp + + void __libcpp_assertion_handler(char const* file, int line, char const* expression, char const* message) + +This mechanism is similar to how one can replace the default definition of ``operator new`` +and ``operator delete``. For example: + +.. code-block:: cpp + + // In HelloWorldHandler.cpp + #include <__assert> // must include <__assert> before defining the handler + + void std::__libcpp_assertion_handler(char const* file, int line, char const* expression, char const* message) { + std::printf("Assertion %s failed at %s:%d, more info: %s", expression, file, line, message); + std::abort(); + } + + // In HelloWorld.cpp + #include + + int main() { + std::vector v; + int& x = v[0]; // Your assertion handler will be called here if _LIBCPP_ENABLE_ASSERTIONS=1 + } + +Also note that the assertion handler should usually not return. Since the assertions in libc++ +catch undefined behavior, your code will proceed with undefined behavior if your assertion +handler is called and does return. + +Furthermore, throwing an exception from the assertion handler is not recommended. Indeed, many +functions in the library are ``noexcept``, and any exception thrown from the assertion handler +will result in ``std::terminate`` being called. + +Back-deploying with a custom assertion handler +---------------------------------------------- +When deploying to an older platform that does not provide a default assertion handler, the +compiler will diagnose the usage of ``std::__libcpp_assertion_handler`` with an error. This +is done to avoid the load-time error that would otherwise happen if the code was being deployed +on the older system. + +If you are providing a custom assertion handler, this error is effectively a false positive. +To let the library know that you are providing a custom assertion handler in back-deployment +scenarios, you must define the ``_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED`` macro, +and the library will assume that you are providing your own definition. If no definition is +provided and the code is back-deployed to the older platform, it will fail to load when the +dynamic linker fails to find a definition for ``std::__libcpp_assertion_handler``, so you +should only remove the guard rails if you really mean it! + Libc++ Configuration Macros =========================== diff --git a/libcxx/include/__assert b/libcxx/include/__assert --- a/libcxx/include/__assert +++ b/libcxx/include/__assert @@ -10,52 +10,39 @@ #ifndef _LIBCPP___ASSERT #define _LIBCPP___ASSERT +#include <__availability> #include <__config> -#include // for std::string #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +// This is for backwards compatibility with code that might have been enabling +// assertions through the Debug mode previously. #if _LIBCPP_DEBUG_LEVEL >= 1 -# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : ::std::__libcpp_debug_function(::std::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) +# ifndef _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ENABLE_ASSERTIONS 1 +# endif +#endif + +#ifndef _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT +#endif + +#if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 +# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" +#endif + +#if _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_ASSERT(expression, message) ((expression) ? (void)0 : ::std::__libcpp_assertion_handler(__FILE__, __LINE__, #expression, message)) #else -# define _LIBCPP_ASSERT(x, m) ((void)0) +# define _LIBCPP_ASSERT(x, m) ((void)0) #endif _LIBCPP_BEGIN_NAMESPACE_STD -struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - __libcpp_debug_info() - : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {} - _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 string what() const; - - const char* __file_; - int __line_; - const char* __pred_; - const char* __msg_; -}; - -/// __libcpp_debug_function_type - The type of the assertion failure handler. -typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); - -/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT -/// fails. -extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function; - -/// __libcpp_abort_debug_function - A debug handler that aborts when called. -_LIBCPP_NORETURN _LIBCPP_FUNC_VIS -void __libcpp_abort_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); +_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_ASSERTION_HANDLER +void __libcpp_assertion_handler(char const* __file, int __line, char const* __expression, char const* __message); _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__availability b/libcxx/include/__availability --- a/libcxx/include/__availability +++ b/libcxx/include/__availability @@ -159,6 +159,23 @@ # define _LIBCPP_AVAILABILITY_FORMAT // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format + // This controls whether the std::__libcpp_assertion_handler default + // assertion handler is provided by the library. + // + // Note that when users provide their own custom assertion handler, + // it doesn't matter whether the dylib provides a default handler, + // and the availability markup can actually give a false positive + // diagnostic (it will think that no handler is provided, when in + // reality the user has provided their own). + // + // Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED + // to the compiler to tell the library to ignore the fact that the + // default handler isn't available on their deployment target. Note that + // defining this macro but failing to define a custom assertion handler + // will lead to a load-time error on back-deployment targets, so it + // should be avoided. +# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER + #elif defined(__APPLE__) # define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ @@ -260,6 +277,9 @@ # define _LIBCPP_AVAILABILITY_FORMAT \ __attribute__((unavailable)) # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format + +# define _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER \ + __attribute__((unavailable)) #else // ...New vendors can add availability markup here... @@ -283,4 +303,14 @@ # define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS #endif +// Define the special assertion handler availability attribute, which can be silenced by +// users if they provide their own custom assertion handler. The rest of the code should +// not use the *_DEFAULT_* macro directly, since that would make it ignore the fact that +// the user provided a custom handler. +#if defined(_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED) +# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER /* nothing */ +#else +# define _LIBCPP_AVAILABILITY_ASSERTION_HANDLER _LIBCPP_AVAILABILITY_DEFAULT_ASSERTION_HANDLER +#endif + #endif // _LIBCPP___AVAILABILITY diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in --- a/libcxx/include/__config_site.in +++ b/libcxx/include/__config_site.in @@ -32,6 +32,7 @@ #cmakedefine _LIBCPP_HAS_NO_WIDE_CHARACTERS #cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_FORMAT #cmakedefine _LIBCPP_HAS_NO_INCOMPLETE_RANGES +#cmakedefine01 _LIBCPP_ENABLE_ASSERTIONS_DEFAULT // __USE_MINGW_ANSI_STDIO gets redefined on MinGW #ifdef __clang__ diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist --- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist +++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist @@ -1561,6 +1561,7 @@ {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__libcpp_debug_functionE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist --- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist +++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist @@ -1534,6 +1534,7 @@ {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist --- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist +++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist @@ -1561,6 +1561,7 @@ {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__libcpp_debug_functionE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist --- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist +++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.nodebug.noincomplete.abilist @@ -1534,6 +1534,7 @@ {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '__ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist --- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist +++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.incomplete.abilist @@ -1252,6 +1252,7 @@ {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__libcpp_debug_functionE', 'size': 8, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.noincomplete.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.noincomplete.abilist --- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.noincomplete.abilist +++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.debug.noincomplete.abilist @@ -1249,6 +1249,7 @@ {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__libcpp_debug_functionE', 'size': 8, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.nodebug.incomplete.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.nodebug.incomplete.abilist --- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.nodebug.incomplete.abilist +++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.nodebug.incomplete.abilist @@ -1228,6 +1228,7 @@ {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.debug.incomplete.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.debug.incomplete.abilist --- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.debug.incomplete.abilist +++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.debug.incomplete.abilist @@ -1224,6 +1224,7 @@ {'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__123__libcpp_debug_functionE', 'size': 8, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__126__libcpp_assertion_handlerEPKciS1_S1_', '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'} {'is_defined': True, 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIddEEPdEEbT0_S5_T_', 'type': 'FUNC'} diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -4,6 +4,7 @@ set(LIBCXX_SOURCES algorithm.cpp any.cpp + assert.cpp atomic.cpp barrier.cpp bind.cpp @@ -65,8 +66,8 @@ if (LIBCXX_ENABLE_DEBUG_MODE_SUPPORT) list(APPEND LIBCXX_SOURCES - assert.cpp debug.cpp + legacy_debug_handler.cpp ) endif() diff --git a/libcxx/src/assert.cpp b/libcxx/src/assert.cpp --- a/libcxx/src/assert.cpp +++ b/libcxx/src/assert.cpp @@ -10,29 +10,13 @@ #include <__config> #include #include -#include _LIBCPP_BEGIN_NAMESPACE_STD -std::string __libcpp_debug_info::what() const { - string msg = __file_; - msg += ":" + std::to_string(__line_) + ": _LIBCPP_ASSERT '"; - msg += __pred_; - msg += "' failed. "; - 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(); -} - -constinit __libcpp_debug_function_type __libcpp_debug_function = __libcpp_abort_debug_function; - -bool __libcpp_set_debug_function(__libcpp_debug_function_type __func) { - __libcpp_debug_function = __func; - return true; +_LIBCPP_WEAK +void __libcpp_assertion_handler(char const* __file, int __line, char const* __expression, char const* __message) { + std::fprintf(stderr, "%s:%d: libc++ assertion '%s' failed. %s\n", __file, __line, __expression, __message); + std::abort(); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/src/assert.cpp b/libcxx/src/legacy_debug_handler.cpp copy from libcxx/src/assert.cpp copy to libcxx/src/legacy_debug_handler.cpp --- a/libcxx/src/assert.cpp +++ b/libcxx/src/legacy_debug_handler.cpp @@ -6,14 +6,26 @@ // //===----------------------------------------------------------------------===// -#include <__assert> #include <__config> #include #include #include +// This file defines the legacy default debug handler and related mechanisms +// to set it. This is for backwards ABI compatibility with code that has been +// using this debug handler previously. + _LIBCPP_BEGIN_NAMESPACE_STD +struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { + _LIBCPP_EXPORTED_FROM_ABI string what() const; + + const char* __file_; + int __line_; + const char* __pred_; + const char* __msg_; +}; + std::string __libcpp_debug_info::what() const { string msg = __file_; msg += ":" + std::to_string(__line_) + ": _LIBCPP_ASSERT '"; @@ -23,13 +35,17 @@ 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_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __libcpp_abort_debug_function(__libcpp_debug_info const& info) { + std::fprintf(stderr, "%s\n", info.what().c_str()); + std::abort(); } +typedef void (*__libcpp_debug_function_type)(__libcpp_debug_info const&); + +_LIBCPP_EXPORTED_FROM_ABI constinit __libcpp_debug_function_type __libcpp_debug_function = __libcpp_abort_debug_function; +_LIBCPP_EXPORTED_FROM_ABI bool __libcpp_set_debug_function(__libcpp_debug_function_type __func) { __libcpp_debug_function = __func; return true; diff --git a/libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp b/libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/assertions/assertions_disabled.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Test that _LIBCPP_ASSERT doesn't do anything when assertions are disabled. +// We need to use -Wno-macro-redefined because the test suite defines +// _LIBCPP_ENABLE_ASSERTIONS=1 under some configurations. + +// ADDITIONAL_COMPILE_FLAGS: -Wno-macro-redefined -D_LIBCPP_ENABLE_ASSERTIONS=0 + +#include <__assert> +#include + +bool executed_condition = false; +bool f() { executed_condition = true; return false; } + +int main(int, char**) { + _LIBCPP_ASSERT(f(), "message"); // should not execute anything + assert(!executed_condition); // really make sure we did not execute anything at all + return 0; +} diff --git a/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp b/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/assertions/customize_handler.backdeployment.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Make sure that we can enable assertions when we back-deploy to older platforms +// if we define _LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED. +// +// Note that this test isn't really different from customize_handler.pass.cpp when +// run outside of back-deployment scenarios, but we still run it all the time. + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 -D_LIBCPP_AVAILABILITY_CUSTOM_ASSERTION_HANDLER_PROVIDED + +#include <__assert> +#include + +bool handler_called = false; +void std::__libcpp_assertion_handler(char const*, int, char const*, char const*) { + handler_called = true; +} + +int main(int, char**) { + _LIBCPP_ASSERT(false, "message"); + assert(handler_called); + return 0; +} diff --git a/libcxx/test/libcxx/assertions/customize_handler.pass.cpp b/libcxx/test/libcxx/assertions/customize_handler.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/assertions/customize_handler.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Test that we can set a custom assertion handler. + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// We flag uses of the assertion handler in older dylibs at compile-time to avoid runtime +// failures when back-deploying. +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} + +#include <__assert> +#include + +bool handler_called = false; +void std::__libcpp_assertion_handler(char const*, int, char const*, char const*) { + handler_called = true; +} + +int main(int, char**) { + _LIBCPP_ASSERT(false, "message"); + assert(handler_called); + return 0; +} diff --git a/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp b/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/assertions/debug_mode_compatibility.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// This test ensures that assertions are still enabled when _LIBCPP_DEBUG=0 is +// defined, for backwards compatibility with code that might have been using +// it to enable assertions previously. + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 + +// We flag uses of the assertion handler in older dylibs at compile-time to avoid runtime +// failures when back-deploying. +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} + +#include <__assert> +#include + +bool handler_called = false; +void std::__libcpp_assertion_handler(char const*, int, char const*, char const*) { + handler_called = true; +} + +int main(int, char**) { + _LIBCPP_ASSERT(false, "message"); + assert(handler_called); + return 0; +} diff --git a/libcxx/test/libcxx/debug/debug_abort.pass.cpp b/libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp rename from libcxx/test/libcxx/debug/debug_abort.pass.cpp rename to libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp --- a/libcxx/test/libcxx/debug/debug_abort.pass.cpp +++ b/libcxx/test/libcxx/assertions/default_handler.abort.pass.cpp @@ -6,26 +6,25 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=1 +// Test that the default assertion handler aborts the program. -// Test that the default debug handler aborts the program. +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// We flag uses of the assertion handler in older dylibs at compile-time to avoid runtime +// failures when back-deploying. +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} #include <__assert> #include #include -#include "test_macros.h" - -void signal_handler(int signal) -{ - if (signal == SIGABRT) - std::_Exit(EXIT_SUCCESS); - std::_Exit(EXIT_FAILURE); +void signal_handler(int signal) { + if (signal == SIGABRT) + std::_Exit(EXIT_SUCCESS); + std::_Exit(EXIT_FAILURE); } -int main(int, char**) -{ +int main(int, char**) { if (std::signal(SIGABRT, signal_handler) != SIG_ERR) _LIBCPP_ASSERT(false, "foo"); return EXIT_FAILURE; diff --git a/libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp b/libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/assertions/default_handler.availability.verify.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Make sure that we diagnose any usage of the default assertion handler on a platform +// that doesn't support it at compile-time. + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// REQUIRES: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} + +#include <__assert> + +void f() { + _LIBCPP_ASSERT(true, "message"); // expected-error {{'__libcpp_assertion_handler' is unavailable}} +} diff --git a/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.back.pass.cpp b/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.back.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.back.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.back.pass.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // test that array::back() triggers an assertion diff --git a/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.front.pass.cpp b/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.front.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.front.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.front.pass.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // test that array::back() triggers an assertion diff --git a/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.subscript.pass.cpp b/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.subscript.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.subscript.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/array/array.zero/assert.subscript.pass.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // test that array::operator[] triggers an assertion diff --git a/libcxx/test/libcxx/containers/sequences/deque/assert.pop_back.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/deque/assert.pop_back.empty.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/deque/assert.pop_back.empty.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/deque/assert.pop_back.empty.pass.cpp @@ -10,8 +10,9 @@ // pop_back() more than the number of elements in a deque -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.erase_iter.end.pass.cpp b/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.erase_iter.end.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.erase_iter.end.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.erase_iter.end.pass.cpp @@ -10,8 +10,9 @@ // Call erase(const_iterator position) with end() -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/list/list.modifiers/assert.pop_back.empty.pass.cpp @@ -10,8 +10,9 @@ // void pop_back(); -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/assert.back.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/assert.back.empty.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/assert.back.empty.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/assert.back.empty.pass.cpp @@ -10,8 +10,9 @@ // Call back() on empty container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/assert.cback.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/assert.cback.empty.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/assert.cback.empty.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/assert.cback.empty.pass.cpp @@ -10,8 +10,9 @@ // Call back() on empty const container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/assert.cfront.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/assert.cfront.empty.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/assert.cfront.empty.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/assert.cfront.empty.pass.cpp @@ -10,8 +10,9 @@ // Call front() on empty const container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/assert.cindex.oob.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/assert.cindex.oob.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/assert.cindex.oob.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/assert.cindex.oob.pass.cpp @@ -10,8 +10,9 @@ // Index const vector out of bounds. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/assert.front.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/assert.front.empty.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/assert.front.empty.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/assert.front.empty.pass.cpp @@ -10,8 +10,9 @@ // Call front() on empty container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/assert.index.oob.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/assert.index.oob.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/assert.index.oob.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/assert.index.oob.pass.cpp @@ -10,8 +10,9 @@ // Index vector out of bounds. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/assert.pop_back.empty.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/assert.pop_back.empty.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/assert.pop_back.empty.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/assert.pop_back.empty.pass.cpp @@ -10,8 +10,9 @@ // pop_back() more than the number of elements in a vector -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp --- a/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp +++ b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03 -// UNSUPPORTED: debug_level=0, debug_level=1 +// UNSUPPORTED: debug_level=0, debug_level=1, libcpp-has-assertions // diff --git a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket.pass.cpp @@ -10,8 +10,9 @@ // size_type bucket(const key_type& __k) const; -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.map/assert.bucket_size.pass.cpp @@ -14,8 +14,9 @@ // size_type bucket_size(size_type n) const -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.map/assert.max_load_factor.pass.cpp @@ -15,8 +15,9 @@ // float max_load_factor() const; // void max_load_factor(float mlf); -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket.pass.cpp @@ -14,8 +14,9 @@ // size_type bucket(const key_type& __k) const; -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.bucket_size.pass.cpp @@ -14,8 +14,9 @@ // size_type bucket_size(size_type n) const -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multimap/assert.max_load_factor.pass.cpp @@ -15,8 +15,9 @@ // float max_load_factor() const; // void max_load_factor(float mlf); -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket.pass.cpp @@ -14,8 +14,9 @@ // size_type bucket(const key_type& __k) const; -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.bucket_size.pass.cpp @@ -14,8 +14,9 @@ // size_type bucket_size(size_type n) const -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.multiset/assert.max_load_factor.pass.cpp @@ -15,8 +15,9 @@ // float max_load_factor() const; // void max_load_factor(float mlf); -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket.pass.cpp @@ -14,8 +14,9 @@ // size_type bucket(const key_type& __k) const; -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.set/assert.bucket_size.pass.cpp @@ -14,8 +14,9 @@ // size_type bucket_size(size_type n) const -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp b/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp --- a/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp +++ b/libcxx/test/libcxx/containers/unord/unord.set/assert.max_load_factor.pass.cpp @@ -15,8 +15,9 @@ // float max_load_factor() const; // void max_load_factor(float mlf); -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/debug/containers/string.pass.cpp b/libcxx/test/libcxx/debug/containers/string.pass.cpp --- a/libcxx/test/libcxx/debug/containers/string.pass.cpp +++ b/libcxx/test/libcxx/debug/containers/string.pass.cpp @@ -82,7 +82,7 @@ EXPECT_DEATH( C1.erase(it1) ); C1.erase(C1.begin(), C1.end()); assert(C1.size() == 0); - EXPECT_DEATH_MATCHES(DebugInfoMatcher("string::pop_back(): string is already empty"), C1.pop_back() ); + TEST_LIBCPP_ASSERT_FAILURE(C1.pop_back(), "string::pop_back(): string is already empty"); } }; diff --git a/libcxx/test/libcxx/debug/register_debug_handler.pass.cpp b/libcxx/test/libcxx/debug/register_debug_handler.pass.cpp deleted file mode 100644 --- a/libcxx/test/libcxx/debug/register_debug_handler.pass.cpp +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=1 -// UNSUPPORTED: libcxx-no-debug-mode - -#include -#include -#include -#include <__debug> -#include - -#include "test_macros.h" - -void my_debug_function(std::__libcpp_debug_info const& info) { - assert(info.__msg_ == std::string("foo")); - std::exit(0); -} - -int main(int, char**) -{ - std::__libcpp_set_debug_function(&my_debug_function); - _LIBCPP_ASSERT(false, "foo"); - return 1; -} diff --git a/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp b/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp --- a/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp +++ b/libcxx/test/libcxx/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/assert.deallocate.pass.cpp @@ -12,8 +12,9 @@ // T* polymorphic_allocator::deallocate(T*, size_t size) -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp b/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp --- a/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp +++ b/libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/assert.deallocate.pass.cpp @@ -12,8 +12,9 @@ // T* polymorphic_allocator::deallocate(T*, size_t size) -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/input.output/filesystems/class.path/path.itr/assert.iterator.pass.cpp b/libcxx/test/libcxx/input.output/filesystems/class.path/path.itr/assert.iterator.pass.cpp --- a/libcxx/test/libcxx/input.output/filesystems/class.path/path.itr/assert.iterator.pass.cpp +++ b/libcxx/test/libcxx/input.output/filesystems/class.path/path.itr/assert.iterator.pass.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // diff --git a/libcxx/test/libcxx/iterators/assert.advance.pass.cpp b/libcxx/test/libcxx/iterators/assert.advance.pass.cpp --- a/libcxx/test/libcxx/iterators/assert.advance.pass.cpp +++ b/libcxx/test/libcxx/iterators/assert.advance.pass.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // diff --git a/libcxx/test/libcxx/iterators/assert.next.pass.cpp b/libcxx/test/libcxx/iterators/assert.next.pass.cpp --- a/libcxx/test/libcxx/iterators/assert.next.pass.cpp +++ b/libcxx/test/libcxx/iterators/assert.next.pass.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // diff --git a/libcxx/test/libcxx/iterators/assert.prev.pass.cpp b/libcxx/test/libcxx/iterators/assert.prev.pass.cpp --- a/libcxx/test/libcxx/iterators/assert.prev.pass.cpp +++ b/libcxx/test/libcxx/iterators/assert.prev.pass.cpp @@ -6,8 +6,9 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.back.pass.cpp @@ -10,8 +10,9 @@ // Call back() on empty container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cback.pass.cpp @@ -10,8 +10,9 @@ // Call back() on empty const container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cfront.pass.cpp @@ -10,8 +10,9 @@ // Call front() on empty const container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.cindex.pass.cpp @@ -10,8 +10,9 @@ // Index const string out of bounds. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.front.pass.cpp @@ -10,8 +10,9 @@ // Call front() on empty container. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.access/assert.index.pass.cpp @@ -10,8 +10,9 @@ // Index string out of bounds. -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include #include diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.erase_iter.null.pass.cpp @@ -10,8 +10,9 @@ // Call erase(const_iterator position) with end() -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp --- a/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp +++ b/libcxx/test/libcxx/strings/basic.string/string.modifiers/assert.pop_back.pass.cpp @@ -10,8 +10,9 @@ // void pop_back(); -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp b/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp --- a/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp +++ b/libcxx/test/libcxx/strings/string.view/assert.ctor.pointer.pass.cpp @@ -8,8 +8,9 @@ // UNSUPPORTED: c++11, c++14 -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // Construct a string_view from a null pointer // constexpr basic_string_view( const CharT* s ); diff --git a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp --- a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp +++ b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception.pass.cpp @@ -8,8 +8,9 @@ // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // diff --git a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp --- a/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp +++ b/libcxx/test/libcxx/thread/futures/futures.promise/assert.set_exception_at_thread_exit.pass.cpp @@ -8,8 +8,9 @@ // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 // diff --git a/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.dereference.pass.cpp b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.dereference.pass.cpp --- a/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.dereference.pass.cpp +++ b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.dereference.pass.cpp @@ -15,8 +15,9 @@ // UNSUPPORTED: c++11, c++14 -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.pass.cpp b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.pass.cpp --- a/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.pass.cpp +++ b/libcxx/test/libcxx/utilities/optional/optional.object/optional.object.observe/assert.op_arrow.pass.cpp @@ -13,8 +13,9 @@ // UNSUPPORTED: c++11, c++14 -// UNSUPPORTED: c++03, windows, libcxx-no-debug-mode -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=0 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 #include diff --git a/libcxx/test/support/check_assertion.h b/libcxx/test/support/check_assertion.h --- a/libcxx/test/support/check_assertion.h +++ b/libcxx/test/support/check_assertion.h @@ -9,16 +9,6 @@ #ifndef TEST_SUPPORT_CHECK_ASSERTION_H #define TEST_SUPPORT_CHECK_ASSERTION_H -#ifndef _LIBCPP_DEBUG -#error _LIBCPP_DEBUG must be defined before including this header -#endif - -#include -#ifndef _LIBCPP_VERSION -#error "This header may only be used for libc++ tests" -#endif - -#include <__debug> #include #include #include @@ -33,28 +23,31 @@ #include "test_macros.h" #include "test_allocator.h" +#ifndef _LIBCPP_VERSION +# error "This header may only be used for libc++ tests" +#endif + #if TEST_STD_VER < 11 # error "C++11 or greater is required to use this header" #endif -struct DebugInfoMatcher { +struct AssertionInfoMatcher { 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, __builtin_strlen(any_msg)), file_(any_file, __builtin_strlen(any_file)), line_(any_line) { } - constexpr DebugInfoMatcher(const char* msg, const char* file = any_file, int line = any_line) + constexpr AssertionInfoMatcher() : is_empty_(true), msg_(any_msg, __builtin_strlen(any_msg)), file_(any_file, __builtin_strlen(any_file)), line_(any_line) { } + constexpr AssertionInfoMatcher(const char* msg, const char* file = any_file, int line = any_line) : is_empty_(false), msg_(msg, __builtin_strlen(msg)), file_(file, __builtin_strlen(file)), line_(line) {} - bool Matches(std::__libcpp_debug_info const& got) const { + bool Matches(char const* file, int line, char const* message) const { assert(!empty() && "empty matcher"); - if (CheckLineMatches(got.__line_) && CheckFileMatches(got.__file_) && - CheckMessageMatches(got.__msg_)) + if (CheckLineMatches(line) && CheckFileMatches(file) && CheckMessageMatches(message)) return true; // Write to stdout because that's the file descriptor captured by the parent // process. - std::printf("Failed to match debug info!\n%s\nVS\n%s\n", ToString().data(), got.what().data()); + std::printf("Failed to match assertion info!\n%s\nVS\n%s:%d (%s)\n", ToString().data(), file, line, message); return false; } @@ -108,10 +101,10 @@ int line_; }; -static constexpr DebugInfoMatcher AnyMatcher(DebugInfoMatcher::any_msg); +static constexpr AssertionInfoMatcher AnyMatcher(AssertionInfoMatcher::any_msg); -inline DebugInfoMatcher& GlobalMatcher() { - static DebugInfoMatcher GMatch; +inline AssertionInfoMatcher& GlobalMatcher() { + static AssertionInfoMatcher GMatch; return GMatch; } @@ -136,15 +129,7 @@ return val >= RK_DidNotDie && val <= RK_Unknown; } - 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); - } - - DeathTest(DebugInfoMatcher const& Matcher) : matcher_(Matcher) {} + DeathTest(AssertionInfoMatcher const& Matcher) : matcher_(Matcher) {} template ResultKind Run(Func&& f) { @@ -180,7 +165,6 @@ DupFD(GetStdErrWriteFD(), STDERR_FILENO); GlobalMatcher() = matcher_; - std::__libcpp_set_debug_function(&DeathTestDebugHandler); f(); std::exit(RK_DidNotDie); } @@ -242,7 +226,7 @@ return stderr_pipe_fd_[1]; } private: - DebugInfoMatcher matcher_; + AssertionInfoMatcher matcher_; pid_t child_pid_ = -1; int exit_code_ = -1; int stdout_pipe_fd_[2]; @@ -251,8 +235,16 @@ std::string stderr_from_child_; }; +void std::__libcpp_assertion_handler(char const* file, int line, char const* /*expression*/, char const* message) { + assert(!GlobalMatcher().empty()); + if (GlobalMatcher().Matches(file, line, message)) { + std::exit(DeathTest::RK_MatchFound); + } + std::exit(DeathTest::RK_MatchFailure); +} + template -inline bool ExpectDeath(const char* stmt, Func&& func, DebugInfoMatcher Matcher) { +inline bool ExpectDeath(const char* stmt, Func&& func, AssertionInfoMatcher Matcher) { DeathTest DT(Matcher); DeathTest::ResultKind RK = DT.Run(func); auto OnFailure = [&](const char* msg) { @@ -293,6 +285,6 @@ #define EXPECT_DEATH_MATCHES(Matcher, ...) assert((ExpectDeath(#__VA_ARGS__, [&]() { __VA_ARGS__; }, Matcher))) -#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) assert((ExpectDeath(#expr, [&]() { (void)(expr); }, DebugInfoMatcher(message)))) +#define TEST_LIBCPP_ASSERT_FAILURE(expr, message) assert((ExpectDeath(#expr, [&]() { (void)(expr); }, AssertionInfoMatcher(message)))) #endif // TEST_SUPPORT_CHECK_ASSERTION_H diff --git a/libcxx/test/libcxx/debug/check_assertion_test.pass.cpp b/libcxx/test/support/test.support/test_check_assertion.pass.cpp rename from libcxx/test/libcxx/debug/check_assertion_test.pass.cpp rename to libcxx/test/support/test.support/test_check_assertion.pass.cpp --- a/libcxx/test/libcxx/debug/check_assertion_test.pass.cpp +++ b/libcxx/test/support/test.support/test_check_assertion.pass.cpp @@ -6,17 +6,18 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: libcxx-no-debug-mode, c++03, windows -// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DEBUG=1 +// UNSUPPORTED: c++03, windows +// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 -#include <__debug> +#include #include +#include #include "check_assertion.h" -#include "test_macros.h" template -inline bool TestDeathTest(const char* stmt, Func&& func, DeathTest::ResultKind ExpectResult, DebugInfoMatcher Matcher = AnyMatcher) { +inline bool TestDeathTest(const char* stmt, Func&& func, DeathTest::ResultKind ExpectResult, AssertionInfoMatcher Matcher = AnyMatcher) { DeathTest DT(Matcher); DeathTest::ResultKind RK = DT.Run(func); auto OnFailure = [&](std::string msg) { @@ -42,7 +43,7 @@ } void test_no_match_found() { - DebugInfoMatcher ExpectMatch("my message"); + AssertionInfoMatcher ExpectMatch("my message"); TEST_DEATH_TEST_MATCHES(DeathTest::RK_MatchFailure, ExpectMatch, my_libcpp_assert()); } diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -183,6 +183,14 @@ AddFeature('libcxx-no-debug-mode') ]), + Parameter(name='enable_assertions', choices=[True, False], type=bool, default=False, + help="Whether to enable assertions when compiling the test suite. This is only meaningful when " + "running the tests against libc++.", + actions=lambda assertions: [ + AddCompileFlag('-D_LIBCPP_ENABLE_ASSERTIONS=1'), + AddFeature('libcpp-has-assertions') + ] if assertions else []), + Parameter(name='additional_features', type=list, default=[], help="A comma-delimited list of additional features that will be enabled when running the tests. " "This should be used sparingly since specifying ad-hoc features manually is error-prone and "