[clang] b25ec45 - Fix __is_pointer builtin type trait to work with Objective-C pointer types.

via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 8 10:03:05 PDT 2020


Author: zoecarver
Date: 2020-04-08T10:02:53-07:00
New Revision: b25ec45809fbb71d0db883c0275dc5ddcd61160d

URL: https://github.com/llvm/llvm-project/commit/b25ec45809fbb71d0db883c0275dc5ddcd61160d
DIFF: https://github.com/llvm/llvm-project/commit/b25ec45809fbb71d0db883c0275dc5ddcd61160d.diff

LOG: Fix __is_pointer builtin type trait to work with Objective-C pointer types.

Summary: 5ade17e broke __is_pointer for Objective-C pointer types. This patch fixes the builtin and re-applies the change to type_traits.

Tags: #clang, #libc

Differential Revision: https://reviews.llvm.org/D77519

Added: 
    clang/test/SemaObjCXX/type-traits-is-pointer.mm

Modified: 
    clang/lib/Sema/SemaExprCXX.cpp
    libcxx/include/type_traits

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 365e6a23b5c5..10739fb48e99 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4692,7 +4692,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
   case UTT_IsArray:
     return T->isArrayType();
   case UTT_IsPointer:
-    return T->isPointerType();
+    return T->isAnyPointerType();
   case UTT_IsLvalueReference:
     return T->isLValueReferenceType();
   case UTT_IsRvalueReference:

diff  --git a/clang/test/SemaObjCXX/type-traits-is-pointer.mm b/clang/test/SemaObjCXX/type-traits-is-pointer.mm
new file mode 100644
index 000000000000..ce7c12c80c6a
--- /dev/null
+++ b/clang/test/SemaObjCXX/type-traits-is-pointer.mm
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -verify %s
+// expected-no-diagnostics
+
+template <typename T>
+void test_is_pointer() {
+    static_assert(__is_pointer(T), "");
+
+    static_assert(__is_pointer(T __weak), "");
+    static_assert(__is_pointer(T __strong), "");
+    static_assert(__is_pointer(T __autoreleasing), "");
+    static_assert(__is_pointer(T __unsafe_unretained), "");
+
+    static_assert(__is_pointer(T __weak const), "");
+    static_assert(__is_pointer(T __strong const), "");
+    static_assert(__is_pointer(T __autoreleasing const), "");
+    static_assert(__is_pointer(T __unsafe_unretained const), "");
+
+    static_assert(__is_pointer(T __weak volatile), "");
+    static_assert(__is_pointer(T __strong volatile), "");
+    static_assert(__is_pointer(T __autoreleasing volatile), "");
+    static_assert(__is_pointer(T __unsafe_unretained volatile), "");
+
+    static_assert(__is_pointer(T __weak const volatile), "");
+    static_assert(__is_pointer(T __strong const volatile), "");
+    static_assert(__is_pointer(T __autoreleasing const volatile), "");
+    static_assert(__is_pointer(T __unsafe_unretained const volatile), "");
+}
+
+ at 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;
+}

diff  --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 029bb4aa2ae9..ece46436a783 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -897,6 +897,19 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v
 
 // 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 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v
     = is_pointer<_Tp>::value;
 #endif
 
+#endif // __has_keyword(__is_pointer)
+
 // is_reference
 
 #if __has_keyword(__is_lvalue_reference) && \


        


More information about the cfe-commits mailing list