1// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s 2 3#define nil (void *)0; 4 5extern void foo(); 6 7@protocol MyProtocol 8- (void) foo; 9+ (void) bar; 10@end 11 12@interface MyClass 13@end 14 15@interface MyOtherClass <MyProtocol> 16- (void) foo; 17@end 18 19int main() 20{ 21 id obj = nil; 22 id<MyProtocol> obj_p = nil; 23 MyClass *obj_c = nil; 24 MyOtherClass *obj_cp = nil; 25 Class obj_C = nil; 26 Class<MyProtocol> obj_CP = nil; 27 28 /* Assigning to an 'id' variable should never 29 generate a warning. */ 30 obj = obj_p; /* Ok */ 31 obj = obj_c; /* Ok */ 32 obj = obj_cp; /* Ok */ 33 obj = obj_C; /* Ok */ 34 obj = obj_CP; /* Ok */ 35 36 /* Assigning to a 'MyClass *' variable should always generate a 37 warning, unless done from an 'id'. */ 38 obj_c = obj; /* Ok */ 39 obj_c = obj_p; // expected-warning {{assigning to 'MyClass *' from incompatible type 'id<MyProtocol>'}} 40 obj_c = obj_cp; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'MyOtherClass *'}} 41 obj_c = obj_C; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'Class'}} 42 obj_c = obj_CP; // expected-warning {{incompatible pointer types assigning to 'MyClass *' from 'Class<MyProtocol>'}} 43 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). */ 48 obj_p = obj; /* Ok */ 49 obj_p = obj_c; // expected-warning {{assigning to 'id<MyProtocol>' from incompatible type 'MyClass *'}} 50 obj_p = obj_cp; /* Ok */ 51 obj_p = obj_C; // expected-warning {{incompatible pointer types assigning to 'id<MyProtocol>' from 'Class'}} 52 obj_p = obj_CP; // expected-warning {{assigning to 'id<MyProtocol>' from incompatible type 'Class<MyProtocol>'}} 53 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-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'MyClass *'}} 59 obj_cp = obj_p; /* Ok */ 60 obj_cp = obj_C; // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class'}} 61 obj_cp = obj_CP; // expected-warning {{incompatible pointer types assigning to 'MyOtherClass *' from 'Class<MyProtocol>'}} 62 63 obj_C = obj; // Ok 64 obj_C = obj_p; // expected-warning {{incompatible pointer types assigning to 'Class' from 'id<MyProtocol>'}} 65 obj_C = obj_c; // expected-warning {{incompatible pointer types assigning to 'Class' from 'MyClass *'}} 66 obj_C = obj_cp; // expected-warning {{incompatible pointer types assigning to 'Class' from 'MyOtherClass *'}} 67 obj_C = obj_CP; // Ok 68 69 obj_CP = obj; // Ok 70 obj_CP = obj_p; // expected-warning {{assigning to 'Class<MyProtocol>' from incompatible type 'id<MyProtocol>'}} 71 obj_CP = obj_c; // expected-warning {{incompatible pointer types assigning to 'Class<MyProtocol>' from 'MyClass *}} 72 obj_CP = obj_cp; // expected-warning {{incompatible pointer types assigning to 'Class<MyProtocol>' from 'MyOtherClass *'}} 73 obj_CP = obj_C; // Ok 74 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 */ 86 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 *')}} 91 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 *')}} 94 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 *')}} 97 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 *')}} 100 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 */ 105 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>')}} 108 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>')}} 111 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 *')}} 115 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 *')}} 118 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 */ 122 123 return 0; 124} 125