From afc449e82cb99424361f95190cec4381e4da11f8 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 3 Nov 2014 02:55:36 +0000 Subject: [PATCH] Check number of arguments in bind expressions. * include/std/functional (_Mem_fn_traits_base::__arity): New typedef. (_Mem_fn_base::_Arity): New typedef. (_Bind_check_arity): New class template. (_Bind_helper, _Bindres_helper, _Bind_simple_helper): Check arity. * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error. From-SVN: r217025 --- libstdc++-v3/ChangeLog | 6 +++++ libstdc++-v3/include/std/functional | 25 +++++++++++++++++++ .../testsuite/20_util/bind/ref_neg.cc | 8 +++--- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 86bc08fe3cc..ac3bc9f0ef5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -9,6 +9,12 @@ (_Mem_fn): Inherit from _Mem_fn_base. * testsuite/20_util/function_objects/mem_fn/refqual.cc: New. + * include/std/functional (_Mem_fn_traits_base::__arity): New typedef. + (_Mem_fn_base::_Arity): New typedef. + (_Bind_check_arity): New class template. + (_Bind_helper, _Bindres_helper, _Bind_simple_helper): Check arity. + * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error. + 2014-10-31 Jonathan Wakely * include/bits/stl_bvector.h (_Bvector_base): Use allocator_traits. diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index ecc5bc98f05..f615ae4ea67 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -515,6 +515,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) using __arg_types = _Pack<_ArgTypes...>; using __maybe_type = _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>; + using __arity = integral_constant; }; template @@ -634,6 +635,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) public: using result_type = typename _Traits::__result_type; + using _Arity = typename _Traits::__arity; private: using _Class = typename _Traits::__class_type; @@ -755,6 +757,8 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) { return (*__ptr).*_M_pm; } public: + using _Arity = integral_constant; + explicit _Mem_fn_base(_Res _Class::*__pm) noexcept : _M_pm(__pm) { } @@ -1485,6 +1489,24 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) struct is_bind_expression> : public true_type { }; + template + struct _Bind_check_arity { }; + + template + struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...> + { + static_assert(sizeof...(_BoundArgs) == sizeof...(_Args), + "Wrong number of arguments for function"); + }; + + template + struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...> + { + using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity; + static_assert(sizeof...(_BoundArgs) == _Arity::value + 1, + "Wrong number of arguments for pointer-to-member"); + }; + // 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. @@ -1493,6 +1515,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template struct _Bind_helper + : _Bind_check_arity::type, _BoundArgs...> { typedef _Maybe_wrap_member_pointer::type> __maybe_type; @@ -1525,6 +1548,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template struct _Bindres_helper + : _Bind_check_arity::type, _BoundArgs...> { typedef _Maybe_wrap_member_pointer::type> __maybe_type; @@ -1599,6 +1623,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) template struct _Bind_simple_helper + : _Bind_check_arity::type, _BoundArgs...> { typedef _Maybe_wrap_member_pointer::type> __maybe_type; diff --git a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc index 6b315c17889..1063dd35d7e 100644 --- a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc +++ b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc @@ -30,10 +30,10 @@ void test01() { const int dummy = 0; std::bind(&inc, _1)(0); // { dg-error "no match" } - // { dg-error "rvalue|const" "" { target *-*-* } 1315 } - // { dg-error "rvalue|const" "" { target *-*-* } 1329 } - // { dg-error "rvalue|const" "" { target *-*-* } 1343 } - // { dg-error "rvalue|const" "" { target *-*-* } 1357 } + // { dg-error "rvalue|const" "" { target *-*-* } 1213 } + // { dg-error "rvalue|const" "" { target *-*-* } 1227 } + // { dg-error "rvalue|const" "" { target *-*-* } 1241 } + // { dg-error "rvalue|const" "" { target *-*-* } 1255 } std::bind(&inc, std::ref(dummy))(); // { dg-error "no match" } } -- 2.30.2