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), ""); +} + +@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) && \ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits