Author: ericwf Date: Sun Sep 10 16:37:47 2017 New Revision: 312891 URL: http://llvm.org/viewvc/llvm-project?rev=312891&view=rev Log: 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. Modified: libcxx/trunk/include/functional libcxx/trunk/include/type_traits libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp Modified: libcxx/trunk/include/functional URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/functional?rev=312891&r1=312890&r2=312891&view=diff ============================================================================== --- libcxx/trunk/include/functional (original) +++ libcxx/trunk/include/functional Sun Sep 10 16:37:47 2017 @@ -1597,11 +1597,9 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp( 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( { 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=(n } 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); Modified: libcxx/trunk/include/type_traits URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=312891&r1=312890&r2=312891&view=diff ============================================================================== --- libcxx/trunk/include/type_traits (original) +++ libcxx/trunk/include/type_traits Sun Sep 10 16:37:47 2017 @@ -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> Modified: libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp?rev=312891&r1=312890&r2=312891&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp Sun Sep 10 16:37:47 2017 @@ -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(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits