xref: /aosp_15_r20/external/clang/test/SemaObjCXX/arc-templates.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
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