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