312 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
			
		
		
	
	
			312 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
| // 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
 |