1/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, June 2011. */ 2/* { dg-do compile } */ 3 4@class NotKnown; 5 6@protocol MyProtocol 7+ (id) classMethod; 8- (id) instanceMethod; 9@end 10 11@protocol MyProtocol2 12+ (id) classMethod2; 13- (id) instanceMethod2; 14@end 15 16void test (Class x, Class <MyProtocol> y, id w, id <MyProtocol> z, NotKnown *a, NotKnown <MyProtocol> *b) 17{ 18 /* "Class x" means that "x" responds to any class methods, and may 19 also respond to instance methods because instance methods of the 20 root class are class methods. */ 21 [x classMethod]; /* No warning here. */ 22 23 [x instanceMethod]; /* No warning here. */ 24 25 26 /* "Class <MyProtocol> y" means that "y" responds to any class 27 methods specified in the protocol MyProtocol, but not to other 28 class or instance methods. If a class method is not found, an 29 instance method from the protocol may be used instead but that is 30 suspicious and gets a warning. */ 31 [y classMethod]; /* No warning here. */ 32 33 [y instanceMethod]; /* { dg-warning "found .\\-instanceMethod. instead of .\\+instanceMethod. in protocol" } */ 34 35 [y classMethod2]; /* { dg-warning ".\\+classMethod2. not found in protocol" } */ 36 37 [y instanceMethod2]; /* { dg-warning ".\\+instanceMethod2. not found in protocol" } */ 38 39 40 /* If a class is specified by name, the @interface must be available 41 to check what it responds to. */ 42 [NotKnown classMethod]; /* { dg-warning ".interface of class .NotKnown. not found" } */ 43 44 45 /* "id w" means that "w" responds to anything, both class and 46 instance methods. */ 47 [w instanceMethod]; /* No warning here. */ 48 49 [w instanceMethod2]; /* No warning here. */ 50 51 [w classMethod]; /* No warning here. */ 52 53 [w classMethod2]; /* No warning here. */ 54 55 56 /* "id <MyProtocol> z" means that "z" responds to any instance 57 methods in the protocol, but not class methods. To select class 58 methods, you use "Class <MyProtocol> z". */ 59 [z instanceMethod]; /* No warning here. */ 60 61 [z instanceMethod2]; /* { dg-warning ".\\-instanceMethod2. not found in protocol" } */ 62 63 [z classMethod]; /* { dg-warning ".\\-classMethod. not found in protocol" } */ 64 65 [z classMethod2]; /* { dg-warning ".\\-classMethod2. not found in protocol" } */ 66 67 68 /* "NotKnown *a" means that "a" is an instance of NotKnown. Since 69 the programmer explicitly specified the class name, it must be 70 because they expect the compiler to do type-checking; the 71 @interface must be available to do this check, otherwise the 72 compiler does not know what "a" responds to. */ 73 [a instanceMethod]; /* { dg-warning ".interface of class .NotKnown. not found" } */ 74 75 /* But, if you cast it to "id", then you're disabling type-checking 76 and the warnings should go away. */ 77 [(id)a instanceMethod]; /* No warning here. */ 78 79 80 /* "NotKnown <MyProtocol> *b" means that "a" is an instance of 81 NotKnown, and also implements protocol <MyProtocol>. If you send 82 a message that is part of the protocol, then the compiler can do 83 type-checking and all is fine. */ 84 [b instanceMethod]; 85 86 /* But if you send a message that is not part of the protocol, then 87 you'll get a warning that the method can not be found in the 88 protocol. */ 89 [b instanceMethod2]; /* { dg-warning ".\\-instanceMethod2. not found in protocol" } */ 90 91 /* But, if you cast it to "id", then you're disabling type-checking 92 and the warnings should go away. */ 93 [(id)b instanceMethod2]; /* No warning here. */ 94} 95