125 lines · plain
1// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s2 3#define nil nullptr4 5extern void foo();6 7@protocol MyProtocol8- (void) foo;9+ (void) bar;10@end11 12@interface MyClass13@end14 15@interface MyOtherClass <MyProtocol>16- (void) foo;17@end18 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 never29 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 a37 warning, unless done from an 'id'. */38 obj_c = obj; /* Ok */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>'}}43 44 /* Assigning to an 'id<MyProtocol>' variable should generate a45 warning if done from a 'MyClass *' (which doesn't implement46 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-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>'}}53 54 /* Assigning to a 'MyOtherClass *' variable should always generate55 a warning, unless done from an 'id' or an 'id<MyProtocol>' (since56 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>'}}62 63 obj_C = obj; // Ok64 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 *'}}67 obj_C = obj_CP; // Ok68 69 obj_CP = obj; // Ok70 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 *'}}73 obj_CP = obj_C; // Ok74 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 implements102 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