1*6777b538SAndroid Build Coastguard Worker// Copyright 2011 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker// found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker// This is a "No Compile Test" suite. 6*6777b538SAndroid Build Coastguard Worker// http://dev.chromium.org/developers/testing/no-compile-tests 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker#define FORCE_UNRETAINED_COMPLETENESS_CHECKS_FOR_TESTS 1 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker#include <stdint.h> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker#include <utility> 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker#include "base/functional/bind.h" 15*6777b538SAndroid Build Coastguard Worker#include "base/functional/callback.h" 16*6777b538SAndroid Build Coastguard Worker#include "base/functional/disallow_unretained.h" 17*6777b538SAndroid Build Coastguard Worker#include "base/memory/raw_ptr.h" 18*6777b538SAndroid Build Coastguard Worker#include "base/memory/raw_ref.h" 19*6777b538SAndroid Build Coastguard Worker#include "base/memory/ref_counted.h" 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Workernamespace base { 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Workervoid NonConstFunctionWithConstObject() { 24*6777b538SAndroid Build Coastguard Worker struct S : RefCounted<S> { 25*6777b538SAndroid Build Coastguard Worker void Method() {} 26*6777b538SAndroid Build Coastguard Worker } s; 27*6777b538SAndroid Build Coastguard Worker const S* const const_s_ptr = &s; 28*6777b538SAndroid Build Coastguard Worker // Non-`const` methods may not be bound with a `const` receiver. 29*6777b538SAndroid Build Coastguard Worker BindRepeating(&S::Method, const_s_ptr); // expected-error@*:* {{Type mismatch between bound argument and bound functor's parameter.}} 30*6777b538SAndroid Build Coastguard Worker // `const` pointer cannot be bound to non-`const` parameter. 31*6777b538SAndroid Build Coastguard Worker BindRepeating([] (S*) {}, const_s_ptr); // expected-error@*:* {{Type mismatch between bound argument and bound functor's parameter.}} 32*6777b538SAndroid Build Coastguard Worker} 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Workervoid WrongReceiverTypeForNonRefcounted() { 35*6777b538SAndroid Build Coastguard Worker // 1. Non-refcounted objects must use `Unretained()` for the `this` argument. 36*6777b538SAndroid Build Coastguard Worker // 2. Reference-like objects may not be used as the receiver. 37*6777b538SAndroid Build Coastguard Worker struct A { 38*6777b538SAndroid Build Coastguard Worker void Method() {} 39*6777b538SAndroid Build Coastguard Worker void ConstMethod() const {} 40*6777b538SAndroid Build Coastguard Worker } a; 41*6777b538SAndroid Build Coastguard Worker // Using distinct types causes distinct template instantiations, so we get 42*6777b538SAndroid Build Coastguard Worker // assertion failures below where we expect. These types facilitate that. 43*6777b538SAndroid Build Coastguard Worker struct B : A {} b; 44*6777b538SAndroid Build Coastguard Worker struct C : A {} c; 45*6777b538SAndroid Build Coastguard Worker struct D : A {} d; 46*6777b538SAndroid Build Coastguard Worker struct E : A {}; 47*6777b538SAndroid Build Coastguard Worker A* ptr_a = &a; 48*6777b538SAndroid Build Coastguard Worker A& ref_a = a; 49*6777b538SAndroid Build Coastguard Worker raw_ptr<A> rawptr_a(&a); 50*6777b538SAndroid Build Coastguard Worker raw_ref<A> rawref_a(a); 51*6777b538SAndroid Build Coastguard Worker const B const_b; 52*6777b538SAndroid Build Coastguard Worker B* ptr_b = &b; 53*6777b538SAndroid Build Coastguard Worker const B* const_ptr_b = &const_b; 54*6777b538SAndroid Build Coastguard Worker B& ref_b = b; 55*6777b538SAndroid Build Coastguard Worker const B& const_ref_b = const_b; 56*6777b538SAndroid Build Coastguard Worker raw_ptr<B> rawptr_b(&b); 57*6777b538SAndroid Build Coastguard Worker raw_ptr<const B> const_rawptr_b(&const_b); 58*6777b538SAndroid Build Coastguard Worker raw_ref<B> rawref_b(b); 59*6777b538SAndroid Build Coastguard Worker raw_ref<const B> const_rawref_b(const_b); 60*6777b538SAndroid Build Coastguard Worker C& ref_c = c; 61*6777b538SAndroid Build Coastguard Worker D& ref_d = d; 62*6777b538SAndroid Build Coastguard Worker const E const_e; 63*6777b538SAndroid Build Coastguard Worker const E& const_ref_e = const_e; 64*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, &a); // expected-error@*:* {{Receivers may not be raw pointers.}} 65*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, ptr_a); // expected-error@*:* {{Receivers may not be raw pointers.}} 66*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, a); // expected-error@*:* {{Cannot convert `this` argument to address.}} 67*6777b538SAndroid Build Coastguard Worker BindRepeating(&C::Method, ref_c); // expected-error@*:* {{Cannot convert `this` argument to address.}} 68*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, std::ref(a)); // expected-error@*:* {{Cannot convert `this` argument to address.}} 69*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, std::cref(a)); // expected-error@*:* {{Cannot convert `this` argument to address.}} 70*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, rawptr_a); // expected-error@*:* {{Receivers may not be raw pointers.}} 71*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, rawref_a); // expected-error@*:* {{Receivers may not be raw_ref<T>.}} 72*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, &b); // expected-error@*:* {{Receivers may not be raw pointers.}} 73*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, &const_b); // expected-error@*:* {{Receivers may not be raw pointers.}} 74*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, ptr_b); // expected-error@*:* {{Receivers may not be raw pointers.}} 75*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, const_ptr_b); // expected-error@*:* {{Receivers may not be raw pointers.}} 76*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, b); // expected-error@*:* {{Cannot convert `this` argument to address.}} 77*6777b538SAndroid Build Coastguard Worker BindRepeating(&D::ConstMethod, ref_d); // expected-error@*:* {{Cannot convert `this` argument to address.}} 78*6777b538SAndroid Build Coastguard Worker BindRepeating(&E::ConstMethod, const_ref_e); // expected-error@*:* {{Cannot convert `this` argument to address.}} 79*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, std::ref(b)); // expected-error@*:* {{Cannot convert `this` argument to address.}} 80*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, std::cref(b)); // expected-error@*:* {{Cannot convert `this` argument to address.}} 81*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, rawptr_b); // expected-error@*:* {{Receivers may not be raw pointers.}} 82*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, const_rawptr_b); // expected-error@*:* {{Receivers may not be raw pointers.}} 83*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, rawref_b); // expected-error@*:* {{Receivers may not be raw_ref<T>.}} 84*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::ConstMethod, const_rawref_b); // expected-error@*:* {{Receivers may not be raw_ref<T>.}} 85*6777b538SAndroid Build Coastguard Worker} 86*6777b538SAndroid Build Coastguard Worker 87*6777b538SAndroid Build Coastguard Workervoid WrongReceiverTypeForRefcounted() { 88*6777b538SAndroid Build Coastguard Worker // Refcounted objects must pass a pointer-like `this` argument. 89*6777b538SAndroid Build Coastguard Worker struct A : RefCounted<A> { 90*6777b538SAndroid Build Coastguard Worker void Method() const {} 91*6777b538SAndroid Build Coastguard Worker } a; 92*6777b538SAndroid Build Coastguard Worker // Using distinct types causes distinct template instantiations, so we get 93*6777b538SAndroid Build Coastguard Worker // assertion failures below where we expect. These types facilitate that. 94*6777b538SAndroid Build Coastguard Worker struct B : A {} b; 95*6777b538SAndroid Build Coastguard Worker struct C : A {}; 96*6777b538SAndroid Build Coastguard Worker const A const_a; 97*6777b538SAndroid Build Coastguard Worker B& ref_b = b; 98*6777b538SAndroid Build Coastguard Worker const C const_c; 99*6777b538SAndroid Build Coastguard Worker const C& const_ref_c = const_c; 100*6777b538SAndroid Build Coastguard Worker raw_ref<A> rawref_a(a); 101*6777b538SAndroid Build Coastguard Worker raw_ref<const A> const_rawref_a(const_a); 102*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, a); // expected-error@*:* {{Cannot convert `this` argument to address.}} 103*6777b538SAndroid Build Coastguard Worker BindRepeating(&B::Method, ref_b); // expected-error@*:* {{Cannot convert `this` argument to address.}} 104*6777b538SAndroid Build Coastguard Worker BindRepeating(&C::Method, const_ref_c); // expected-error@*:* {{Cannot convert `this` argument to address.}} 105*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, std::ref(a)); // expected-error@*:* {{Cannot convert `this` argument to address.}} 106*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, std::cref(a)); // expected-error@*:* {{Cannot convert `this` argument to address.}} 107*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, rawref_a); // expected-error@*:* {{Receivers may not be raw_ref<T>.}} 108*6777b538SAndroid Build Coastguard Worker BindRepeating(&A::Method, const_rawref_a); // expected-error@*:* {{Receivers may not be raw_ref<T>.}} 109*6777b538SAndroid Build Coastguard Worker} 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Workervoid RemovesConst() { 112*6777b538SAndroid Build Coastguard Worker // Callbacks that expect non-const refs/ptrs should not be callable with const 113*6777b538SAndroid Build Coastguard Worker // ones. 114*6777b538SAndroid Build Coastguard Worker const int i = 0; 115*6777b538SAndroid Build Coastguard Worker const int* p = &i; 116*6777b538SAndroid Build Coastguard Worker BindRepeating([] (int&) {}).Run(i); // expected-error {{no matching member function for call to 'Run'}} 117*6777b538SAndroid Build Coastguard Worker BindRepeating([] (int*) {}, p); // expected-error@*:* {{Type mismatch between bound argument and bound functor's parameter.}} 118*6777b538SAndroid Build Coastguard Worker BindRepeating([] (int*) {}).Run(p); // expected-error {{no matching member function for call to 'Run'}} 119*6777b538SAndroid Build Coastguard Worker} 120*6777b538SAndroid Build Coastguard Worker 121*6777b538SAndroid Build Coastguard Workervoid PassingIncorrectRef() { 122*6777b538SAndroid Build Coastguard Worker // Functions that take non-const reference arguments require the parameters to 123*6777b538SAndroid Build Coastguard Worker // be bound as matching `std::ref()`s or `OwnedRef()`s. 124*6777b538SAndroid Build Coastguard Worker int i = 1; 125*6777b538SAndroid Build Coastguard Worker float f = 1.0f; 126*6777b538SAndroid Build Coastguard Worker // No wrapper. 127*6777b538SAndroid Build Coastguard Worker BindOnce([] (int&) {}, i); // expected-error@*:* {{Bound argument for non-const reference parameter must be wrapped in std::ref() or base::OwnedRef().}} 128*6777b538SAndroid Build Coastguard Worker BindRepeating([] (int&) {}, i); // expected-error@*:* {{Bound argument for non-const reference parameter must be wrapped in std::ref() or base::OwnedRef().}} 129*6777b538SAndroid Build Coastguard Worker // Wrapper, but with mismatched type. 130*6777b538SAndroid Build Coastguard Worker BindOnce([] (int&) {}, f); // expected-error@*:* {{Type mismatch between bound argument and bound functor's parameter.}} 131*6777b538SAndroid Build Coastguard Worker BindOnce([] (int&) {}, std::ref(f)); // expected-error@*:* {{Type mismatch between bound argument and bound functor's parameter.}} 132*6777b538SAndroid Build Coastguard Worker BindOnce([] (int&) {}, OwnedRef(f)); // expected-error@*:* {{Type mismatch between bound argument and bound functor's parameter.}} 133*6777b538SAndroid Build Coastguard Worker} 134*6777b538SAndroid Build Coastguard Worker 135*6777b538SAndroid Build Coastguard Workervoid ArrayAsReceiver() { 136*6777b538SAndroid Build Coastguard Worker // A method should not be bindable with an array of objects. Users could 137*6777b538SAndroid Build Coastguard Worker // unintentionally attempt to do this via array->pointer decay. 138*6777b538SAndroid Build Coastguard Worker struct S : RefCounted<S> { 139*6777b538SAndroid Build Coastguard Worker void Method() const {} 140*6777b538SAndroid Build Coastguard Worker }; 141*6777b538SAndroid Build Coastguard Worker S s[2]; 142*6777b538SAndroid Build Coastguard Worker BindRepeating(&S::Method, s); // expected-error@*:* {{First bound argument to a method cannot be an array.}} 143*6777b538SAndroid Build Coastguard Worker} 144*6777b538SAndroid Build Coastguard Worker 145*6777b538SAndroid Build Coastguard Workervoid RefCountedArgs() { 146*6777b538SAndroid Build Coastguard Worker // Refcounted types should not be bound as a raw pointers. 147*6777b538SAndroid Build Coastguard Worker struct S : RefCounted<S> {}; 148*6777b538SAndroid Build Coastguard Worker S s; 149*6777b538SAndroid Build Coastguard Worker const S const_s; 150*6777b538SAndroid Build Coastguard Worker S* ptr_s = &s; 151*6777b538SAndroid Build Coastguard Worker const S* const_ptr_s = &const_s; 152*6777b538SAndroid Build Coastguard Worker raw_ptr<S> rawptr(&s); 153*6777b538SAndroid Build Coastguard Worker raw_ptr<const S> const_rawptr(&const_s); 154*6777b538SAndroid Build Coastguard Worker raw_ref<S> rawref(s); 155*6777b538SAndroid Build Coastguard Worker raw_ref<const S> const_rawref(const_s); 156*6777b538SAndroid Build Coastguard Worker BindRepeating([] (S*) {}, &s); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 157*6777b538SAndroid Build Coastguard Worker BindRepeating([] (const S*) {}, &const_s); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 158*6777b538SAndroid Build Coastguard Worker BindRepeating([] (S*) {}, ptr_s); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 159*6777b538SAndroid Build Coastguard Worker BindRepeating([] (const S*) {}, const_ptr_s); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 160*6777b538SAndroid Build Coastguard Worker BindRepeating([] (S*) {}, rawptr); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 161*6777b538SAndroid Build Coastguard Worker BindRepeating([] (const S*) {}, const_rawptr); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 162*6777b538SAndroid Build Coastguard Worker BindRepeating([] (raw_ref<S>) {}, rawref); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 163*6777b538SAndroid Build Coastguard Worker BindRepeating([] (raw_ref<const S>) {}, const_rawref); // expected-error@*:* {{A parameter is a refcounted type and needs scoped_refptr.}} 164*6777b538SAndroid Build Coastguard Worker} 165*6777b538SAndroid Build Coastguard Worker 166*6777b538SAndroid Build Coastguard Workervoid WeakPtrWithReturnType() { 167*6777b538SAndroid Build Coastguard Worker // WeakPtrs cannot be bound to methods with return types, since if the WeakPtr 168*6777b538SAndroid Build Coastguard Worker // is null when the callback runs, it's not clear what the framework should 169*6777b538SAndroid Build Coastguard Worker // return. 170*6777b538SAndroid Build Coastguard Worker struct S { 171*6777b538SAndroid Build Coastguard Worker int ReturnsInt() const { return 1; } 172*6777b538SAndroid Build Coastguard Worker } s; 173*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<S> weak_factory(&s); 174*6777b538SAndroid Build Coastguard Worker BindRepeating(&S::ReturnsInt, weak_factory.GetWeakPtr()); // expected-error@*:* {{WeakPtrs can only bind to methods without return values.}} 175*6777b538SAndroid Build Coastguard Worker} 176*6777b538SAndroid Build Coastguard Worker 177*6777b538SAndroid Build Coastguard Workervoid CallbackConversion() { 178*6777b538SAndroid Build Coastguard Worker // Callbacks should not be constructible from other callbacks in ways that 179*6777b538SAndroid Build Coastguard Worker // would drop ref or pointer constness or change arity. 180*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int&)> wrong_ref_constness = BindRepeating([] (const int&) {}); // expected-error {{no viable conversion from 'RepeatingCallback<UnboundRunType>' to 'RepeatingCallback<int (int &)>'}} 181*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int*)> wrong_ptr_constness = BindRepeating([] (const int*) {}); // expected-error {{no viable conversion from 'RepeatingCallback<UnboundRunType>' to 'RepeatingCallback<int (int *)>'}} 182*6777b538SAndroid Build Coastguard Worker RepeatingClosure arg_count_too_low = BindRepeating([] (int) {}); // expected-error {{no viable conversion from 'RepeatingCallback<UnboundRunType>' to 'RepeatingCallback<void ()>'}} 183*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int)> arg_count_too_high = BindRepeating([] { return 0; }); // expected-error {{no viable conversion from 'RepeatingCallback<UnboundRunType>' to 'RepeatingCallback<int (int)>'}} 184*6777b538SAndroid Build Coastguard Worker RepeatingClosure discarding_return = BindRepeating([] { return 0; }); // expected-error {{no viable conversion from 'RepeatingCallback<UnboundRunType>' to 'RepeatingCallback<void ()>'}} 185*6777b538SAndroid Build Coastguard Worker} 186*6777b538SAndroid Build Coastguard Worker 187*6777b538SAndroid Build Coastguard Workervoid CapturingLambdaOrFunctor() { 188*6777b538SAndroid Build Coastguard Worker // Bind disallows capturing lambdas and stateful functors. 189*6777b538SAndroid Build Coastguard Worker int i = 0, j = 0; 190*6777b538SAndroid Build Coastguard Worker struct S { 191*6777b538SAndroid Build Coastguard Worker void operator()() const {} 192*6777b538SAndroid Build Coastguard Worker int x; 193*6777b538SAndroid Build Coastguard Worker }; 194*6777b538SAndroid Build Coastguard Worker BindOnce([&]() { j = i; }); // expected-error@*:* {{Capturing lambdas and stateful functors are intentionally not supported.}} 195*6777b538SAndroid Build Coastguard Worker BindRepeating([&]() { j = i; }); // expected-error@*:* {{Capturing lambdas and stateful functors are intentionally not supported.}} 196*6777b538SAndroid Build Coastguard Worker BindRepeating(S()); // expected-error@*:* {{Capturing lambdas and stateful functors are intentionally not supported.}} 197*6777b538SAndroid Build Coastguard Worker} 198*6777b538SAndroid Build Coastguard Worker 199*6777b538SAndroid Build Coastguard Workervoid OnceCallbackRequiresNonConstRvalue() { 200*6777b538SAndroid Build Coastguard Worker // `OnceCallback::Run()` can only be invoked on a non-const rvalue. 201*6777b538SAndroid Build Coastguard Worker // Using distinct types causes distinct template instantiations, so we get 202*6777b538SAndroid Build Coastguard Worker // assertion failures below where we expect. These types facilitate that. 203*6777b538SAndroid Build Coastguard Worker enum class A {}; 204*6777b538SAndroid Build Coastguard Worker enum class B {}; 205*6777b538SAndroid Build Coastguard Worker enum class C {}; 206*6777b538SAndroid Build Coastguard Worker OnceCallback<void(A)> cb_a = BindOnce([] (A) {}); 207*6777b538SAndroid Build Coastguard Worker const OnceCallback<void(B)> const_cb_b = BindOnce([] (B) {}); 208*6777b538SAndroid Build Coastguard Worker const OnceCallback<void(C)> const_cb_c = BindOnce([] (C) {}); 209*6777b538SAndroid Build Coastguard Worker cb_a.Run(A{}); // expected-error@*:* {{OnceCallback::Run() may only be invoked on a non-const rvalue, i.e. std::move(callback).Run().}} 210*6777b538SAndroid Build Coastguard Worker const_cb_b.Run(B{}); // expected-error@*:* {{OnceCallback::Run() may only be invoked on a non-const rvalue, i.e. std::move(callback).Run().}} 211*6777b538SAndroid Build Coastguard Worker std::move(const_cb_c).Run(C{}); // expected-error@*:* {{OnceCallback::Run() may only be invoked on a non-const rvalue, i.e. std::move(callback).Run().}} 212*6777b538SAndroid Build Coastguard Worker} 213*6777b538SAndroid Build Coastguard Worker 214*6777b538SAndroid Build Coastguard Workervoid OnceCallbackAsArgMustBeNonConstRvalue() { 215*6777b538SAndroid Build Coastguard Worker // A `OnceCallback` passed to another callback must be a non-const rvalue. 216*6777b538SAndroid Build Coastguard Worker auto cb = BindOnce([] (int) {}); 217*6777b538SAndroid Build Coastguard Worker const auto const_cb = BindOnce([] (int) {}); 218*6777b538SAndroid Build Coastguard Worker BindOnce(cb, 0); // expected-error@*:* {{BindOnce() requires non-const rvalue for OnceCallback binding, i.e. base::BindOnce(std::move(callback)).}} 219*6777b538SAndroid Build Coastguard Worker BindOnce(std::move(const_cb), 0); // expected-error@*:* {{BindOnce() requires non-const rvalue for OnceCallback binding, i.e. base::BindOnce(std::move(callback)).}} 220*6777b538SAndroid Build Coastguard Worker} 221*6777b538SAndroid Build Coastguard Worker 222*6777b538SAndroid Build Coastguard Workervoid OnceCallbackBoundByRepeatingCallback() { 223*6777b538SAndroid Build Coastguard Worker // `BindRepeating()` does not accept `OnceCallback`s. 224*6777b538SAndroid Build Coastguard Worker BindRepeating(BindOnce([] (int) {}), 0); // expected-error@*:* {{BindRepeating() cannot bind OnceCallback. Use BindOnce() with std::move().}} 225*6777b538SAndroid Build Coastguard Worker} 226*6777b538SAndroid Build Coastguard Worker 227*6777b538SAndroid Build Coastguard Workervoid MoveOnlyArg() { 228*6777b538SAndroid Build Coastguard Worker // Move-only types require `std::move()` for `BindOnce()` and `base::Passed()` for `BindRepeating()`. 229*6777b538SAndroid Build Coastguard Worker struct S { 230*6777b538SAndroid Build Coastguard Worker S() = default; 231*6777b538SAndroid Build Coastguard Worker S(S&&) = default; 232*6777b538SAndroid Build Coastguard Worker S& operator=(S&&) = default; 233*6777b538SAndroid Build Coastguard Worker } s1, s2; 234*6777b538SAndroid Build Coastguard Worker BindOnce([] (S) {}, s1); // expected-error@*:* {{Attempting to bind a move-only type. Use std::move() to transfer ownership to the created callback.}} 235*6777b538SAndroid Build Coastguard Worker BindOnce([] (S) {}, Passed(&s1)); // expected-error@*:* {{Use std::move() instead of base::Passed() with base::BindOnce().}} 236*6777b538SAndroid Build Coastguard Worker BindRepeating([] (S) {}, s2); // expected-error@*:* {{base::BindRepeating() argument is a move-only type. Use base::Passed() instead of std::move() to transfer ownership from the callback to the bound functor.}} 237*6777b538SAndroid Build Coastguard Worker BindRepeating([] (S) {}, std::move(s2)); // expected-error@*:* {{base::BindRepeating() argument is a move-only type. Use base::Passed() instead of std::move() to transfer ownership from the callback to the bound functor.}} 238*6777b538SAndroid Build Coastguard Worker} 239*6777b538SAndroid Build Coastguard Worker 240*6777b538SAndroid Build Coastguard Workervoid NonCopyableNonMovable() { 241*6777b538SAndroid Build Coastguard Worker // Arguments must be either copyable or movable to be captured. 242*6777b538SAndroid Build Coastguard Worker struct S { 243*6777b538SAndroid Build Coastguard Worker S() = default; 244*6777b538SAndroid Build Coastguard Worker S(const S&) = delete; 245*6777b538SAndroid Build Coastguard Worker S& operator=(const S&) = delete; 246*6777b538SAndroid Build Coastguard Worker } s; 247*6777b538SAndroid Build Coastguard Worker BindOnce([](const S&) {}, s); // expected-error@*:* {{Cannot capture argument: is the argument copyable or movable?}} 248*6777b538SAndroid Build Coastguard Worker} 249*6777b538SAndroid Build Coastguard Worker 250*6777b538SAndroid Build Coastguard Workervoid OverloadedFunction() { 251*6777b538SAndroid Build Coastguard Worker // Overloaded function types cannot be disambiguated. (It might be nice to fix 252*6777b538SAndroid Build Coastguard Worker // this.) 253*6777b538SAndroid Build Coastguard Worker void F(int); 254*6777b538SAndroid Build Coastguard Worker void F(float); 255*6777b538SAndroid Build Coastguard Worker BindOnce(&F, 1); // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} 256*6777b538SAndroid Build Coastguard Worker BindRepeating(&F, 1.0f); // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} 257*6777b538SAndroid Build Coastguard Worker} 258*6777b538SAndroid Build Coastguard Worker 259*6777b538SAndroid Build Coastguard Workervoid OverloadedOperator() { 260*6777b538SAndroid Build Coastguard Worker // It's not possible to bind to a functor with an overloaded `operator()()` 261*6777b538SAndroid Build Coastguard Worker // unless the caller supplies arguments that can invoke a unique overload. 262*6777b538SAndroid Build Coastguard Worker struct A { 263*6777b538SAndroid Build Coastguard Worker int64_t operator()(int, int64_t x) { return x; } 264*6777b538SAndroid Build Coastguard Worker uint64_t operator()(int, uint64_t x) { return x; } 265*6777b538SAndroid Build Coastguard Worker A operator()(double, A a) { return a; } 266*6777b538SAndroid Build Coastguard Worker } a; 267*6777b538SAndroid Build Coastguard Worker // Using distinct types causes distinct template instantiations, so we get 268*6777b538SAndroid Build Coastguard Worker // assertion failures below where we expect. These types facilitate that. 269*6777b538SAndroid Build Coastguard Worker struct B : A {} b; 270*6777b538SAndroid Build Coastguard Worker struct C : A {} c; 271*6777b538SAndroid Build Coastguard Worker struct D : A {} d; 272*6777b538SAndroid Build Coastguard Worker 273*6777b538SAndroid Build Coastguard Worker // Partial function application isn't supported, even if it's sufficient to 274*6777b538SAndroid Build Coastguard Worker // "narrow the field" to a single candidate that _could_ eventually match. 275*6777b538SAndroid Build Coastguard Worker BindOnce(a); // expected-error@*:* {{Could not determine how to invoke functor.}} 276*6777b538SAndroid Build Coastguard Worker BindOnce(b, 1.0); // expected-error@*:* {{Could not determine how to invoke functor.}} 277*6777b538SAndroid Build Coastguard Worker 278*6777b538SAndroid Build Coastguard Worker // The supplied args don't match any candidates. 279*6777b538SAndroid Build Coastguard Worker BindOnce(c, 1, nullptr); // expected-error@*:* {{Could not determine how to invoke functor.}} 280*6777b538SAndroid Build Coastguard Worker 281*6777b538SAndroid Build Coastguard Worker // The supplied args inexactly match multiple candidates. 282*6777b538SAndroid Build Coastguard Worker BindOnce(d, 1, 1); // expected-error@*:* {{Could not determine how to invoke functor.}} 283*6777b538SAndroid Build Coastguard Worker} 284*6777b538SAndroid Build Coastguard Worker 285*6777b538SAndroid Build Coastguard Workervoid RefQualifiedOverloadedOperator() { 286*6777b538SAndroid Build Coastguard Worker // Invocations with lvalues should attempt to use lvalue-ref-qualified 287*6777b538SAndroid Build Coastguard Worker // methods. 288*6777b538SAndroid Build Coastguard Worker struct A { 289*6777b538SAndroid Build Coastguard Worker void operator()() const& = delete; 290*6777b538SAndroid Build Coastguard Worker void operator()() && {} 291*6777b538SAndroid Build Coastguard Worker } a; 292*6777b538SAndroid Build Coastguard Worker // Using distinct types causes distinct template instantiations, so we get 293*6777b538SAndroid Build Coastguard Worker // assertion failures below where we expect. This type facilitates that. 294*6777b538SAndroid Build Coastguard Worker struct B : A {}; 295*6777b538SAndroid Build Coastguard Worker BindRepeating(a); // expected-error@*:* {{Could not determine how to invoke functor.}} 296*6777b538SAndroid Build Coastguard Worker BindRepeating(B()); // expected-error@*:* {{Could not determine how to invoke functor.}} 297*6777b538SAndroid Build Coastguard Worker 298*6777b538SAndroid Build Coastguard Worker // Invocations with rvalues should attempt to use rvalue-ref-qualified 299*6777b538SAndroid Build Coastguard Worker // methods. 300*6777b538SAndroid Build Coastguard Worker struct C { 301*6777b538SAndroid Build Coastguard Worker void operator()() const& {} 302*6777b538SAndroid Build Coastguard Worker void operator()() && = delete; 303*6777b538SAndroid Build Coastguard Worker }; 304*6777b538SAndroid Build Coastguard Worker BindRepeating(Passed(C())); // expected-error@*:* {{Could not determine how to invoke functor.}} 305*6777b538SAndroid Build Coastguard Worker BindOnce(C()); // expected-error@*:* {{Could not determine how to invoke functor.}} 306*6777b538SAndroid Build Coastguard Worker} 307*6777b538SAndroid Build Coastguard Worker 308*6777b538SAndroid Build Coastguard Worker// Define a type that disallows `Unretained()` via the internal customization 309*6777b538SAndroid Build Coastguard Worker// point, so the next test can use it. 310*6777b538SAndroid Build Coastguard Workerstruct BlockViaCustomizationPoint {}; 311*6777b538SAndroid Build Coastguard Workernamespace internal { 312*6777b538SAndroid Build Coastguard Workertemplate <> 313*6777b538SAndroid Build Coastguard Workerconstexpr bool kCustomizeSupportsUnretained<BlockViaCustomizationPoint> = false; 314*6777b538SAndroid Build Coastguard Worker} // namespace internal 315*6777b538SAndroid Build Coastguard Worker 316*6777b538SAndroid Build Coastguard Workervoid CanDetectTypesThatDisallowUnretained() { 317*6777b538SAndroid Build Coastguard Worker // It shouldn't be possible to directly bind any type that doesn't support 318*6777b538SAndroid Build Coastguard Worker // `Unretained()`, whether because it's incomplete, or is marked with 319*6777b538SAndroid Build Coastguard Worker // `DISALLOW_RETAINED()`, or has `kCustomizeSupportsUnretained` specialized to 320*6777b538SAndroid Build Coastguard Worker // be `false`. 321*6777b538SAndroid Build Coastguard Worker struct BlockPublicly { 322*6777b538SAndroid Build Coastguard Worker DISALLOW_UNRETAINED(); 323*6777b538SAndroid Build Coastguard Worker } publicly; 324*6777b538SAndroid Build Coastguard Worker class BlockPrivately { 325*6777b538SAndroid Build Coastguard Worker DISALLOW_UNRETAINED(); 326*6777b538SAndroid Build Coastguard Worker } privately; 327*6777b538SAndroid Build Coastguard Worker struct BlockViaInheritance : BlockPublicly {} inheritance; 328*6777b538SAndroid Build Coastguard Worker BlockViaCustomizationPoint customization; 329*6777b538SAndroid Build Coastguard Worker struct BlockDueToBeingIncomplete; 330*6777b538SAndroid Build Coastguard Worker BlockDueToBeingIncomplete* ptr_incomplete; 331*6777b538SAndroid Build Coastguard Worker BindOnce([](BlockPublicly*) {}, &publicly); // expected-error@*:* {{Argument requires unretained storage, but type does not support `Unretained()`.}} 332*6777b538SAndroid Build Coastguard Worker BindOnce([](BlockPrivately*) {}, &privately); // expected-error@*:* {{Argument requires unretained storage, but type does not support `Unretained()`.}} 333*6777b538SAndroid Build Coastguard Worker BindOnce([](BlockViaInheritance*) {}, &inheritance); // expected-error@*:* {{Argument requires unretained storage, but type does not support `Unretained()`.}} 334*6777b538SAndroid Build Coastguard Worker BindOnce([](BlockViaCustomizationPoint*) {}, &customization); // expected-error@*:* {{Argument requires unretained storage, but type does not support `Unretained()`.}} 335*6777b538SAndroid Build Coastguard Worker BindOnce([](BlockDueToBeingIncomplete*) {}, ptr_incomplete); // expected-error@*:* {{Argument requires unretained storage, but type is not fully defined.}} 336*6777b538SAndroid Build Coastguard Worker} 337*6777b538SAndroid Build Coastguard Worker 338*6777b538SAndroid Build Coastguard Workervoid OtherWaysOfPassingDisallowedTypes() { 339*6777b538SAndroid Build Coastguard Worker // In addition to the direct passing tested above, arguments passed as 340*6777b538SAndroid Build Coastguard Worker // `Unretained()` pointers or as refs must support `Unretained()`. 341*6777b538SAndroid Build Coastguard Worker struct A { 342*6777b538SAndroid Build Coastguard Worker void Method() {} 343*6777b538SAndroid Build Coastguard Worker DISALLOW_UNRETAINED(); 344*6777b538SAndroid Build Coastguard Worker } a; 345*6777b538SAndroid Build Coastguard Worker // Using distinct types causes distinct template instantiations, so we get 346*6777b538SAndroid Build Coastguard Worker // assertion failures below where we expect. This type facilitates that. 347*6777b538SAndroid Build Coastguard Worker struct B : A {} b; 348*6777b538SAndroid Build Coastguard Worker BindOnce(&A::Method, Unretained(&a)); // expected-error@*:* {{Argument requires unretained storage, but type does not support `Unretained()`.}} 349*6777b538SAndroid Build Coastguard Worker BindOnce([] (const A&) {}, std::cref(a)); // expected-error@*:* {{Argument requires unretained storage, but type does not support `Unretained()`.}} 350*6777b538SAndroid Build Coastguard Worker BindOnce([] (B&) {}, std::ref(b)); // expected-error@*:* {{Argument requires unretained storage, but type does not support `Unretained()`.}} 351*6777b538SAndroid Build Coastguard Worker} 352*6777b538SAndroid Build Coastguard Worker 353*6777b538SAndroid Build Coastguard Workervoid UnsafeDangling() { 354*6777b538SAndroid Build Coastguard Worker // Pointers marked as `UnsafeDangling` may only be be received by 355*6777b538SAndroid Build Coastguard Worker // `MayBeDangling` args with matching traits. 356*6777b538SAndroid Build Coastguard Worker int i; 357*6777b538SAndroid Build Coastguard Worker BindOnce([] (int*) {}, UnsafeDangling(&i)); // expected-error@*:* {{base::UnsafeDangling() pointers should only be passed to parameters marked MayBeDangling<T>.}} 358*6777b538SAndroid Build Coastguard Worker BindOnce([] (MayBeDangling<int>) {}, 359*6777b538SAndroid Build Coastguard Worker UnsafeDangling<int, RawPtrTraits::kDummyForTest>(&i)); // expected-error@*:* {{Pointers passed to MayBeDangling<T> parameters must be created by base::UnsafeDangling() with the same RawPtrTraits.}} 360*6777b538SAndroid Build Coastguard Worker BindOnce([] (raw_ptr<int>) {}, UnsafeDanglingUntriaged(&i)); // expected-error@*:* {{Use T* or T& instead of raw_ptr<T> for function parameters, unless you must mark the parameter as MayBeDangling<T>.}} 361*6777b538SAndroid Build Coastguard Worker} 362*6777b538SAndroid Build Coastguard Worker 363*6777b538SAndroid Build Coastguard Worker} // namespace base 364