1*67e74705SXin Li// RUN: %clang_cc1 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -fblocks -std=c++11 %s 2*67e74705SXin Li 3*67e74705SXin Li#define CONSUMED __attribute__((ns_consumed)) 4*67e74705SXin Li#define PRODUCED __attribute__((ns_returns_retained)) 5*67e74705SXin Li 6*67e74705SXin Li@interface A 7*67e74705SXin Li@end 8*67e74705SXin Li 9*67e74705SXin Li@class NSString; 10*67e74705SXin Li 11*67e74705SXin Litemplate<typename T, typename U> 12*67e74705SXin Listruct is_same { 13*67e74705SXin Li static const bool value = false; 14*67e74705SXin Li}; 15*67e74705SXin Li 16*67e74705SXin Litemplate<typename T> 17*67e74705SXin Listruct is_same<T, T> { 18*67e74705SXin Li static const bool value = true; 19*67e74705SXin Li}; 20*67e74705SXin Li 21*67e74705SXin Li// Instantiation for reference/pointer types that will get lifetime 22*67e74705SXin Li// adjustments. 23*67e74705SXin Litemplate<typename T> 24*67e74705SXin Listruct X0 { 25*67e74705SXin Li typedef T* pointer; // okay: ends up being strong. 26*67e74705SXin Li typedef T& reference; // okay: ends up being strong 27*67e74705SXin Li}; 28*67e74705SXin Li 29*67e74705SXin Livoid test_X0() { 30*67e74705SXin Li X0<id> x0id; 31*67e74705SXin Li X0<A*> x0a; 32*67e74705SXin Li X0<__strong A*> x0sa; 33*67e74705SXin Li 34*67e74705SXin Li id __strong *ptr; 35*67e74705SXin Li id __strong val; 36*67e74705SXin Li X0<__strong id>::pointer &ptr_ref = ptr; 37*67e74705SXin Li X0<__strong id>::reference ref = val; 38*67e74705SXin Li} 39*67e74705SXin Li 40*67e74705SXin Liint check_infer_strong[is_same<id, __strong id>::value? 1 : -1]; 41*67e74705SXin Li 42*67e74705SXin Li// Check template argument deduction (e.g., for specialization) using 43*67e74705SXin Li// lifetime qualifiers. 44*67e74705SXin Litemplate<typename T> 45*67e74705SXin Listruct is_pointer_strong { 46*67e74705SXin Li static const bool value = false; 47*67e74705SXin Li}; 48*67e74705SXin Li 49*67e74705SXin Litemplate<typename T> 50*67e74705SXin Listruct is_pointer_strong<__strong T*> { 51*67e74705SXin Li static const bool value = true; 52*67e74705SXin Li}; 53*67e74705SXin Li 54*67e74705SXin Liint check_ptr_strong1[is_pointer_strong<__strong id*>::value? 1 : -1]; 55*67e74705SXin Liint check_ptr_strong2[is_pointer_strong<__weak id*>::value? -1 : 1]; 56*67e74705SXin Liint check_ptr_strong3[is_pointer_strong<__autoreleasing id*>::value? -1 : 1]; 57*67e74705SXin Liint check_ptr_strong4[is_pointer_strong<__unsafe_unretained id*>::value? -1 : 1]; 58*67e74705SXin Liint check_ptr_strong5[is_pointer_strong<id>::value? -1 : 1]; 59*67e74705SXin Li 60*67e74705SXin Li// Check substitution into lifetime-qualified dependent types. 61*67e74705SXin Litemplate<typename T> 62*67e74705SXin Listruct make_strong_pointer { 63*67e74705SXin Li typedef __strong T *type; 64*67e74705SXin Li}; 65*67e74705SXin Li 66*67e74705SXin Litemplate<typename T> 67*67e74705SXin Listruct make_strong_pointer<__weak T> { 68*67e74705SXin Li typedef __strong T *type; 69*67e74705SXin Li}; 70*67e74705SXin Li 71*67e74705SXin Litemplate<typename T> 72*67e74705SXin Listruct make_strong_pointer<__autoreleasing T> { 73*67e74705SXin Li typedef __strong T *type; 74*67e74705SXin Li}; 75*67e74705SXin Li 76*67e74705SXin Litemplate<typename T> 77*67e74705SXin Listruct make_strong_pointer<__unsafe_unretained T> { 78*67e74705SXin Li typedef __strong T *type; 79*67e74705SXin Li}; 80*67e74705SXin Li 81*67e74705SXin Li// Adding qualifiers 82*67e74705SXin Liint check_make_strong1[is_same<make_strong_pointer<id>::type, __strong id *>::value ? 1 : -1]; 83*67e74705SXin Liint check_make_strong2[is_same<make_strong_pointer<A*>::type, A* __strong *>::value ? 1 : -1]; 84*67e74705SXin Li 85*67e74705SXin Li// Adding redundant qualifiers 86*67e74705SXin Liint check_make_strong3[is_same<make_strong_pointer<__strong id>::type, __strong id *>::value ? 1 : -1]; 87*67e74705SXin Liint check_make_strong4[is_same<make_strong_pointer<__strong A*>::type, A* __strong *>::value ? 1 : -1]; 88*67e74705SXin Li 89*67e74705SXin Li// Adding nonsensical qualifiers. 90*67e74705SXin Liint check_make_strong5[is_same<make_strong_pointer<int>::type, int *>::value ? 1 : -1]; 91*67e74705SXin Liint check_make_strong6[is_same<make_strong_pointer<__weak id>::type, __strong id *>::value ? 1 : -1]; 92*67e74705SXin Li 93*67e74705SXin Litemplate<typename T> 94*67e74705SXin Listruct make_weak { 95*67e74705SXin Li typedef __weak T type; 96*67e74705SXin Li}; 97*67e74705SXin Li 98*67e74705SXin Liint check_make_weak0[is_same<make_weak<id>::type, __weak id>::value? 1 : -1]; 99*67e74705SXin Liint check_make_weak1[is_same<make_weak<__strong id>::type, __weak id>::value? 1 : -1]; 100*67e74705SXin Liint check_make_weak2[is_same<make_weak<__autoreleasing id>::type, __weak id>::value? 1 : -1]; 101*67e74705SXin Li 102*67e74705SXin Litemplate<typename T> 103*67e74705SXin Listruct make_weak_fail { 104*67e74705SXin Li typedef T T_type; 105*67e74705SXin Li typedef __weak T_type type; // expected-error{{the type 'T_type' (aka '__weak id') is already explicitly ownership-qualified}} \ 106*67e74705SXin Li // expected-error{{the type 'T_type' (aka '__strong id') is already explicitly ownership-qualified}} 107*67e74705SXin Li}; 108*67e74705SXin Li 109*67e74705SXin Liint check_make_weak_fail0[is_same<make_weak_fail<__weak id>::type, __weak id>::value? 1 : -1]; // expected-note{{in instantiation of template class 'make_weak_fail<__weak id>' requested here}} 110*67e74705SXin Li 111*67e74705SXin Liint check_make_weak_fail1[is_same<make_weak_fail<id>::type, __weak id>::value? -1 : 1]; // expected-note{{in instantiation of template class 'make_weak_fail<id>' requested here}} 112*67e74705SXin Li 113*67e74705SXin Li// Check template argument deduction from function templates. 114*67e74705SXin Litemplate<typename T> struct identity { }; 115*67e74705SXin Li 116*67e74705SXin Litemplate<typename T> identity<T> accept_strong_ptr(__strong T*); 117*67e74705SXin Litemplate<typename T> identity<T> accept_strong_ref(__strong T&); 118*67e74705SXin Li 119*67e74705SXin Litemplate<typename T> identity<T> accept_any_ptr(T*); 120*67e74705SXin Litemplate<typename T> identity<T> accept_any_ref(T&); 121*67e74705SXin Li 122*67e74705SXin Livoid test_func_deduction_id() { 123*67e74705SXin Li __strong id *sip; 124*67e74705SXin Li __weak id *wip; 125*67e74705SXin Li __autoreleasing id *aip; 126*67e74705SXin Li __unsafe_unretained id *uip; 127*67e74705SXin Li 128*67e74705SXin Li identity<id> res1 = accept_strong_ptr(sip); 129*67e74705SXin Li identity<__strong id> res2 = accept_any_ptr(sip); 130*67e74705SXin Li 131*67e74705SXin Li __strong id si; 132*67e74705SXin Li __weak id wi; 133*67e74705SXin Li __autoreleasing id ai; 134*67e74705SXin Li __unsafe_unretained id ui; 135*67e74705SXin Li identity<id> res3 = accept_strong_ref(si); 136*67e74705SXin Li identity<__strong id> res4 = accept_any_ref(si); 137*67e74705SXin Li identity<__weak id> res5 = accept_any_ref(wi); 138*67e74705SXin Li identity<__autoreleasing id> res6 = accept_any_ref(ai); 139*67e74705SXin Li identity<__unsafe_unretained id> res7 = accept_any_ref(ui); 140*67e74705SXin Li} 141*67e74705SXin Li 142*67e74705SXin Livoid test_func_deduction_A() { 143*67e74705SXin Li __strong A * *sip; 144*67e74705SXin Li __weak A * *wip; 145*67e74705SXin Li __autoreleasing A * *aip; 146*67e74705SXin Li __unsafe_unretained A * *uip; 147*67e74705SXin Li 148*67e74705SXin Li identity<A *> res1 = accept_strong_ptr(sip); 149*67e74705SXin Li identity<__strong A *> res2 = accept_any_ptr(sip); 150*67e74705SXin Li 151*67e74705SXin Li __strong A * si; 152*67e74705SXin Li __weak A * wi; 153*67e74705SXin Li __autoreleasing A * ai; 154*67e74705SXin Li __unsafe_unretained A * ui; 155*67e74705SXin Li identity<A *> res3 = accept_strong_ref(si); 156*67e74705SXin Li identity<__strong A *> res4 = accept_any_ref(si); 157*67e74705SXin Li identity<__weak A *> res5 = accept_any_ref(wi); 158*67e74705SXin Li identity<__autoreleasing A *> res6 = accept_any_ref(ai); 159*67e74705SXin Li identity<__unsafe_unretained A *> res7 = accept_any_ref(ui); 160*67e74705SXin Li} 161*67e74705SXin Li 162*67e74705SXin Li// Test partial ordering (qualified vs. non-qualified). 163*67e74705SXin Litemplate<typename T> 164*67e74705SXin Listruct classify_pointer_pointer { 165*67e74705SXin Li static const unsigned value = 0; 166*67e74705SXin Li}; 167*67e74705SXin Li 168*67e74705SXin Litemplate<typename T> 169*67e74705SXin Listruct classify_pointer_pointer<T*> { 170*67e74705SXin Li static const unsigned value = 1; 171*67e74705SXin Li}; 172*67e74705SXin Li 173*67e74705SXin Litemplate<typename T> 174*67e74705SXin Listruct classify_pointer_pointer<__strong T*> { 175*67e74705SXin Li static const unsigned value = 2; 176*67e74705SXin Li}; 177*67e74705SXin Li 178*67e74705SXin Litemplate<typename T> 179*67e74705SXin Listruct classify_pointer_pointer<__weak T*> { 180*67e74705SXin Li static const unsigned value = 3; 181*67e74705SXin Li}; 182*67e74705SXin Li 183*67e74705SXin Litemplate<typename T> 184*67e74705SXin Listruct classify_pointer_pointer<T&> { 185*67e74705SXin Li static const unsigned value = 4; 186*67e74705SXin Li}; 187*67e74705SXin Li 188*67e74705SXin Litemplate<typename T> 189*67e74705SXin Listruct classify_pointer_pointer<__strong T&> { 190*67e74705SXin Li static const unsigned value = 5; 191*67e74705SXin Li}; 192*67e74705SXin Li 193*67e74705SXin Litemplate<typename T> 194*67e74705SXin Listruct classify_pointer_pointer<__weak T&> { 195*67e74705SXin Li static const unsigned value = 6; 196*67e74705SXin Li}; 197*67e74705SXin Li 198*67e74705SXin Liint classify_ptr1[classify_pointer_pointer<int>::value == 0? 1 : -1]; 199*67e74705SXin Liint classify_ptr2[classify_pointer_pointer<int *>::value == 1? 1 : -1]; 200*67e74705SXin Liint classify_ptr3[classify_pointer_pointer<id __strong *>::value == 2? 1 : -1]; 201*67e74705SXin Liint classify_ptr4[classify_pointer_pointer<id __weak *>::value == 3? 1 : -1]; 202*67e74705SXin Liint classify_ptr5[classify_pointer_pointer<int&>::value == 4? 1 : -1]; 203*67e74705SXin Liint classify_ptr6[classify_pointer_pointer<id __strong&>::value == 5? 1 : -1]; 204*67e74705SXin Liint classify_ptr7[classify_pointer_pointer<id __weak&>::value == 6? 1 : -1]; 205*67e74705SXin Liint classify_ptr8[classify_pointer_pointer<id __autoreleasing&>::value == 4? 1 : -1]; 206*67e74705SXin Liint classify_ptr9[classify_pointer_pointer<id __unsafe_unretained&>::value == 4? 1 : -1]; 207*67e74705SXin Liint classify_ptr10[classify_pointer_pointer<id __autoreleasing *>::value == 1? 1 : -1]; 208*67e74705SXin Liint classify_ptr11[classify_pointer_pointer<id __unsafe_unretained *>::value == 1? 1 : -1]; 209*67e74705SXin Liint classify_ptr12[classify_pointer_pointer<int *>::value == 1? 1 : -1]; 210*67e74705SXin Liint classify_ptr13[classify_pointer_pointer<A * __strong *>::value == 2? 1 : -1]; 211*67e74705SXin Liint classify_ptr14[classify_pointer_pointer<A * __weak *>::value == 3? 1 : -1]; 212*67e74705SXin Liint classify_ptr15[classify_pointer_pointer<int&>::value == 4? 1 : -1]; 213*67e74705SXin Liint classify_ptr16[classify_pointer_pointer<A * __strong&>::value == 5? 1 : -1]; 214*67e74705SXin Liint classify_ptr17[classify_pointer_pointer<A * __weak&>::value == 6? 1 : -1]; 215*67e74705SXin Liint classify_ptr18[classify_pointer_pointer<A * __autoreleasing&>::value == 4? 1 : -1]; 216*67e74705SXin Liint classify_ptr19[classify_pointer_pointer<A * __unsafe_unretained&>::value == 4? 1 : -1]; 217*67e74705SXin Liint classify_ptr20[classify_pointer_pointer<A * __autoreleasing *>::value == 1? 1 : -1]; 218*67e74705SXin Liint classify_ptr21[classify_pointer_pointer<A * __unsafe_unretained *>::value == 1? 1 : -1]; 219*67e74705SXin Li 220*67e74705SXin Litemplate<typename T> int& qual_vs_unqual_ptr(__strong T*); 221*67e74705SXin Litemplate<typename T> double& qual_vs_unqual_ptr(__weak T*); 222*67e74705SXin Litemplate<typename T> float& qual_vs_unqual_ptr(T*); 223*67e74705SXin Litemplate<typename T> int& qual_vs_unqual_ref(__strong T&); 224*67e74705SXin Litemplate<typename T> double& qual_vs_unqual_ref(__weak T&); 225*67e74705SXin Litemplate<typename T> float& qual_vs_unqual_ref(T&); 226*67e74705SXin Li 227*67e74705SXin Livoid test_qual_vs_unqual_id() { 228*67e74705SXin Li __strong id *sip; 229*67e74705SXin Li __weak id *wip; 230*67e74705SXin Li __autoreleasing id *aip; 231*67e74705SXin Li __unsafe_unretained id *uip; 232*67e74705SXin Li 233*67e74705SXin Li int &ir1 = qual_vs_unqual_ptr(sip); 234*67e74705SXin Li double &dr1 = qual_vs_unqual_ptr(wip); 235*67e74705SXin Li float &fr1 = qual_vs_unqual_ptr(aip); 236*67e74705SXin Li float &fr2 = qual_vs_unqual_ptr(uip); 237*67e74705SXin Li 238*67e74705SXin Li int &ir2 = qual_vs_unqual_ref(*sip); 239*67e74705SXin Li double &dr2 = qual_vs_unqual_ref(*wip); 240*67e74705SXin Li float &fr3 = qual_vs_unqual_ref(*aip); 241*67e74705SXin Li float &fr4 = qual_vs_unqual_ref(*uip); 242*67e74705SXin Li} 243*67e74705SXin Li 244*67e74705SXin Livoid test_qual_vs_unqual_a() { 245*67e74705SXin Li __strong A * *sap; 246*67e74705SXin Li __weak A * *wap; 247*67e74705SXin Li __autoreleasing A * *aap; 248*67e74705SXin Li __unsafe_unretained A * *uap; 249*67e74705SXin Li 250*67e74705SXin Li int &ir1 = qual_vs_unqual_ptr(sap); 251*67e74705SXin Li double &dr1 = qual_vs_unqual_ptr(wap); 252*67e74705SXin Li float &fr1 = qual_vs_unqual_ptr(aap); 253*67e74705SXin Li float &fr2 = qual_vs_unqual_ptr(uap); 254*67e74705SXin Li 255*67e74705SXin Li int &ir2 = qual_vs_unqual_ref(*sap); 256*67e74705SXin Li double &dr2 = qual_vs_unqual_ref(*wap); 257*67e74705SXin Li float &fr3 = qual_vs_unqual_ref(*aap); 258*67e74705SXin Li float &fr4 = qual_vs_unqual_ref(*uap); 259*67e74705SXin Li} 260*67e74705SXin Li 261*67e74705SXin Linamespace rdar9828157 { 262*67e74705SXin Li // Template argument deduction involving lifetime qualifiers and 263*67e74705SXin Li // non-lifetime types. 264*67e74705SXin Li class A { }; 265*67e74705SXin Li 266*67e74705SXin Li template<typename T> float& f(T&); 267*67e74705SXin Li template<typename T> int& f(__strong T&); 268*67e74705SXin Li template<typename T> double& f(__weak T&); 269*67e74705SXin Li 270*67e74705SXin Li void test_f(A* ap) { 271*67e74705SXin Li float &fr = (f)(ap); 272*67e74705SXin Li } 273*67e74705SXin Li} 274*67e74705SXin Li 275*67e74705SXin Linamespace rdar10862386 { 276*67e74705SXin Li // More deduction with lifetime qualifiers. 277*67e74705SXin Li template <typename T> 278*67e74705SXin Li int testing(const T &) { 279*67e74705SXin Li return 1; 280*67e74705SXin Li } 281*67e74705SXin Li 282*67e74705SXin Li void test() { 283*67e74705SXin Li testing(1); 284*67e74705SXin Li testing("hi"); 285*67e74705SXin Li testing<NSString *>(@"hi"); 286*67e74705SXin Li testing(@"hi"); 287*67e74705SXin Li } 288*67e74705SXin Li} 289*67e74705SXin Li 290*67e74705SXin Linamespace rdar12367446 { 291*67e74705SXin Li template <class T> class A; 292*67e74705SXin Li template <class R> class A<R()> {}; 293*67e74705SXin Li 294*67e74705SXin Li void test() { 295*67e74705SXin Li A<id()> value; 296*67e74705SXin Li } 297*67e74705SXin Li} 298*67e74705SXin Li 299*67e74705SXin Linamespace rdar14467941 { 300*67e74705SXin Li template<typename T> int &takePtr(const T &); 301*67e74705SXin Li template<typename T> float &takePtr(T * const &); 302*67e74705SXin Li 303*67e74705SXin Li void testTakePtr(A *a) { 304*67e74705SXin Li float &fr1 = takePtr(a); 305*67e74705SXin Li float &fr2 = takePtr<A>(a); 306*67e74705SXin Li } 307*67e74705SXin Li} 308*67e74705SXin Li 309*67e74705SXin Linamespace rdar15713945 { 310*67e74705SXin Li template <class T> int &f(__strong T &); 311*67e74705SXin Li template <class T> float &f(__weak T &); 312*67e74705SXin Li template <class T> double &f(__unsafe_unretained T &); 313*67e74705SXin Li template <class T> char &f(T &); 314*67e74705SXin Li 315*67e74705SXin Li void foo() { 316*67e74705SXin Li __strong NSString * const strong = 0; 317*67e74705SXin Li int &ir = (f)(strong); 318*67e74705SXin Li __weak NSString * const weak = 0; 319*67e74705SXin Li float &fr = (f)(weak); 320*67e74705SXin Li __unsafe_unretained NSString * const unsafe = 0; 321*67e74705SXin Li double &dr = (f)(unsafe); 322*67e74705SXin Li } 323*67e74705SXin Li} 324*67e74705SXin Li 325*67e74705SXin Linamespace consumed { 326*67e74705SXin Li void take_yes_no(void (&)(id CONSUMED, id)); // expected-note 2 {{candidate function not viable}} 327*67e74705SXin Li void take_no_yes(void (&)(id, CONSUMED id)); // expected-note 2 {{candidate function not viable}} 328*67e74705SXin Li void take_yes_yes(void (&)(CONSUMED id, CONSUMED id)); // expected-note 2 {{candidate function not viable}} 329*67e74705SXin Li 330*67e74705SXin Li template <class... As> void consumes_first(id CONSUMED, As...); 331*67e74705SXin Li void test1() { 332*67e74705SXin Li take_yes_no(consumes_first<id>); 333*67e74705SXin Li take_no_yes(consumes_first<id>); // expected-error {{no matching function}} 334*67e74705SXin Li take_yes_yes(consumes_first<id>); // expected-error {{no matching function}} 335*67e74705SXin Li } 336*67e74705SXin Li 337*67e74705SXin Li template <class... As> void consumes_rest(id, CONSUMED As...); 338*67e74705SXin Li void test2() { 339*67e74705SXin Li take_yes_no(consumes_rest<id>); // expected-error {{no matching function}} 340*67e74705SXin Li take_no_yes(consumes_rest<id>); 341*67e74705SXin Li take_yes_yes(consumes_rest<id>); // expected-error {{no matching function}} 342*67e74705SXin Li } 343*67e74705SXin Li 344*67e74705SXin Li template <class T, class U> void consumes_two(CONSUMED T, CONSUMED U); 345*67e74705SXin Li void test3() { 346*67e74705SXin Li take_yes_no(consumes_two); // expected-error {{no matching function}} 347*67e74705SXin Li take_no_yes(consumes_two); // expected-error {{no matching function}} 348*67e74705SXin Li take_yes_yes(consumes_two); 349*67e74705SXin Li } 350*67e74705SXin Li} 351*67e74705SXin Li 352*67e74705SXin Linamespace consumed_nested { 353*67e74705SXin Li void take_yes_no(void (&)(id CONSUMED, id)); // expected-note 4 {{candidate function not viable}} 354*67e74705SXin Li void take_no_yes(void (&)(id, CONSUMED id)); // expected-note 4 {{candidate function not viable}} 355*67e74705SXin Li void take_yes_yes(void (&)(CONSUMED id, CONSUMED id)); // expected-note 4 {{candidate function not viable}} 356*67e74705SXin Li 357*67e74705SXin Li template <unsigned N> struct consumes_first { 358*67e74705SXin Li template <class... As> static void fn(id CONSUMED, As...); 359*67e74705SXin Li }; 360*67e74705SXin Li void test1() { 361*67e74705SXin Li take_yes_no(consumes_first<1>::fn<id>); 362*67e74705SXin Li take_no_yes(consumes_first<2>::fn<id>); // expected-error {{no matching function}} 363*67e74705SXin Li take_yes_yes(consumes_first<3>::fn<id>); // expected-error {{no matching function}} 364*67e74705SXin Li take_yes_no(consumes_first<4>::fn); 365*67e74705SXin Li take_no_yes(consumes_first<5>::fn); // expected-error {{no matching function}} 366*67e74705SXin Li take_yes_yes(consumes_first<6>::fn); // expected-error {{no matching function}} 367*67e74705SXin Li } 368*67e74705SXin Li 369*67e74705SXin Li template <unsigned N> struct consumes_rest { 370*67e74705SXin Li template <class... As> static void fn(id, CONSUMED As...); 371*67e74705SXin Li }; 372*67e74705SXin Li void test2() { 373*67e74705SXin Li take_yes_no(consumes_rest<1>::fn<id>); // expected-error {{no matching function}} 374*67e74705SXin Li take_no_yes(consumes_rest<2>::fn<id>); 375*67e74705SXin Li take_yes_yes(consumes_rest<3>::fn<id>); // expected-error {{no matching function}} 376*67e74705SXin Li take_yes_no(consumes_rest<4>::fn<id>); // expected-error {{no matching function}} 377*67e74705SXin Li take_no_yes(consumes_rest<5>::fn<id>); 378*67e74705SXin Li take_yes_yes(consumes_rest<6>::fn<id>); // expected-error {{no matching function}} 379*67e74705SXin Li } 380*67e74705SXin Li 381*67e74705SXin Li template <unsigned N> struct consumes_two { 382*67e74705SXin Li template <class T, class U> static void fn(CONSUMED T, CONSUMED U); 383*67e74705SXin Li }; 384*67e74705SXin Li void test3() { 385*67e74705SXin Li take_yes_no(consumes_two<1>::fn<id, id>); // expected-error {{no matching function}} 386*67e74705SXin Li take_no_yes(consumes_two<2>::fn<id, id>); // expected-error {{no matching function}} 387*67e74705SXin Li take_yes_yes(consumes_two<3>::fn<id, id>); 388*67e74705SXin Li take_yes_no(consumes_two<1>::fn); // expected-error {{no matching function}} 389*67e74705SXin Li take_no_yes(consumes_two<2>::fn); // expected-error {{no matching function}} 390*67e74705SXin Li take_yes_yes(consumes_two<3>::fn); 391*67e74705SXin Li } 392*67e74705SXin Li} 393*67e74705SXin Li 394*67e74705SXin Linamespace produced { 395*67e74705SXin Li void take_yes(PRODUCED id (&)()); // expected-note 2 {{candidate function not viable}} 396*67e74705SXin Li void take_no(id (&)()); // expected-note 2 {{candidate function not viable}} 397*67e74705SXin Li 398*67e74705SXin Li template <class T> T non_produces1(); 399*67e74705SXin Li template <class T> T non_produces2(); 400*67e74705SXin Li template <class T> T non_produces3(); 401*67e74705SXin Li template <class T> T non_produces4(); 402*67e74705SXin Li void test1() { 403*67e74705SXin Li take_yes(non_produces1<id>); // expected-error {{no matching function}} 404*67e74705SXin Li take_yes(non_produces2); // expected-error {{no matching function}} 405*67e74705SXin Li take_no(non_produces3<id>); 406*67e74705SXin Li take_no(non_produces4); 407*67e74705SXin Li } 408*67e74705SXin Li 409*67e74705SXin Li template <class T> PRODUCED T produces1(); 410*67e74705SXin Li template <class T> PRODUCED T produces2(); 411*67e74705SXin Li template <class T> PRODUCED T produces3(); 412*67e74705SXin Li template <class T> PRODUCED T produces4(); 413*67e74705SXin Li void test2() { 414*67e74705SXin Li take_yes(produces1<id>); 415*67e74705SXin Li take_yes(produces2); 416*67e74705SXin Li take_no(produces3<id>); // expected-error {{no matching function}} 417*67e74705SXin Li take_no(produces4); // expected-error {{no matching function}} 418*67e74705SXin Li } 419*67e74705SXin Li} 420*67e74705SXin Li 421*67e74705SXin Linamespace produced_nested { 422*67e74705SXin Li void take_yes(PRODUCED id (&)()); // expected-note 2 {{candidate function not viable}} 423*67e74705SXin Li void take_no(id (&)()); // expected-note 2 {{candidate function not viable}} 424*67e74705SXin Li 425*67e74705SXin Li template <unsigned N> struct non_produces { 426*67e74705SXin Li template <class T> static T fn(); 427*67e74705SXin Li }; 428*67e74705SXin Li void test1() { 429*67e74705SXin Li take_yes(non_produces<1>::fn<id>); // expected-error {{no matching function}} 430*67e74705SXin Li take_yes(non_produces<2>::fn); // expected-error {{no matching function}} 431*67e74705SXin Li take_no(non_produces<3>::fn<id>); 432*67e74705SXin Li take_no(non_produces<4>::fn); 433*67e74705SXin Li } 434*67e74705SXin Li 435*67e74705SXin Li template <unsigned N> struct produces { 436*67e74705SXin Li template <class T> static PRODUCED T fn(); 437*67e74705SXin Li }; 438*67e74705SXin Li void test2() { 439*67e74705SXin Li take_yes(produces<1>::fn<id>); 440*67e74705SXin Li take_yes(produces<2>::fn); 441*67e74705SXin Li take_no(produces<3>::fn<id>); // expected-error {{no matching function}} 442*67e74705SXin Li take_no(produces<4>::fn); // expected-error {{no matching function}} 443*67e74705SXin Li } 444*67e74705SXin Li} 445*67e74705SXin Li 446*67e74705SXin Linamespace instantiate_consumed { 447*67e74705SXin Li template <class T> void take(CONSUMED T t) {} // expected-note {{candidate template ignored: substitution failure [with T = int]: ns_consumed attribute only applies to Objective-C object parameters}} 448*67e74705SXin Li void test() { 449*67e74705SXin Li take((id) 0); 450*67e74705SXin Li take((int) 0); // expected-error {{no matching function for call to 'take'}} 451*67e74705SXin Li } 452*67e74705SXin Li} 453