diff options
-rw-r--r-- | base/bind_internal.h | 94 | ||||
-rw-r--r-- | base/bind_internal.h.pump | 9 | ||||
-rw-r--r-- | base/bind_unittest.cc | 8 |
3 files changed, 72 insertions, 39 deletions
diff --git a/base/bind_internal.h b/base/bind_internal.h index 404b795..7beba51 100644 --- a/base/bind_internal.h +++ b/base/bind_internal.h @@ -14,6 +14,7 @@ #include "base/bind_helpers.h" #include "base/callback_internal.h" +#include "base/memory/raw_scoped_refptr_mismatch_checker.h" #include "base/memory/weak_ptr.h" #include "base/template_util.h" #include "build/build_config.h" @@ -1815,7 +1816,8 @@ class InvokerStorage1 : public InvokerStorageBase { // scoped_refptr check because the binder itself takes care of this. We also // disallow binding of an array as the method's target object. COMPILE_ASSERT(IsMethod::value || - !internal::UnsafeBindtoRefCountedArg<P1>::value, + internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P1>::StorageType>::value == 0, p1_is_refcounted_type_and_needs_scoped_refptr); COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, first_bound_argument_to_method_cannot_be_array); @@ -1862,12 +1864,14 @@ class InvokerStorage2 : public InvokerStorageBase { // scoped_refptr check because the binder itself takes care of this. We also // disallow binding of an array as the method's target object. COMPILE_ASSERT(IsMethod::value || - !internal::UnsafeBindtoRefCountedArg<P1>::value, + internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P1>::StorageType>::value == 0, p1_is_refcounted_type_and_needs_scoped_refptr); COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value, - p2_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P2>::StorageType>::value == 0, + p2_is_refcounted_type_and_needs_scoped_refptr); // Do not allow binding a non-const reference parameter. Non-const reference // parameters are disallowed by the Google style guide. Also, binding a @@ -1915,14 +1919,17 @@ class InvokerStorage3 : public InvokerStorageBase { // scoped_refptr check because the binder itself takes care of this. We also // disallow binding of an array as the method's target object. COMPILE_ASSERT(IsMethod::value || - !internal::UnsafeBindtoRefCountedArg<P1>::value, + internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P1>::StorageType>::value == 0, p1_is_refcounted_type_and_needs_scoped_refptr); COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value, - p3_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P2>::StorageType>::value == 0, + p2_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P3>::StorageType>::value == 0, + p3_is_refcounted_type_and_needs_scoped_refptr); // Do not allow binding a non-const reference parameter. Non-const reference // parameters are disallowed by the Google style guide. Also, binding a @@ -1974,16 +1981,20 @@ class InvokerStorage4 : public InvokerStorageBase { // scoped_refptr check because the binder itself takes care of this. We also // disallow binding of an array as the method's target object. COMPILE_ASSERT(IsMethod::value || - !internal::UnsafeBindtoRefCountedArg<P1>::value, + internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P1>::StorageType>::value == 0, p1_is_refcounted_type_and_needs_scoped_refptr); COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value, - p4_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P2>::StorageType>::value == 0, + p2_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P3>::StorageType>::value == 0, + p3_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P4>::StorageType>::value == 0, + p4_is_refcounted_type_and_needs_scoped_refptr); // Do not allow binding a non-const reference parameter. Non-const reference // parameters are disallowed by the Google style guide. Also, binding a @@ -2040,18 +2051,23 @@ class InvokerStorage5 : public InvokerStorageBase { // scoped_refptr check because the binder itself takes care of this. We also // disallow binding of an array as the method's target object. COMPILE_ASSERT(IsMethod::value || - !internal::UnsafeBindtoRefCountedArg<P1>::value, + internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P1>::StorageType>::value == 0, p1_is_refcounted_type_and_needs_scoped_refptr); COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value, - p4_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value, - p5_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P2>::StorageType>::value == 0, + p2_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P3>::StorageType>::value == 0, + p3_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P4>::StorageType>::value == 0, + p4_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P5>::StorageType>::value == 0, + p5_is_refcounted_type_and_needs_scoped_refptr); // Do not allow binding a non-const reference parameter. Non-const reference // parameters are disallowed by the Google style guide. Also, binding a @@ -2113,20 +2129,26 @@ class InvokerStorage6 : public InvokerStorageBase { // scoped_refptr check because the binder itself takes care of this. We also // disallow binding of an array as the method's target object. COMPILE_ASSERT(IsMethod::value || - !internal::UnsafeBindtoRefCountedArg<P1>::value, + internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P1>::StorageType>::value == 0, p1_is_refcounted_type_and_needs_scoped_refptr); COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value, first_bound_argument_to_method_cannot_be_array); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P2>::value, - p2_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P3>::value, - p3_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P4>::value, - p4_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P5>::value, - p5_is_refcounted_type_and_needs_scoped_refptr); - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P6>::value, - p6_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P2>::StorageType>::value == 0, + p2_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P3>::StorageType>::value == 0, + p3_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P4>::StorageType>::value == 0, + p4_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P5>::StorageType>::value == 0, + p5_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P6>::StorageType>::value == 0, + p6_is_refcounted_type_and_needs_scoped_refptr); // Do not allow binding a non-const reference parameter. Non-const reference // parameters are disallowed by the Google style guide. Also, binding a diff --git a/base/bind_internal.h.pump b/base/bind_internal.h.pump index 532fe3d..429e13f 100644 --- a/base/bind_internal.h.pump +++ b/base/bind_internal.h.pump @@ -17,6 +17,7 @@ $var MAX_ARITY = 6 #include "base/bind_helpers.h" #include "base/callback_internal.h" +#include "base/memory/raw_scoped_refptr_mismatch_checker.h" #include "base/memory/weak_ptr.h" #include "base/template_util.h" #include "build/build_config.h" @@ -334,14 +335,16 @@ $if BOUND_ARG == 1 [[ // scoped_refptr check because the binder itself takes care of this. We also // disallow binding of an array as the method's target object. COMPILE_ASSERT(IsMethod::value || - !internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value, + internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P$(BOUND_ARG)>::StorageType>::value == 0, p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value, first_bound_argument_to_method_cannot_be_array); ]] $else [[ - COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value, - p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); + COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr< + typename ParamTraits<P$(BOUND_ARG)>::StorageType>::value == 0, + p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); ]] $$ $if BOUND_ARG ]] $$ $for BOUND_ARG diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc index 0c24710..648096d 100644 --- a/base/bind_unittest.cc +++ b/base/bind_unittest.cc @@ -15,6 +15,8 @@ using ::testing::StrictMock; namespace base { namespace { +class IncompleteType; + class NoRef { public: NoRef() {} @@ -362,6 +364,7 @@ TEST_F(BindTest, IgnoreReturn) { // - Argument binding to a literal string. // - Argument binding with template function. // - Argument binding to an object. +// - Argument binding to pointer to incomplete type. // - Argument gets type converted. // - Pointer argument gets converted. // - Const Reference forces conversion. @@ -391,6 +394,11 @@ TEST_F(BindTest, ArgumentBinding) { Callback<int(void)> bind_object_cb = Bind(&UnwrapNoRefParent, p); EXPECT_EQ(5, bind_object_cb.Run()); + IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123); + Callback<IncompleteType*(void)> bind_incomplete_ptr_cb = + Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr); + EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run()); + NoRefChild c; c.value = 6; Callback<int(void)> bind_promotes_cb = Bind(&UnwrapNoRefParent, c); |