From ecc9742f277c65ad28be1ff5e9ff68a8a1df94ee Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Tue, 7 May 2013 23:40:12 +0000 Subject: [PATCH] Constrain __invoke functions more accurately. This fixes http://llvm.org/bugs/show_bug.cgi?id=15861 . git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@181377 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__functional_base | 12 ++++--- include/type_traits | 36 ++++++++++++++++--- .../meta.trans.other/result_of.pass.cpp | 7 ++++ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/include/__functional_base b/include/__functional_base index 40a63a853..5b0d7201d 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -292,7 +292,8 @@ struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> // bullets 1 and 2 -template +template inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) @@ -301,7 +302,8 @@ __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...); } -template +template inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) @@ -312,7 +314,8 @@ __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) // bullets 3 and 4 -template +template inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) @@ -321,7 +324,8 @@ __invoke(_Fp&& __f, _A0&& __a0) return _VSTD::forward<_A0>(__a0).*__f; } -template +template inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) diff --git a/include/type_traits b/include/type_traits index ab0e22201..cc8a68ecc 100644 --- a/include/type_traits +++ b/include/type_traits @@ -2878,13 +2878,27 @@ __invoke(__any, _Args&& ...__args) // bullets 1 and 2 -template +template ::type>::value && + is_base_of::type>::_ClassType, + typename remove_reference<_A0>::type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)); -template +template ::type>::value && + !is_base_of::type>::_ClassType, + typename remove_reference<_A0>::type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) @@ -2892,13 +2906,27 @@ __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) // bullets 3 and 4 -template +template ::type>::value && + is_base_of::type>::_ClassType, + typename remove_reference<_A0>::type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) -> decltype(_VSTD::forward<_A0>(__a0).*__f); -template +template ::type>::value && + !is_base_of::type>::_ClassType, + typename remove_reference<_A0>::type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) diff --git a/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp b/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp index eac8ba0c3..33c0ed4af 100644 --- a/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp +++ b/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp @@ -28,6 +28,12 @@ struct S typedef void (S::*PMS)(long) const; typedef char S::*PMD; +struct wat +{ + wat& operator*() { return *this; } + void foo(); +}; + int main() { static_assert((std::is_same::type, short>::value), "Error!"); @@ -40,4 +46,5 @@ int main() static_assert((std::is_same::type, char&&>::value), "Error!"); #endif static_assert((std::is_same::type, const char&>::value), "Error!"); + using type = std::result_of::type; }