1/* Check Class <protocol> types */ 2/* Author: David Ayers <d.ayers@inode.at> */ 3/* { dg-do compile } */ 4 5#include <objc/objc.h> 6#include "../objc-obj-c++-shared/runtime.h" 7 8@protocol MyProto1 9+(void)doItClass1; 10-(void)doItInstance1; 11@end 12 13@protocol MyProto2 14+(void)doItClass2; 15-(void)doItInstance2; 16@end 17 18@interface MyClass1 <MyProto1> 19{ 20 Class isa; 21} 22@end 23@implementation MyClass1 24+(void)doItClass1{} 25-(void)doItInstance1{} 26@end 27 28@interface MyClass2 : MyClass1 <MyProto2> 29@end 30@implementation MyClass2 31+(void)doItClass2{} 32-(void)doItInstance2{} 33@end 34 35@interface MyClass3 36{ 37 Class isa; 38} 39@end 40@interface MyClass4 : MyClass3 <MyProto1> 41@end 42 43/*----------------------------------------*/ 44 45Class cls = 0; 46Class <MyProto1> clsP1 = 0; 47Class <MyProto2> clsP2 = 0; 48 49void 50testSimple(void) 51{ 52 [cls doItClass1]; 53 [cls doItInstance1]; 54 [cls doItClass2]; 55 [cls doItInstance2]; 56 57 [clsP1 doItClass1]; 58 [clsP1 doItInstance1]; /* { dg-warning "instead of" } */ 59 [clsP1 doItClass2]; /* { dg-warning "not found in protocol" } */ 60 [clsP1 doItInstance2]; /* { dg-warning "not found in protocol" } */ 61 62 [clsP2 doItClass1]; /* { dg-warning "not found in protocol" } */ 63 [clsP2 doItInstance1]; /* { dg-warning "not found in protocol" } */ 64 [clsP2 doItClass2]; 65 [clsP2 doItInstance2]; /* { dg-warning "instead of" } */ 66 67 [MyClass1 doItClass1]; 68 [MyClass1 doItInstance1]; 69 [MyClass1 doItClass2]; /* { dg-warning "may not respond to" } */ 70 [MyClass1 doItInstance2]; /* { dg-warning "may not respond to" } */ 71 72 [MyClass2 doItClass1]; 73 [MyClass2 doItInstance1]; 74 [MyClass2 doItClass2]; 75 [MyClass2 doItInstance2]; /* { dg-warning "may not respond to" } */ 76 77 [MyClass3 doItClass1]; /* { dg-warning "may not respond to" } */ 78 [MyClass3 doItInstance1]; /* { dg-warning "may not respond to" } */ 79 80 [MyClass4 doItClass1]; 81 [MyClass4 doItInstance1]; /* { dg-warning "may not respond to" } */ 82} 83 84/*----------------------------------------*/ 85/* Protocols declared by categories */ 86 87@protocol MyProto3 88+(void)doItClass3; 89-(void)doItInstance3; 90@end 91@protocol MyProto4 92+(void)doItClass4; 93-(void)doItInstance4; 94@end 95 96@interface MyClass1 (Category1) <MyProto3> 97@end 98@interface MyClass2 (Category2) <MyProto4> 99@end 100 101void 102testCategory(void) 103{ 104 [cls doItClass3]; 105 [cls doItInstance3]; 106 [cls doItClass4]; 107 [cls doItInstance4]; 108 109 [MyClass1 doItClass3]; 110 [MyClass1 doItInstance3]; 111 [MyClass1 doItClass4]; /* { dg-warning "may not respond" } */ 112 [MyClass1 doItInstance4]; /* { dg-warning "may not respond" } */ 113 114 [MyClass2 doItClass3]; 115 [MyClass2 doItInstance3]; 116 [MyClass2 doItClass4]; 117 [MyClass2 doItInstance4]; /* { dg-warning "may not respond" } */ 118 119} 120 121/*----------------------------------------*/ 122/* Inherited protocols declared by categories */ 123 124@protocol MyProto5 <MyProto1> 125+(void)doItClass5; 126-(void)doItInstance5; 127@end 128 129@protocol MyProto6 <MyProto2> 130+(void)doItClass6; 131-(void)doItInstance6; 132@end 133 134@interface MyClass1 (Category3) <MyProto5> 135@end 136@interface MyClass2 (Category4) <MyProto6> 137@end 138 139Class <MyProto5> clsP5 = 0; 140Class <MyProto6> clsP6 = 0; 141 142void 143testCategoryInherited(void) 144{ 145 [cls doItClass5]; 146 [cls doItInstance5]; 147 [cls doItClass6]; 148 [cls doItInstance6]; 149 150 [clsP5 doItClass1]; 151 [clsP5 doItInstance1]; /* { dg-warning "instead of" } */ 152 [clsP5 doItClass2]; /* { dg-warning "not found in protocol" } */ 153 [clsP5 doItInstance2]; /* { dg-warning "not found in protocol" } */ 154 155 [clsP6 doItClass1]; /* { dg-warning "not found in protocol" } */ 156 [clsP6 doItInstance1]; /* { dg-warning "not found in protocol" } */ 157 [clsP6 doItClass2]; 158 [clsP6 doItInstance2]; /* { dg-warning "instead of" } */ 159 160 161 [MyClass1 doItClass5]; 162 [MyClass1 doItInstance5]; 163 [MyClass1 doItClass6]; /* { dg-warning "may not respond" } */ 164 [MyClass1 doItInstance6]; /* { dg-warning "may not respond" } */ 165 166 [MyClass2 doItClass5]; 167 [MyClass2 doItInstance5]; 168 [MyClass2 doItClass6]; 169 [MyClass2 doItInstance6]; /* { dg-warning "may not respond" } */ 170 171} 172 173/*----------------------------------------*/ 174/* Forward declared root protocols */ 175 176@protocol FwProto; 177 178@interface MyClass1 (Forward) <FwProto> /* { dg-warning "definition of protocol .FwProto. not found" } */ 179@end 180 181Class <FwProto> clsP7 = 0; 182 183void 184testForwardeDeclared1(void) 185{ 186 [cls doItClass7]; /* { dg-warning "no .\\+doItClass7. method found" } */ 187 [cls doItInstance7]; /* { dg-warning "no .\\+doItInstance7. method found" } */ 188 189 [clsP7 doItClass7]; /* { dg-warning "not found in protocol" } */ 190 /* { dg-warning "no .\\+doItClass7. method found" "" { target *-*-* } 189 } */ 191 [clsP7 doItInstance7]; /* { dg-warning "not found in protocol" } */ 192 /* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } 191 } */ 193 194 [MyClass1 doItClass7]; /* { dg-warning "may not respond" } */ 195 [MyClass1 doItInstance7]; /* { dg-warning "may not respond" } */ 196 197 [MyClass2 doItClass7]; /* { dg-warning "may not respond" } */ 198 [MyClass2 doItInstance7]; /* { dg-warning "may not respond" } */ 199 200} 201 202@protocol FwProto 203+(void)doItClass7; 204-(void)doItInstance7; 205@end 206 207void 208testForwardeDeclared2(void) 209{ 210 [cls doItClass7]; 211 [cls doItInstance7]; 212 213 [clsP7 doItClass7]; 214 [clsP7 doItInstance7]; /* { dg-warning "instead of" } */ 215 216 [MyClass1 doItClass7]; 217 [MyClass1 doItInstance7]; 218 219 [MyClass2 doItClass7]; 220 [MyClass2 doItInstance7]; 221} 222 223/*----------------------------------------*/ 224/* Inherited non root protocols */ 225 226@protocol MyProto8 227+(void)doItClass8; 228-(void)doItInstance8; 229@end 230 231@protocol MyProto9 <MyProto8> 232+(void)doItClass9; 233-(void)doItInstance9; 234@end 235 236@interface MyClass1 (InheritedNonRoot) <MyProto9> 237@end 238 239Class <MyProto8> clsP8 = 0; 240Class <MyProto9> clsP9 = 0; 241 242void 243testInheritedNonRoot(void) 244{ 245 [cls doItClass8]; 246 [cls doItInstance8]; 247 [cls doItClass9]; 248 [cls doItInstance9]; 249 250 [clsP8 doItClass8]; 251 [clsP8 doItInstance8]; /* { dg-warning "instead of" } */ 252 [clsP8 doItClass9]; /* { dg-warning "not found in protocol" } */ 253 [clsP8 doItInstance9]; /* { dg-warning "not found in protocol" } */ 254 255 [clsP9 doItClass8]; 256 [clsP9 doItInstance8]; /* { dg-warning "instead of" } */ 257 [clsP9 doItClass9]; 258 [clsP9 doItInstance9]; /* { dg-warning "instead of" } */ 259 260 [MyClass1 doItClass8]; 261 [MyClass1 doItInstance8]; 262 [MyClass1 doItClass9]; 263 [MyClass1 doItInstance9]; 264 265 [MyClass2 doItClass8]; 266 [MyClass2 doItInstance8]; 267 [MyClass2 doItClass9]; 268 [MyClass2 doItInstance9]; 269 270} 271 272/*----------------------------------------*/ 273/* Prototype mismatch */ 274 275@protocol MyOtherProto1 276+(id)doItClass1; 277-(id)doItInstance1; 278@end 279@interface MyOtherClass1 <MyOtherProto1> 280@end 281 282Class <MyOtherProto1> oclsP1; 283 284void 285testPrototypeMismatch(void) 286{ 287 id tmp1 = [oclsP1 doItClass1]; 288 id tmp2 = [oclsP1 doItInstance1]; /* { dg-warning "instead of" } */ 289 290 [clsP1 doItClass1]; 291 [clsP1 doItInstance1]; /* { dg-warning "instead of" } */ 292} 293 294id obj = nil; 295id <MyProto1> objP1 = nil; 296id <MyProto2> objP2 = nil; 297id <MyProto5> objP5 = nil; 298int num = 0; 299void *ptr = 0; 300 301MyClass1 *mc1 = nil; 302 303void 304testComptypes(void) 305{ 306 { /* id <protocol>, id <protocol> */ 307 objP1 == objP2; /* { dg-warning "lacks a cast" } */ 308 objP2 == objP1; /* { dg-warning "lacks a cast" } */ 309 310 objP1 == objP5; 311 objP5 == objP1; 312 } 313 { /* id <protocol>, SomeClass * */ 314 mc1 == objP1; 315 objP1 == mc1; 316 317 mc1 == objP2; /* { dg-warning "lacks a cast" } */ 318 objP2 == mc1; /* { dg-warning "lacks a cast" } */ 319 } 320 { /* id <protocol>, id */ 321 obj == objP1; 322 objP1 == obj; 323 } 324 { /* id <protocol>, Class */ 325 cls == objP1; /* { dg-warning "lacks a cast" } */ 326 objP1 == cls; /* { dg-warning "lacks a cast" } */ 327 } 328 { /* id <protocol>, non-ObjC */ 329 num == objP1; /* { dg-error "between pointer" } */ 330 objP1 == num; /* { dg-error "between pointer" } */ 331 332 ptr == objP1; 333 objP1 == ptr; 334 } 335 { /* Class <protocol>, Class <protocol> */ 336 clsP1 == clsP2; /* { dg-warning "lacks a cast" } */ 337 clsP2 == clsP1; /* { dg-warning "lacks a cast" } */ 338 339 clsP1 == clsP5; 340 clsP5 == clsP1; 341 } 342 { /* Class <protocol>, SomeClass * */ 343 mc1 == clsP1; /* { dg-warning "lacks a cast" } */ 344 clsP1 == mc1; /* { dg-warning "lacks a cast" } */ 345 } 346 { /* Class <protocol>, id */ 347 obj == clsP1; 348 clsP1 == obj; 349 } 350 { /* Class <protocol>, Class */ 351 cls == clsP1; 352 clsP1 == cls; 353 } 354 { /* Class <protocol>, non-ObjC */ 355 num == clsP1; /* { dg-error "between pointer" } */ 356 clsP1 == num; /* { dg-error "between pointer" } */ 357 358 ptr == clsP1; 359 clsP1 == ptr; 360 } 361 { /* Class <protocol>, id <protocol> */ 362 clsP1 == objP1; /* { dg-warning "lacks a cast" } */ 363 objP1 == clsP1; /* { dg-warning "lacks a cast" } */ 364 } 365 366 { /* id <protocol>, id <protocol> */ 367 objP1 = objP2; /* { dg-warning "does not conform" } */ 368 objP2 = objP1; /* { dg-warning "does not conform" } */ 369 370 objP1 = objP5; 371 objP5 = objP1; /* { dg-warning "does not conform" } */ 372 } 373 { /* id <protocol>, SomeClass * */ 374 mc1 = objP1; 375 objP1 = mc1; 376 377 mc1 = objP2; /* { dg-warning "does not conform" } */ 378 objP2 = mc1; /* { dg-warning "does not implement" } */ 379 } 380 { /* id <protocol>, id */ 381 obj = objP1; 382 objP1 = obj; 383 } 384 { /* id <protocol>, Class */ 385 cls = objP1; /* { dg-warning "distinct Objective\\-C type" } */ 386 objP1 = cls; /* { dg-warning "distinct Objective\\-C type" } */ 387 } 388 { /* id <protocol>, non-ObjC */ 389 num = objP1; /* { dg-error "invalid conversion" } */ 390 objP1 = num; /* { dg-error "invalid conversion" } */ 391 392 ptr = objP1; 393 objP1 = ptr; /* { dg-error "invalid conversion" } */ 394 } 395 { /* Class <protocol>, Class <protocol> */ 396 clsP1 = clsP2; /* { dg-warning "does not conform" } */ 397 clsP2 = clsP1; /* { dg-warning "does not conform" } */ 398 399 clsP1 = clsP5; 400 clsP5 = clsP1; /* { dg-warning "does not conform" } */ 401 } 402 { /* Class <protocol>, SomeClass * */ 403 /* These combinations should always elicit a warning. */ 404 mc1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ 405 clsP1 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ 406 407 mc1 = clsP2; /* { dg-warning "distinct Objective\\-C type" } */ 408 clsP2 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ 409 } 410 { /* Class <protocol>, id */ 411 obj = clsP1; 412 clsP1 = obj; 413 } 414 { /* Class <protocol>, Class */ 415 cls = clsP1; 416 clsP1 = cls; 417 } 418 { /* Class <protocol>, non-ObjC */ 419 num = clsP1; /* { dg-error "invalid conversion" } */ 420 clsP1 = num; /* { dg-error "invalid conversion" } */ 421 422 ptr = clsP1; 423 clsP1 = ptr; /* { dg-error "invalid conversion" } */ 424 } 425 { /* Class <protocol>, id <protocol> */ 426 clsP1 = objP1; /* { dg-warning "distinct Objective\\-C type" } */ 427 objP1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ 428 } 429} 430 431int main () 432{ 433 testSimple(); 434 testCategory(); 435 testCategoryInherited(); 436 return(0); 437} 438 439/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */ 440/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */ 441/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */ 442