| // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10.4 -verify -Wno-objc-root-class %s |
| // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple x86_64-apple-darwin10.4 -verify -Wno-objc-root-class %s |
| |
| @interface A { |
| int X __attribute__((deprecated)); // expected-note 2 {{'X' has been explicitly marked deprecated here}} |
| } |
| + (void)F __attribute__((deprecated)); // expected-note 2 {{'F' has been explicitly marked deprecated here}} |
| - (void)f __attribute__((deprecated)); // expected-note 5 {{'f' has been explicitly marked deprecated here}} |
| @end |
| |
| @implementation A |
| + (void)F __attribute__((deprecated)) |
| { |
| [self F]; // no warning, since the caller is also deprecated. |
| } |
| |
| - (void)g |
| { |
| X++; // expected-warning{{'X' is deprecated}} |
| self->X++; // expected-warning{{'X' is deprecated}} |
| [self f]; // expected-warning{{'f' is deprecated}} |
| } |
| |
| - (void)f |
| { |
| [self f]; // no warning, the caller is deprecated in its interface. |
| } |
| @end |
| |
| @interface B: A |
| @end |
| |
| @implementation B |
| + (void)G |
| { |
| [super F]; // expected-warning{{'F' is deprecated}} |
| } |
| |
| - (void)g |
| { |
| [super f]; // // expected-warning{{'f' is deprecated}} |
| } |
| @end |
| |
| @protocol P |
| - (void)p __attribute__((deprecated)); // expected-note {{'p' has been explicitly marked deprecated here}} |
| @end |
| |
| void t1(A *a) |
| { |
| [A F]; // expected-warning{{'F' is deprecated}} |
| [a f]; // expected-warning{{'f' is deprecated}} |
| } |
| |
| void t2(id a) |
| { |
| [a f]; // expected-warning {{'f' is deprecated}} |
| } |
| |
| void t3(A<P>* a) |
| { |
| [a f]; // expected-warning{{'f' is deprecated}} |
| [a p]; // expected-warning{{'p' is deprecated}} |
| } |
| |
| void t4(Class c) |
| { |
| [c F]; |
| } |
| |
| |
| |
| @interface Bar |
| |
| @property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{'FooBar' has been explicitly marked deprecated here}} |
| - (void) MySetter : (int) value; |
| @end |
| |
| int t5() { |
| Bar *f; |
| f.FooBar = 1; // expected-warning {{'FooBar' is deprecated}} |
| return f.FooBar; // expected-warning {{'FooBar' is deprecated}} |
| } |
| |
| |
| __attribute ((deprecated)) // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}} |
| @interface DEPRECATED { |
| @public int ivar; |
| DEPRECATED *ivar2; // no warning. |
| } |
| - (int) instancemethod; |
| - (DEPRECATED *) meth; // no warning. |
| @property int prop; |
| @end |
| |
| @interface DEPRECATED (Category) // no warning. |
| - (DEPRECATED *) meth2; // no warning. |
| @end |
| |
| @interface DEPRECATED (Category2) // no warning. |
| - (id)meth; |
| @end |
| |
| __attribute__((deprecated)) |
| void depr_function(); |
| |
| @implementation DEPRECATED (Category2) // no warning |
| - (id)meth { |
| depr_function(); // no warning. |
| return 0; |
| } |
| @end |
| |
| @interface NS : DEPRECATED // expected-warning {{'DEPRECATED' is deprecated}} |
| @end |
| |
| |
| @interface Test2 |
| @property int test2 __attribute__((deprecated)); // expected-note 2 {{property 'test2' is declared deprecated here}} expected-note 3 {{'test2' has been explicitly marked deprecated here}} \ |
| // expected-note {{'setTest2:' has been explicitly marked deprecated here}} |
| @end |
| |
| void test(Test2 *foo) { |
| int x; |
| x = foo.test2; // expected-warning {{'test2' is deprecated}} |
| x = [foo test2]; // expected-warning {{'test2' is deprecated}} |
| foo.test2 = x; // expected-warning {{'test2' is deprecated}} |
| [foo setTest2: x]; // expected-warning {{'setTest2:' is deprecated}} |
| } |
| |
| __attribute__((deprecated)) |
| @interface A(Blah) // no warning |
| - (A*)getA; |
| @end |
| |
| @implementation A(Blah) // Don't warn by default |
| - (A*)getA { |
| return self; |
| } |
| @end |
| |
| typedef struct { |
| int x; |
| } footype __attribute((deprecated)); // expected-note 2 {{'footype' has been explicitly marked deprecated here}} |
| |
| @interface foo { |
| footype a; // expected-warning {{'footype' is deprecated}} |
| footype b __attribute((deprecated)); |
| } |
| @property footype c; // expected-warning {{'footype' is deprecated}} |
| @property footype d __attribute((deprecated)); |
| @end |
| |
| // rdar://13569424 |
| @interface NewI |
| +(void)cmeth; |
| @end |
| |
| typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' has been explicitly marked deprecated here}} |
| |
| @interface SI : DeprI // expected-warning {{'DeprI' is deprecated: blah}} |
| -(DeprI*)meth; // expected-warning {{'DeprI' is deprecated: blah}} |
| @end |
| |
| @implementation SI |
| -(DeprI*)meth { // expected-warning {{'DeprI' is deprecated: blah}} |
| [DeprI cmeth]; // expected-warning {{'DeprI' is deprecated: blah}} |
| return 0; |
| } |
| @end |
| |
| // <rdar://problem/15407366> and <rdar://problem/15466783>: |
| // - Using deprecated class name inside class should not warn about deprecation. |
| // - Implementations of deprecated classes should not result in deprecation warnings. |
| __attribute__((deprecated)) |
| @interface DeprecatedClassA |
| @end |
| |
| __attribute__((deprecated)) |
| @interface DeprecatedClassB |
| // The self-reference return value should not be |
| // flagged as the use of a deprecated declaration. |
| + (DeprecatedClassB *)sharedInstance; // no-warning |
| |
| // Since this class is deprecated, returning a reference |
| // to another deprecated class is fine as they may |
| // have been deprecated together. From a user's |
| // perspective they are all deprecated. |
| + (DeprecatedClassA *)somethingElse; // no-warning |
| @end |
| |
| @implementation DeprecatedClassB |
| + (DeprecatedClassB *)sharedInstance |
| { |
| // This self-reference should not |
| // be flagged as a use of a deprecated |
| // declaration. |
| static DeprecatedClassB *x; // no-warning |
| return x; |
| } |
| + (DeprecatedClassA *)somethingElse { |
| // Since this class is deprecated, referencing |
| // another deprecated class is also OK. |
| static DeprecatedClassA *x; // no-warning |
| return x; |
| } |
| |
| @end |
| |
| // rdar://16068470 |
| @interface TestBase |
| @property (nonatomic, strong) id object __attribute__((deprecated("deprecated"))); // expected-note {{'object' has been explicitly marked deprecated here}} \ |
| expected-note {{property 'object' is declared deprecated here}} \ |
| expected-note {{'setObject:' has been explicitly marked deprecated here}} \ |
| expected-note {{property declared here}} |
| @end |
| |
| @interface TestDerived : TestBase |
| @property (nonatomic, strong) id object; //expected-warning {{auto property synthesis will not synthesize property 'object'; it will be implemented by its superclass}} |
| @end |
| |
| @interface TestUse @end |
| |
| @implementation TestBase @end |
| |
| @implementation TestDerived @end // expected-note {{detected while default synthesizing properties in class implementation}} |
| |
| @implementation TestUse |
| |
| - (void) use |
| { |
| TestBase *base = (id)0; |
| TestDerived *derived = (id)0; |
| id object = (id)0; |
| |
| base.object = object; // expected-warning {{'object' is deprecated: deprecated}} |
| derived.object = object; |
| |
| [base setObject:object]; // expected-warning {{'setObject:' is deprecated: deprecated}} |
| [derived setObject:object]; |
| } |
| |
| @end |
| |
| // rdar://18848183 |
| @interface NSString |
| - (const char *)cString __attribute__((availability(macosx,introduced=10.0 ,deprecated=10.4,message="" ))); // expected-note {{'cString' has been explicitly marked deprecated here}} |
| @end |
| |
| id PID = 0; |
| const char * func() { |
| return [PID cString]; // expected-warning {{'cString' is deprecated: first deprecated in macOS 10.4}} |
| } |
| |
| // rdar://18960378 |
| @interface NSObject |
| + (instancetype)alloc; |
| - (instancetype)init; |
| @end |
| |
| @interface NSLocale |
| - (instancetype)init __attribute__((unavailable)); |
| @end |
| |
| @interface PLBatteryProperties : NSObject |
| + (id)properties; |
| @end |
| |
| @implementation PLBatteryProperties |
| + (id)properties { |
| return [[self alloc] init]; |
| } |
| @end |
| |
| @implementation UndeclaredImpl // expected-warning{{cannot find interface declaration}} |
| - (void)partiallyUnavailableMethod {} |
| @end |
| |
| @interface InterfaceWithSameMethodAsUndeclaredImpl |
| - (void)partiallyUnavailableMethod __attribute__((unavailable)); |
| @end |
| |
| void f(id a) { |
| [a partiallyUnavailableMethod]; // no warning, `a` could be an UndeclaredImpl. |
| } |
| |
| @interface InterfaceWithImplementation |
| - (void)anotherPartiallyUnavailableMethod; |
| @end |
| @implementation InterfaceWithImplementation |
| - (void)anotherPartiallyUnavailableMethod {} |
| @end |
| |
| @interface InterfaceWithSameMethodAsInterfaceWithImplementation |
| - (void)anotherPartiallyUnavailableMethod __attribute__((unavailable)); |
| @end |
| |
| void g(id a) { |
| [a anotherPartiallyUnavailableMethod]; // no warning, `a` could be an InterfaceWithImplementation. |
| } |
| |
| typedef struct {} S1 __attribute__((unavailable)); // expected-note2{{marked unavailable here}} |
| typedef struct {} S2 __attribute__((deprecated)); // expected-note2{{marked deprecated here}} |
| @interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}} |
| - (void)method1:(S1) x; // expected-error{{is unavailable}} |
| - (void)method2:(S2) x; // expected-warning{{is deprecated}} |
| @end |
| @interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}} |
| - (void)method1:(S1) x; // expected-error{{is unavailable}} |
| - (void)method2:(S2) x; // expected-warning{{is deprecated}} |
| @end |