summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2019-04-03 14:29:52 +0000
committerLouis Dionne <ldionne@apple.com>2019-04-03 14:29:52 +0000
commit3b8c90b80d46897c22ade3f7a9419344e4d040a7 (patch)
tree84df29c5e443702930378c9e88348bc5667db3d7
parent6911ff562fc685136c8e4b8ed4bc6cce059ab2e5 (diff)
downloadbcm5719-llvm-3b8c90b80d46897c22ade3f7a9419344e4d040a7.tar.gz
bcm5719-llvm-3b8c90b80d46897c22ade3f7a9419344e4d040a7.zip
[libc++] (Take 2) Correctly handle Objective-C++ ARC qualifiers in std::is_pointer
Summary: Otherwise, std::is_pointer<id __strong> works, but std::is_pointer<id __weak> (and others) don't work as expected. The previous patch (r357517) had to be reverted in r357569 because it broke the Chromium build. This patch shouldn't have the same problem. rdar://problem/49126333 Reviewers: ahatanak, EricWF Subscribers: christof, jkorous, dexonsmith, libcxx-commits Differential Revision: https://reviews.llvm.org/D60087 llvm-svn: 357586
-rw-r--r--libcxx/include/type_traits10
-rw-r--r--libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm64
2 files changed, 73 insertions, 1 deletions
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 2b79490941c..43faf275cff 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -785,8 +785,16 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v
template <class _Tp> struct __libcpp_is_pointer : public false_type {};
template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
+template <class _Tp> struct __libcpp_remove_objc_qualifiers { typedef _Tp type; };
+#if defined(_LIBCPP_HAS_OBJC_ARC)
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; };
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; };
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; };
+template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; };
+#endif
+
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer
- : public __libcpp_is_pointer<typename remove_cv<_Tp>::type> {};
+ : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<typename remove_cv<_Tp>::type>::type> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
diff --git a/libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm b/libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm
new file mode 100644
index 00000000000..1f4c5089af9
--- /dev/null
+++ b/libcxx/test/libcxx/type_traits/is_pointer.arc.pass.mm
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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++98, c++03
+
+// <type_traits>
+
+// std::is_pointer
+
+// Test that we correctly handle Objective-C++ ARC qualifiers on pointers.
+
+#include <type_traits>
+
+
+template <typename T>
+void test_is_pointer() {
+ static_assert(std::is_pointer<T>::value, "");
+
+ static_assert(std::is_pointer<T __weak>::value, "");
+ static_assert(std::is_pointer<T __strong>::value, "");
+ static_assert(std::is_pointer<T __autoreleasing>::value, "");
+ static_assert(std::is_pointer<T __unsafe_unretained>::value, "");
+
+ static_assert(std::is_pointer<T __weak const>::value, "");
+ static_assert(std::is_pointer<T __strong const>::value, "");
+ static_assert(std::is_pointer<T __autoreleasing const>::value, "");
+ static_assert(std::is_pointer<T __unsafe_unretained const>::value, "");
+
+ static_assert(std::is_pointer<T __weak volatile>::value, "");
+ static_assert(std::is_pointer<T __strong volatile>::value, "");
+ static_assert(std::is_pointer<T __autoreleasing volatile>::value, "");
+ static_assert(std::is_pointer<T __unsafe_unretained volatile>::value, "");
+
+ static_assert(std::is_pointer<T __weak const volatile>::value, "");
+ static_assert(std::is_pointer<T __strong const volatile>::value, "");
+ static_assert(std::is_pointer<T __autoreleasing const volatile>::value, "");
+ static_assert(std::is_pointer<T __unsafe_unretained const volatile>::value, "");
+}
+
+@class Foo;
+
+int main(int, char**) {
+ test_is_pointer<id>();
+ test_is_pointer<id const>();
+ test_is_pointer<id volatile>();
+ test_is_pointer<id const volatile>();
+
+ test_is_pointer<Foo*>();
+ test_is_pointer<Foo const*>();
+ test_is_pointer<Foo volatile*>();
+ test_is_pointer<Foo const volatile*>();
+
+ test_is_pointer<void*>();
+ test_is_pointer<void const*>();
+ test_is_pointer<void volatile*>();
+ test_is_pointer<void const volatile*>();
+
+ return 0;
+}
OpenPOWER on IntegriCloud