xref: /llvm-project/clang/test/SemaObjC/attr-deprecated.m (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10.4 -verify -Wno-objc-root-class %s
2// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple x86_64-apple-darwin10.4 -verify -Wno-objc-root-class %s
3
4@interface A {
5  int X __attribute__((deprecated)); // expected-note 2 {{'X' has been explicitly marked deprecated here}}
6}
7+ (void)F __attribute__((deprecated)); // expected-note 2 {{'F' has been explicitly marked deprecated here}}
8- (void)f __attribute__((deprecated)); // expected-note 5 {{'f' has been explicitly marked deprecated here}}
9@end
10
11@implementation A
12+ (void)F __attribute__((deprecated))
13{
14  [self F]; // no warning, since the caller is also deprecated.
15}
16
17- (void)g
18{
19  X++;        // expected-warning{{'X' is deprecated}}
20  self->X++;  // expected-warning{{'X' is deprecated}}
21  [self f]; // expected-warning{{'f' is deprecated}}
22}
23
24- (void)f
25{
26  [self f]; // no warning, the caller is deprecated in its interface.
27}
28@end
29
30@interface B: A
31@end
32
33@implementation B
34+ (void)G
35{
36  [super F]; // expected-warning{{'F' is deprecated}}
37}
38
39- (void)g
40{
41  [super f]; // // expected-warning{{'f' is deprecated}}
42}
43@end
44
45@protocol P
46- (void)p __attribute__((deprecated)); // expected-note {{'p' has been explicitly marked deprecated here}}
47@end
48
49void t1(A *a)
50{
51  [A F]; // expected-warning{{'F' is deprecated}}
52  [a f]; // expected-warning{{'f' is deprecated}}
53}
54
55void t2(id a)
56{
57  [a f]; // expected-warning {{'f' is deprecated}}
58}
59
60void t3(A<P>* a)
61{
62  [a f]; // expected-warning{{'f' is deprecated}}
63  [a p]; // expected-warning{{'p' is deprecated}}
64}
65
66void t4(Class c)
67{
68  [c F];
69}
70
71
72
73@interface Bar
74
75@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{'FooBar' has been explicitly marked deprecated here}}
76- (void) MySetter : (int) value;
77@end
78
79int t5(void) {
80  Bar *f;
81  f.FooBar = 1;	   // expected-warning {{'FooBar' is deprecated}}
82  return f.FooBar; // expected-warning {{'FooBar' is deprecated}}
83}
84
85
86__attribute ((deprecated)) // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
87@interface DEPRECATED {
88  @public int ivar;
89  DEPRECATED *ivar2; // no warning.
90}
91- (int) instancemethod;
92- (DEPRECATED *) meth; // no warning.
93@property  int prop;
94@end
95
96@interface DEPRECATED (Category) // no warning.
97- (DEPRECATED *) meth2; // no warning.
98@end
99
100@interface DEPRECATED (Category2) // no warning.
101- (id)meth;
102@end
103
104__attribute__((deprecated))
105void depr_function(void);
106
107@implementation DEPRECATED (Category2) // no warning
108- (id)meth {
109  depr_function(); // no warning.
110  return 0;
111}
112@end
113
114@interface NS : DEPRECATED  // expected-warning {{'DEPRECATED' is deprecated}}
115@end
116
117
118@interface Test2
119@property int test2 __attribute__((deprecated)); // expected-note 2 {{property 'test2' is declared deprecated here}} expected-note 3 {{'test2' has been explicitly marked deprecated here}} \
120						 // expected-note {{'setTest2:' has been explicitly marked deprecated here}}
121@end
122
123void test(Test2 *foo) {
124  int x;
125  x = foo.test2; // expected-warning {{'test2' is deprecated}}
126  x = [foo test2]; // expected-warning {{'test2' is deprecated}}
127  foo.test2 = x; // expected-warning {{'test2' is deprecated}}
128  [foo setTest2: x]; // expected-warning {{'setTest2:' is deprecated}}
129}
130
131__attribute__((deprecated))
132@interface A(Blah) // no warning
133- (A*)getA;
134@end
135
136@implementation A(Blah) // Don't warn by default
137- (A*)getA {
138  return self;
139}
140@end
141
142typedef struct {
143	int x;
144} footype __attribute((deprecated)); // expected-note 2 {{'footype' has been explicitly marked deprecated here}}
145
146@interface foo {
147	footype a; // expected-warning {{'footype' is deprecated}}
148	footype b __attribute((deprecated));
149}
150@property footype c; // expected-warning {{'footype' is deprecated}}
151@property footype d __attribute((deprecated));
152@end
153
154@interface NewI
155+(void)cmeth;
156@end
157
158typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' has been explicitly marked deprecated here}}
159
160@interface SI : DeprI // expected-warning {{'DeprI' is deprecated: blah}}
161-(DeprI*)meth; // expected-warning {{'DeprI' is deprecated: blah}}
162@end
163
164@implementation SI
165-(DeprI*)meth { // expected-warning {{'DeprI' is deprecated: blah}}
166  [DeprI cmeth]; // expected-warning {{'DeprI' is deprecated: blah}}
167  return 0;
168}
169@end
170
171// - Using deprecated class name inside class should not warn about deprecation.
172// - Implementations of deprecated classes should not result in deprecation warnings.
173__attribute__((deprecated))
174@interface DeprecatedClassA
175@end
176
177__attribute__((deprecated))
178@interface DeprecatedClassB
179// The self-reference return value should not be
180// flagged as the use of a deprecated declaration.
181+ (DeprecatedClassB *)sharedInstance; // no-warning
182
183// Since this class is deprecated, returning a reference
184// to another deprecated class is fine as they may
185// have been deprecated together.  From a user's
186// perspective they are all deprecated.
187+ (DeprecatedClassA *)somethingElse; // no-warning
188@end
189
190@implementation DeprecatedClassB
191+ (DeprecatedClassB *)sharedInstance
192{
193  // This self-reference should not
194  // be flagged as a use of a deprecated
195  // declaration.
196  static DeprecatedClassB *x; // no-warning
197  return x;
198}
199+ (DeprecatedClassA *)somethingElse {
200  // Since this class is deprecated, referencing
201  // another deprecated class is also OK.
202  static DeprecatedClassA *x; // no-warning
203  return x;
204}
205
206@end
207
208@interface TestBase
209@property (nonatomic, strong) id object __attribute__((deprecated("deprecated"))); // expected-note {{'object' has been explicitly marked deprecated here}} \
210expected-note {{property 'object' is declared deprecated here}} \
211expected-note {{'setObject:' has been explicitly marked deprecated here}} \
212expected-note {{property declared here}}
213@end
214
215@interface TestDerived : TestBase
216@property (nonatomic, strong) id object; //expected-warning {{auto property synthesis will not synthesize property 'object'; it will be implemented by its superclass}}
217@end
218
219@interface TestUse @end
220
221@implementation TestBase @end
222
223@implementation TestDerived @end // expected-note {{detected while default synthesizing properties in class implementation}}
224
225@implementation TestUse
226
227- (void) use
228{
229    TestBase *base = (id)0;
230    TestDerived *derived = (id)0;
231    id object = (id)0;
232
233    base.object = object; // expected-warning {{'object' is deprecated: deprecated}}
234    derived.object = object;
235
236    [base setObject:object];  // expected-warning {{'setObject:' is deprecated: deprecated}}
237    [derived setObject:object];
238}
239
240@end
241
242@interface NSString
243- (const char *)cString __attribute__((availability(macosx,introduced=10.0 ,deprecated=10.4,message="" ))); // expected-note {{'cString' has been explicitly marked deprecated here}}
244@end
245
246id PID = 0;
247const char * func(void) {
248  return [PID cString]; // expected-warning {{'cString' is deprecated: first deprecated in macOS 10.4}}
249}
250
251@interface NSObject
252+ (instancetype)alloc;
253- (instancetype)init;
254@end
255
256@interface NSLocale
257- (instancetype)init __attribute__((unavailable));
258@end
259
260@interface PLBatteryProperties : NSObject
261+ (id)properties;
262@end
263
264@implementation PLBatteryProperties
265+ (id)properties {
266    return [[self alloc] init];
267}
268@end
269
270@implementation UndeclaredImpl // expected-warning{{cannot find interface declaration}}
271- (void)partiallyUnavailableMethod {}
272@end
273
274@interface InterfaceWithSameMethodAsUndeclaredImpl
275- (void)partiallyUnavailableMethod __attribute__((unavailable));
276@end
277
278void f(id a) {
279  [a partiallyUnavailableMethod]; // no warning, `a` could be an UndeclaredImpl.
280}
281
282@interface InterfaceWithImplementation
283- (void)anotherPartiallyUnavailableMethod;
284@end
285@implementation InterfaceWithImplementation
286- (void)anotherPartiallyUnavailableMethod {}
287@end
288
289@interface InterfaceWithSameMethodAsInterfaceWithImplementation
290- (void)anotherPartiallyUnavailableMethod __attribute__((unavailable));
291@end
292
293void g(id a) {
294  [a anotherPartiallyUnavailableMethod]; // no warning, `a` could be an InterfaceWithImplementation.
295}
296
297typedef struct {} S1 __attribute__((unavailable)); // expected-note2{{marked unavailable here}}
298typedef struct {} S2 __attribute__((deprecated)); // expected-note2{{marked deprecated here}}
299@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}}
300- (void)method1:(S1) x; // expected-error{{is unavailable}}
301- (void)method2:(S2) x; // expected-warning{{is deprecated}}
302@end
303@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
304- (void)method1:(S1) x; // expected-error{{is unavailable}}
305- (void)method2:(S2) x; // expected-warning{{is deprecated}}
306@end
307