[llvm-branch-commits] [libcxx] e479b95 - [libc++] Temporarily not use compiler intrinsics for some type traits in Objective-C++ mode.
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Mar 5 23:21:44 PST 2023
Author: Konstantin Varlamov
Date: 2023-03-06T08:21:06+01:00
New Revision: e479b9520706f6e77fc69ff77eeafa213d9edd63
URL: https://github.com/llvm/llvm-project/commit/e479b9520706f6e77fc69ff77eeafa213d9edd63
DIFF: https://github.com/llvm/llvm-project/commit/e479b9520706f6e77fc69ff77eeafa213d9edd63.diff
LOG: [libc++] Temporarily not use compiler intrinsics for some type traits in Objective-C++ mode.
Currently, there are bugs in Clang's intrinsics for type traits when
handling Objective-C++ `id` (e.g. in `add_pointer`). As a temporary
workaround, don't use these intrinsics in the Objective-C++ mode.
Differential Revision: https://reviews.llvm.org/D145186
(cherry picked from commit 87cf39aa349b83ae3b7d16c30ac7a8ffa0ad098c)
Added:
libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm
Modified:
libcxx/include/__config
libcxx/include/__type_traits/add_pointer.h
libcxx/include/__type_traits/remove_pointer.h
Removed:
################################################################################
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 5daa348c79b5f..ac6a1422bfe3b 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1259,6 +1259,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
# define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "")
#endif
+// TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use
+// compiler intrinsics in the Objective-C++ mode.
+# ifdef __OBJC__
+# define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS
+# endif
+
#endif // __cplusplus
#endif // _LIBCPP___CONFIG
diff --git a/libcxx/include/__type_traits/add_pointer.h b/libcxx/include/__type_traits/add_pointer.h
index 9d0c2010077bd..1af5eca65c631 100644
--- a/libcxx/include/__type_traits/add_pointer.h
+++ b/libcxx/include/__type_traits/add_pointer.h
@@ -22,7 +22,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_builtin(__add_pointer)
+#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
template <class _Tp>
using __add_pointer_t = __add_pointer(_Tp);
@@ -39,7 +39,7 @@ template <class _Tp> struct __add_pointer_impl<_Tp, false>
template <class _Tp>
using __add_pointer_t = typename __add_pointer_impl<_Tp>::type;
-#endif // __has_builtin(__add_pointer)
+#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer)
template <class _Tp>
struct add_pointer {
diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h
index 33ddb7103f0dd..2f810ba666bb6 100644
--- a/libcxx/include/__type_traits/remove_pointer.h
+++ b/libcxx/include/__type_traits/remove_pointer.h
@@ -17,7 +17,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if __has_builtin(__remove_pointer)
+#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
template <class _Tp>
struct remove_pointer {
using type _LIBCPP_NODEBUG = __remove_pointer(_Tp);
@@ -34,7 +34,7 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volat
template <class _Tp>
using __remove_pointer_t = typename remove_pointer<_Tp>::type;
-#endif // __has_builtin(__remove_pointer)
+#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer)
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_pointer_t = __remove_pointer_t<_Tp>;
diff --git a/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm b/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm
new file mode 100644
index 0000000000000..e1fb119e190c3
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: objective-c++
+
+// Simple test to check that type traits support Objective-C types.
+
+#include <type_traits>
+#include "test_macros.h"
+
+ at interface I;
+ at end
+
+// add_pointer
+static_assert(std::is_same<std::add_pointer<id>::type, id*>::value, "");
+static_assert(std::is_same<std::add_pointer<I>::type, I*>::value, "");
+
+// add_lvalue_reference
+static_assert(std::is_same<std::add_lvalue_reference<id>::type, id&>::value, "");
+static_assert(std::is_same<std::add_lvalue_reference<I>::type, I&>::value, "");
+
+// add_rvalue_reference
+static_assert(std::is_same<std::add_rvalue_reference<id>::type, id&&>::value, "");
+static_assert(std::is_same<std::add_rvalue_reference<I>::type, I&&>::value, "");
+
+// decay
+static_assert(std::is_same<std::decay<id>::type, id>::value, "");
+static_assert(std::is_same<std::decay<I>::type, I>::value, "");
+static_assert(std::is_same<std::decay<id(&)[5]>::type, id*>::value, "");
+
+// __libcpp_is_referenceable
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id>::value, "");
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id*>::value, "");
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id&>::value, "");
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<id&&>::value, "");
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I>::value, "");
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I*>::value, "");
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I&>::value, "");
+LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable<I&&>::value, "");
+
+// remove_all_extents
+static_assert(std::is_same<std::remove_all_extents<id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_all_extents<id[5]>::type, id>::value, "");
+static_assert(std::is_same<std::remove_all_extents<id[5][10]>::type, id>::value, "");
+static_assert(std::is_same<std::remove_all_extents<I>::type, I>::value, "");
+
+// remove_const
+static_assert(std::is_same<std::remove_const<id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_const<const id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_const<I>::type, I>::value, "");
+static_assert(std::is_same<std::remove_const<const I>::type, I>::value, "");
+
+// remove_cv
+static_assert(std::is_same<std::remove_cv<id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_cv<const volatile id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_cv<I>::type, I>::value, "");
+static_assert(std::is_same<std::remove_cv<const volatile I>::type, I>::value, "");
+
+#if TEST_STD_VER >= 20
+// remove_cvref
+static_assert(std::is_same<std::remove_cvref<id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_cvref<const volatile id&>::type, id>::value, "");
+static_assert(std::is_same<std::remove_cvref<const volatile id&&>::type, id>::value, "");
+static_assert(std::is_same<std::remove_cvref<I>::type, I>::value, "");
+static_assert(std::is_same<std::remove_cvref<const volatile I&>::type, I>::value, "");
+static_assert(std::is_same<std::remove_cvref<const volatile I&&>::type, I>::value, "");
+#endif
+
+// remove_extent
+static_assert(std::is_same<std::remove_all_extents<id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_all_extents<id[5]>::type, id>::value, "");
+static_assert(std::is_same<std::remove_all_extents<I>::type, I>::value, "");
+
+// remove_pointer
+static_assert(!std::is_same<std::remove_pointer<id>::type, id>::value, "");
+// The result of removing and re-adding pointer to `id` should be still `id`.
+static_assert(std::is_same<std::remove_pointer<id>::type*, id>::value, "");
+static_assert(std::is_same<std::add_pointer<std::remove_pointer<id>::type>::type, id>::value, "");
+static_assert(std::is_same<std::remove_pointer<std::add_pointer<id>::type>::type, id>::value, "");
+
+// remove_reference
+static_assert(std::is_same<std::remove_reference<id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_reference<id&>::type, id>::value, "");
+static_assert(std::is_same<std::remove_reference<const id&>::type, const id>::value, "");
+static_assert(std::is_same<std::remove_reference<id&&>::type, id>::value, "");
+static_assert(std::is_same<std::remove_reference<const id&&>::type, const id>::value, "");
+static_assert(std::is_same<std::remove_reference<I>::type, I>::value, "");
+static_assert(std::is_same<std::remove_reference<I&>::type, I>::value, "");
+static_assert(std::is_same<std::remove_reference<const I&>::type, const I>::value, "");
+static_assert(std::is_same<std::remove_reference<I&&>::type, I>::value, "");
+static_assert(std::is_same<std::remove_reference<const I&&>::type, const I>::value, "");
+
+// remove_volatile
+static_assert(std::is_same<std::remove_volatile<id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_volatile<volatile id>::type, id>::value, "");
+static_assert(std::is_same<std::remove_volatile<I>::type, I>::value, "");
+static_assert(std::is_same<std::remove_volatile<volatile I>::type, I>::value, "");
+
+int main(int, char**) {
+ return 0;
+}
More information about the llvm-branch-commits
mailing list