[libcxx] r201101 - Fix for PR17606 - result_of (and INVOKE) works incorrectly for member function pointers with ref qualifiers. Also a drive-by fix for common_type in C++03 mode. Thanks to Michel Morin for the bug report and the proposed fix.
Marshall Clow
mclow.lists at gmail.com
Mon Feb 10 09:40:28 PST 2014
Author: marshall
Date: Mon Feb 10 11:40:28 2014
New Revision: 201101
URL: http://llvm.org/viewvc/llvm-project?rev=201101&view=rev
Log:
Fix for PR17606 - result_of (and INVOKE) works incorrectly for member function pointers with ref qualifiers. Also a drive-by fix for common_type in C++03 mode. Thanks to Michel Morin for the bug report and the proposed fix.
Added:
libcxx/trunk/test/utilities/function.objects/func.require/invoke.pass.cpp
Modified:
libcxx/trunk/include/type_traits
libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=201101&r1=201100&r2=201101&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Mon Feb 10 11:40:28 2014
@@ -1385,7 +1385,7 @@ template <class _Tp>
struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, void, void>
{
public:
- typedef _Tp type;
+ typedef typename decay<_Tp>::type type;
};
template <class _Tp, class _Up>
@@ -3079,7 +3079,7 @@ template <class _Fp, class _A0, class ..
class = typename enable_if
<
is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
- is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+ is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type,
typename remove_reference<_A0>::type>::value
>::type
>
@@ -3092,7 +3092,7 @@ template <class _Fp, class _A0, class ..
class = typename enable_if
<
is_member_function_pointer<typename remove_reference<_Fp>::type>::value &&
- !is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType,
+ !is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type,
typename remove_reference<_A0>::type>::value
>::type
>
Added: libcxx/trunk/test/utilities/function.objects/func.require/invoke.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/function.objects/func.require/invoke.pass.cpp?rev=201101&view=auto
==============================================================================
--- libcxx/trunk/test/utilities/function.objects/func.require/invoke.pass.cpp (added)
+++ libcxx/trunk/test/utilities/function.objects/func.require/invoke.pass.cpp Mon Feb 10 11:40:28 2014
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// [func.require]
+
+// INVOKE
+#if __cplusplus < 201103L
+int main () {} // no __invoke in C++03
+#else
+
+#include <type_traits>
+
+template <typename T, int N>
+struct Array
+{
+ typedef T type[N];
+};
+
+struct Type
+{
+ Array<char, 1>::type& f1();
+ Array<char, 2>::type& f2() const;
+
+ Array<char, 1>::type& g1() &;
+ Array<char, 2>::type& g2() const &;
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ Array<char, 3>::type& g3() &&;
+ Array<char, 4>::type& g4() const &&;
+#endif
+};
+
+int main()
+{
+ static_assert(sizeof(std::__invoke(&Type::f1, std::declval<Type >())) == 1, "");
+ static_assert(sizeof(std::__invoke(&Type::f2, std::declval<Type const >())) == 2, "");
+
+ static_assert(sizeof(std::__invoke(&Type::g1, std::declval<Type &>())) == 1, "");
+ static_assert(sizeof(std::__invoke(&Type::g2, std::declval<Type const &>())) == 2, "");
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ static_assert(sizeof(std::__invoke(&Type::g3, std::declval<Type &&>())) == 3, "");
+ static_assert(sizeof(std::__invoke(&Type::g4, std::declval<Type const&&>())) == 4, "");
+#endif
+}
+#endif
Modified: libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp?rev=201101&r1=201100&r2=201101&view=diff
==============================================================================
--- libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp (original)
+++ libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp Mon Feb 10 11:40:28 2014
@@ -34,6 +34,8 @@ struct wat
void foo();
};
+struct F {};
+
template <class T, class U>
void test_result_of_imp()
{
@@ -55,6 +57,14 @@ int main()
test_result_of_imp<PMD(S), char&&> ();
#endif
test_result_of_imp<PMD(const S*), const char&> ();
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ test_result_of_imp<int (F::* (F &)) () &, int> ();
+ test_result_of_imp<int (F::* (F &)) () const &, int> ();
+ test_result_of_imp<int (F::* (F const &)) () const &, int> ();
+ test_result_of_imp<int (F::* (F &&)) () &&, int> ();
+ test_result_of_imp<int (F::* (F &&)) () const&&, int> ();
+ test_result_of_imp<int (F::* (F const&&)) () const&&, int> ();
+#endif
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
using type1 = std::result_of<decltype(&wat::foo)(wat)>::type;
#endif
@@ -74,6 +84,14 @@ int main()
static_assert((std::is_same<std::result_of<PMD(S)>::type, char&&>::value), "Error!");
#endif
static_assert((std::is_same<std::result_of<PMD(const S*)>::type, const char&>::value), "Error!");
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ static_assert((std::is_same<std::result_of<int (F::* (F &)) () &>::type, int>::value), "Error!");
+ static_assert((std::is_same<std::result_of<int (F::* (F &)) () const &>::type, int>::value), "Error!");
+ static_assert((std::is_same<std::result_of<int (F::* (F const &)) () const &>::type, int>::value), "Error!");
+ static_assert((std::is_same<std::result_of<int (F::* (F &&)) () &&>::type, int>::value), "Error!");
+ static_assert((std::is_same<std::result_of<int (F::* (F &&)) () const&&>::type, int>::value), "Error!");
+ static_assert((std::is_same<std::result_of<int (F::* (F const&&)) () const&&>::type, int>::value), "Error!");
+#endif
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
using type = std::result_of<decltype(&wat::foo)(wat)>::type;
#endif
More information about the cfe-commits
mailing list