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