Fix __is_referenceable to work with vector types. Fixes PR#26654 and 26656. Thanks to Evgeniy for the reports, and to Eric for the suggestion on how to fix it.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@261581 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/type_traits b/include/type_traits
index b0675e1..33124d2 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -959,34 +959,15 @@
 
 
 // __is_referenceable  [defns.referenceable]
-template <class _Tp> struct __is_referenceable
-    : public std::integral_constant<bool, is_object<_Tp>::value || is_reference<_Tp>::value> {};
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-template <class _Ret, class... _Args>
-struct __is_referenceable<_Ret(_Args...)>           : public std::true_type {};
+struct __is_referenceable_impl {
+    template <class _Tp> static _Tp& __test(int);
+    template <class _Tp> static __two __test(...);
+};
 
-template <class _Ret, class... _Args>
-struct __is_referenceable<_Ret(_Args..., ...)>      : public std::true_type {};
-#else
-template <class _Ret>
-struct __is_referenceable<_Ret()>                   : public std::true_type {};
-template <class _Ret, class _A0>
-struct __is_referenceable<_Ret(_A0)>                : public std::true_type {};
-template <class _Ret, class _A0, class _A1>
-struct __is_referenceable<_Ret(_A0, _A1)>           : public std::true_type {};
-template <class _Ret, class _A0, class _A1, class _A2>
-struct __is_referenceable<_Ret(_A0, _A1, _A2)>      : public std::true_type {};
-
-template <class _Ret>
-struct __is_referenceable<_Ret(...)>                : public std::true_type {};
-template <class _Ret, class _A0>
-struct __is_referenceable<_Ret(_A0, ...)>           : public std::true_type {};
-template <class _Ret, class _A0, class _A1>
-struct __is_referenceable<_Ret(_A0, _A1, ...)>      : public std::true_type {};
-template <class _Ret, class _A0, class _A1, class _A2>
-struct __is_referenceable<_Ret(_A0, _A1, _A2, ...)> : public std::true_type {};
-#endif
+template <class _Tp>
+struct __is_referenceable : std::integral_constant<bool,
+    !std::is_same<decltype(__is_referenceable_impl::__test<_Tp>(0)), __two>::value> {};
 
 
 // add_const
diff --git a/test/libcxx/utilities/meta/is_referenceable.pass.cpp b/test/libcxx/utilities/meta/is_referenceable.pass.cpp
index f42011d..dd31ab5 100644
--- a/test/libcxx/utilities/meta/is_referenceable.pass.cpp
+++ b/test/libcxx/utilities/meta/is_referenceable.pass.cpp
@@ -39,6 +39,11 @@
 static_assert(( std::__is_referenceable<const Foo &&>::value), "");
 #endif
 
+static_assert(( std::__is_referenceable<int   __attribute__((__vector_size__( 8)))>::value), "");
+static_assert(( std::__is_referenceable<const int   __attribute__((__vector_size__( 8)))>::value), "");
+static_assert(( std::__is_referenceable<float __attribute__((__vector_size__(16)))>::value), "");
+static_assert(( std::__is_referenceable<const float __attribute__((__vector_size__(16)))>::value), "");
+
 // Functions without cv-qualifiers are referenceable 
 static_assert(( std::__is_referenceable<void ()>::value), "");
 #if TEST_STD_VER >= 11