1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | |
3 | @interface A { |
4 | @public |
5 | int ivar; |
6 | } |
7 | @property int prop; |
8 | @end |
9 | |
10 | typedef struct objc_object { |
11 | Class isa; |
12 | } *id; |
13 | |
14 | // Test instantiation of value-dependent ObjCIvarRefExpr, |
15 | // ObjCIsaRefExpr, and ObjCPropertyRefExpr nodes. |
16 | A *get_an_A(unsigned); |
17 | id get_an_id(unsigned); |
18 | |
19 | template<unsigned N, typename T, typename U, typename V> |
20 | void f(U value, V value2) { |
21 | get_an_A(N)->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} |
22 | get_an_A(N).prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}} |
23 | T c = get_an_id(N)->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \ |
24 | // expected-warning 3 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} |
25 | } |
26 | |
27 | template void f<6, Class>(int, int); // expected-note{{in instantiation of}} |
28 | template void f<7, Class>(int*, int); // expected-note{{in instantiation of}} |
29 | template void f<8, Class>(int, double*); // expected-note{{in instantiation of}} |
30 | template void f<9, int>(int, int); // expected-note{{in instantiation of}} |
31 | |
32 | // Test instantiation of unresolved member reference expressions to an |
33 | // ivar reference. |
34 | template<typename T, typename U, typename V> |
35 | void f2(T ptr, U value, V value2) { |
36 | ptr->ivar = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} |
37 | ptr.prop = value2; // expected-error{{assigning to 'int' from incompatible type 'double *'}} |
38 | } |
39 | |
40 | template void f2(A*, int, int); |
41 | template void f2(A*, int*, int); // expected-note{{instantiation of}} |
42 | template void f2(A*, int, double*); // expected-note{{instantiation of}} |
43 | |
44 | // Test instantiation of unresolved member referfence expressions to |
45 | // an isa. |
46 | template<typename T, typename U> |
47 | void f3(U ptr) { |
48 | T c = ptr->isa; // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'Class'}} \ |
49 | // expected-warning 1 {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} |
50 | } |
51 | |
52 | template void f3<Class>(id); // expected-note{{in instantiation of}} |
53 | template void f3<int>(id); // expected-note{{instantiation of}} |
54 | |
55 | // Implicit setter/getter |
56 | @interface B |
57 | - (int)foo; |
58 | - (void)setFoo:(int)value; |
59 | @end |
60 | |
61 | template<typename T> |
62 | void f4(B *b, T value) { |
63 | b.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} |
64 | } |
65 | |
66 | template void f4(B*, int); |
67 | template void f4(B*, int*); // expected-note{{in instantiation of function template specialization 'f4<int *>' requested here}} |
68 | |
69 | template<typename T, typename U> |
70 | void f5(T ptr, U value) { |
71 | ptr.foo = value; // expected-error{{assigning to 'int' from incompatible type 'int *'}} |
72 | } |
73 | |
74 | template void f5(B*, int); |
75 | template void f5(B*, int*); // expected-note{{in instantiation of function template specialization 'f5<B *, int *>' requested here}} |
76 | |