diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/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: diff --git a/clang/test/SemaObjC/type-traits-is-pointer.mm b/clang/test/SemaObjC/type-traits-is-pointer.mm new file mode 100644 --- /dev/null +++ b/clang/test/SemaObjC/type-traits-is-pointer.mm @@ -0,0 +1,52 @@ +// RUN: %clang -fobjc-arc %s + +template +void assert_is_pointer() { + static_assert(__is_pointer(T), ""); +} + +template +void test_is_pointer() { + assert_is_pointer(); + + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); + + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); + + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); + + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); + assert_is_pointer(); +} + +@class Foo; + +int main(int, char**) { + test_is_pointer(); + test_is_pointer(); + test_is_pointer(); + test_is_pointer(); + + test_is_pointer(); + test_is_pointer(); + test_is_pointer(); + test_is_pointer(); + + test_is_pointer(); + test_is_pointer(); + test_is_pointer(); + test_is_pointer(); + + return 0; +} diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/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 +struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v = __is_pointer(_Tp); +#endif + +#else // __has_keyword(__is_pointer) + template struct __libcpp_is_pointer : public false_type {}; template 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) && \