diff --git a/libcxx/include/__utility/unreachable.h b/libcxx/include/__utility/unreachable.h --- a/libcxx/include/__utility/unreachable.h +++ b/libcxx/include/__utility/unreachable.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___UTILITY_UNREACHABLE_H #define _LIBCPP___UTILITY_UNREACHABLE_H +#include <__assert> #include <__config> -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -18,21 +18,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD -_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable() -{ -#if __has_builtin(__builtin_unreachable) - __builtin_unreachable(); -#else - std::abort(); -#endif +_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable() { + _LIBCPP_ASSERT(false, "std::unreachable() was reached"); + __builtin_unreachable(); } #if _LIBCPP_STD_VER > 20 [[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void unreachable() { __libcpp_unreachable(); } -#endif // _LIBCPP_STD_VER > 20 +#endif _LIBCPP_END_NAMESPACE_STD -#endif +#endif // _LIBCPP___UTILITY_UNREACHABLE_H diff --git a/libcxx/include/utility b/libcxx/include/utility --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -274,6 +274,7 @@ #endif #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 +# include # include # include #endif diff --git a/libcxx/test/libcxx/transitive_includes/cxx2b.csv b/libcxx/test/libcxx/transitive_includes/cxx2b.csv --- a/libcxx/test/libcxx/transitive_includes/cxx2b.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx2b.csv @@ -693,7 +693,6 @@ unordered_set version utility compare utility cstddef -utility cstdlib utility initializer_list utility limits utility version diff --git a/libcxx/test/std/utilities/utility/utility.unreachable/assert.unreachable.pass.cpp b/libcxx/test/std/utilities/utility/utility.unreachable/assert.unreachable.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/utility/utility.unreachable/assert.unreachable.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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// REQUIRES: has-unix-headers +// 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}} +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// Make sure that reaching std::unreachable() with assertions enabled triggers an assertion. + +#include + +#include "check_assertion.h" + +int main(int, char**) { + TEST_LIBCPP_ASSERT_FAILURE(std::unreachable(), "std::unreachable() was reached"); + + return 0; +} diff --git a/libcxx/test/std/utilities/utility/utility.unreachable/unreachable.compile.pass.cpp b/libcxx/test/std/utilities/utility/utility.unreachable/unreachable.pass.cpp rename from libcxx/test/std/utilities/utility/utility.unreachable/unreachable.compile.pass.cpp rename to libcxx/test/std/utilities/utility/utility.unreachable/unreachable.pass.cpp --- a/libcxx/test/std/utilities/utility/utility.unreachable/unreachable.compile.pass.cpp +++ b/libcxx/test/std/utilities/utility/utility.unreachable/unreachable.pass.cpp @@ -8,7 +8,20 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -#include +// Make sure we can use `std::unreachable()`. We can't actually execute it cause that would be +// UB, but we can make sure that it doesn't cause a linker error or something like that. + +#include #include +#include + +int main(int argc, char**) { + assert(argc == 1); + if (argc != 1) { + std::unreachable(); + } + + static_assert(std::is_same_v); -static_assert(std::is_same_v); + return 0; +}