diff options
| author | Eric Fiselier <eric@efcs.ca> | 2017-09-10 23:37:47 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2017-09-10 23:37:47 +0000 |
| commit | 85cde7d2f410353ee5c143ad931da571e9be11bf (patch) | |
| tree | 7c1f758b0e811d05d7a28fbe52a6038cc0a29fd5 | |
| parent | 358ca0c04bc297a9d34577d19e8814b0ca2e9411 (diff) | |
| download | bcm5719-llvm-85cde7d2f410353ee5c143ad931da571e9be11bf.tar.gz bcm5719-llvm-85cde7d2f410353ee5c143ad931da571e9be11bf.zip | |
Revert "Fix PR34298 - Allow std::function with an incomplete return type."
This reverts commit r312890 because the test case fails to compile for
older versions of Clang that reject initializing a const object without
a user defined constructor.
Since this patch should go into 5.0.1, I want to keep it an atomic change,
and will re-commit it with a fixed test case.
llvm-svn: 312891
| -rw-r--r-- | libcxx/include/functional | 36 | ||||
| -rw-r--r-- | libcxx/include/type_traits | 7 | ||||
| -rw-r--r-- | libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp | 37 |
3 files changed, 26 insertions, 54 deletions
diff --git a/libcxx/include/functional b/libcxx/include/functional index f73c3ca56a8..83a2e5a39a8 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -1597,11 +1597,9 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> return reinterpret_cast<__base*>(p); } - template <class _Fp, bool = __lazy_and< - integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>, - __invokable<_Fp&, _ArgTypes...> - >::value> - struct __callable; + template <class _Fp, bool = !is_same<_Fp, function>::value && + __invokable<_Fp&, _ArgTypes...>::value> + struct __callable; template <class _Fp> struct __callable<_Fp, true> { @@ -1614,9 +1612,6 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> { static const bool value = false; }; - - template <class _Fp> - using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type; public: typedef _Rp result_type; @@ -1627,7 +1622,9 @@ public: function(nullptr_t) _NOEXCEPT : __f_(0) {} function(const function&); function(function&&) _NOEXCEPT; - template<class _Fp, class = _EnableIfCallable<_Fp>> + template<class _Fp, class = typename enable_if< + __callable<_Fp>::value && !is_same<_Fp, function>::value + >::type> function(_Fp); #if _LIBCPP_STD_VER <= 14 @@ -1641,15 +1638,21 @@ public: function(allocator_arg_t, const _Alloc&, const function&); template<class _Alloc> function(allocator_arg_t, const _Alloc&, function&&); - template<class _Fp, class _Alloc, class = _EnableIfCallable<_Fp>> + template<class _Fp, class _Alloc, class = typename enable_if<__callable<_Fp>::value>::type> function(allocator_arg_t, const _Alloc& __a, _Fp __f); #endif function& operator=(const function&); function& operator=(function&&) _NOEXCEPT; function& operator=(nullptr_t) _NOEXCEPT; - template<class _Fp, class = _EnableIfCallable<_Fp>> - function& operator=(_Fp&&); + template<class _Fp> + typename enable_if + < + __callable<typename decay<_Fp>::type>::value && + !is_same<typename remove_reference<_Fp>::type, function>::value, + function& + >::type + operator=(_Fp&&); ~function(); @@ -1851,8 +1854,13 @@ function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT } template<class _Rp, class ..._ArgTypes> -template <class _Fp, class> -function<_Rp(_ArgTypes...)>& +template <class _Fp> +typename enable_if +< + function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value && + !is_same<typename remove_reference<_Fp>::type, function<_Rp(_ArgTypes...)>>::value, + function<_Rp(_ArgTypes...)>& +>::type function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) { function(_VSTD::forward<_Fp>(__f)).swap(*this); diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 6c111abfd1e..9db4d66145f 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -4339,8 +4339,8 @@ struct __invokable_r using _Result = decltype( _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)); - using type = - typename conditional< + static const bool value = + conditional< !is_same<_Result, __nat>::value, typename conditional< is_void<_Ret>::value, @@ -4348,8 +4348,7 @@ struct __invokable_r is_convertible<_Result, _Ret> >::type, false_type - >::type; - static const bool value = type::value; + >::type::value; }; template <class _Fp, class ..._Args> diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp index 136b15b2a2a..c8f4178a26b 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp @@ -16,7 +16,6 @@ // Allow incomplete argument types in the __is_callable check #include <functional> -#include <cassert> struct X{ typedef std::function<void(X&)> callback_type; @@ -25,40 +24,6 @@ private: callback_type _cb; }; -struct IncompleteReturnType { - std::function<IncompleteReturnType ()> fn; -}; - - -int called = 0; -IncompleteReturnType test_fn() { - ++called; - IncompleteReturnType I; - return I; -} - -// See llvm.org/PR34298 -void test_pr34298() +int main() { - static_assert(std::is_copy_constructible<IncompleteReturnType>::value, ""); - static_assert(std::is_copy_assignable<IncompleteReturnType>::value, ""); - { - IncompleteReturnType X; - X.fn = test_fn; - const IncompleteReturnType& CX = X; - IncompleteReturnType X2 = CX; - assert(X2.fn); - assert(called == 0); - X2.fn(); - assert(called == 1); - } - { - const IncompleteReturnType Empty; - IncompleteReturnType X2 = Empty; - assert(!X2.fn); - } -} - -int main() { - test_pr34298(); } |

