Check number of arguments in bind expressions.
authorJonathan Wakely <jwakely@redhat.com>
Mon, 3 Nov 2014 02:55:36 +0000 (02:55 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 3 Nov 2014 02:55:36 +0000 (02:55 +0000)
* 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
libstdc++-v3/include/std/functional
libstdc++-v3/testsuite/20_util/bind/ref_neg.cc

index 86bc08fe3cce9122a63b8853170442afa00832ec..ac3bc9f0ef556ee7a64e40e2544ab4f51bfe1866 100644 (file)
@@ -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  <jwakely@redhat.com>
 
        * include/bits/stl_bvector.h (_Bvector_base): Use allocator_traits.
index ecc5bc98f05ce1e47ac4a43c416f2440fcc0b0dc..f615ae4ea67cd8d75ab9e6857be0d4319a7c2b82 100644 (file)
@@ -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<size_t, sizeof...(_ArgTypes)>;
     };
 
   template<typename _Res, typename _Class, typename... _ArgTypes>
@@ -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<size_t, 0>;
+
       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<const volatile _Bind_result<_Result, _Signature>>
     : public true_type { };
 
+  template<typename _Func, typename... _BoundArgs>
+    struct _Bind_check_arity { };
+
+  template<typename _Ret, typename... _Args, typename... _BoundArgs>
+    struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...>
+    {
+      static_assert(sizeof...(_BoundArgs) == sizeof...(_Args),
+                   "Wrong number of arguments for function");
+    };
+
+  template<typename _Tp, typename _Class, typename... _BoundArgs>
+    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<bool _SocketLike, typename _Func, typename... _BoundArgs>
     struct _Bind_helper
+    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
     {
       typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
        __maybe_type;
@@ -1525,6 +1548,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
 
   template<typename _Result, typename _Func, typename... _BoundArgs>
     struct _Bindres_helper
+    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
     {
       typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
        __maybe_type;
@@ -1599,6 +1623,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
 
   template<typename _Func, typename... _BoundArgs>
     struct _Bind_simple_helper
+    : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...>
     {
       typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type>
         __maybe_type;
index 6b315c17889126e00176247982df38065f8ef777..1063dd35d7e0752124aae0dbae9afcf417a7cb04 100644 (file)
@@ -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" }
 }