| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This is a "No Compile Test" suite. | 5 // This is a "No Compile Test" suite. |
| 6 // http://dev.chromium.org/developers/testing/no-compile-tests | 6 // http://dev.chromium.org/developers/testing/no-compile-tests |
| 7 | 7 |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 void VoidMethod0() {} | 22 void VoidMethod0() {} |
| 23 void VoidConstMethod0() const {} | 23 void VoidConstMethod0() const {} |
| 24 int IntMethod0() { return 1; } | 24 int IntMethod0() { return 1; } |
| 25 }; | 25 }; |
| 26 | 26 |
| 27 class HasRef : public NoRef, public base::RefCounted<HasRef> { | 27 class HasRef : public NoRef, public base::RefCounted<HasRef> { |
| 28 }; | 28 }; |
| 29 | 29 |
| 30 class Parent { | 30 class Parent { |
| 31 public: | 31 public: |
| 32 void AddRef(void) const {} | 32 void AddRef() const {} |
| 33 void Release(void) const {} | 33 void Release() const {} |
| 34 virtual void VirtualSet() { value = kParentValue; } | 34 virtual void VirtualSet() { value = kParentValue; } |
| 35 void NonVirtualSet() { value = kParentValue; } | 35 void NonVirtualSet() { value = kParentValue; } |
| 36 int value; | 36 int value; |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 class Child : public Parent { | 39 class Child : public Parent { |
| 40 public: | 40 public: |
| 41 virtual void VirtualSet() { value = kChildValue; } | 41 virtual void VirtualSet() { value = kChildValue; } |
| 42 void NonVirtualSet() { value = kChildValue; } | 42 void NonVirtualSet() { value = kChildValue; } |
| 43 }; | 43 }; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 68 } | 68 } |
| 69 | 69 |
| 70 #if defined(NCTEST_METHOD_ON_CONST_OBJECT) // [r"fatal error: cannot initialize
a parameter of type 'base::NoRef \*' with an lvalue of type 'typename std::enab
le_if<!IsMoveOnlyType<const HasRef \*const>::value, const HasRef \*const>::type'
\(aka 'const base::HasRef \*const'\)"] | 70 #if defined(NCTEST_METHOD_ON_CONST_OBJECT) // [r"fatal error: cannot initialize
a parameter of type 'base::NoRef \*' with an lvalue of type 'typename std::enab
le_if<!IsMoveOnlyType<const HasRef \*const>::value, const HasRef \*const>::type'
\(aka 'const base::HasRef \*const'\)"] |
| 71 | 71 |
| 72 // Method bound to const-object. | 72 // Method bound to const-object. |
| 73 // | 73 // |
| 74 // Only const methods should be allowed to work with const objects. | 74 // Only const methods should be allowed to work with const objects. |
| 75 void WontCompile() { | 75 void WontCompile() { |
| 76 HasRef has_ref; | 76 HasRef has_ref; |
| 77 const HasRef* const_has_ref_ptr_ = &has_ref; | 77 const HasRef* const_has_ref_ptr_ = &has_ref; |
| 78 Callback<void(void)> method_to_const_cb = | 78 Callback<void()> method_to_const_cb = |
| 79 Bind(&HasRef::VoidMethod0, const_has_ref_ptr_); | 79 Bind(&HasRef::VoidMethod0, const_has_ref_ptr_); |
| 80 method_to_const_cb.Run(); | 80 method_to_const_cb.Run(); |
| 81 } | 81 } |
| 82 | 82 |
| 83 #elif defined(NCTEST_METHOD_BIND_NEEDS_REFCOUNTED_OBJECT) // [r"fatal error: no
member named 'AddRef' in 'base::NoRef'"] | 83 #elif defined(NCTEST_METHOD_BIND_NEEDS_REFCOUNTED_OBJECT) // [r"fatal error: no
member named 'AddRef' in 'base::NoRef'"] |
| 84 | 84 |
| 85 // Method bound to non-refcounted object. | 85 // Method bound to non-refcounted object. |
| 86 // | 86 // |
| 87 // We require refcounts unless you have Unretained(). | 87 // We require refcounts unless you have Unretained(). |
| 88 void WontCompile() { | 88 void WontCompile() { |
| 89 NoRef no_ref; | 89 NoRef no_ref; |
| 90 Callback<void(void)> no_ref_cb = | 90 Callback<void()> no_ref_cb = |
| 91 Bind(&NoRef::VoidMethod0, &no_ref); | 91 Bind(&NoRef::VoidMethod0, &no_ref); |
| 92 no_ref_cb.Run(); | 92 no_ref_cb.Run(); |
| 93 } | 93 } |
| 94 | 94 |
| 95 #elif defined(NCTEST_CONST_METHOD_NEEDS_REFCOUNTED_OBJECT) // [r"fatal error: n
o member named 'AddRef' in 'base::NoRef'"] | 95 #elif defined(NCTEST_CONST_METHOD_NEEDS_REFCOUNTED_OBJECT) // [r"fatal error: n
o member named 'AddRef' in 'base::NoRef'"] |
| 96 | 96 |
| 97 // Const Method bound to non-refcounted object. | 97 // Const Method bound to non-refcounted object. |
| 98 // | 98 // |
| 99 // We require refcounts unless you have Unretained(). | 99 // We require refcounts unless you have Unretained(). |
| 100 void WontCompile() { | 100 void WontCompile() { |
| 101 NoRef no_ref; | 101 NoRef no_ref; |
| 102 Callback<void(void)> no_ref_const_cb = | 102 Callback<void()> no_ref_const_cb = |
| 103 Bind(&NoRef::VoidConstMethod0, &no_ref); | 103 Bind(&NoRef::VoidConstMethod0, &no_ref); |
| 104 no_ref_const_cb.Run(); | 104 no_ref_const_cb.Run(); |
| 105 } | 105 } |
| 106 | 106 |
| 107 #elif defined(NCTEST_CONST_POINTER) // [r"fatal error: reference to type 'base:
:NoRef \*const' could not bind to an lvalue of type 'typename std::enable_if<!Is
MoveOnlyType<const NoRef \*const>::value, const NoRef \*const>::type' \(aka 'con
st base::NoRef \*const'\)"] | 107 #elif defined(NCTEST_CONST_POINTER) // [r"fatal error: reference to type 'base:
:NoRef \*const' could not bind to an lvalue of type 'typename std::enable_if<!Is
MoveOnlyType<const NoRef \*const>::value, const NoRef \*const>::type' \(aka 'con
st base::NoRef \*const'\)"] |
| 108 | 108 |
| 109 // Const argument used with non-const pointer parameter of same type. | 109 // Const argument used with non-const pointer parameter of same type. |
| 110 // | 110 // |
| 111 // This is just a const-correctness check. | 111 // This is just a const-correctness check. |
| 112 void WontCompile() { | 112 void WontCompile() { |
| 113 const NoRef* const_no_ref_ptr; | 113 const NoRef* const_no_ref_ptr; |
| 114 Callback<NoRef*(void)> pointer_same_cb = | 114 Callback<NoRef*()> pointer_same_cb = |
| 115 Bind(&PolymorphicIdentity<NoRef*>, const_no_ref_ptr); | 115 Bind(&PolymorphicIdentity<NoRef*>, const_no_ref_ptr); |
| 116 pointer_same_cb.Run(); | 116 pointer_same_cb.Run(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 #elif defined(NCTEST_CONST_POINTER_SUBTYPE) // [r"fatal error: reference to typ
e 'base::NoRefParent \*const' could not bind to an lvalue of type 'typename std:
:enable_if<!IsMoveOnlyType<const NoRefChild \*const>::value, const NoRefChild \*
const>::type' \(aka 'const base::NoRefChild \*const'\)"] | 119 #elif defined(NCTEST_CONST_POINTER_SUBTYPE) // [r"fatal error: reference to typ
e 'base::NoRefParent \*const' could not bind to an lvalue of type 'typename std:
:enable_if<!IsMoveOnlyType<const NoRefChild \*const>::value, const NoRefChild \*
const>::type' \(aka 'const base::NoRefChild \*const'\)"] |
| 120 | 120 |
| 121 // Const argument used with non-const pointer parameter of super type. | 121 // Const argument used with non-const pointer parameter of super type. |
| 122 // | 122 // |
| 123 // This is just a const-correctness check. | 123 // This is just a const-correctness check. |
| 124 void WontCompile() { | 124 void WontCompile() { |
| 125 const NoRefChild* const_child_ptr; | 125 const NoRefChild* const_child_ptr; |
| 126 Callback<NoRefParent*(void)> pointer_super_cb = | 126 Callback<NoRefParent*()> pointer_super_cb = |
| 127 Bind(&PolymorphicIdentity<NoRefParent*>, const_child_ptr); | 127 Bind(&PolymorphicIdentity<NoRefParent*>, const_child_ptr); |
| 128 pointer_super_cb.Run(); | 128 pointer_super_cb.Run(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 #elif defined(DISABLED_NCTEST_DISALLOW_NON_CONST_REF_PARAM) // [r"fatal error:
no member named 'AddRef' in 'base::NoRef'"] | 131 #elif defined(DISABLED_NCTEST_DISALLOW_NON_CONST_REF_PARAM) // [r"fatal error:
no member named 'AddRef' in 'base::NoRef'"] |
| 132 // TODO(dcheng): I think there's a type safety promotion issue here where we can | 132 // TODO(dcheng): I think there's a type safety promotion issue here where we can |
| 133 // pass a const ref to a non const-ref function, or vice versa accidentally. Or | 133 // pass a const ref to a non const-ref function, or vice versa accidentally. Or |
| 134 // we make a copy accidentally. Check. | 134 // we make a copy accidentally. Check. |
| 135 | 135 |
| 136 // Functions with reference parameters, unsupported. | 136 // Functions with reference parameters, unsupported. |
| 137 // | 137 // |
| 138 // First, non-const reference parameters are disallowed by the Google | 138 // First, non-const reference parameters are disallowed by the Google |
| 139 // style guide. Second, since we are doing argument forwarding it becomes | 139 // style guide. Second, since we are doing argument forwarding it becomes |
| 140 // very tricky to avoid copies, maintain const correctness, and not | 140 // very tricky to avoid copies, maintain const correctness, and not |
| 141 // accidentally have the function be modifying a temporary, or a copy. | 141 // accidentally have the function be modifying a temporary, or a copy. |
| 142 void WontCompile() { | 142 void WontCompile() { |
| 143 Parent p; | 143 Parent p; |
| 144 Callback<int(Parent&)> ref_arg_cb = Bind(&UnwrapParentRef); | 144 Callback<int(Parent&)> ref_arg_cb = Bind(&UnwrapParentRef); |
| 145 ref_arg_cb.Run(p); | 145 ref_arg_cb.Run(p); |
| 146 } | 146 } |
| 147 | 147 |
| 148 #elif defined(NCTEST_DISALLOW_BIND_TO_NON_CONST_REF_PARAM) // [r"fatal error: s
tatic_assert failed \"do not bind functions with nonconst ref\""] | 148 #elif defined(NCTEST_DISALLOW_BIND_TO_NON_CONST_REF_PARAM) // [r"fatal error: s
tatic_assert failed \"do not bind functions with nonconst ref\""] |
| 149 | 149 |
| 150 // Binding functions with reference parameters, unsupported. | 150 // Binding functions with reference parameters, unsupported. |
| 151 // | 151 // |
| 152 // See comment in NCTEST_DISALLOW_NON_CONST_REF_PARAM | 152 // See comment in NCTEST_DISALLOW_NON_CONST_REF_PARAM |
| 153 void WontCompile() { | 153 void WontCompile() { |
| 154 Parent p; | 154 Parent p; |
| 155 Callback<int(void)> ref_cb = Bind(&UnwrapParentRef, p); | 155 Callback<int()> ref_cb = Bind(&UnwrapParentRef, p); |
| 156 ref_cb.Run(); | 156 ref_cb.Run(); |
| 157 } | 157 } |
| 158 | 158 |
| 159 #elif defined(NCTEST_NO_IMPLICIT_ARRAY_PTR_CONVERSION) // [r"fatal error: stati
c_assert failed \"first bound argument to method cannot be array\""] | 159 #elif defined(NCTEST_NO_IMPLICIT_ARRAY_PTR_CONVERSION) // [r"fatal error: stati
c_assert failed \"first bound argument to method cannot be array\""] |
| 160 | 160 |
| 161 // A method should not be bindable with an array of objects. | 161 // A method should not be bindable with an array of objects. |
| 162 // | 162 // |
| 163 // This is likely not wanted behavior. We specifically check for it though | 163 // This is likely not wanted behavior. We specifically check for it though |
| 164 // because it is possible, depending on how you implement prebinding, to | 164 // because it is possible, depending on how you implement prebinding, to |
| 165 // implicitly convert an array type to a pointer type. | 165 // implicitly convert an array type to a pointer type. |
| 166 void WontCompile() { | 166 void WontCompile() { |
| 167 HasRef p[10]; | 167 HasRef p[10]; |
| 168 Callback<void(void)> method_bound_to_array_cb = | 168 Callback<void()> method_bound_to_array_cb = |
| 169 Bind(&HasRef::VoidMethod0, p); | 169 Bind(&HasRef::VoidMethod0, p); |
| 170 method_bound_to_array_cb.Run(); | 170 method_bound_to_array_cb.Run(); |
| 171 } | 171 } |
| 172 | 172 |
| 173 #elif defined(NCTEST_NO_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static
_assert failed \"a parameter is a refcounted type and needs scoped_refptr\""] | 173 #elif defined(NCTEST_NO_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static
_assert failed \"a parameter is a refcounted type and needs scoped_refptr\""] |
| 174 | 174 |
| 175 // Refcounted types should not be bound as a raw pointer. | 175 // Refcounted types should not be bound as a raw pointer. |
| 176 void WontCompile() { | 176 void WontCompile() { |
| 177 HasRef for_raw_ptr; | 177 HasRef for_raw_ptr; |
| 178 int a; | 178 int a; |
| 179 Callback<void(void)> ref_count_as_raw_ptr_a = | 179 Callback<void()> ref_count_as_raw_ptr_a = |
| 180 Bind(&VoidPolymorphic1<int*>, &a); | 180 Bind(&VoidPolymorphic1<int*>, &a); |
| 181 Callback<void(void)> ref_count_as_raw_ptr = | 181 Callback<void()> ref_count_as_raw_ptr = |
| 182 Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr); | 182 Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr); |
| 183 } | 183 } |
| 184 | 184 |
| 185 #elif defined(NCTEST_WEAKPTR_BIND_MUST_RETURN_VOID) // [r"fatal error: static_a
ssert failed \"weak_ptrs can only bind to methods without return values\""] | 185 #elif defined(NCTEST_WEAKPTR_BIND_MUST_RETURN_VOID) // [r"fatal error: static_a
ssert failed \"weak_ptrs can only bind to methods without return values\""] |
| 186 | 186 |
| 187 // WeakPtrs cannot be bound to methods with return types. | 187 // WeakPtrs cannot be bound to methods with return types. |
| 188 void WontCompile() { | 188 void WontCompile() { |
| 189 NoRef no_ref; | 189 NoRef no_ref; |
| 190 WeakPtrFactory<NoRef> weak_factory(&no_ref); | 190 WeakPtrFactory<NoRef> weak_factory(&no_ref); |
| 191 Callback<int(void)> weak_ptr_with_non_void_return_type = | 191 Callback<int()> weak_ptr_with_non_void_return_type = |
| 192 Bind(&NoRef::IntMethod0, weak_factory.GetWeakPtr()); | 192 Bind(&NoRef::IntMethod0, weak_factory.GetWeakPtr()); |
| 193 weak_ptr_with_non_void_return_type.Run(); | 193 weak_ptr_with_non_void_return_type.Run(); |
| 194 } | 194 } |
| 195 | 195 |
| 196 #elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES) // [r"fatal error: no via
ble conversion from 'Callback<typename internal::BindState<typename internal::Fu
nctorTraits<void \(\*\)\(int\)>::RunnableType, typename internal::FunctorTraits<
void \(\*\)\(int\)>::RunType>::UnboundRunType>' to 'Callback<void \(\)>'"] | 196 #elif defined(NCTEST_DISALLOW_ASSIGN_DIFFERENT_TYPES) // [r"fatal error: no via
ble conversion from 'Callback<typename internal::BindState<typename internal::Fu
nctorTraits<void \(\*\)\(int\)>::RunnableType, typename internal::FunctorTraits<
void \(\*\)\(int\)>::RunType>::UnboundRunType>' to 'Callback<void \(\)>'"] |
| 197 | 197 |
| 198 // Bind result cannot be assigned to Callbacks with a mismatching type. | 198 // Bind result cannot be assigned to Callbacks with a mismatching type. |
| 199 void WontCompile() { | 199 void WontCompile() { |
| 200 Closure callback_mismatches_bind_type = Bind(&VoidPolymorphic1<int>); | 200 Closure callback_mismatches_bind_type = Bind(&VoidPolymorphic1<int>); |
| 201 } | 201 } |
| 202 | 202 |
| 203 #endif | 203 #endif |
| 204 | 204 |
| 205 } // namespace base | 205 } // namespace base |
| OLD | NEW |