From 1e6278ed2ace08ba2ebd627818e83e6a7ef2dfa9 Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Wed, 13 Sep 2023 13:47:36 +0000 Subject: [PATCH 1/2] [libc][utils] cpp::always_false to enable static_assert(false) --- libc/src/__support/CPP/CMakeLists.txt | 1 + .../__support/CPP/type_traits/always_false.h | 25 +++++++++++++++++++ libc/src/__support/CPP/utility/declval.h | 8 ++---- .../llvm-project-overlay/libc/BUILD.bazel | 1 + 4 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 libc/src/__support/CPP/type_traits/always_false.h diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt index d24c023ec28ebc..4e3e4a3edf381d 100644 --- a/libc/src/__support/CPP/CMakeLists.txt +++ b/libc/src/__support/CPP/CMakeLists.txt @@ -95,6 +95,7 @@ add_header_library( type_traits HDRS type_traits.h + type_traits/always_false.h type_traits/add_lvalue_reference.h type_traits/add_pointer.h type_traits/add_rvalue_reference.h diff --git a/libc/src/__support/CPP/type_traits/always_false.h b/libc/src/__support/CPP/type_traits/always_false.h new file mode 100644 index 00000000000000..84be58d16ec8da --- /dev/null +++ b/libc/src/__support/CPP/type_traits/always_false.h @@ -0,0 +1,25 @@ +//===-- convenient static_assert(false) helper ------------------*- C++ -*-===// +// +// 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 LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ALWAYS_FALSE_H +#define LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ALWAYS_FALSE_H + +#include "src/__support/macros/attributes.h" + +namespace __llvm_libc::cpp { + +// This is technically not part of the standard but it come often enough that +// it's convenient to have around. +// +// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2593r0.html#valid-workaround + +template LIBC_INLINE_VAR constexpr bool always_false = false; + +} // namespace __llvm_libc::cpp + +#endif // LLVM_LIBC_SRC_SUPPORT_CPP_TYPE_TRAITS_ALWAYS_FALSE_H diff --git a/libc/src/__support/CPP/utility/declval.h b/libc/src/__support/CPP/utility/declval.h index 9261ceb9332d51..21bb973de0dd04 100644 --- a/libc/src/__support/CPP/utility/declval.h +++ b/libc/src/__support/CPP/utility/declval.h @@ -9,17 +9,13 @@ #define LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_DECLVAL_H #include "src/__support/CPP/type_traits/add_rvalue_reference.h" -#include "src/__support/macros/attributes.h" +#include "src/__support/CPP/type_traits/always_false.h" namespace __llvm_libc::cpp { // declval -namespace detail { -template LIBC_INLINE_VAR constexpr bool always_false = false; -} - template cpp::add_rvalue_reference_t declval() { - static_assert(detail::always_false, + static_assert(cpp::always_false, "declval not allowed in an evaluated context"); } diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 17e4913749d51c..160998049fcd2a 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -289,6 +289,7 @@ libc_support_library( "src/__support/CPP/type_traits/add_lvalue_reference.h", "src/__support/CPP/type_traits/add_pointer.h", "src/__support/CPP/type_traits/add_rvalue_reference.h", + "src/__support/CPP/type_traits/always_false.h", "src/__support/CPP/type_traits/bool_constant.h", "src/__support/CPP/type_traits/conditional.h", "src/__support/CPP/type_traits/decay.h", From e5ab8fdaad9ef89d9fe28e2ce13e95005dda3895 Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Wed, 13 Sep 2023 13:52:42 +0000 Subject: [PATCH 2/2] Add more documentation --- libc/src/__support/CPP/type_traits/always_false.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libc/src/__support/CPP/type_traits/always_false.h b/libc/src/__support/CPP/type_traits/always_false.h index 84be58d16ec8da..5e3a51479e3d25 100644 --- a/libc/src/__support/CPP/type_traits/always_false.h +++ b/libc/src/__support/CPP/type_traits/always_false.h @@ -17,7 +17,11 @@ namespace __llvm_libc::cpp { // it's convenient to have around. // // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2593r0.html#valid-workaround +// +// This will be fixed in C++23 according to [CWG +// 2518](https://cplusplus.github.io/CWG/issues/2518.html). +// Usage `static_assert(cpp::always_false, "error message");` template LIBC_INLINE_VAR constexpr bool always_false = false; } // namespace __llvm_libc::cpp