1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/functional/bind.h"
6
7 #include <functional>
8 #include <memory>
9 #include <utility>
10 #include <vector>
11
12 #include "base/allocator/partition_alloc_features.h"
13 #include "base/allocator/partition_alloc_support.h"
14 #include "base/allocator/partition_allocator/dangling_raw_ptr_checks.h"
15 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
16 #include "base/allocator/partition_allocator/partition_alloc_for_testing.h" // nogncheck
17 #include "base/functional/callback.h"
18 #include "base/functional/disallow_unretained.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/memory/raw_ptr.h"
21 #include "base/memory/raw_ref.h"
22 #include "base/memory/ref_counted.h"
23 #include "base/memory/weak_ptr.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/test/bind.h"
26 #include "base/test/gtest_util.h"
27 #include "base/test/scoped_feature_list.h"
28 #include "build/build_config.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31
32 using ::testing::_;
33 using ::testing::AnyNumber;
34 using ::testing::ByMove;
35 using ::testing::Mock;
36 using ::testing::Return;
37 using ::testing::StrictMock;
38
39 namespace base {
40 namespace {
41
42 class AllowsUnretained {};
43
44 class BansUnretained {
45 public:
46 DISALLOW_UNRETAINED();
47 };
48
49 class BansUnretainedInPrivate {
50 DISALLOW_UNRETAINED();
51 };
52
53 class DerivedButBaseBansUnretained : public BansUnretained {};
54
55 static_assert(internal::TypeSupportsUnretainedV<AllowsUnretained>);
56 static_assert(!internal::TypeSupportsUnretainedV<BansUnretained>);
57 static_assert(!internal::TypeSupportsUnretainedV<BansUnretainedInPrivate>);
58 static_assert(!internal::TypeSupportsUnretainedV<DerivedButBaseBansUnretained>);
59
60 class NoRef {
61 public:
62 NoRef() = default;
63 NoRef(const NoRef&) = delete;
64 // Particularly important in this test to ensure no copies are made.
65 NoRef& operator=(const NoRef&) = delete;
66
67 MOCK_METHOD0(VoidMethod0, void());
68 MOCK_CONST_METHOD0(VoidConstMethod0, void());
69
70 MOCK_METHOD0(IntMethod0, int());
71 MOCK_CONST_METHOD0(IntConstMethod0, int());
72
73 MOCK_METHOD1(VoidMethodWithIntArg, void(int));
74 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
75 };
76
77 class HasRef : public NoRef {
78 public:
79 HasRef() = default;
80 HasRef(const HasRef&) = delete;
81 // Particularly important in this test to ensure no copies are made.
82 HasRef& operator=(const HasRef&) = delete;
83
84 MOCK_CONST_METHOD0(AddRef, void());
85 MOCK_CONST_METHOD0(Release, bool());
86 MOCK_CONST_METHOD0(HasAtLeastOneRef, bool());
87 };
88
89 class HasRefPrivateDtor : public HasRef {
90 private:
91 ~HasRefPrivateDtor() = default;
92 };
93
94 static const int kParentValue = 1;
95 static const int kChildValue = 2;
96
97 class Parent {
98 public:
AddRef() const99 void AddRef() const {}
Release() const100 void Release() const {}
HasAtLeastOneRef() const101 bool HasAtLeastOneRef() const { return true; }
VirtualSet()102 virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()103 void NonVirtualSet() { value = kParentValue; }
104 int value;
105 };
106
107 class Child : public Parent {
108 public:
VirtualSet()109 void VirtualSet() override { value = kChildValue; }
NonVirtualSet()110 void NonVirtualSet() { value = kChildValue; }
111 };
112
113 class NoRefParent {
114 public:
VirtualSet()115 virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()116 void NonVirtualSet() { value = kParentValue; }
117 int value;
118 };
119
120 class NoRefChild : public NoRefParent {
VirtualSet()121 void VirtualSet() override { value = kChildValue; }
NonVirtualSet()122 void NonVirtualSet() { value = kChildValue; }
123 };
124
125 // Used for probing the number of copies and moves that occur if a type must be
126 // coerced during argument forwarding in the Run() methods.
127 struct DerivedCopyMoveCounter {
DerivedCopyMoveCounterbase::__anona623ab4c0111::DerivedCopyMoveCounter128 DerivedCopyMoveCounter(int* copies,
129 int* assigns,
130 int* move_constructs,
131 int* move_assigns)
132 : copies_(copies),
133 assigns_(assigns),
134 move_constructs_(move_constructs),
135 move_assigns_(move_assigns) {}
136 raw_ptr<int> copies_;
137 raw_ptr<int> assigns_;
138 raw_ptr<int> move_constructs_;
139 raw_ptr<int> move_assigns_;
140 };
141
142 // Used for probing the number of copies and moves in an argument.
143 class CopyMoveCounter {
144 public:
CopyMoveCounter(int * copies,int * assigns,int * move_constructs,int * move_assigns)145 CopyMoveCounter(int* copies,
146 int* assigns,
147 int* move_constructs,
148 int* move_assigns)
149 : copies_(copies),
150 assigns_(assigns),
151 move_constructs_(move_constructs),
152 move_assigns_(move_assigns) {}
153
CopyMoveCounter(const CopyMoveCounter & other)154 CopyMoveCounter(const CopyMoveCounter& other)
155 : copies_(other.copies_),
156 assigns_(other.assigns_),
157 move_constructs_(other.move_constructs_),
158 move_assigns_(other.move_assigns_) {
159 (*copies_)++;
160 }
161
CopyMoveCounter(CopyMoveCounter && other)162 CopyMoveCounter(CopyMoveCounter&& other)
163 : copies_(other.copies_),
164 assigns_(other.assigns_),
165 move_constructs_(other.move_constructs_),
166 move_assigns_(other.move_assigns_) {
167 (*move_constructs_)++;
168 }
169
170 // Probing for copies from coercion.
CopyMoveCounter(const DerivedCopyMoveCounter & other)171 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
172 : copies_(other.copies_),
173 assigns_(other.assigns_),
174 move_constructs_(other.move_constructs_),
175 move_assigns_(other.move_assigns_) {
176 (*copies_)++;
177 }
178
179 // Probing for moves from coercion.
CopyMoveCounter(DerivedCopyMoveCounter && other)180 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
181 : copies_(other.copies_),
182 assigns_(other.assigns_),
183 move_constructs_(other.move_constructs_),
184 move_assigns_(other.move_assigns_) {
185 (*move_constructs_)++;
186 }
187
operator =(const CopyMoveCounter & rhs)188 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
189 copies_ = rhs.copies_;
190 assigns_ = rhs.assigns_;
191 move_constructs_ = rhs.move_constructs_;
192 move_assigns_ = rhs.move_assigns_;
193
194 (*assigns_)++;
195
196 return *this;
197 }
198
operator =(CopyMoveCounter && rhs)199 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
200 copies_ = rhs.copies_;
201 assigns_ = rhs.assigns_;
202 move_constructs_ = rhs.move_constructs_;
203 move_assigns_ = rhs.move_assigns_;
204
205 (*move_assigns_)++;
206
207 return *this;
208 }
209
copies() const210 int copies() const { return *copies_; }
211
212 private:
213 raw_ptr<int> copies_;
214 raw_ptr<int> assigns_;
215 raw_ptr<int> move_constructs_;
216 raw_ptr<int> move_assigns_;
217 };
218
219 // Used for probing the number of copies in an argument. The instance is a
220 // copyable and non-movable type.
221 class CopyCounter {
222 public:
CopyCounter(int * copies,int * assigns)223 CopyCounter(int* copies, int* assigns)
224 : counter_(copies, assigns, nullptr, nullptr) {}
225 CopyCounter(const CopyCounter& other) = default;
226 CopyCounter& operator=(const CopyCounter& other) = default;
227
CopyCounter(const DerivedCopyMoveCounter & other)228 explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {}
229
copies() const230 int copies() const { return counter_.copies(); }
231
232 private:
233 CopyMoveCounter counter_;
234 };
235
236 // Used for probing the number of moves in an argument. The instance is a
237 // non-copyable and movable type.
238 class MoveCounter {
239 public:
MoveCounter(int * move_constructs,int * move_assigns)240 MoveCounter(int* move_constructs, int* move_assigns)
241 : counter_(nullptr, nullptr, move_constructs, move_assigns) {}
MoveCounter(MoveCounter && other)242 MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {}
operator =(MoveCounter && other)243 MoveCounter& operator=(MoveCounter&& other) {
244 counter_ = std::move(other.counter_);
245 return *this;
246 }
247
MoveCounter(DerivedCopyMoveCounter && other)248 explicit MoveCounter(DerivedCopyMoveCounter&& other)
249 : counter_(std::move(other)) {}
250
251 private:
252 CopyMoveCounter counter_;
253 };
254
255 class DeleteCounter {
256 public:
DeleteCounter(int * deletes)257 explicit DeleteCounter(int* deletes) : deletes_(deletes) {}
258
~DeleteCounter()259 ~DeleteCounter() { (*deletes_)++; }
260
VoidMethod0()261 void VoidMethod0() {}
262
263 private:
264 raw_ptr<int> deletes_;
265 };
266
267 template <typename T>
PassThru(T scoper)268 T PassThru(T scoper) {
269 return scoper;
270 }
271
272 // Some test functions that we can Bind to.
273 template <typename T>
PolymorphicIdentity(T t)274 T PolymorphicIdentity(T t) {
275 return t;
276 }
277
278 template <typename... Ts>
279 struct VoidPolymorphic {
Runbase::__anona623ab4c0111::VoidPolymorphic280 static void Run(Ts... t) {}
281 };
282
Identity(int n)283 int Identity(int n) {
284 return n;
285 }
286
ArrayGet(const int array[],int n)287 int ArrayGet(const int array[], int n) {
288 return array[n];
289 }
290
Sum(int a,int b,int c,int d,int e,int f)291 int Sum(int a, int b, int c, int d, int e, int f) {
292 return a + b + c + d + e + f;
293 }
294
CStringIdentity(const char * s)295 const char* CStringIdentity(const char* s) {
296 return s;
297 }
298
GetCopies(const CopyMoveCounter & counter)299 int GetCopies(const CopyMoveCounter& counter) {
300 return counter.copies();
301 }
302
UnwrapNoRefParent(NoRefParent p)303 int UnwrapNoRefParent(NoRefParent p) {
304 return p.value;
305 }
306
UnwrapNoRefParentPtr(NoRefParent * p)307 int UnwrapNoRefParentPtr(NoRefParent* p) {
308 return p->value;
309 }
310
UnwrapNoRefParentConstRef(const NoRefParent & p)311 int UnwrapNoRefParentConstRef(const NoRefParent& p) {
312 return p.value;
313 }
314
RefArgSet(int & n)315 void RefArgSet(int& n) {
316 n = 2;
317 }
318
PtrArgSet(int * n)319 void PtrArgSet(int* n) {
320 *n = 2;
321 }
322
FunctionWithWeakFirstParam(WeakPtr<NoRef> o,int n)323 int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
324 return n;
325 }
326
FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef> & o,int n)327 int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
328 return n;
329 }
330
TakesACallback(const RepeatingClosure & callback)331 void TakesACallback(const RepeatingClosure& callback) {
332 callback.Run();
333 }
334
Noexcept()335 int Noexcept() noexcept {
336 return 42;
337 }
338
339 class NoexceptFunctor {
340 public:
operator ()()341 int operator()() noexcept { return 42; }
342 };
343
344 class ConstNoexceptFunctor {
345 public:
operator ()()346 int operator()() noexcept { return 42; }
347 };
348
349 class BindTest : public ::testing::Test {
350 public:
BindTest()351 BindTest() {
352 const_has_ref_ptr_ = &has_ref_;
353 const_no_ref_ptr_ = &no_ref_;
354 static_func_mock_ptr = &static_func_mock_;
355 }
356 BindTest(const BindTest&) = delete;
357 BindTest& operator=(const BindTest&) = delete;
358 ~BindTest() override = default;
359
VoidFunc0()360 static void VoidFunc0() { static_func_mock_ptr->VoidMethod0(); }
361
IntFunc0()362 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
NoexceptMethod()363 int NoexceptMethod() noexcept { return 42; }
ConstNoexceptMethod() const364 int ConstNoexceptMethod() const noexcept { return 42; }
365
366 protected:
367 StrictMock<NoRef> no_ref_;
368 StrictMock<HasRef> has_ref_;
369 raw_ptr<const HasRef> const_has_ref_ptr_;
370 raw_ptr<const NoRef> const_no_ref_ptr_;
371 StrictMock<NoRef> static_func_mock_;
372
373 // Used by the static functions to perform expectations.
374 static StrictMock<NoRef>* static_func_mock_ptr;
375 };
376
377 StrictMock<NoRef>* BindTest::static_func_mock_ptr;
378 StrictMock<NoRef>* g_func_mock_ptr;
379
VoidFunc0()380 void VoidFunc0() {
381 g_func_mock_ptr->VoidMethod0();
382 }
383
IntFunc0()384 int IntFunc0() {
385 return g_func_mock_ptr->IntMethod0();
386 }
387
TEST_F(BindTest,BasicTest)388 TEST_F(BindTest, BasicTest) {
389 RepeatingCallback<int(int, int, int)> cb = BindRepeating(&Sum, 32, 16, 8);
390 EXPECT_EQ(92, cb.Run(13, 12, 11));
391
392 RepeatingCallback<int(int, int, int, int, int, int)> c1 = BindRepeating(&Sum);
393 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
394
395 RepeatingCallback<int(int, int, int)> c2 = BindRepeating(c1, 32, 16, 8);
396 EXPECT_EQ(86, c2.Run(11, 10, 9));
397
398 RepeatingCallback<int()> c3 = BindRepeating(c2, 4, 2, 1);
399 EXPECT_EQ(63, c3.Run());
400 }
401
402 // Test that currying the rvalue result of another BindRepeating() works
403 // correctly.
404 // - rvalue should be usable as argument to BindRepeating().
405 // - multiple runs of resulting RepeatingCallback remain valid.
TEST_F(BindTest,CurryingRvalueResultOfBind)406 TEST_F(BindTest, CurryingRvalueResultOfBind) {
407 int n = 0;
408 RepeatingClosure cb =
409 BindRepeating(&TakesACallback, BindRepeating(&PtrArgSet, &n));
410
411 // If we implement BindRepeating() such that the return value has
412 // auto_ptr-like semantics, the second call here will fail because ownership
413 // of the internal BindState<> would have been transferred to a *temporary*
414 // construction of a RepeatingCallback object on the first call.
415 cb.Run();
416 EXPECT_EQ(2, n);
417
418 n = 0;
419 cb.Run();
420 EXPECT_EQ(2, n);
421 }
422
TEST_F(BindTest,RepeatingCallbackBasicTest)423 TEST_F(BindTest, RepeatingCallbackBasicTest) {
424 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
425
426 // RepeatingCallback can run via a lvalue-reference.
427 EXPECT_EQ(63, c0.Run(32));
428
429 // It is valid to call a RepeatingCallback more than once.
430 EXPECT_EQ(54, c0.Run(23));
431
432 // BindRepeating can handle a RepeatingCallback as the target functor.
433 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
434
435 // RepeatingCallback can run via a rvalue-reference.
436 EXPECT_EQ(42, std::move(c1).Run());
437
438 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
439 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
440 }
441
TEST_F(BindTest,OnceCallbackBasicTest)442 TEST_F(BindTest, OnceCallbackBasicTest) {
443 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
444
445 // OnceCallback can run via a rvalue-reference.
446 EXPECT_EQ(63, std::move(c0).Run(32));
447
448 // After running via the rvalue-reference, the value of the OnceCallback
449 // is undefined. The implementation simply clears the instance after the
450 // invocation.
451 EXPECT_TRUE(c0.is_null());
452
453 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
454
455 // BindOnce can handle a rvalue-reference of OnceCallback as the target
456 // functor.
457 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
458 EXPECT_EQ(41, std::move(c1).Run());
459
460 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
461 EXPECT_EQ(41, BindOnce(c2, 13).Run());
462 }
463
464 // IgnoreResult adapter test.
465 // - Function with return value.
466 // - Method with return value.
467 // - Const Method with return.
468 // - Method with return value bound to WeakPtr<>.
469 // - Const Method with return bound to WeakPtr<>.
TEST_F(BindTest,IgnoreResultForRepeating)470 TEST_F(BindTest, IgnoreResultForRepeating) {
471 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
472 EXPECT_CALL(has_ref_, AddRef()).Times(2);
473 EXPECT_CALL(has_ref_, Release()).Times(2);
474 EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
475 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
476 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
477 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
478 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
479
480 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
481 normal_func_cb.Run();
482
483 RepeatingClosure non_void_method_cb =
484 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
485 non_void_method_cb.Run();
486
487 RepeatingClosure non_void_const_method_cb =
488 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
489 non_void_const_method_cb.Run();
490
491 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
492 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
493
494 RepeatingClosure non_void_weak_method_cb = BindRepeating(
495 IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
496 non_void_weak_method_cb.Run();
497
498 RepeatingClosure non_void_weak_const_method_cb = BindRepeating(
499 IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
500 non_void_weak_const_method_cb.Run();
501
502 weak_factory.InvalidateWeakPtrs();
503 non_void_weak_const_method_cb.Run();
504 non_void_weak_method_cb.Run();
505 }
506
TEST_F(BindTest,IgnoreResultForOnce)507 TEST_F(BindTest, IgnoreResultForOnce) {
508 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
509 EXPECT_CALL(has_ref_, AddRef()).Times(2);
510 EXPECT_CALL(has_ref_, Release()).Times(2);
511 EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
512 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
513 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
514
515 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
516 std::move(normal_func_cb).Run();
517
518 OnceClosure non_void_method_cb =
519 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
520 std::move(non_void_method_cb).Run();
521
522 OnceClosure non_void_const_method_cb =
523 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
524 std::move(non_void_const_method_cb).Run();
525
526 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
527 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
528
529 OnceClosure non_void_weak_method_cb =
530 BindOnce(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
531 OnceClosure non_void_weak_const_method_cb = BindOnce(
532 IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
533
534 weak_factory.InvalidateWeakPtrs();
535 std::move(non_void_weak_const_method_cb).Run();
536 std::move(non_void_weak_method_cb).Run();
537 }
538
TEST_F(BindTest,IgnoreResultForRepeatingCallback)539 TEST_F(BindTest, IgnoreResultForRepeatingCallback) {
540 std::string s;
541 RepeatingCallback<int(int)> cb = BindRepeating(
542 [](std::string* s, int i) {
543 *s += "Run" + base::NumberToString(i);
544 return 5;
545 },
546 &s);
547 RepeatingCallback<void(int)> noreturn = BindRepeating(IgnoreResult(cb));
548 noreturn.Run(2);
549 EXPECT_EQ(s, "Run2");
550 }
551
TEST_F(BindTest,IgnoreResultForOnceCallback)552 TEST_F(BindTest, IgnoreResultForOnceCallback) {
553 std::string s;
554 OnceCallback<int(int)> cb = BindOnce(
555 [](std::string* s, int i) {
556 *s += "Run" + base::NumberToString(i);
557 return 5;
558 },
559 &s);
560 OnceCallback<void(int)> noreturn = BindOnce(IgnoreResult(std::move(cb)));
561 std::move(noreturn).Run(2);
562 EXPECT_EQ(s, "Run2");
563 }
564
SetFromRef(int & ref)565 void SetFromRef(int& ref) {
566 EXPECT_EQ(ref, 1);
567 ref = 2;
568 EXPECT_EQ(ref, 2);
569 }
570
TEST_F(BindTest,BindOnceWithNonConstRef)571 TEST_F(BindTest, BindOnceWithNonConstRef) {
572 int v = 1;
573
574 // Mutates `v` because it's not bound to callback instead it's forwarded by
575 // Run().
576 auto cb1 = BindOnce(SetFromRef);
577 std::move(cb1).Run(v);
578 EXPECT_EQ(v, 2);
579 v = 1;
580
581 // Mutates `v` through std::reference_wrapper bound to callback.
582 auto cb2 = BindOnce(SetFromRef, std::ref(v));
583 std::move(cb2).Run();
584 EXPECT_EQ(v, 2);
585 v = 1;
586
587 // Everything past here following will make a copy of the argument. The copy
588 // will be mutated and leave `v` unmodified.
589 auto cb3 = BindOnce(SetFromRef, base::OwnedRef(v));
590 std::move(cb3).Run();
591 EXPECT_EQ(v, 1);
592
593 int& ref = v;
594 auto cb4 = BindOnce(SetFromRef, base::OwnedRef(ref));
595 std::move(cb4).Run();
596 EXPECT_EQ(v, 1);
597
598 const int cv = 1;
599 auto cb5 = BindOnce(SetFromRef, base::OwnedRef(cv));
600 std::move(cb5).Run();
601 EXPECT_EQ(cv, 1);
602
603 const int& cref = v;
604 auto cb6 = BindOnce(SetFromRef, base::OwnedRef(cref));
605 std::move(cb6).Run();
606 EXPECT_EQ(cref, 1);
607
608 auto cb7 = BindOnce(SetFromRef, base::OwnedRef(1));
609 std::move(cb7).Run();
610 }
611
TEST_F(BindTest,BindRepeatingWithNonConstRef)612 TEST_F(BindTest, BindRepeatingWithNonConstRef) {
613 int v = 1;
614
615 // Mutates `v` because it's not bound to callback instead it's forwarded by
616 // Run().
617 auto cb1 = BindRepeating(SetFromRef);
618 std::move(cb1).Run(v);
619 EXPECT_EQ(v, 2);
620 v = 1;
621
622 // Mutates `v` through std::reference_wrapper bound to callback.
623 auto cb2 = BindRepeating(SetFromRef, std::ref(v));
624 std::move(cb2).Run();
625 EXPECT_EQ(v, 2);
626 v = 1;
627
628 // Everything past here following will make a copy of the argument. The copy
629 // will be mutated and leave `v` unmodified.
630 auto cb3 = BindRepeating(SetFromRef, base::OwnedRef(v));
631 std::move(cb3).Run();
632 EXPECT_EQ(v, 1);
633
634 int& ref = v;
635 auto cb4 = BindRepeating(SetFromRef, base::OwnedRef(ref));
636 std::move(cb4).Run();
637 EXPECT_EQ(v, 1);
638
639 const int cv = 1;
640 auto cb5 = BindRepeating(SetFromRef, base::OwnedRef(cv));
641 std::move(cb5).Run();
642 EXPECT_EQ(cv, 1);
643
644 const int& cref = v;
645 auto cb6 = BindRepeating(SetFromRef, base::OwnedRef(cref));
646 std::move(cb6).Run();
647 EXPECT_EQ(cref, 1);
648
649 auto cb7 = BindRepeating(SetFromRef, base::OwnedRef(1));
650 std::move(cb7).Run();
651 }
652
653 // Functions that take reference parameters.
654 // - Forced reference parameter type still stores a copy.
655 // - Forced const reference parameter type still stores a copy.
TEST_F(BindTest,ReferenceArgumentBindingForRepeating)656 TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
657 int n = 1;
658 int& ref_n = n;
659 const int& const_ref_n = n;
660
661 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
662 EXPECT_EQ(n, ref_copies_cb.Run());
663 n++;
664 EXPECT_EQ(n - 1, ref_copies_cb.Run());
665
666 RepeatingCallback<int()> const_ref_copies_cb =
667 BindRepeating(&Identity, const_ref_n);
668 EXPECT_EQ(n, const_ref_copies_cb.Run());
669 n++;
670 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
671 }
672
TEST_F(BindTest,ReferenceArgumentBindingForOnce)673 TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
674 int n = 1;
675 int& ref_n = n;
676 const int& const_ref_n = n;
677
678 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
679 n++;
680 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
681
682 OnceCallback<int()> const_ref_copies_cb = BindOnce(&Identity, const_ref_n);
683 n++;
684 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
685 }
686
687 // Check that we can pass in arrays and have them be stored as a pointer.
688 // - Array of values stores a pointer.
689 // - Array of const values stores a pointer.
TEST_F(BindTest,ArrayArgumentBindingForRepeating)690 TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
691 int array[4] = {1, 1, 1, 1};
692 const int(*const_array_ptr)[4] = &array;
693
694 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
695 EXPECT_EQ(1, array_cb.Run());
696
697 RepeatingCallback<int()> const_array_cb =
698 BindRepeating(&ArrayGet, *const_array_ptr, 1);
699 EXPECT_EQ(1, const_array_cb.Run());
700
701 array[1] = 3;
702 EXPECT_EQ(3, array_cb.Run());
703 EXPECT_EQ(3, const_array_cb.Run());
704 }
705
TEST_F(BindTest,ArrayArgumentBindingForOnce)706 TEST_F(BindTest, ArrayArgumentBindingForOnce) {
707 int array[4] = {1, 1, 1, 1};
708 const int(*const_array_ptr)[4] = &array;
709
710 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
711 OnceCallback<int()> const_array_cb = BindOnce(&ArrayGet, *const_array_ptr, 1);
712
713 array[1] = 3;
714 EXPECT_EQ(3, std::move(array_cb).Run());
715 EXPECT_EQ(3, std::move(const_array_cb).Run());
716 }
717
718 // WeakPtr() support.
719 // - Method bound to WeakPtr<> to non-const object.
720 // - Const method bound to WeakPtr<> to non-const object.
721 // - Const method bound to WeakPtr<> to const object.
722 // - Normal Function with WeakPtr<> as P1 can have return type and is
723 // not canceled.
TEST_F(BindTest,WeakPtrForRepeating)724 TEST_F(BindTest, WeakPtrForRepeating) {
725 EXPECT_CALL(no_ref_, VoidMethod0());
726 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
727
728 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
729 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
730
731 RepeatingClosure method_cb =
732 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
733 method_cb.Run();
734
735 RepeatingClosure const_method_cb =
736 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
737 const_method_cb.Run();
738
739 RepeatingClosure const_method_const_ptr_cb =
740 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
741 const_method_const_ptr_cb.Run();
742
743 RepeatingCallback<int(int)> normal_func_cb =
744 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
745 EXPECT_EQ(1, normal_func_cb.Run(1));
746
747 weak_factory.InvalidateWeakPtrs();
748 const_weak_factory.InvalidateWeakPtrs();
749
750 method_cb.Run();
751 const_method_cb.Run();
752 const_method_const_ptr_cb.Run();
753
754 // Still runs even after the pointers are invalidated.
755 EXPECT_EQ(2, normal_func_cb.Run(2));
756 }
757
TEST_F(BindTest,WeakPtrForOnce)758 TEST_F(BindTest, WeakPtrForOnce) {
759 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
760 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
761
762 OnceClosure method_cb =
763 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
764 OnceClosure const_method_cb =
765 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
766 OnceClosure const_method_const_ptr_cb =
767 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
768 OnceCallback<int(int)> normal_func_cb =
769 BindOnce(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
770
771 weak_factory.InvalidateWeakPtrs();
772 const_weak_factory.InvalidateWeakPtrs();
773
774 std::move(method_cb).Run();
775 std::move(const_method_cb).Run();
776 std::move(const_method_const_ptr_cb).Run();
777
778 // Still runs even after the pointers are invalidated.
779 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
780 }
781
782 // std::cref() wrapper support.
783 // - Binding w/o std::cref takes a copy.
784 // - Binding a std::cref takes a reference.
785 // - Binding std::cref to a function std::cref does not copy on invoke.
TEST_F(BindTest,StdCrefForRepeating)786 TEST_F(BindTest, StdCrefForRepeating) {
787 int n = 1;
788
789 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
790 RepeatingCallback<int()> const_ref_cb =
791 BindRepeating(&Identity, std::cref(n));
792 EXPECT_EQ(n, copy_cb.Run());
793 EXPECT_EQ(n, const_ref_cb.Run());
794 n++;
795 EXPECT_EQ(n - 1, copy_cb.Run());
796 EXPECT_EQ(n, const_ref_cb.Run());
797
798 int copies = 0;
799 int assigns = 0;
800 int move_constructs = 0;
801 int move_assigns = 0;
802 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
803 RepeatingCallback<int()> all_const_ref_cb =
804 BindRepeating(&GetCopies, std::cref(counter));
805 EXPECT_EQ(0, all_const_ref_cb.Run());
806 EXPECT_EQ(0, copies);
807 EXPECT_EQ(0, assigns);
808 EXPECT_EQ(0, move_constructs);
809 EXPECT_EQ(0, move_assigns);
810 }
811
TEST_F(BindTest,StdCrefForOnce)812 TEST_F(BindTest, StdCrefForOnce) {
813 int n = 1;
814
815 OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
816 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, std::cref(n));
817 n++;
818 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
819 EXPECT_EQ(n, std::move(const_ref_cb).Run());
820
821 int copies = 0;
822 int assigns = 0;
823 int move_constructs = 0;
824 int move_assigns = 0;
825 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
826 OnceCallback<int()> all_const_ref_cb =
827 BindOnce(&GetCopies, std::cref(counter));
828 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
829 EXPECT_EQ(0, copies);
830 EXPECT_EQ(0, assigns);
831 EXPECT_EQ(0, move_constructs);
832 EXPECT_EQ(0, move_assigns);
833 }
834
835 // Test Owned() support.
TEST_F(BindTest,OwnedForRepeatingRawPtr)836 TEST_F(BindTest, OwnedForRepeatingRawPtr) {
837 int deletes = 0;
838 DeleteCounter* counter = new DeleteCounter(&deletes);
839
840 // If we don't capture, delete happens on Callback destruction/reset.
841 // return the same value.
842 RepeatingCallback<DeleteCounter*()> no_capture_cb =
843 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
844 ASSERT_EQ(counter, no_capture_cb.Run());
845 ASSERT_EQ(counter, no_capture_cb.Run());
846 EXPECT_EQ(0, deletes);
847 no_capture_cb.Reset(); // This should trigger a delete.
848 EXPECT_EQ(1, deletes);
849
850 deletes = 0;
851 counter = new DeleteCounter(&deletes);
852 RepeatingClosure own_object_cb =
853 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
854 own_object_cb.Run();
855 EXPECT_EQ(0, deletes);
856 own_object_cb.Reset();
857 EXPECT_EQ(1, deletes);
858 }
859
TEST_F(BindTest,OwnedForOnceRawPtr)860 TEST_F(BindTest, OwnedForOnceRawPtr) {
861 int deletes = 0;
862 DeleteCounter* counter = new DeleteCounter(&deletes);
863
864 // If we don't capture, delete happens on Callback destruction/reset.
865 // return the same value.
866 OnceCallback<DeleteCounter*()> no_capture_cb =
867 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
868 EXPECT_EQ(0, deletes);
869 no_capture_cb.Reset(); // This should trigger a delete.
870 EXPECT_EQ(1, deletes);
871
872 deletes = 0;
873 counter = new DeleteCounter(&deletes);
874 OnceClosure own_object_cb =
875 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
876 EXPECT_EQ(0, deletes);
877 own_object_cb.Reset();
878 EXPECT_EQ(1, deletes);
879 }
880
TEST_F(BindTest,OwnedForRepeatingUniquePtr)881 TEST_F(BindTest, OwnedForRepeatingUniquePtr) {
882 int deletes = 0;
883 auto counter = std::make_unique<DeleteCounter>(&deletes);
884 DeleteCounter* raw_counter = counter.get();
885
886 // If we don't capture, delete happens on Callback destruction/reset.
887 // return the same value.
888 RepeatingCallback<DeleteCounter*()> no_capture_cb = BindRepeating(
889 &PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
890 ASSERT_EQ(raw_counter, no_capture_cb.Run());
891 ASSERT_EQ(raw_counter, no_capture_cb.Run());
892 EXPECT_EQ(0, deletes);
893 no_capture_cb.Reset(); // This should trigger a delete.
894 EXPECT_EQ(1, deletes);
895
896 deletes = 0;
897 counter = std::make_unique<DeleteCounter>(&deletes);
898 RepeatingClosure own_object_cb =
899 BindRepeating(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
900 own_object_cb.Run();
901 EXPECT_EQ(0, deletes);
902 own_object_cb.Reset();
903 EXPECT_EQ(1, deletes);
904 }
905
TEST_F(BindTest,OwnedForOnceUniquePtr)906 TEST_F(BindTest, OwnedForOnceUniquePtr) {
907 int deletes = 0;
908 auto counter = std::make_unique<DeleteCounter>(&deletes);
909
910 // If we don't capture, delete happens on Callback destruction/reset.
911 // return the same value.
912 OnceCallback<DeleteCounter*()> no_capture_cb =
913 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
914 EXPECT_EQ(0, deletes);
915 no_capture_cb.Reset(); // This should trigger a delete.
916 EXPECT_EQ(1, deletes);
917
918 deletes = 0;
919 counter = std::make_unique<DeleteCounter>(&deletes);
920 OnceClosure own_object_cb =
921 BindOnce(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
922 EXPECT_EQ(0, deletes);
923 own_object_cb.Reset();
924 EXPECT_EQ(1, deletes);
925 }
926
927 // Tests OwnedRef
TEST_F(BindTest,OwnedRefForCounter)928 TEST_F(BindTest, OwnedRefForCounter) {
929 int counter = 0;
930 RepeatingCallback<int()> counter_callback =
931 BindRepeating([](int& counter) { return ++counter; }, OwnedRef(counter));
932
933 EXPECT_EQ(1, counter_callback.Run());
934 EXPECT_EQ(2, counter_callback.Run());
935 EXPECT_EQ(3, counter_callback.Run());
936 EXPECT_EQ(4, counter_callback.Run());
937
938 EXPECT_EQ(0, counter); // counter should remain unchanged.
939 }
940
TEST_F(BindTest,OwnedRefForIgnoringArguments)941 TEST_F(BindTest, OwnedRefForIgnoringArguments) {
942 OnceCallback<std::string(std::string)> echo_callback =
943 BindOnce([](int& ignore, std::string s) { return s; }, OwnedRef(0));
944
945 EXPECT_EQ("Hello World", std::move(echo_callback).Run("Hello World"));
946 }
947
948 template <typename T>
949 class BindVariantsTest : public ::testing::Test {};
950
951 struct RepeatingTestConfig {
952 template <typename Signature>
953 using CallbackType = RepeatingCallback<Signature>;
954 using ClosureType = RepeatingClosure;
955
956 template <typename F, typename... Args>
Bindbase::__anona623ab4c0111::RepeatingTestConfig957 static CallbackType<internal::MakeUnboundRunType<F, Args...>> Bind(
958 F&& f,
959 Args&&... args) {
960 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
961 }
962 };
963
964 struct OnceTestConfig {
965 template <typename Signature>
966 using CallbackType = OnceCallback<Signature>;
967 using ClosureType = OnceClosure;
968
969 template <typename F, typename... Args>
Bindbase::__anona623ab4c0111::OnceTestConfig970 static CallbackType<internal::MakeUnboundRunType<F, Args...>> Bind(
971 F&& f,
972 Args&&... args) {
973 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
974 }
975 };
976
977 using BindVariantsTestConfig =
978 ::testing::Types<RepeatingTestConfig, OnceTestConfig>;
979 TYPED_TEST_SUITE(BindVariantsTest, BindVariantsTestConfig);
980
981 template <typename TypeParam, typename Signature>
982 using CallbackType = typename TypeParam::template CallbackType<Signature>;
983
984 // Function type support.
985 // - Normal function.
986 // - Normal function bound with non-refcounted first argument.
987 // - Method bound to non-const object.
988 // - Method bound to scoped_refptr.
989 // - Const method bound to non-const object.
990 // - Const method bound to const object.
991 // - Derived classes can be used with pointers to non-virtual base functions.
992 // - Derived classes can be used with pointers to virtual base functions (and
993 // preserve virtual dispatch).
TYPED_TEST(BindVariantsTest,FunctionTypeSupport)994 TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
995 using ClosureType = typename TypeParam::ClosureType;
996
997 StrictMock<HasRef> has_ref;
998 StrictMock<NoRef> no_ref;
999 StrictMock<NoRef> static_func_mock;
1000 const HasRef* const_has_ref_ptr = &has_ref;
1001 g_func_mock_ptr = &static_func_mock;
1002
1003 EXPECT_CALL(static_func_mock, VoidMethod0());
1004 EXPECT_CALL(has_ref, AddRef()).Times(4);
1005 EXPECT_CALL(has_ref, Release()).Times(4);
1006 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1007 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
1008 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
1009
1010 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
1011 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
1012 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
1013 std::move(normal_cb).Run();
1014 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
1015
1016 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
1017 ClosureType method_refptr_cb =
1018 TypeParam::Bind(&HasRef::VoidMethod0, WrapRefCounted(&has_ref));
1019 ClosureType const_method_nonconst_obj_cb =
1020 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
1021 ClosureType const_method_const_obj_cb =
1022 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
1023 std::move(method_cb).Run();
1024 std::move(method_refptr_cb).Run();
1025 std::move(const_method_nonconst_obj_cb).Run();
1026 std::move(const_method_const_obj_cb).Run();
1027
1028 Child child;
1029 child.value = 0;
1030 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
1031 std::move(virtual_set_cb).Run();
1032 EXPECT_EQ(kChildValue, child.value);
1033
1034 child.value = 0;
1035 ClosureType non_virtual_set_cb =
1036 TypeParam::Bind(&Parent::NonVirtualSet, &child);
1037 std::move(non_virtual_set_cb).Run();
1038 EXPECT_EQ(kParentValue, child.value);
1039 }
1040
1041 // Return value support.
1042 // - Function with return value.
1043 // - Method with return value.
1044 // - Const method with return value.
1045 // - Move-only return value.
TYPED_TEST(BindVariantsTest,ReturnValues)1046 TYPED_TEST(BindVariantsTest, ReturnValues) {
1047 StrictMock<NoRef> static_func_mock;
1048 StrictMock<HasRef> has_ref;
1049 g_func_mock_ptr = &static_func_mock;
1050 const HasRef* const_has_ref_ptr = &has_ref;
1051
1052 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
1053 EXPECT_CALL(has_ref, AddRef()).Times(4);
1054 EXPECT_CALL(has_ref, Release()).Times(4);
1055 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1056 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
1057 EXPECT_CALL(has_ref, IntConstMethod0())
1058 .WillOnce(Return(41337))
1059 .WillOnce(Return(51337));
1060 EXPECT_CALL(has_ref, UniquePtrMethod0())
1061 .WillOnce(Return(ByMove(std::make_unique<int>(42))));
1062
1063 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
1064 CallbackType<TypeParam, int()> method_cb =
1065 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
1066 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
1067 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
1068 CallbackType<TypeParam, int()> const_method_const_obj_cb =
1069 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
1070 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
1071 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
1072 EXPECT_EQ(1337, std::move(normal_cb).Run());
1073 EXPECT_EQ(31337, std::move(method_cb).Run());
1074 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
1075 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
1076 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
1077 }
1078
1079 // Argument binding tests.
1080 // - Argument binding to primitive.
1081 // - Argument binding to primitive pointer.
1082 // - Argument binding to a literal integer.
1083 // - Argument binding to a literal string.
1084 // - Argument binding with template function.
1085 // - Argument binding to an object.
1086 // - Argument binding to pointer to incomplete type.
1087 // - Argument gets type converted.
1088 // - Pointer argument gets converted.
1089 // - Const Reference forces conversion.
TYPED_TEST(BindVariantsTest,ArgumentBinding)1090 TYPED_TEST(BindVariantsTest, ArgumentBinding) {
1091 int n = 2;
1092
1093 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
1094 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
1095 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
1096 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
1097 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
1098
1099 NoRefParent p;
1100 p.value = 5;
1101 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
1102
1103 NoRefChild c;
1104 c.value = 6;
1105 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
1106
1107 c.value = 7;
1108 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
1109
1110 c.value = 8;
1111 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
1112 }
1113
1114 // Unbound argument type support tests.
1115 // - Unbound value.
1116 // - Unbound pointer.
1117 // - Unbound reference.
1118 // - Unbound const reference.
1119 // - Unbound unsized array.
1120 // - Unbound sized array.
1121 // - Unbound array-of-arrays.
TYPED_TEST(BindVariantsTest,UnboundArgumentTypeSupport)1122 TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
1123 CallbackType<TypeParam, void(int)> unbound_value_cb =
1124 TypeParam::Bind(&VoidPolymorphic<int>::Run);
1125 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
1126 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
1127 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
1128 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
1129 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
1130 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
1131 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
1132 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
1133 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
1134 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
1135 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
1136 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
1137 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
1138 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
1139 }
1140
1141 // Function with unbound reference parameter.
1142 // - Original parameter is modified by callback.
TYPED_TEST(BindVariantsTest,UnboundReferenceSupport)1143 TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
1144 int n = 0;
1145 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
1146 TypeParam::Bind(&RefArgSet);
1147 std::move(unbound_ref_cb).Run(n);
1148 EXPECT_EQ(2, n);
1149 }
1150
1151 // Unretained() wrapper support.
1152 // - Method bound to Unretained() non-const object.
1153 // - Const method bound to Unretained() non-const object.
1154 // - Const method bound to Unretained() const object.
TYPED_TEST(BindVariantsTest,Unretained)1155 TYPED_TEST(BindVariantsTest, Unretained) {
1156 StrictMock<NoRef> no_ref;
1157 const NoRef* const_no_ref_ptr = &no_ref;
1158
1159 EXPECT_CALL(no_ref, VoidMethod0());
1160 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
1161
1162 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
1163 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
1164 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
1165 }
1166
TYPED_TEST(BindVariantsTest,ScopedRefptr)1167 TYPED_TEST(BindVariantsTest, ScopedRefptr) {
1168 StrictMock<HasRef> has_ref;
1169 EXPECT_CALL(has_ref, AddRef()).Times(1);
1170 EXPECT_CALL(has_ref, Release()).Times(1);
1171 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1172
1173 const scoped_refptr<HasRef> refptr(&has_ref);
1174 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb = TypeParam::Bind(
1175 &FunctionWithScopedRefptrFirstParam, std::cref(refptr), 1);
1176 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
1177 }
1178
TYPED_TEST(BindVariantsTest,UniquePtrReceiver)1179 TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
1180 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
1181 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
1182 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
1183 }
1184
TYPED_TEST(BindVariantsTest,ImplicitRefPtrReceiver)1185 TYPED_TEST(BindVariantsTest, ImplicitRefPtrReceiver) {
1186 StrictMock<HasRef> has_ref;
1187 EXPECT_CALL(has_ref, AddRef()).Times(1);
1188 EXPECT_CALL(has_ref, Release()).Times(1);
1189 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1190
1191 HasRef* ptr = &has_ref;
1192 auto ptr_cb = TypeParam::Bind(&HasRef::HasAtLeastOneRef, ptr);
1193 EXPECT_EQ(1, std::move(ptr_cb).Run());
1194 }
1195
TYPED_TEST(BindVariantsTest,RawPtrReceiver)1196 TYPED_TEST(BindVariantsTest, RawPtrReceiver) {
1197 StrictMock<HasRef> has_ref;
1198 EXPECT_CALL(has_ref, AddRef()).Times(1);
1199 EXPECT_CALL(has_ref, Release()).Times(1);
1200 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1201
1202 raw_ptr<HasRef> rawptr(&has_ref);
1203 auto rawptr_cb = TypeParam::Bind(&HasRef::HasAtLeastOneRef, rawptr);
1204 EXPECT_EQ(1, std::move(rawptr_cb).Run());
1205 }
1206
TYPED_TEST(BindVariantsTest,UnretainedRawRefReceiver)1207 TYPED_TEST(BindVariantsTest, UnretainedRawRefReceiver) {
1208 StrictMock<HasRef> has_ref;
1209 EXPECT_CALL(has_ref, AddRef()).Times(0);
1210 EXPECT_CALL(has_ref, Release()).Times(0);
1211 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1212
1213 raw_ref<HasRef> raw_has_ref(has_ref);
1214 auto has_ref_cb =
1215 TypeParam::Bind(&HasRef::HasAtLeastOneRef, Unretained(raw_has_ref));
1216 EXPECT_EQ(1, std::move(has_ref_cb).Run());
1217
1218 StrictMock<NoRef> no_ref;
1219 EXPECT_CALL(has_ref, IntMethod0()).WillRepeatedly(Return(1));
1220
1221 raw_ref<NoRef> raw_no_ref(has_ref);
1222 auto no_ref_cb = TypeParam::Bind(&NoRef::IntMethod0, Unretained(raw_no_ref));
1223 EXPECT_EQ(1, std::move(no_ref_cb).Run());
1224 }
1225
1226 // Tests for Passed() wrapper support:
1227 // - Passed() can be constructed from a pointer to scoper.
1228 // - Passed() can be constructed from a scoper rvalue.
1229 // - Using Passed() gives Callback Ownership.
1230 // - Ownership is transferred from Callback to callee on the first Run().
1231 // - Callback supports unbound arguments.
1232 template <typename T>
1233 class BindMoveOnlyTypeTest : public ::testing::Test {};
1234
1235 struct CustomDeleter {
operator ()base::__anona623ab4c0111::CustomDeleter1236 void operator()(DeleteCounter* c) { delete c; }
1237 };
1238
1239 using MoveOnlyTypesToTest =
1240 ::testing::Types<std::unique_ptr<DeleteCounter>,
1241 std::unique_ptr<DeleteCounter, CustomDeleter>>;
1242 TYPED_TEST_SUITE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
1243
TYPED_TEST(BindMoveOnlyTypeTest,PassedToBoundCallback)1244 TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
1245 int deletes = 0;
1246
1247 TypeParam ptr(new DeleteCounter(&deletes));
1248 RepeatingCallback<TypeParam()> callback =
1249 BindRepeating(&PassThru<TypeParam>, Passed(&ptr));
1250 EXPECT_FALSE(ptr.get());
1251 EXPECT_EQ(0, deletes);
1252
1253 // If we never invoke the Callback, it retains ownership and deletes.
1254 callback.Reset();
1255 EXPECT_EQ(1, deletes);
1256 }
1257
TYPED_TEST(BindMoveOnlyTypeTest,PassedWithRvalue)1258 TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
1259 int deletes = 0;
1260 RepeatingCallback<TypeParam()> callback = BindRepeating(
1261 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
1262 EXPECT_EQ(0, deletes);
1263
1264 // If we never invoke the Callback, it retains ownership and deletes.
1265 callback.Reset();
1266 EXPECT_EQ(1, deletes);
1267 }
1268
1269 // Check that ownership can be transferred back out.
TYPED_TEST(BindMoveOnlyTypeTest,ReturnMoveOnlyType)1270 TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
1271 int deletes = 0;
1272 DeleteCounter* counter = new DeleteCounter(&deletes);
1273 RepeatingCallback<TypeParam()> callback =
1274 BindRepeating(&PassThru<TypeParam>, Passed(TypeParam(counter)));
1275 TypeParam result = callback.Run();
1276 ASSERT_EQ(counter, result.get());
1277 EXPECT_EQ(0, deletes);
1278
1279 // Resetting does not delete since ownership was transferred.
1280 callback.Reset();
1281 EXPECT_EQ(0, deletes);
1282
1283 // Ensure that we actually did get ownership.
1284 result.reset();
1285 EXPECT_EQ(1, deletes);
1286 }
1287
TYPED_TEST(BindMoveOnlyTypeTest,UnboundForwarding)1288 TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
1289 int deletes = 0;
1290 TypeParam ptr(new DeleteCounter(&deletes));
1291 // Test unbound argument forwarding.
1292 RepeatingCallback<TypeParam(TypeParam)> cb_unbound =
1293 BindRepeating(&PassThru<TypeParam>);
1294 cb_unbound.Run(std::move(ptr));
1295 EXPECT_EQ(1, deletes);
1296 }
1297
VerifyVector(const std::vector<std::unique_ptr<int>> & v)1298 void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
1299 ASSERT_EQ(1u, v.size());
1300 EXPECT_EQ(12345, *v[0]);
1301 }
1302
AcceptAndReturnMoveOnlyVector(std::vector<std::unique_ptr<int>> v)1303 std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
1304 std::vector<std::unique_ptr<int>> v) {
1305 VerifyVector(v);
1306 return v;
1307 }
1308
1309 // Test that a vector containing move-only types can be used with Callback.
TEST_F(BindTest,BindMoveOnlyVector)1310 TEST_F(BindTest, BindMoveOnlyVector) {
1311 using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
1312
1313 MoveOnlyVector v;
1314 v.push_back(std::make_unique<int>(12345));
1315
1316 // Early binding should work:
1317 base::RepeatingCallback<MoveOnlyVector()> bound_cb =
1318 base::BindRepeating(&AcceptAndReturnMoveOnlyVector, Passed(&v));
1319 MoveOnlyVector intermediate_result = bound_cb.Run();
1320 VerifyVector(intermediate_result);
1321
1322 // As should passing it as an argument to Run():
1323 base::RepeatingCallback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
1324 base::BindRepeating(&AcceptAndReturnMoveOnlyVector);
1325 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
1326 VerifyVector(final_result);
1327 }
1328
1329 // Argument copy-constructor usage for non-reference copy-only parameters.
1330 // - Bound arguments are only copied once.
1331 // - Forwarded arguments are only copied once.
1332 // - Forwarded arguments with coercions are only copied twice (once for the
1333 // coercion, and one for the final dispatch).
TEST_F(BindTest,ArgumentCopies)1334 TEST_F(BindTest, ArgumentCopies) {
1335 int copies = 0;
1336 int assigns = 0;
1337
1338 CopyCounter counter(&copies, &assigns);
1339 BindRepeating(&VoidPolymorphic<CopyCounter>::Run, counter);
1340 EXPECT_EQ(1, copies);
1341 EXPECT_EQ(0, assigns);
1342
1343 copies = 0;
1344 assigns = 0;
1345 BindRepeating(&VoidPolymorphic<CopyCounter>::Run,
1346 CopyCounter(&copies, &assigns));
1347 EXPECT_EQ(1, copies);
1348 EXPECT_EQ(0, assigns);
1349
1350 copies = 0;
1351 assigns = 0;
1352 BindRepeating(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
1353 EXPECT_EQ(2, copies);
1354 EXPECT_EQ(0, assigns);
1355
1356 copies = 0;
1357 assigns = 0;
1358 BindRepeating(&VoidPolymorphic<CopyCounter>::Run)
1359 .Run(CopyCounter(&copies, &assigns));
1360 EXPECT_EQ(1, copies);
1361 EXPECT_EQ(0, assigns);
1362
1363 copies = 0;
1364 assigns = 0;
1365 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
1366 BindRepeating(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
1367 EXPECT_EQ(2, copies);
1368 EXPECT_EQ(0, assigns);
1369
1370 copies = 0;
1371 assigns = 0;
1372 BindRepeating(&VoidPolymorphic<CopyCounter>::Run)
1373 .Run(CopyCounter(
1374 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
1375 EXPECT_EQ(2, copies);
1376 EXPECT_EQ(0, assigns);
1377 }
1378
1379 // Argument move-constructor usage for move-only parameters.
1380 // - Bound arguments passed by move are not copied.
TEST_F(BindTest,ArgumentMoves)1381 TEST_F(BindTest, ArgumentMoves) {
1382 int move_constructs = 0;
1383 int move_assigns = 0;
1384
1385 BindRepeating(&VoidPolymorphic<const MoveCounter&>::Run,
1386 MoveCounter(&move_constructs, &move_assigns));
1387 EXPECT_EQ(1, move_constructs);
1388 EXPECT_EQ(0, move_assigns);
1389
1390 // TODO(tzik): Support binding move-only type into a non-reference parameter
1391 // of a variant of Callback.
1392
1393 move_constructs = 0;
1394 move_assigns = 0;
1395 BindRepeating(&VoidPolymorphic<MoveCounter>::Run)
1396 .Run(MoveCounter(&move_constructs, &move_assigns));
1397 EXPECT_EQ(1, move_constructs);
1398 EXPECT_EQ(0, move_assigns);
1399
1400 move_constructs = 0;
1401 move_assigns = 0;
1402 BindRepeating(&VoidPolymorphic<MoveCounter>::Run)
1403 .Run(MoveCounter(DerivedCopyMoveCounter(
1404 nullptr, nullptr, &move_constructs, &move_assigns)));
1405 EXPECT_EQ(2, move_constructs);
1406 EXPECT_EQ(0, move_assigns);
1407 }
1408
1409 // Argument constructor usage for non-reference movable-copyable
1410 // parameters.
1411 // - Bound arguments passed by move are not copied.
1412 // - Forwarded arguments are only copied once.
1413 // - Forwarded arguments with coercions are only copied once and moved once.
TEST_F(BindTest,ArgumentCopiesAndMoves)1414 TEST_F(BindTest, ArgumentCopiesAndMoves) {
1415 int copies = 0;
1416 int assigns = 0;
1417 int move_constructs = 0;
1418 int move_assigns = 0;
1419
1420 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
1421 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
1422 EXPECT_EQ(1, copies);
1423 EXPECT_EQ(0, assigns);
1424 EXPECT_EQ(0, move_constructs);
1425 EXPECT_EQ(0, move_assigns);
1426
1427 copies = 0;
1428 assigns = 0;
1429 move_constructs = 0;
1430 move_assigns = 0;
1431 BindRepeating(
1432 &VoidPolymorphic<CopyMoveCounter>::Run,
1433 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1434 EXPECT_EQ(0, copies);
1435 EXPECT_EQ(0, assigns);
1436 EXPECT_EQ(1, move_constructs);
1437 EXPECT_EQ(0, move_assigns);
1438
1439 copies = 0;
1440 assigns = 0;
1441 move_constructs = 0;
1442 move_assigns = 0;
1443 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter);
1444 EXPECT_EQ(1, copies);
1445 EXPECT_EQ(0, assigns);
1446 EXPECT_EQ(1, move_constructs);
1447 EXPECT_EQ(0, move_assigns);
1448
1449 copies = 0;
1450 assigns = 0;
1451 move_constructs = 0;
1452 move_assigns = 0;
1453 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
1454 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1455 EXPECT_EQ(0, copies);
1456 EXPECT_EQ(0, assigns);
1457 EXPECT_EQ(1, move_constructs);
1458 EXPECT_EQ(0, move_assigns);
1459
1460 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1461 &move_assigns);
1462 copies = 0;
1463 assigns = 0;
1464 move_constructs = 0;
1465 move_assigns = 0;
1466 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
1467 .Run(CopyMoveCounter(derived_counter));
1468 EXPECT_EQ(1, copies);
1469 EXPECT_EQ(0, assigns);
1470 EXPECT_EQ(1, move_constructs);
1471 EXPECT_EQ(0, move_assigns);
1472
1473 copies = 0;
1474 assigns = 0;
1475 move_constructs = 0;
1476 move_assigns = 0;
1477 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
1478 .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1479 &copies, &assigns, &move_constructs, &move_assigns)));
1480 EXPECT_EQ(0, copies);
1481 EXPECT_EQ(0, assigns);
1482 EXPECT_EQ(2, move_constructs);
1483 EXPECT_EQ(0, move_assigns);
1484 }
1485
TEST_F(BindTest,CapturelessLambda)1486 TEST_F(BindTest, CapturelessLambda) {
1487 EXPECT_FALSE(internal::IsCallableObject<void>::value);
1488 EXPECT_FALSE(internal::IsCallableObject<int>::value);
1489 EXPECT_FALSE(internal::IsCallableObject<void (*)()>::value);
1490 EXPECT_FALSE(internal::IsCallableObject<void (NoRef::*)()>::value);
1491
1492 auto f = []() {};
1493 EXPECT_TRUE(internal::IsCallableObject<decltype(f)>::value);
1494
1495 int i = 0;
1496 auto g = [i]() { (void)i; };
1497 EXPECT_TRUE(internal::IsCallableObject<decltype(g)>::value);
1498
1499 auto h = [](int, double) { return 'k'; };
1500 EXPECT_TRUE(
1501 (std::is_same<char(int, double),
1502 internal::ExtractCallableRunType<decltype(h)>>::value));
1503
1504 EXPECT_EQ(42, BindRepeating([] { return 42; }).Run());
1505 EXPECT_EQ(42, BindRepeating([](int i) { return i * 7; }, 6).Run());
1506
1507 int x = 1;
1508 base::RepeatingCallback<void(int)> cb =
1509 BindRepeating([](int* x, int i) { *x *= i; }, Unretained(&x));
1510 cb.Run(6);
1511 EXPECT_EQ(6, x);
1512 cb.Run(7);
1513 EXPECT_EQ(42, x);
1514 }
1515
TEST_F(BindTest,EmptyFunctor)1516 TEST_F(BindTest, EmptyFunctor) {
1517 struct NonEmptyFunctor {
1518 int operator()() const { return x; }
1519 int x = 42;
1520 };
1521
1522 struct EmptyFunctor {
1523 int operator()() { return 42; }
1524 };
1525
1526 struct EmptyFunctorConst {
1527 int operator()() const { return 42; }
1528 };
1529
1530 EXPECT_TRUE(internal::IsCallableObject<NonEmptyFunctor>::value);
1531 EXPECT_TRUE(internal::IsCallableObject<EmptyFunctor>::value);
1532 EXPECT_TRUE(internal::IsCallableObject<EmptyFunctorConst>::value);
1533 EXPECT_EQ(42, BindOnce(EmptyFunctor()).Run());
1534 EXPECT_EQ(42, BindOnce(EmptyFunctorConst()).Run());
1535 EXPECT_EQ(42, BindRepeating(EmptyFunctorConst()).Run());
1536 }
1537
TEST_F(BindTest,CapturingLambdaForTesting)1538 TEST_F(BindTest, CapturingLambdaForTesting) {
1539 // Test copyable lambdas.
1540 int x = 6;
1541 EXPECT_EQ(42, BindLambdaForTesting([=](int y) { return x * y; }).Run(7));
1542 EXPECT_EQ(42,
1543 BindLambdaForTesting([=](int y) mutable { return x *= y; }).Run(7));
1544 auto f = [x](std::unique_ptr<int> y) { return x * *y; };
1545 EXPECT_EQ(42, BindLambdaForTesting(f).Run(std::make_unique<int>(7)));
1546
1547 // Test move-only lambdas.
1548 auto y = std::make_unique<int>(7);
1549 auto g = [y = std::move(y)](int& x) mutable {
1550 return x * *std::exchange(y, nullptr);
1551 };
1552 EXPECT_EQ(42, BindLambdaForTesting(std::move(g)).Run(x));
1553
1554 y = std::make_unique<int>(7);
1555 auto h = [x, y = std::move(y)] { return x * *y; };
1556 EXPECT_EQ(42, BindLambdaForTesting(std::move(h)).Run());
1557 }
1558
TEST_F(BindTest,Cancellation)1559 TEST_F(BindTest, Cancellation) {
1560 EXPECT_CALL(no_ref_, VoidMethodWithIntArg(_)).Times(2);
1561
1562 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
1563 RepeatingCallback<void(int)> cb =
1564 BindRepeating(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1565 RepeatingClosure cb2 = BindRepeating(cb, 8);
1566 OnceClosure cb3 = BindOnce(cb, 8);
1567
1568 OnceCallback<void(int)> cb4 =
1569 BindOnce(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1570 EXPECT_FALSE(cb4.IsCancelled());
1571
1572 OnceClosure cb5 = BindOnce(std::move(cb4), 8);
1573
1574 EXPECT_FALSE(cb.IsCancelled());
1575 EXPECT_FALSE(cb2.IsCancelled());
1576 EXPECT_FALSE(cb3.IsCancelled());
1577 EXPECT_FALSE(cb5.IsCancelled());
1578
1579 cb.Run(6);
1580 cb2.Run();
1581
1582 weak_factory.InvalidateWeakPtrs();
1583
1584 EXPECT_TRUE(cb.IsCancelled());
1585 EXPECT_TRUE(cb2.IsCancelled());
1586 EXPECT_TRUE(cb3.IsCancelled());
1587 EXPECT_TRUE(cb5.IsCancelled());
1588
1589 cb.Run(6);
1590 cb2.Run();
1591 std::move(cb3).Run();
1592 std::move(cb5).Run();
1593 }
1594
TEST_F(BindTest,OnceCallback)1595 TEST_F(BindTest, OnceCallback) {
1596 // Check if Callback variants have declarations of conversions as expected.
1597 // Copy constructor and assignment of RepeatingCallback.
1598 static_assert(
1599 std::is_constructible<RepeatingClosure, const RepeatingClosure&>::value,
1600 "RepeatingClosure should be copyable.");
1601 static_assert(
1602 std::is_assignable<RepeatingClosure, const RepeatingClosure&>::value,
1603 "RepeatingClosure should be copy-assignable.");
1604
1605 // Move constructor and assignment of RepeatingCallback.
1606 static_assert(
1607 std::is_constructible<RepeatingClosure, RepeatingClosure&&>::value,
1608 "RepeatingClosure should be movable.");
1609 static_assert(std::is_assignable<RepeatingClosure, RepeatingClosure&&>::value,
1610 "RepeatingClosure should be move-assignable");
1611
1612 // Conversions from OnceCallback to RepeatingCallback.
1613 static_assert(
1614 !std::is_constructible<RepeatingClosure, const OnceClosure&>::value,
1615 "OnceClosure should not be convertible to RepeatingClosure.");
1616 static_assert(
1617 !std::is_assignable<RepeatingClosure, const OnceClosure&>::value,
1618 "OnceClosure should not be convertible to RepeatingClosure.");
1619
1620 // Destructive conversions from OnceCallback to RepeatingCallback.
1621 static_assert(!std::is_constructible<RepeatingClosure, OnceClosure&&>::value,
1622 "OnceClosure should not be convertible to RepeatingClosure.");
1623 static_assert(!std::is_assignable<RepeatingClosure, OnceClosure&&>::value,
1624 "OnceClosure should not be convertible to RepeatingClosure.");
1625
1626 // Copy constructor and assignment of OnceCallback.
1627 static_assert(!std::is_constructible<OnceClosure, const OnceClosure&>::value,
1628 "OnceClosure should not be copyable.");
1629 static_assert(!std::is_assignable<OnceClosure, const OnceClosure&>::value,
1630 "OnceClosure should not be copy-assignable");
1631
1632 // Move constructor and assignment of OnceCallback.
1633 static_assert(std::is_constructible<OnceClosure, OnceClosure&&>::value,
1634 "OnceClosure should be movable.");
1635 static_assert(std::is_assignable<OnceClosure, OnceClosure&&>::value,
1636 "OnceClosure should be move-assignable.");
1637
1638 // Conversions from RepeatingCallback to OnceCallback.
1639 static_assert(
1640 std::is_constructible<OnceClosure, const RepeatingClosure&>::value,
1641 "RepeatingClosure should be convertible to OnceClosure.");
1642 static_assert(std::is_assignable<OnceClosure, const RepeatingClosure&>::value,
1643 "RepeatingClosure should be convertible to OnceClosure.");
1644
1645 // Destructive conversions from RepeatingCallback to OnceCallback.
1646 static_assert(std::is_constructible<OnceClosure, RepeatingClosure&&>::value,
1647 "RepeatingClosure should be convertible to OnceClosure.");
1648 static_assert(std::is_assignable<OnceClosure, RepeatingClosure&&>::value,
1649 "RepeatingClosure should be covretible to OnceClosure.");
1650
1651 OnceClosure cb = BindOnce(&VoidPolymorphic<>::Run);
1652 std::move(cb).Run();
1653
1654 // RepeatingCallback should be convertible to OnceCallback.
1655 OnceClosure cb2 = BindRepeating(&VoidPolymorphic<>::Run);
1656 std::move(cb2).Run();
1657
1658 RepeatingClosure cb3 = BindRepeating(&VoidPolymorphic<>::Run);
1659 cb = cb3;
1660 std::move(cb).Run();
1661
1662 cb = std::move(cb2);
1663
1664 OnceCallback<void(int)> cb4 =
1665 BindOnce(&VoidPolymorphic<std::unique_ptr<int>, int>::Run,
1666 std::make_unique<int>(0));
1667 BindOnce(std::move(cb4), 1).Run();
1668 }
1669
1670 // Callback construction and assignment tests.
1671 // - Construction from an InvokerStorageHolder should not cause ref/deref.
1672 // - Assignment from other callback should only cause one ref
1673 //
1674 // TODO(ajwong): Is there actually a way to test this?
1675
1676 #if BUILDFLAG(IS_WIN)
FastCallFunc(int n)1677 int __fastcall FastCallFunc(int n) {
1678 return n;
1679 }
1680
StdCallFunc(int n)1681 int __stdcall StdCallFunc(int n) {
1682 return n;
1683 }
1684
1685 // Windows specific calling convention support.
1686 // - Can bind a __fastcall function.
1687 // - Can bind a __stdcall function.
1688 // - Can bind const and non-const __stdcall methods.
TEST_F(BindTest,WindowsCallingConventions)1689 TEST_F(BindTest, WindowsCallingConventions) {
1690 auto fastcall_cb = BindRepeating(&FastCallFunc, 1);
1691 EXPECT_EQ(1, fastcall_cb.Run());
1692
1693 auto stdcall_cb = BindRepeating(&StdCallFunc, 2);
1694 EXPECT_EQ(2, stdcall_cb.Run());
1695
1696 class MethodHolder {
1697 public:
1698 int __stdcall Func(int n) { return n; }
1699 int __stdcall ConstFunc(int n) const { return -n; }
1700 };
1701
1702 MethodHolder obj;
1703 auto stdcall_method_cb =
1704 BindRepeating(&MethodHolder::Func, base::Unretained(&obj), 1);
1705 EXPECT_EQ(1, stdcall_method_cb.Run());
1706
1707 const MethodHolder const_obj;
1708 auto stdcall_const_method_cb =
1709 BindRepeating(&MethodHolder::ConstFunc, base::Unretained(&const_obj), 1);
1710 EXPECT_EQ(-1, stdcall_const_method_cb.Run());
1711 }
1712 #endif
1713
1714 // Test unwrapping the various wrapping functions.
1715
TEST_F(BindTest,UnwrapUnretained)1716 TEST_F(BindTest, UnwrapUnretained) {
1717 int i = 0;
1718 auto unretained = Unretained(&i);
1719 EXPECT_EQ(&i, internal::Unwrap(unretained));
1720 EXPECT_EQ(&i, internal::Unwrap(std::move(unretained)));
1721 }
1722
TEST_F(BindTest,UnwrapRetainedRef)1723 TEST_F(BindTest, UnwrapRetainedRef) {
1724 auto p = MakeRefCounted<RefCountedData<int>>();
1725 auto retained_ref = RetainedRef(p);
1726 EXPECT_EQ(p.get(), internal::Unwrap(retained_ref));
1727 EXPECT_EQ(p.get(), internal::Unwrap(std::move(retained_ref)));
1728 }
1729
TEST_F(BindTest,UnwrapOwned)1730 TEST_F(BindTest, UnwrapOwned) {
1731 {
1732 int* p = new int;
1733 auto owned = Owned(p);
1734 EXPECT_EQ(p, internal::Unwrap(owned));
1735 EXPECT_EQ(p, internal::Unwrap(std::move(owned)));
1736 }
1737
1738 {
1739 auto p = std::make_unique<int>();
1740 int* raw_p = p.get();
1741 auto owned = Owned(std::move(p));
1742 EXPECT_EQ(raw_p, internal::Unwrap(owned));
1743 EXPECT_EQ(raw_p, internal::Unwrap(std::move(owned)));
1744 }
1745 }
1746
TEST_F(BindTest,UnwrapPassed)1747 TEST_F(BindTest, UnwrapPassed) {
1748 int* p = new int;
1749 auto passed = Passed(WrapUnique(p));
1750 EXPECT_EQ(p, internal::Unwrap(passed).get());
1751
1752 p = new int;
1753 EXPECT_EQ(p, internal::Unwrap(Passed(WrapUnique(p))).get());
1754 }
1755
TEST_F(BindTest,BindNoexcept)1756 TEST_F(BindTest, BindNoexcept) {
1757 EXPECT_EQ(42, base::BindOnce(&Noexcept).Run());
1758 EXPECT_EQ(
1759 42,
1760 base::BindOnce(&BindTest::NoexceptMethod, base::Unretained(this)).Run());
1761 EXPECT_EQ(
1762 42, base::BindOnce(&BindTest::ConstNoexceptMethod, base::Unretained(this))
1763 .Run());
1764 EXPECT_EQ(42, base::BindOnce(NoexceptFunctor()).Run());
1765 EXPECT_EQ(42, base::BindOnce(ConstNoexceptFunctor()).Run());
1766 }
1767
PingPong(int * i_ptr)1768 int PingPong(int* i_ptr) {
1769 return *i_ptr;
1770 }
1771
TEST_F(BindTest,BindAndCallbacks)1772 TEST_F(BindTest, BindAndCallbacks) {
1773 int i = 123;
1774 raw_ptr<int> p = &i;
1775
1776 auto callback = base::BindOnce(PingPong, base::Unretained(p));
1777 int res = std::move(callback).Run();
1778 EXPECT_EQ(123, res);
1779 }
1780
1781 } // namespace
1782
1783 // This simulates a race weak pointer that, unlike our `base::WeakPtr<>`,
1784 // may become invalidated between `operator bool()` is tested and `Lock()`
1785 // is called in the implementation of `Unwrap()`.
1786 template <typename T>
1787 struct MockRacyWeakPtr {
MockRacyWeakPtrbase::MockRacyWeakPtr1788 explicit MockRacyWeakPtr(T*) {}
Lockbase::MockRacyWeakPtr1789 T* Lock() const { return nullptr; }
1790
operator boolbase::MockRacyWeakPtr1791 explicit operator bool() const { return true; }
1792 };
1793
1794 template <typename T>
1795 struct IsWeakReceiver<MockRacyWeakPtr<T>> : std::true_type {};
1796
1797 template <typename T>
1798 struct BindUnwrapTraits<MockRacyWeakPtr<T>> {
Unwrapbase::BindUnwrapTraits1799 static T* Unwrap(const MockRacyWeakPtr<T>& o) { return o.Lock(); }
1800 };
1801
1802 template <typename T>
1803 struct MaybeValidTraits<MockRacyWeakPtr<T>> {
MaybeValidbase::MaybeValidTraits1804 static bool MaybeValid(const MockRacyWeakPtr<T>& o) { return true; }
1805 };
1806
1807 namespace {
1808
1809 // Note this only covers a case of racy weak pointer invalidation. Other
1810 // weak pointer scenarios (such as a valid pointer) are covered
1811 // in BindTest.WeakPtrFor{Once,Repeating}.
TEST_F(BindTest,BindRacyWeakPtrTest)1812 TEST_F(BindTest, BindRacyWeakPtrTest) {
1813 MockRacyWeakPtr<NoRef> weak(&no_ref_);
1814
1815 RepeatingClosure cb = base::BindRepeating(&NoRef::VoidMethod0, weak);
1816 cb.Run();
1817 }
1818
1819 // Test null callbacks cause a DCHECK.
TEST(BindDeathTest,NullCallback)1820 TEST(BindDeathTest, NullCallback) {
1821 base::RepeatingCallback<void(int)> null_cb;
1822 ASSERT_TRUE(null_cb.is_null());
1823 EXPECT_CHECK_DEATH(base::BindRepeating(null_cb, 42));
1824 }
1825
TEST(BindDeathTest,NullFunctionPointer)1826 TEST(BindDeathTest, NullFunctionPointer) {
1827 void (*null_function)(int) = nullptr;
1828 EXPECT_DCHECK_DEATH(base::BindRepeating(null_function, 42));
1829 }
1830
TEST(BindDeathTest,NullCallbackWithoutBoundArgs)1831 TEST(BindDeathTest, NullCallbackWithoutBoundArgs) {
1832 base::OnceCallback<void(int)> null_cb;
1833 ASSERT_TRUE(null_cb.is_null());
1834 EXPECT_CHECK_DEATH(base::BindOnce(std::move(null_cb)));
1835 }
1836
TEST(BindDeathTest,BanFirstOwnerOfRefCountedType)1837 TEST(BindDeathTest, BanFirstOwnerOfRefCountedType) {
1838 StrictMock<HasRef> has_ref;
1839 EXPECT_DCHECK_DEATH({
1840 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillOnce(Return(false));
1841 base::BindOnce(&HasRef::VoidMethod0, &has_ref);
1842 });
1843
1844 EXPECT_DCHECK_DEATH({
1845 raw_ptr<HasRef> rawptr(&has_ref);
1846 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillOnce(Return(false));
1847 base::BindOnce(&HasRef::VoidMethod0, rawptr);
1848 });
1849 }
1850
1851 #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
1852
HandleOOM(size_t unused_size)1853 void HandleOOM(size_t unused_size) {
1854 LOG(FATAL) << "Out of memory";
1855 }
1856
1857 // Basic set of options to mostly only enable `BackupRefPtr::kEnabled`.
1858 // This avoids the boilerplate of having too much options enabled for simple
1859 // testing purpose.
1860 static constexpr partition_alloc::PartitionOptions
1861 kOnlyEnableBackupRefPtrOptions = {
1862 partition_alloc::PartitionOptions::AlignedAlloc::kDisallowed,
1863 partition_alloc::PartitionOptions::ThreadCache::kDisabled,
1864 partition_alloc::PartitionOptions::Quarantine::kDisallowed,
1865 partition_alloc::PartitionOptions::Cookie::kAllowed,
1866 partition_alloc::PartitionOptions::BackupRefPtr::kEnabled,
1867 partition_alloc::PartitionOptions::BackupRefPtrZapping::kEnabled,
1868 partition_alloc::PartitionOptions::UseConfigurablePool::kNo,
1869 };
1870
1871 class BindUnretainedDanglingInternalFixture : public BindTest {
1872 public:
SetUp()1873 void SetUp() override {
1874 partition_alloc::PartitionAllocGlobalInit(HandleOOM);
1875 enabled_feature_list_.InitWithFeaturesAndParameters(
1876 {{features::kPartitionAllocUnretainedDanglingPtr, {{"mode", "crash"}}}},
1877 {/* disabled_features */});
1878 allocator::InstallUnretainedDanglingRawPtrChecks();
1879 }
1880
TearDown()1881 void TearDown() override {
1882 enabled_feature_list_.Reset();
1883 allocator::InstallUnretainedDanglingRawPtrChecks();
1884 }
1885
1886 // In unit tests, allocations being tested need to live in a separate PA
1887 // root so the test code doesn't interfere with various counters. Following
1888 // methods are helpers for managing allocations inside the separate allocator
1889 // root.
1890 template <typename T,
1891 RawPtrTraits Traits = RawPtrTraits::kEmpty,
1892 typename... Args>
Alloc(Args &&...args)1893 raw_ptr<T, Traits> Alloc(Args&&... args) {
1894 void* ptr = allocator_.root()->Alloc(sizeof(T), "");
1895 T* p = new (reinterpret_cast<T*>(ptr)) T(std::forward<Args>(args)...);
1896 return raw_ptr<T, Traits>(p);
1897 }
1898 template <typename T, RawPtrTraits Traits>
Free(raw_ptr<T,Traits> & ptr)1899 void Free(raw_ptr<T, Traits>& ptr) {
1900 allocator_.root()->Free(ptr);
1901 }
1902
1903 private:
1904 test::ScopedFeatureList enabled_feature_list_;
1905 partition_alloc::PartitionAllocatorForTesting allocator_{
1906 kOnlyEnableBackupRefPtrOptions};
1907 };
1908
1909 class BindUnretainedDanglingTest
1910 : public BindUnretainedDanglingInternalFixture {};
1911 class BindUnretainedDanglingDeathTest
1912 : public BindUnretainedDanglingInternalFixture {};
1913
PtrCheckFn(int * p)1914 bool PtrCheckFn(int* p) {
1915 return p != nullptr;
1916 }
1917
RefCheckFn(const int & p)1918 bool RefCheckFn(const int& p) {
1919 return true;
1920 }
1921
MayBeDanglingCheckFn(MayBeDangling<int> p)1922 bool MayBeDanglingCheckFn(MayBeDangling<int> p) {
1923 return p != nullptr;
1924 }
1925
MayBeDanglingAndDummyTraitCheckFn(MayBeDangling<int,RawPtrTraits::kDummyForTest> p)1926 bool MayBeDanglingAndDummyTraitCheckFn(
1927 MayBeDangling<int, RawPtrTraits::kDummyForTest> p) {
1928 return p != nullptr;
1929 }
1930
1931 class ClassWithWeakPtr {
1932 public:
1933 ClassWithWeakPtr() = default;
RawPtrArg(int * p)1934 void RawPtrArg(int* p) { *p = 123; }
RawRefArg(int & p)1935 void RawRefArg(int& p) { p = 123; }
GetWeakPtr()1936 WeakPtr<ClassWithWeakPtr> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
1937
1938 private:
1939 WeakPtrFactory<ClassWithWeakPtr> weak_factory_{this};
1940 };
1941
TEST_F(BindUnretainedDanglingTest,UnretainedNoDanglingPtr)1942 TEST_F(BindUnretainedDanglingTest, UnretainedNoDanglingPtr) {
1943 raw_ptr<int> p = Alloc<int>(3);
1944 auto callback = base::BindOnce(PingPong, base::Unretained(p));
1945 EXPECT_EQ(std::move(callback).Run(), 3);
1946 Free(p);
1947 }
1948
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtr)1949 TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtr) {
1950 raw_ptr<int> p = Alloc<int>(3);
1951 auto callback = base::BindOnce(MayBeDanglingCheckFn, base::UnsafeDangling(p));
1952 Free(p);
1953 EXPECT_EQ(std::move(callback).Run(), true);
1954 }
1955
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtrWithDummyTrait)1956 TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtrWithDummyTrait) {
1957 raw_ptr<int, RawPtrTraits::kDummyForTest> p =
1958 Alloc<int, RawPtrTraits::kDummyForTest>(3);
1959 auto callback = base::BindOnce(MayBeDanglingAndDummyTraitCheckFn,
1960 base::UnsafeDangling(p));
1961 Free(p);
1962 EXPECT_EQ(std::move(callback).Run(), true);
1963 }
1964
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtrWithDummyAndDanglingTraits)1965 TEST_F(BindUnretainedDanglingTest,
1966 UnsafeDanglingPtrWithDummyAndDanglingTraits) {
1967 raw_ptr<int, RawPtrTraits::kDummyForTest | RawPtrTraits::kMayDangle> p =
1968 Alloc<int, RawPtrTraits::kDummyForTest | RawPtrTraits::kMayDangle>(3);
1969 auto callback = base::BindOnce(MayBeDanglingAndDummyTraitCheckFn,
1970 base::UnsafeDangling(p));
1971 Free(p);
1972 EXPECT_EQ(std::move(callback).Run(), true);
1973 }
1974
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtrNoRawPtrReceiver)1975 TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtrNoRawPtrReceiver) {
1976 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
1977 int val = 0;
1978 auto callback =
1979 base::BindOnce(&ClassWithWeakPtr::RawPtrArg,
1980 base::UnsafeDangling(r.get()), base::Unretained(&val));
1981 std::move(callback).Run();
1982 EXPECT_EQ(val, 123);
1983 }
1984
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingUntriagedPtr)1985 TEST_F(BindUnretainedDanglingTest, UnsafeDanglingUntriagedPtr) {
1986 raw_ptr<int> p = Alloc<int>(3);
1987 auto callback = base::BindOnce(PtrCheckFn, base::UnsafeDanglingUntriaged(p));
1988 Free(p);
1989 EXPECT_EQ(std::move(callback).Run(), true);
1990 }
1991
TEST_F(BindUnretainedDanglingTest,UnretainedWeakReceiverValidNoDangling)1992 TEST_F(BindUnretainedDanglingTest, UnretainedWeakReceiverValidNoDangling) {
1993 raw_ptr<int> p = Alloc<int>(3);
1994 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
1995 auto callback = base::BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(),
1996 base::Unretained(p));
1997 std::move(callback).Run();
1998 EXPECT_EQ(*p, 123);
1999 Free(p);
2000 }
2001
TEST_F(BindUnretainedDanglingTest,UnretainedRefWeakReceiverValidNoDangling)2002 TEST_F(BindUnretainedDanglingTest, UnretainedRefWeakReceiverValidNoDangling) {
2003 raw_ptr<int> p = Alloc<int>(3);
2004 int& ref = *p;
2005 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2006 auto callback = base::BindOnce(&ClassWithWeakPtr::RawRefArg, r->GetWeakPtr(),
2007 std::ref(ref));
2008 std::move(callback).Run();
2009 EXPECT_EQ(*p, 123);
2010 Free(p);
2011 }
2012
TEST_F(BindUnretainedDanglingTest,UnretainedWeakReceiverInvalidNoDangling)2013 TEST_F(BindUnretainedDanglingTest, UnretainedWeakReceiverInvalidNoDangling) {
2014 raw_ptr<int> p = Alloc<int>(3);
2015 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2016 auto callback = base::BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(),
2017 base::Unretained(p));
2018 r.reset();
2019 Free(p);
2020 std::move(callback).Run();
2021 // Should reach this point without crashing; there is a dangling pointer, but
2022 // the callback is cancelled because the WeakPtr is already invalidated.
2023 }
2024
TEST_F(BindUnretainedDanglingTest,UnretainedRefWeakReceiverInvalidNoDangling)2025 TEST_F(BindUnretainedDanglingTest, UnretainedRefWeakReceiverInvalidNoDangling) {
2026 raw_ptr<int> p = Alloc<int>(3);
2027 int& ref = *p;
2028 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2029 auto callback = base::BindOnce(&ClassWithWeakPtr::RawRefArg, r->GetWeakPtr(),
2030 std::ref(ref));
2031 r.reset();
2032 Free(p);
2033 std::move(callback).Run();
2034 // Should reach this point without crashing; there is a dangling pointer, but
2035 // the callback is cancelled because the WeakPtr is already invalidated.
2036 }
2037
TEST_F(BindUnretainedDanglingTest,UnretainedRefUnsafeDangling)2038 TEST_F(BindUnretainedDanglingTest, UnretainedRefUnsafeDangling) {
2039 raw_ptr<int> p = Alloc<int>(3);
2040 int& ref = *p;
2041 auto callback =
2042 base::BindOnce(RefCheckFn, base::UnsafeDangling(base::raw_ref<int>(ref)));
2043 Free(p);
2044 EXPECT_EQ(std::move(callback).Run(), true);
2045 // Should reach this point without crashing; there is a dangling pointer, but
2046 // the we marked the reference as `UnsafeDangling`.
2047 }
2048
TEST_F(BindUnretainedDanglingTest,UnretainedRefUnsafeDanglingUntriaged)2049 TEST_F(BindUnretainedDanglingTest, UnretainedRefUnsafeDanglingUntriaged) {
2050 raw_ptr<int> p = Alloc<int>(3);
2051 int& ref = *p;
2052 auto callback = base::BindOnce(
2053 RefCheckFn, base::UnsafeDanglingUntriaged(base::raw_ref<const int>(ref)));
2054 Free(p);
2055 EXPECT_EQ(std::move(callback).Run(), true);
2056 // Should reach this point without crashing; there is a dangling pointer, but
2057 // the we marked the reference as `UnsafeDanglingUntriaged`.
2058 }
2059
2060 // Death tests misbehave on Android, http://crbug.com/643760.
2061 #if defined(GTEST_HAS_DEATH_TEST) && !BUILDFLAG(IS_ANDROID)
2062
FuncWithRefArgument(int & i_ptr)2063 int FuncWithRefArgument(int& i_ptr) {
2064 return i_ptr;
2065 }
2066
TEST_F(BindUnretainedDanglingDeathTest,UnretainedDanglingPtr)2067 TEST_F(BindUnretainedDanglingDeathTest, UnretainedDanglingPtr) {
2068 raw_ptr<int> p = Alloc<int>(3);
2069 auto callback = base::BindOnce(PingPong, base::Unretained(p));
2070 Free(p);
2071 EXPECT_DEATH(std::move(callback).Run(), "");
2072 }
2073
TEST_F(BindUnretainedDanglingDeathTest,UnretainedRefDanglingPtr)2074 TEST_F(BindUnretainedDanglingDeathTest, UnretainedRefDanglingPtr) {
2075 raw_ptr<int> p = Alloc<int>(3);
2076 int& ref = *p;
2077 auto callback = base::BindOnce(FuncWithRefArgument, std::ref(ref));
2078 Free(p);
2079 EXPECT_DEATH(std::move(callback).Run(), "");
2080 }
2081
TEST_F(BindUnretainedDanglingDeathTest,UnretainedRefWithManualUnretainedDanglingPtr)2082 TEST_F(BindUnretainedDanglingDeathTest,
2083 UnretainedRefWithManualUnretainedDanglingPtr) {
2084 raw_ptr<int> p = Alloc<int>(3);
2085 int& ref = *p;
2086 auto callback = base::BindOnce(FuncWithRefArgument,
2087 base::Unretained(base::raw_ref<int>(ref)));
2088 Free(p);
2089 EXPECT_DEATH(std::move(callback).Run(), "");
2090 }
2091
TEST_F(BindUnretainedDanglingDeathTest,UnretainedWeakReceiverDangling)2092 TEST_F(BindUnretainedDanglingDeathTest, UnretainedWeakReceiverDangling) {
2093 raw_ptr<int> p = Alloc<int>(3);
2094 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2095 auto callback = base::BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(),
2096 base::Unretained(p));
2097 Free(p);
2098 EXPECT_DEATH(std::move(callback).Run(), "");
2099 }
2100
2101 #endif // defined(GTEST_HAS_DEATH_TEST) && !BUILDFLAG(IS_ANDROID)
2102
2103 #endif // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
2104
2105 } // namespace
2106 } // namespace base
2107