zoecarver created this revision.
Herald added projects: clang, libc++.
Herald added subscribers: libcxx-commits, cfe-commits.
Herald added a reviewer: libc++.
zoecarver added reviewers: ldionne, rsmith, EricWF.
Herald added a subscriber: dexonsmith.

5ade17e <https://reviews.llvm.org/rG5ade17e0ca8b11f57cb15a1bee6d30a3815d8cac> 
broke __is_pointer for Objective-C pointer types. This patch fixes the builtin 
and re-applies the change to type_traits.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77519

Files:
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/SemaObjC/type-traits-is-pointer.mm
  libcxx/include/type_traits

Index: libcxx/include/type_traits
===================================================================
--- libcxx/include/type_traits
+++ libcxx/include/type_traits
@@ -897,6 +897,19 @@
 
 // is_pointer
 
+// In clang 10.0.0 and earlier __is_pointer didn't work with Objective-C types.
+#if __has_keyword(__is_pointer) && _LIBCPP_CLANG_VER > 1000
+
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
+
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template <class _Tp>
+_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v = __is_pointer(_Tp);
+#endif
+
+#else // __has_keyword(__is_pointer)
+
 template <class _Tp> struct __libcpp_is_pointer       : public false_type {};
 template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
 
@@ -917,6 +930,8 @@
     = is_pointer<_Tp>::value;
 #endif
 
+#endif // __has_keyword(__is_pointer)
+
 // is_reference
 
 #if __has_keyword(__is_lvalue_reference) && \
Index: clang/test/SemaObjC/type-traits-is-pointer.mm
===================================================================
--- /dev/null
+++ clang/test/SemaObjC/type-traits-is-pointer.mm
@@ -0,0 +1,52 @@
+// RUN: %clang -fobjc-arc %s
+
+template <typename T>
+void assert_is_pointer() {
+    static_assert(__is_pointer(T), "");
+}
+
+template <typename T>
+void test_is_pointer() {
+    assert_is_pointer<T>();
+
+    assert_is_pointer<T __weak>();
+    assert_is_pointer<T __strong>();
+    assert_is_pointer<T __autoreleasing>();
+    assert_is_pointer<T __unsafe_unretained>();
+
+    assert_is_pointer<T __weak const>();
+    assert_is_pointer<T __strong const>();
+    assert_is_pointer<T __autoreleasing const>();
+    assert_is_pointer<T __unsafe_unretained const>();
+
+    assert_is_pointer<T __weak volatile>();
+    assert_is_pointer<T __strong volatile>();
+    assert_is_pointer<T __autoreleasing volatile>();
+    assert_is_pointer<T __unsafe_unretained volatile>();
+
+    assert_is_pointer<T __weak const volatile>();
+    assert_is_pointer<T __strong const volatile>();
+    assert_is_pointer<T __autoreleasing const volatile>();
+    assert_is_pointer<T __unsafe_unretained const volatile>();
+}
+
+@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;
+}
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -4692,7 +4692,7 @@
   case UTT_IsArray:
     return T->isArrayType();
   case UTT_IsPointer:
-    return T->isPointerType();
+    return T->isAnyPointerType();
   case UTT_IsLvalueReference:
     return T->isLValueReferenceType();
   case UTT_IsRvalueReference:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to