Arcoth created this revision. Herald added a reviewer: EricWF. See https://bugs.llvm.org/show_bug.cgi?id=32856. Basically, as this code was written before placeholder return types for functions were a thing, the function call operators of __bind apply decltype on the call expression to infer the return type. This can lead to hard errors when we pass template functors. Another consequence of this is that the validity or invalidity of these call expressions influences overload resolution (via SFINAE), hence the const version could be selected where the __bind object was non-const, which is not the prescribed behaviour. This is fixed by using placeholder return types.
https://reviews.llvm.org/D32824 Files: include/functional Index: include/functional =================================================================== --- include/functional +++ include/functional @@ -1006,7 +1006,7 @@ { _Predicate __pred_; public: - _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 binary_negate(const _Predicate& __pred) : __pred_(__pred) {} _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY @@ -1793,7 +1793,7 @@ typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF; typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; _Ap __a(__a0); - if (sizeof(_FF) <= sizeof(__buf_) && + if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value) { __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a)); @@ -2254,16 +2254,24 @@ template <class ..._Args> _LIBCPP_INLINE_VISIBILITY +#ifndef __cpp_decltype_auto typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type +#else + decltype(auto) +#endif operator()(_Args&& ...__args) { return __apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); } template <class ..._Args> _LIBCPP_INLINE_VISIBILITY +#ifndef __cpp_decltype_auto typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type +#else + decltype(auto) +#endif operator()(_Args&& ...__args) const { return __apply_functor(__f_, __bound_args_, __indices(),
Index: include/functional =================================================================== --- include/functional +++ include/functional @@ -1006,7 +1006,7 @@ { _Predicate __pred_; public: - _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 binary_negate(const _Predicate& __pred) : __pred_(__pred) {} _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY @@ -1793,7 +1793,7 @@ typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF; typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; _Ap __a(__a0); - if (sizeof(_FF) <= sizeof(__buf_) && + if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value) { __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a)); @@ -2254,16 +2254,24 @@ template <class ..._Args> _LIBCPP_INLINE_VISIBILITY +#ifndef __cpp_decltype_auto typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type +#else + decltype(auto) +#endif operator()(_Args&& ...__args) { return __apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); } template <class ..._Args> _LIBCPP_INLINE_VISIBILITY +#ifndef __cpp_decltype_auto typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type +#else + decltype(auto) +#endif operator()(_Args&& ...__args) const { return __apply_functor(__f_, __bound_args_, __indices(),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits