When an assertion fails, the program is aborted through a special verbose termination function. The
library provides a default function that prints an error message and calls ``std::abort()``. Note
that this function 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
-function with their own, which can be useful to provide custom behavior, or when deploying to older
-platforms where the default function isn't available.
+to a platform where the compiled library is sufficiently recent. On older platforms, the program will
+terminate in an unspecified unsuccessful manner, but the quality of diagnostics won't be great.
+However, users can also override that function with their own, which can be useful to either provide
+custom behavior or when deploying to an older platform where the default function isn't available.
-Replacing the default verbose termination function is done by defining the following function:
+Replacing the default verbose termination function is done by defining the
+``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED`` macro in all translation units of your program
+and defining the following function in exactly one translation unit:
.. code-block:: cpp
library are ``noexcept``, and any exception thrown from the termination function will result
in ``std::terminate`` being called.
-Back-deploying with a custom verbose termination function
----------------------------------------------------------
-When deploying to an older platform that does not provide a default verbose termination function,
-the compiler will diagnose the usage of ``std::__libcpp_verbose_abort`` with an error. This is done
-to avoid the load-time error that would otherwise happen if the code was being deployed on older
-systems.
-
-If you are providing a custom verbose termination function, this error is effectively a false positive.
-To let the library know that you are providing a custom function in back-deployment scenarios, you must
-define the ``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_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 an older
-platform, it will fail to load when the dynamic linker fails to find a definition of the function, so you
-should only remove the guard rails if you really mean it!
-
Libc++ Configuration Macros
===========================
// user has provided their own).
//
// Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED
- // to the compiler to tell the library to ignore the fact that the
- // default function isn't available on their deployment target. Note that
- // defining this macro but failing to define a custom function will lead to
- // a load-time error on back-deployment targets, so it should be avoided.
-# define _LIBCPP_AVAILABILITY_DEFAULT_VERBOSE_ABORT
+ // to the compiler to tell the library not to define its own verbose abort.
+ // Note that defining this macro but failing to define a custom function
+ // will lead to a load-time error on back-deployment targets, so it should
+ // be avoided.
+// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
#elif defined(__APPLE__)
__attribute__((unavailable))
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
-# define _LIBCPP_AVAILABILITY_DEFAULT_VERBOSE_ABORT \
- __attribute__((unavailable))
+# define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
+
#else
// ...New vendors can add availability markup here...
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
#endif
-// Define the special verbose termination function availability attribute, which can be silenced by
-// users if they provide their own custom function. 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 function.
-#if defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
-# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT /* nothing */
-#else
-# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_AVAILABILITY_DEFAULT_VERBOSE_ABORT
-#endif
-
#endif // _LIBCPP___AVAILABILITY
# pragma GCC system_header
#endif
+// Provide a default implementation of __libcpp_verbose_abort if we know that neither the built
+// library not the user is providing one. Otherwise, just declare it and use the one from the
+// built library or the one provided by the user.
+//
+// We can't provide a great implementation because it needs to be pretty much
+// dependency-free (this is included everywhere else in the library).
+#if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && !defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
+
+extern "C" void abort();
+
_LIBCPP_BEGIN_NAMESPACE_STD
-_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
+_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) _LIBCPP_HIDE_FROM_ABI inline
+void __libcpp_verbose_abort(const char *, ...) {
+ ::abort();
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
+#else
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
void __libcpp_verbose_abort(const char *__format, ...);
_LIBCPP_END_NAMESPACE_STD
+#endif
+
#endif // _LIBCPP___VERBOSE_ABORT
+++ /dev/null
-//===----------------------------------------------------------------------===//
-//
-// 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 verbose termination function
-// 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 <version> // any header would work
-
-void f() {
- _LIBCPP_ASSERT(true, "message"); // expected-error {{'__libcpp_verbose_abort' is unavailable}}
-}
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
-// We flag uses of the verbose termination function in older dylibs at compile-time to avoid runtime
-// failures when back-deploying.
-// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
-
#include <csignal>
#include <cstdlib>
// Test that all public C++ headers define the verbose termination function.
-// We flag uses of the verbose termination function in older dylibs at compile-time to avoid runtime
-// failures when back-deploying.
-// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
-
// The system-provided <uchar.h> seems to be broken on AIX, which trips up this test.
// XFAIL: LIBCXX-AIX-FIXME
// RUN: %{build} -Wno-macro-redefined -D_LIBCPP_ENABLE_ASSERTIONS=0 -D_LIBCPP_ASSERTIONS_DISABLE_ASSUME
// RUN: %{run}
-// We flag uses of the assertion handler in older dylibs at compile-time to avoid runtime
-// failures when back-deploying.
-// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
-
#include <__assert>
#include <cassert>
limit: 2
timeout_in_minutes: 120
+ - label: "Apple back-deployment with assertions enabled"
+ command: "libcxx/utils/ci/run-buildbot apple-system-backdeployment-assertions-11.0"
+ artifact_paths:
+ - "**/test-results.xml"
+ - "**/*.abilist"
+ agents:
+ queue: "libcxx-builders"
+ os: "macos"
+ retry:
+ automatic:
+ - exit_status: -1 # Agent was lost
+ limit: 2
+ timeout_in_minutes: 120
+
- group: "ARM"
steps:
- label: "AArch64"
# TODO: It would be better to run the tests against the fake-installed version of libc++ instead
xcrun --sdk macosx ninja -vC "${BUILD_DIR}/${arch}" check-cxx check-cxxabi check-cxx-abilist
;;
+apple-system-backdeployment-assertions-*)
+ clean
+
+ if [[ "${OSX_ROOTS}" == "" ]]; then
+ echo "--- Downloading previous macOS dylibs"
+ PREVIOUS_DYLIBS_URL="https://dl.dropboxusercontent.com/s/gmcfxwgl9f9n6pu/libcxx-roots.tar.gz"
+ OSX_ROOTS="${BUILD_DIR}/macos-roots"
+ mkdir -p "${OSX_ROOTS}"
+ curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${OSX_ROOTS}"
+ fi
+
+ DEPLOYMENT_TARGET="${BUILDER#apple-system-backdeployment-assertions-}"
+
+ # TODO: On Apple platforms, we never produce libc++abi.1.dylib or libunwind.1.dylib,
+ # only libc++abi.dylib and libunwind.dylib. Fix that in the build so that the
+ # tests stop searching for @rpath/libc++abi.1.dylib and @rpath/libunwind.1.dylib.
+ cp "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.dylib" \
+ "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.1.dylib"
+ cp "${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.dylib" \
+ "${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.1.dylib"
+
+ arch="$(uname -m)"
+ PARAMS="target_triple=${arch}-apple-macosx${DEPLOYMENT_TARGET}"
+ PARAMS+=";cxx_runtime_root=${OSX_ROOTS}/macOS/libc++/${DEPLOYMENT_TARGET}"
+ PARAMS+=";abi_runtime_root=${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}"
+ PARAMS+=";unwind_runtime_root=${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}"
+ PARAMS+=";use_system_cxx_lib=True"
+ PARAMS+=";enable_assertions=True"
+ # TODO: Enable experimental features during back-deployment -- right now some of the availability
+ # annotations are incorrect, leading to test failures that could be avoided.
+ PARAMS+=";enable_experimental=False"
+
+ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
+ -DLIBCXX_TEST_CONFIG="apple-libc++-backdeployment.cfg.in" \
+ -DLIBCXXABI_TEST_CONFIG="apple-libc++abi-backdeployment.cfg.in" \
+ -DLIBUNWIND_TEST_CONFIG="apple-libunwind-backdeployment.cfg.in" \
+ -DLIBCXX_TEST_PARAMS="${PARAMS}" \
+ -DLIBCXXABI_TEST_PARAMS="${PARAMS}" \
+ -DLIBUNWIND_TEST_PARAMS="${PARAMS}"
+
+ check-runtimes
+;;
apple-system-backdeployment-*)
clean