[libc++] Implement P0627R6 (Function to mark unreachable code)

Reviewed By: ldionne, Quuxplusone, #libc

Spies: arichardson, mstorsjo, libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D119152
This commit is contained in:
Nikolas Klauser 2022-02-14 18:26:02 +01:00
parent b305de142c
commit 2a8f9a5e95
28 changed files with 152 additions and 76 deletions

View File

@ -350,6 +350,6 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_to_underlying`` ``202102L``
------------------------------------------------- -----------------
``__cpp_lib_unreachable`` *unimplemented*
``__cpp_lib_unreachable`` ``202202L``
================================================= =================

View File

@ -38,6 +38,8 @@ What's New in Libc++ 15.0.0?
New Features
------------
- Implemented P0627R6 (Function to mark unreachable code)
API Changes
-----------

View File

@ -40,7 +40,7 @@
"","","","","",""
"`P0323R12 <https://wg21.link/P0323R12>`__","LWG","``std::expected``","February 2022","",""
"`P0533R9 <https://wg21.link/P0533R9>`__","LWG","``constexpr`` for ``<cmath>`` and ``<cstdlib>``","February 2022","",""
"`P0627R6 <https://wg21.link/P0627R6>`__","LWG","Function to mark unreachable code","February 2022","",""
"`P0627R6 <https://wg21.link/P0627R6>`__","LWG","Function to mark unreachable code","February 2022","|Complete|","15.0"
"`P1206R7 <https://wg21.link/P1206R7>`__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","",""
"`P1413R3 <https://wg21.link/P1413R3>`__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","",""
"`P2255R3 <https://wg21.link/P2255R3>`__","LWG","A type trait to detect reference binding to temporary","February 2022","",""

1 Paper # Group Paper Name Meeting Status First released version
40
41 `P0323R12 <https://wg21.link/P0323R12>`__ LWG ``std::expected`` February 2022
42 `P0533R9 <https://wg21.link/P0533R9>`__ LWG ``constexpr`` for ``<cmath>`` and ``<cstdlib>`` February 2022
43 `P0627R6 <https://wg21.link/P0627R6>`__ LWG Function to mark unreachable code February 2022 |Complete| 15.0
44 `P1206R7 <https://wg21.link/P1206R7>`__ LWG ``ranges::to``: A function to convert any range to a container February 2022
45 `P1413R3 <https://wg21.link/P1413R3>`__ LWG Deprecate ``std::aligned_storage`` and ``std::aligned_union`` February 2022
46 `P2255R3 <https://wg21.link/P2255R3>`__ LWG A type trait to detect reference binding to temporary February 2022

View File

@ -401,6 +401,7 @@ set(files
__utility/swap.h
__utility/to_underlying.h
__utility/transaction.h
__utility/unreachable.h
__variant/monostate.h
algorithm
any

View File

@ -20,6 +20,7 @@
#include <__filesystem/operations.h>
#include <__filesystem/path.h>
#include <__filesystem/perms.h>
#include <__utility/unreachable.h>
#include <chrono>
#include <cstdint>
#include <cstdlib>
@ -362,7 +363,7 @@ private:
__ec->clear();
return __data_.__type_;
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@ -383,7 +384,7 @@ private:
return __data_.__type_;
}
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@ -398,7 +399,7 @@ private:
case _RefreshSymlink:
return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@ -414,7 +415,7 @@ private:
case _RefreshSymlinkUnresolved:
return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@ -439,7 +440,7 @@ private:
return __data_.__size_;
}
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@ -458,7 +459,7 @@ private:
return __data_.__nlink_;
}
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY
@ -481,7 +482,7 @@ private:
return __data_.__write_time_;
}
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
private:

View File

@ -16,6 +16,7 @@
#include <__format/format_fwd.h>
#include <__format/format_parse_context.h>
#include <__memory/addressof.h>
#include <__utility/unreachable.h>
#include <__variant/monostate.h>
#include <string>
#include <string_view>
@ -77,7 +78,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
#ifndef _LIBCPP_HAS_NO_INT128
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__i128);
#else
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
#endif
case __format::__arg_t::__unsigned:
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__unsigned);
@ -88,7 +89,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
#ifndef _LIBCPP_HAS_NO_INT128
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__u128);
#else
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
#endif
case __format::__arg_t::__float:
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__float);
@ -106,7 +107,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
case __format::__arg_t::__handle:
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__handle);
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
template <class _Context>

View File

@ -18,6 +18,7 @@
#include <__format/format_fwd.h>
#include <__format/format_string.h>
#include <__format/parser_std_format_spec.h>
#include <__utility/unreachable.h>
#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@ -116,7 +117,7 @@ __padding_size(size_t __size, size_t __width,
size_t __fill = __width - __size;
switch (__align) {
case __format_spec::_Flags::_Alignment::__default:
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
case __format_spec::_Flags::_Alignment::__left:
return {0, __fill};
@ -132,7 +133,7 @@ __padding_size(size_t __size, size_t __width,
case __format_spec::_Flags::_Alignment::__right:
return {__fill, 0};
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
/**

View File

@ -27,6 +27,7 @@
#include <__format/formatter_integral.h>
#include <__format/parser_std_format_spec.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
#include <charconv>
#include <cmath>
@ -689,7 +690,7 @@ private:
default:
_LIBCPP_ASSERT(false, "The parser should have validated the type");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
}
};

View File

@ -19,6 +19,7 @@
#include <__format/format_fwd.h>
#include <__format/formatter.h>
#include <__format/parser_std_format_spec.h>
#include <__utility/unreachable.h>
#include <array>
#include <charconv>
#include <concepts>
@ -176,7 +177,7 @@ __determine_grouping(ptrdiff_t __size, const string& __grouping) {
}
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
template <class _Parser>
@ -292,7 +293,7 @@ private:
}
default:
_LIBCPP_ASSERT(false, "The parser should have validated the type");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
}

View File

@ -16,6 +16,7 @@
#include <__iterator/incrementable_traits.h>
#include <__iterator/iterator_traits.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
#include <concepts>
#include <cstdlib>
#include <limits>
@ -181,7 +182,7 @@ public:
return __n;
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
};

View File

@ -0,0 +1,38 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___UTILITY_UNREACHABLE_H
#define _LIBCPP___UTILITY_UNREACHABLE_H
#include <__config>
#include <cstdlib>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_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
}
#if _LIBCPP_STD_VER > 20
[[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void unreachable() { __libcpp_unreachable(); }
#endif // _LIBCPP_STD_VER > 20
_LIBCPP_END_NAMESPACE_STD
#endif

View File

@ -111,8 +111,8 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
#include <__config>
#include <__debug>
#include <__tuple>
#include <__utility/unreachable.h>
#include <algorithm>
#include <cstdlib> // for _LIBCPP_UNREACHABLE
#include <iterator>
#include <stdexcept>
#include <type_traits>
@ -309,54 +309,54 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator[](size_type) _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference operator[](size_type) const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference at(size_type) {
__throw_out_of_range("array<T, 0>::at");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference at(size_type) const {
__throw_out_of_range("array<T, 0>::at");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference front() _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference front() const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference back() _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference back() const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
};
#if _LIBCPP_STD_VER >= 17
#if _LIBCPP_STD_VER > 14
template<class _Tp, class... _Args,
class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value>
>

View File

@ -83,16 +83,16 @@ namespace std {
#include <__charconv/from_chars_result.h>
#include <__charconv/to_chars_result.h>
#include <__config>
#include <__debug>
#include <__errc>
#include <__utility/unreachable.h>
#include <cmath> // for log2f
#include <cstdint>
#include <cstdlib> // for _LIBCPP_UNREACHABLE
#include <cstdlib>
#include <cstring>
#include <limits>
#include <type_traits>
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@ -341,7 +341,7 @@ _LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_INLINE_VISIBILITY int __to_chars_integral_
__r += 4;
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
template <typename _Tp>

View File

@ -88,12 +88,6 @@ void *aligned_alloc(size_t alignment, size_t size); // C11
# pragma GCC system_header
#endif
#ifdef __GNUC__
#define _LIBCPP_UNREACHABLE() __builtin_unreachable()
#else
#define _LIBCPP_UNREACHABLE() _VSTD::abort()
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
using ::size_t _LIBCPP_USING_IF_EXISTS;

View File

@ -183,6 +183,7 @@ typedef basic_fstream<wchar_t> wfstream;
#include <__config>
#include <__debug>
#include <__locale>
#include <__utility/unreachable.h>
#include <cstdio>
#include <cstdlib>
#include <istream>
@ -538,7 +539,7 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
default:
return nullptr;
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
template <class _CharT, class _Traits>

View File

@ -961,6 +961,7 @@ module std [system] {
module swap { private header "__utility/swap.h" }
module to_underlying { private header "__utility/to_underlying.h" }
module transaction { private header "__utility/transaction.h" }
module unreachable { private header "__utility/unreachable.h" }
}
}
module valarray {

View File

@ -239,6 +239,7 @@ template <class T>
#include <__utility/swap.h>
#include <__utility/to_underlying.h>
#include <__utility/transaction.h>
#include <__utility/unreachable.h>
#include <compare>
#include <initializer_list>
#include <version>

View File

@ -400,7 +400,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_string_contains 202011L
# define __cpp_lib_string_resize_and_overwrite 202110L
# define __cpp_lib_to_underlying 202102L
// # define __cpp_lib_unreachable 202202L
# define __cpp_lib_unreachable 202202L
#endif
// clang-format on

View File

@ -14,11 +14,11 @@
#include "chrono"
#include "climits"
#include "cstdarg"
#include "cstdlib"
#include "ctime"
#include "filesystem"
#include "ratio"
#include "system_error"
#include <utility>
#if defined(_LIBCPP_WIN32API)
# define WIN32_LEAN_AND_MEAN
@ -178,7 +178,7 @@ struct ErrorHandler {
case 2:
__throw_filesystem_error(what, *p1_, *p2_, ec);
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
@ -197,7 +197,7 @@ struct ErrorHandler {
case 2:
__throw_filesystem_error(what, *p1_, *p2_, ec);
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)

View File

@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include <__utility/unreachable.h>
#include "filesystem"
#include "array"
#include "iterator"
@ -154,7 +155,7 @@ public:
return makeState(PS_AtEnd);
case PS_AtEnd:
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
}
@ -202,7 +203,7 @@ public:
return makeState(PS_InRootName, Path.data(), RStart + 1);
case PS_InRootName:
case PS_BeforeBegin:
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
}
@ -224,7 +225,7 @@ public:
case PS_InFilenames:
return RawEntry;
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
explicit operator bool() const noexcept {
@ -285,7 +286,7 @@ private:
case PS_AtEnd:
return getAfterBack();
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
/// \brief Return a pointer to the first character in the currently lexed
@ -302,7 +303,7 @@ private:
case PS_AtEnd:
return &Path.back() + 1;
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
// Consume all consecutive separators.
@ -681,7 +682,7 @@ void filesystem_error::__create_what(int __num_paths) {
return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]",
derived_what, path1().c_str(), path2().c_str());
}
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}();
}
@ -1188,7 +1189,7 @@ bool __fs_is_empty(const path& p, error_code* ec) {
} else if (is_regular_file(st))
return static_cast<uintmax_t>(pst.st_size) == 0;
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
static file_time_type __extract_last_write_time(const path& p, const StatT& st,
@ -1801,7 +1802,7 @@ path path::lexically_normal() const {
break;
}
case PK_None:
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
}
// [fs.path.generic]p6.8: If the path is empty, add a dot.

View File

@ -12,6 +12,7 @@
#define _LCONV_C99
#endif
#include <__utility/unreachable.h>
#include "algorithm"
#include "clocale"
#include "codecvt"
@ -4623,7 +4624,7 @@ static bool checked_string_to_char_convert(char& dest,
return false;
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}

View File

@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include <__utility/unreachable.h>
#include "strstream"
#include "algorithm"
#include "climits"
@ -268,7 +269,7 @@ strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmod
newoff = seekhigh - eback();
break;
default:
_LIBCPP_UNREACHABLE();
__libcpp_unreachable();
}
newoff += __off;
if (0 <= newoff && newoff <= seekhigh - eback())

View File

@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: modules-build
// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.
// expected-error@*:* {{use of private header from outside its module: '__utility/unreachable.h'}}
#include <__utility/unreachable.h>

View File

@ -297,17 +297,11 @@
# error "__cpp_lib_tuples_by_type should have the value 201304L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_unreachable
# error "__cpp_lib_unreachable should be defined in c++2b"
# endif
# if __cpp_lib_unreachable != 202202L
# error "__cpp_lib_unreachable should have the value 202202L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_unreachable
# error "__cpp_lib_unreachable should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_unreachable
# error "__cpp_lib_unreachable should be defined in c++2b"
# endif
# if __cpp_lib_unreachable != 202202L
# error "__cpp_lib_unreachable should have the value 202202L in c++2b"
# endif
#endif // TEST_STD_VER > 20

View File

@ -5005,17 +5005,11 @@
# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_unreachable
# error "__cpp_lib_unreachable should be defined in c++2b"
# endif
# if __cpp_lib_unreachable != 202202L
# error "__cpp_lib_unreachable should have the value 202202L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_unreachable
# error "__cpp_lib_unreachable should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_unreachable
# error "__cpp_lib_unreachable should be defined in c++2b"
# endif
# if __cpp_lib_unreachable != 202202L
# error "__cpp_lib_unreachable should have the value 202202L in c++2b"
# endif
# ifndef __cpp_lib_unwrap_ref

View File

@ -0,0 +1,14 @@
//===----------------------------------------------------------------------===//
//
// 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
#include <utility>
#include <type_traits>
static_assert(std::is_same_v<decltype(std::unreachable()), void>);

View File

@ -0,0 +1,13 @@
//===----------------------------------------------------------------------===//
//
// 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
#include <utility>
[[noreturn]] void unreachable() { std::unreachable(); } // expected-no-diagnostics

View File

@ -744,7 +744,6 @@ feature_test_macros = [ add_version_header(x) for x in [
"name": "__cpp_lib_unreachable",
"values": { "c++2b": 202202 },
"headers": ["utility"],
"unimplemented": True,
}, {
"name": "__cpp_lib_unwrap_ref",
"values": { "c++20": 201811 },