1 // RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
15 @interface MyOtherClass <MyProtocol>
22 id<MyProtocol> obj_p = nil;
24 MyOtherClass *obj_cp = nil;
26 Class<MyProtocol> obj_CP = nil;
28 /* Assigning to an 'id' variable should never
29 generate a warning. */
32 obj = obj_cp; /* Ok */
34 obj = obj_CP; /* Ok */
36 /* Assigning to a 'MyClass *' variable should always generate a
37 warning, unless done from an 'id'. */
39 obj_c = obj_p; // expected-error {{assigning to 'MyClass *' from incompatible type 'id<MyProtocol>'}}
40 obj_c = obj_cp; // expected-error {{incompatible pointer types assigning to 'MyClass *' from 'MyOtherClass *'}}
41 obj_c = obj_C; // expected-error {{incompatible pointer types assigning to 'MyClass *' from 'Class'}}
42 obj_c = obj_CP; // expected-error {{incompatible pointer types assigning to 'MyClass *' from 'Class<MyProtocol>'}}
44 /* Assigning to an 'id<MyProtocol>' variable should generate a
45 warning if done from a 'MyClass *' (which doesn't implement
46 MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
47 (which implements MyProtocol). */
49 obj_p = obj_c; // expected-error {{assigning to 'id<MyProtocol>' from incompatible type 'MyClass *'}}
50 obj_p = obj_cp; /* Ok */
51 obj_p = obj_C; // expected-error {{incompatible pointer types assigning to 'id<MyProtocol>' from 'Class'}}
52 obj_p = obj_CP; // expected-error {{assigning to 'id<MyProtocol>' from incompatible type 'Class<MyProtocol>'}}
54 /* Assigning to a 'MyOtherClass *' variable should always generate
55 a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
56 MyOtherClass implements MyProtocol). */
57 obj_cp = obj; /* Ok */
58 obj_cp = obj_c; // expected-error {{incompatible pointer types assigning to 'MyOtherClass *' from 'MyClass *'}}
59 obj_cp = obj_p; /* Ok */
60 obj_cp = obj_C; // expected-error {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class'}}
61 obj_cp = obj_CP; // expected-error {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class<MyProtocol>'}}
64 obj_C = obj_p; // expected-error {{incompatible pointer types assigning to 'Class' from 'id<MyProtocol>'}}
65 obj_C = obj_c; // expected-error {{incompatible pointer types assigning to 'Class' from 'MyClass *'}}
66 obj_C = obj_cp; // expected-error {{incompatible pointer types assigning to 'Class' from 'MyOtherClass *'}}
70 obj_CP = obj_p; // expected-error {{assigning to 'Class<MyProtocol>' from incompatible type 'id<MyProtocol>'}}
71 obj_CP = obj_c; // expected-error {{incompatible pointer types assigning to 'Class<MyProtocol>' from 'MyClass *'}}
72 obj_CP = obj_cp; // expected-error {{incompatible pointer types assigning to 'Class<MyProtocol>' from 'MyOtherClass *'}}
75 /* Any comparison involving an 'id' must be without warnings. */
76 if (obj == obj_p) foo(); /* Ok */ /*Bogus warning here in 2.95.4*/
77 if (obj_p == obj) foo(); /* Ok */
78 if (obj == obj_c) foo(); /* Ok */
79 if (obj_c == obj) foo(); /* Ok */
80 if (obj == obj_cp) foo(); /* Ok */
81 if (obj_cp == obj) foo(); /* Ok */
82 if (obj == obj_C) foo(); /* Ok */
83 if (obj_C == obj) foo(); /* Ok */
84 if (obj == obj_CP) foo(); /* Ok */
85 if (obj_CP == obj) foo(); /* Ok */
87 /* Any comparison between 'MyClass *' and anything which is not an 'id'
88 must generate a warning. */
89 if (obj_c == obj_p) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'id<MyProtocol>')}}
90 if (obj_p == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}}
92 if (obj_c == obj_cp) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}}
93 if (obj_cp == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
95 if (obj_c == obj_C) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'Class')}}
96 if (obj_C == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('Class' and 'MyClass *')}}
98 if (obj_c == obj_CP) foo(); // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'Class<MyProtocol>')}}
99 if (obj_CP == obj_c) foo(); // expected-warning {{comparison of distinct pointer types ('Class<MyProtocol>' and 'MyClass *')}}
101 /* Any comparison between 'MyOtherClass *' (which implements
102 MyProtocol) and an 'id' implementing MyProtocol are Ok. */
103 if (obj_p == obj_cp) foo(); /* Ok */
104 if (obj_cp == obj_p) foo(); /* Ok */
106 if (obj_p == obj_C) foo(); // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'Class')}}
107 if (obj_C == obj_p) foo(); // expected-warning {{comparison of distinct pointer types ('Class' and 'id<MyProtocol>')}}
109 if (obj_p == obj_CP) foo(); // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'Class<MyProtocol>')}}
110 if (obj_CP == obj_p) foo(); // expected-warning {{comparison of distinct pointer types ('Class<MyProtocol>' and 'id<MyProtocol>')}}
112 /* Comparisons between MyOtherClass * and Class types is a warning */
113 if (obj_cp == obj_C) foo(); // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'Class')}}
114 if (obj_C == obj_cp) foo(); // expected-warning {{comparison of distinct pointer types ('Class' and 'MyOtherClass *')}}
116 if (obj_cp == obj_CP) foo(); // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'Class<MyProtocol>')}}
117 if (obj_CP == obj_cp) foo(); // expected-warning {{comparison of distinct pointer types ('Class<MyProtocol>' and 'MyOtherClass *')}}
119 /* Comparisons between a Class and a Class<MyProtocol> are ok */
120 if (obj_C == obj_CP) foo(); /* Ok */
121 if (obj_CP == obj_C) foo(); /* Ok */