1// RUN: %clang_cc1 %s -Wpotentially-direct-selector -verify
2// RUN: %clang_cc1 %s -Wstrict-potentially-direct-selector -verify=expected,strict
3
4#define NS_DIRECT __attribute__((objc_direct))
5
6__attribute__((objc_root_class))
7@interface Dummies
8-(void)inBase;
9-(void)inBaseImpl;
10-(void)inBaseCat;
11-(void)inBaseCatImpl;
12-(void)inDerived;
13-(void)inDerivedImpl;
14-(void)inDerivedCat;
15-(void)inDerivedCatImpl;
16+(void)inBaseClass;
17+(void)inDerivedClass;
18+(void)inDerivedCatClass;
19@end
20
21__attribute__((objc_root_class))
22@interface Base
23-(void)inBase NS_DIRECT; // expected-note + {{direct method}}
24+(void)inBaseClass NS_DIRECT;  // expected-note + {{direct method}}
25@end
26
27@implementation Base
28-(void)inBaseImpl NS_DIRECT { // expected-note + {{direct method}}
29}
30-(void)inBase {}
31+(void)inBaseClass {}
32@end
33
34@interface Base (Cat)
35-(void)inBaseCat NS_DIRECT; // expected-note + {{direct method}}
36@end
37
38@implementation Base (Cat)
39-(void)inBaseCatImpl NS_DIRECT { // expected-note + {{direct method}}
40}
41-(void)inBaseCat {}
42@end
43
44@interface Derived : Base
45-(void)inDerived NS_DIRECT; // expected-note + {{direct method}}
46+(void)inDerivedClass NS_DIRECT;  // expected-note + {{direct method}}
47@end
48
49@implementation Derived
50-(void)inDerivedImpl NS_DIRECT { // expected-note + {{direct method}}
51}
52-(void)inDerived {}
53+(void)inDerivedClass {}
54@end
55
56@interface Derived (Cat)
57-(void)inDerivedCat NS_DIRECT; // expected-note + {{direct method}}
58+(void)inDerivedCatClass NS_DIRECT; // expected-note + {{direct method}}
59@end
60
61@implementation Derived (Cat)
62-(void)inDerivedCatImpl NS_DIRECT { // expected-note + {{direct method}}
63}
64-(void)inDerivedCat {}
65+(void)inDerivedCatClass {}
66
67-(void)test1 {
68  (void)@selector(inBase); // expected-warning{{@selector expression formed with potentially direct selector}}
69  (void)@selector(inBaseImpl); // expected-warning{{@selector expression formed with potentially direct selector}}
70  (void)@selector(inBaseCat); // expected-warning{{@selector expression formed with potentially direct selector}}
71  (void)@selector(inBaseCatImpl); // expected-warning{{@selector expression formed with potentially direct selector}}
72  (void)@selector(inDerived); // expected-warning{{@selector expression formed with potentially direct selector}}
73  (void)@selector(inDerivedImpl); // expected-warning{{@selector expression formed with potentially direct selector}}
74  (void)@selector(inDerivedCat); // expected-warning{{@selector expression formed with potentially direct selector}}
75  (void)@selector(inDerivedCatImpl); // expected-warning{{@selector expression formed with potentially direct selector}}
76  (void)@selector(inDerivedClass); // expected-warning{{@selector expression formed with potentially direct selector}}
77  (void)@selector(inBaseClass); // expected-warning{{@selector expression formed with potentially direct selector}}
78  (void)@selector(inDerivedCatClass); // expected-warning{{@selector expression formed with potentially direct selector}}
79}
80@end
81
82void test2() {
83  (void)@selector(inBase); // strict-warning{{@selector expression formed with potentially direct selector}}
84  (void)@selector(inBaseImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
85  (void)@selector(inBaseCat); // strict-warning{{@selector expression formed with potentially direct selector}}
86  (void)@selector(inBaseCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
87  (void)@selector(inDerived); // strict-warning{{@selector expression formed with potentially direct selector}}
88  (void)@selector(inDerivedImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
89  (void)@selector(inDerivedCat); // strict-warning{{@selector expression formed with potentially direct selector}}
90  (void)@selector(inDerivedCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
91  (void)@selector(inDerivedClass); // strict-warning{{@selector expression formed with potentially direct selector}}
92  (void)@selector(inBaseClass); // strict-warning{{@selector expression formed with potentially direct selector}}
93  (void)@selector(inDerivedCatClass); // strict-warning{{@selector expression formed with potentially direct selector}}
94}
95
96@interface OnlyBase : Base @end
97@implementation OnlyBase
98-(void)test3 {
99  (void)@selector(inBase); // expected-warning{{@selector expression formed with potentially direct selector}}
100  (void)@selector(inBaseImpl); // expected-warning{{@selector expression formed with potentially direct selector}}
101  (void)@selector(inBaseCat); // expected-warning{{@selector expression formed with potentially direct selector}}
102  (void)@selector(inBaseCatImpl); // expected-warning{{@selector expression formed with potentially direct selector}}
103  (void)@selector(inDerived); // strict-warning{{@selector expression formed with potentially direct selector}}
104  (void)@selector(inDerivedImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
105  (void)@selector(inDerivedCat); // strict-warning{{@selector expression formed with potentially direct selector}}
106  (void)@selector(inDerivedCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
107  (void)@selector(inDerivedClass); // strict-warning{{@selector expression formed with potentially direct selector}}
108  (void)@selector(inBaseClass); // expected-warning{{@selector expression formed with potentially direct selector}}
109  (void)@selector(inDerivedCatClass); // strict-warning{{@selector expression formed with potentially direct selector}}
110}
111@end
112
113__attribute__((objc_root_class))
114@interface Unrelated @end
115@implementation Unrelated
116-(void)test4 {
117  (void)@selector(inBase); // strict-warning{{@selector expression formed with potentially direct selector}}
118  (void)@selector(inBaseImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
119  (void)@selector(inBaseCat); // strict-warning{{@selector expression formed with potentially direct selector}}
120  (void)@selector(inBaseCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
121  (void)@selector(inDerived); // strict-warning{{@selector expression formed with potentially direct selector}}
122  (void)@selector(inDerivedImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
123  (void)@selector(inDerivedCat); // strict-warning{{@selector expression formed with potentially direct selector}}
124  (void)@selector(inDerivedCatImpl); // strict-warning{{@selector expression formed with potentially direct selector}}
125  (void)@selector(inDerivedClass); // strict-warning{{@selector expression formed with potentially direct selector}}
126  (void)@selector(inBaseClass); // strict-warning{{@selector expression formed with potentially direct selector}}
127  (void)@selector(inDerivedCatClass); // strict-warning{{@selector expression formed with potentially direct selector}}
128}
129@end
130
131@implementation Dummies
132-(void)inBase {}
133-(void)inBaseImpl {}
134-(void)inBaseCat {}
135-(void)inBaseCatImpl {}
136-(void)inDerived {}
137-(void)inDerivedImpl {}
138-(void)inDerivedCat {}
139-(void)inDerivedCatImpl {}
140+(void)inBaseClass {}
141+(void)inDerivedClass {}
142+(void)inDerivedCatClass {}
143
144-(void)test5 {
145  (void)@selector(inBase);
146  (void)@selector(inBaseImpl);
147  (void)@selector(inBaseCat);
148  (void)@selector(inBaseCatImpl);
149  (void)@selector(inDerived);
150  (void)@selector(inDerivedImpl);
151  (void)@selector(inDerivedCat);
152  (void)@selector(inDerivedCatImpl);
153  (void)@selector(inDerivedClass);
154  (void)@selector(inBaseClass);
155  (void)@selector(inDerivedCatClass);
156}
157@end
158