203 lines
5.0 KiB
Objective-C
203 lines
5.0 KiB
Objective-C
// RUN: %clang_cc1 -verify -Wno-deprecated-declarations -Wno-objc-root-class %s
|
|
|
|
@interface Unrelated
|
|
@end
|
|
|
|
@interface NSObject
|
|
+ (id)new;
|
|
+ (id)alloc;
|
|
- (NSObject *)init;
|
|
|
|
- (id)retain; // expected-note{{instance method 'retain' is assumed to return an instance of its receiver type ('NSArray *')}}
|
|
- autorelease;
|
|
|
|
- (id)self;
|
|
|
|
- (id)copy;
|
|
- (id)mutableCopy;
|
|
|
|
// Do not infer when instance/class mismatches
|
|
- (id)newNotInferred;
|
|
- (id)alloc;
|
|
+ (id)initWithBlarg;
|
|
+ (id)self;
|
|
|
|
// Do not infer when the return types mismatch.
|
|
- (Unrelated *)initAsUnrelated;
|
|
@end
|
|
|
|
@interface NSString : NSObject
|
|
- (id)init;
|
|
- (id)initWithCString:(const char*)string;
|
|
@end
|
|
|
|
@interface NSArray : NSObject
|
|
- (unsigned)count;
|
|
@end
|
|
|
|
@interface NSBlah
|
|
@end
|
|
|
|
@interface NSMutableArray : NSArray
|
|
@end
|
|
|
|
@interface NSBlah ()
|
|
+ (Unrelated *)newUnrelated;
|
|
@end
|
|
|
|
void test_inference() {
|
|
// Inference based on method family
|
|
__typeof__(([[NSString alloc] init])) *str = (NSString**)0;
|
|
__typeof__(([[[[NSString new] self] retain] autorelease])) *str2 = (NSString **)0;
|
|
__typeof__(([[NSString alloc] initWithCString:"blah"])) *str3 = (NSString**)0;
|
|
|
|
// Not inferred
|
|
__typeof__(([[NSString new] copy])) *id1 = (id*)0;
|
|
|
|
// Not inferred due to instance/class mismatches
|
|
__typeof__(([[NSString new] newNotInferred])) *id2 = (id*)0;
|
|
__typeof__(([[NSString new] alloc])) *id3 = (id*)0;
|
|
__typeof__(([NSString self])) *id4 = (id*)0;
|
|
__typeof__(([NSString initWithBlarg])) *id5 = (id*)0;
|
|
|
|
// Not inferred due to return type mismatch
|
|
__typeof__(([[NSString alloc] initAsUnrelated])) *unrelated = (Unrelated**)0;
|
|
__typeof__(([NSBlah newUnrelated])) *unrelated2 = (Unrelated**)0;
|
|
|
|
|
|
NSArray *arr = [[NSMutableArray alloc] init];
|
|
NSMutableArray *marr = [arr retain]; // expected-warning{{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}}
|
|
}
|
|
|
|
@implementation NSBlah
|
|
+ (Unrelated *)newUnrelated {
|
|
return (Unrelated *)0;
|
|
}
|
|
@end
|
|
|
|
@implementation NSBlah (Cat)
|
|
+ (Unrelated *)newUnrelated2 {
|
|
return (Unrelated *)0;
|
|
}
|
|
@end
|
|
|
|
@interface A
|
|
- (id)initBlah; // expected-note 2{{overridden method is part of the 'init' method family}}
|
|
@end
|
|
|
|
@interface B : A
|
|
- (Unrelated *)initBlah; // expected-warning{{method is expected to return an instance of its class type 'B', but is declared to return 'Unrelated *'}}
|
|
@end
|
|
|
|
@interface C : A
|
|
@end
|
|
|
|
@implementation C
|
|
- (Unrelated *)initBlah { // expected-warning{{method is expected to return an instance of its class type 'C', but is declared to return 'Unrelated *'}}
|
|
return (Unrelated *)0;
|
|
}
|
|
@end
|
|
|
|
@interface D
|
|
+ (id)newBlarg; // expected-note{{overridden method is part of the 'new' method family}}
|
|
@end
|
|
|
|
@interface D ()
|
|
+ alloc; // expected-note{{overridden method is part of the 'alloc' method family}}
|
|
@end
|
|
|
|
@implementation D
|
|
+ (Unrelated *)newBlarg { // expected-warning{{method is expected to return an instance of its class type 'D', but is declared to return 'Unrelated *'}}
|
|
return (Unrelated *)0;
|
|
}
|
|
|
|
+ (Unrelated *)alloc { // expected-warning{{method is expected to return an instance of its class type 'D', but is declared to return 'Unrelated *'}}
|
|
return (Unrelated *)0;
|
|
}
|
|
@end
|
|
|
|
@protocol P1
|
|
- (id)initBlah; // expected-note{{overridden method is part of the 'init' method family}}
|
|
- (int)initBlarg;
|
|
@end
|
|
|
|
@protocol P2 <P1>
|
|
- (int)initBlah; // expected-warning{{protocol method is expected to return an instance of the implementing class, but is declared to return 'int'}}
|
|
- (int)initBlarg;
|
|
- (int)initBlech;
|
|
@end
|
|
|
|
@interface E
|
|
- init;
|
|
@end
|
|
|
|
@implementation E
|
|
- init {
|
|
return self;
|
|
}
|
|
@end
|
|
|
|
@protocol P3
|
|
+ (NSString *)newString;
|
|
@end
|
|
|
|
@interface F<P3>
|
|
@end
|
|
|
|
@implementation F
|
|
+ (NSString *)newString { return @"blah"; }
|
|
@end
|
|
|
|
// <rdar://problem/9340699>
|
|
@interface G
|
|
- (id)_ABC_init __attribute__((objc_method_family(init))); // expected-note {{method '_ABC_init' declared here}}
|
|
@end
|
|
|
|
@interface G (Additions)
|
|
- (id)_ABC_init2 __attribute__((objc_method_family(init)));
|
|
@end
|
|
|
|
@implementation G (Additions)
|
|
- (id)_ABC_init { // expected-warning {{category is implementing a method which will also be implemented by its primary class}}
|
|
return 0;
|
|
}
|
|
- (id)_ABC_init2 {
|
|
return 0;
|
|
}
|
|
- (id)_ABC_init3 {
|
|
return 0;
|
|
}
|
|
@end
|
|
|
|
// PR12384
|
|
@interface Fail @end
|
|
@protocol X @end
|
|
@implementation Fail
|
|
- (id<X>) initWithX // expected-note {{compiler has implicitly changed method 'initWithX' return type}}
|
|
{
|
|
return (id)self; // expected-warning {{casting 'Fail *' to incompatible type 'id<X>'}}
|
|
}
|
|
@end
|
|
|
|
// <rdar://problem/11460990>
|
|
|
|
@interface WeirdNSString : NSString
|
|
- (id)initWithCString:(const char*)string, void *blah;
|
|
@end
|
|
|
|
|
|
// rdar://14121570
|
|
@protocol PMFilterManager
|
|
@end
|
|
|
|
@interface UIViewController : NSObject
|
|
@end
|
|
|
|
@implementation UIViewController
|
|
+ (UIViewController<PMFilterManager> *)newFilterViewControllerForType // expected-note {{compiler has implicitly changed method 'newFilterViewControllerForType' return type}}
|
|
{
|
|
UIViewController<PMFilterManager> *filterVC;
|
|
return filterVC; // expected-warning {{incompatible pointer types casting 'UIViewController *' to type 'UIViewController<PMFilterManager> *'}}
|
|
}
|
|
@end
|