[PATCH] D32824: [libc++] Use placeholder return types to avoid hard errors during overload resolution

Robert Haberlach via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed May 3 12:46:10 PDT 2017


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(),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32824.97709.patch
Type: text/x-patch
Size: 1741 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170503/859d3c96/attachment.bin>


More information about the cfe-commits mailing list