From: Jonathan Wakely Date: Tue, 3 May 2011 00:03:38 +0000 (+0000) Subject: functional (bind): Remove from overload set when first argument type might be a socke... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f88da8d149befbc51768aa0205af7914bab5ccf;p=gcc.git functional (bind): Remove from overload set when first argument type might be a socket file descriptor. 2011-05-03 Jonathan Wakely * include/std/functional (bind): Remove from overload set when first argument type might be a socket file descriptor. * testsuite/20_util/bind/socket.cc: New. From-SVN: r173279 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 65c9b8f7135..2a3a80f3a1a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2011-05-03 Jonathan Wakely + + * include/std/functional (bind): Remove from overload set when first + argument type might be a socket file descriptor. + * testsuite/20_util/bind/socket.cc: New. + 2011-05-03 Jonathan Wakely PR libstdc++/48848 diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 57ec5062133..f8ea41cc3ee 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1422,39 +1422,58 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) struct is_bind_expression<_Bind_result<_Result, _Signature> > : public true_type { }; - template + // Trait type used to remove std::bind() from overload set via SFINAE + // when first argument has integer type, so that std::bind() will + // not be a better match than ::bind() from the BSD Sockets API. + template + class __is_socketlike + { + typedef typename decay<_Tp>::type _Tp2; + public: + static const bool value = + is_integral<_Tp2>::value || is_enum<_Tp2>::value; + }; + + template struct _Bind_helper { - typedef _Maybe_wrap_member_pointer::type> + typedef _Maybe_wrap_member_pointer::type> __maybe_type; - typedef typename __maybe_type::type __functor_type; - typedef _Bind<__functor_type(typename decay<_ArgTypes>::type...)> type; + typedef typename __maybe_type::type __func_type; + typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; }; + // Partial specialization for is_socketlike == true, does not define + // nested type so std::bind() will not participate in overload resolution + // when the first argument might be a socket file descriptor. + template + struct _Bind_helper + { }; + /** * @brief Function template for std::bind. * @ingroup binders */ - template - inline - typename _Bind_helper<_Functor, _ArgTypes...>::type - bind(_Functor&& __f, _ArgTypes&&... __args) + template + inline typename + _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type + bind(_Func&& __f, _BoundArgs&&... __args) { - typedef _Bind_helper<_Functor, _ArgTypes...> __helper_type; + typedef _Bind_helper __helper_type; typedef typename __helper_type::__maybe_type __maybe_type; typedef typename __helper_type::type __result_type; - return __result_type(__maybe_type::__do_wrap(std::forward<_Functor>(__f)), - std::forward<_ArgTypes>(__args)...); + return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)), + std::forward<_BoundArgs>(__args)...); } - template + template struct _Bindres_helper { - typedef _Maybe_wrap_member_pointer::type> + typedef _Maybe_wrap_member_pointer::type> __maybe_type; typedef typename __maybe_type::type __functor_type; typedef _Bind_result<_Result, - __functor_type(typename decay<_ArgTypes>::type...)> + __functor_type(typename decay<_BoundArgs>::type...)> type; }; @@ -1462,16 +1481,16 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) * @brief Function template for std::bind. * @ingroup binders */ - template + template inline - typename _Bindres_helper<_Result, _Functor, _ArgTypes...>::type - bind(_Functor&& __f, _ArgTypes&&... __args) + typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type + bind(_Func&& __f, _BoundArgs&&... __args) { - typedef _Bindres_helper<_Result, _Functor, _ArgTypes...> __helper_type; + typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type; typedef typename __helper_type::__maybe_type __maybe_type; typedef typename __helper_type::type __result_type; - return __result_type(__maybe_type::__do_wrap(std::forward<_Functor>(__f)), - std::forward<_ArgTypes>(__args)...); + return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)), + std::forward<_BoundArgs>(__args)...); } /** diff --git a/libstdc++-v3/testsuite/20_util/bind/socket.cc b/libstdc++-v3/testsuite/20_util/bind/socket.cc new file mode 100644 index 00000000000..d3ccea2b3eb --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bind/socket.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 20.8.9 Function template bind + +// Verify that calls to bind() in BSD sockets API do not match std::bind() +// (this is a GNU extension) + +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +#include + +struct my_sockaddr { }; +typedef long my_socklen_t; +int bind(int, const my_sockaddr*, my_socklen_t); + +using namespace std; + +int test01() +{ + int fd = 1; + my_sockaddr sa; // N.B. non-const + size_t len = sizeof(sa); // N.B. size_t not socklen_t + return bind(fd, &sa, sizeof(sa)); +} +