1*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -fblocks -Woverriding-method-mismatch -Wno-nullability-declspec %s -verify 2*67e74705SXin Li 3*67e74705SXin Li__attribute__((objc_root_class)) 4*67e74705SXin Li@interface NSFoo 5*67e74705SXin Li- (void)methodTakingIntPtr:(_Nonnull int *)ptr; 6*67e74705SXin Li- (_Nonnull int *)methodReturningIntPtr; 7*67e74705SXin Li@end 8*67e74705SXin Li 9*67e74705SXin Li// Nullability applies to all pointer types. 10*67e74705SXin Litypedef NSFoo * _Nonnull nonnull_NSFoo_ptr; 11*67e74705SXin Litypedef id _Nonnull nonnull_id; 12*67e74705SXin Litypedef SEL _Nonnull nonnull_SEL; 13*67e74705SXin Li 14*67e74705SXin Li// Nullability can move into Objective-C pointer types. 15*67e74705SXin Litypedef _Nonnull NSFoo * nonnull_NSFoo_ptr_2; 16*67e74705SXin Li 17*67e74705SXin Li// Conflicts from nullability moving into Objective-C pointer type. 18*67e74705SXin Litypedef _Nonnull NSFoo * _Nullable conflict_NSFoo_ptr_2; // expected-error{{'_Nonnull' cannot be applied to non-pointer type 'NSFoo'}} 19*67e74705SXin Li 20*67e74705SXin Livoid testBlocksPrinting(NSFoo * _Nullable (^bp)(int)) { 21*67e74705SXin Li int *ip = bp; // expected-error{{'NSFoo * _Nullable (^)(int)'}} 22*67e74705SXin Li} 23*67e74705SXin Li 24*67e74705SXin Li// Check returning nil from a _Nonnull-returning method. 25*67e74705SXin Li@implementation NSFoo 26*67e74705SXin Li- (void)methodTakingIntPtr:(_Nonnull int *)ptr { } 27*67e74705SXin Li- (_Nonnull int *)methodReturningIntPtr { 28*67e74705SXin Li return 0; // no warning 29*67e74705SXin Li} 30*67e74705SXin Li@end 31*67e74705SXin Li 32*67e74705SXin Li// Context-sensitive keywords and property attributes for nullability. 33*67e74705SXin Li__attribute__((objc_root_class)) 34*67e74705SXin Li@interface NSBar 35*67e74705SXin Li- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo; 36*67e74705SXin Li 37*67e74705SXin Li- (nonnull NSFoo **)invalidMethod1; // expected-error{{nullability keyword 'nonnull' cannot be applied to multi-level pointer type 'NSFoo **'}} 38*67e74705SXin Li// expected-note@-1{{use nullability type specifier '_Nonnull' to affect the innermost pointer type of 'NSFoo **'}} 39*67e74705SXin Li- (nonnull NSFoo * _Nullable)conflictingMethod1; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}} 40*67e74705SXin Li- (nonnull NSFoo * _Nonnull)redundantMethod1; // expected-warning{{duplicate nullability specifier '_Nonnull'}} 41*67e74705SXin Li 42*67e74705SXin Li@property(nonnull,retain) NSFoo *property1; 43*67e74705SXin Li@property(nullable,assign) NSFoo ** invalidProperty1; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}} 44*67e74705SXin Li// expected-note@-1{{use nullability type specifier '_Nullable' to affect the innermost pointer type of 'NSFoo **'}} 45*67e74705SXin Li@property(null_unspecified,retain) NSFoo * _Nullable conflictingProperty1; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Null_unspecified'}} 46*67e74705SXin Li@property(retain,nonnull) NSFoo * _Nonnull redundantProperty1; // expected-warning{{duplicate nullability specifier '_Nonnull'}} 47*67e74705SXin Li 48*67e74705SXin Li@property(null_unspecified,retain,nullable) NSFoo *conflictingProperty3; // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'null_unspecified'}} 49*67e74705SXin Li@property(nullable,retain,nullable) NSFoo *redundantProperty3; // expected-warning{{duplicate nullability specifier 'nullable'}} 50*67e74705SXin Li@end 51*67e74705SXin Li 52*67e74705SXin Li@interface NSBar () 53*67e74705SXin Li@property(nonnull,retain) NSFoo *property2; 54*67e74705SXin Li@property(nullable,assign) NSFoo ** invalidProperty2; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}} 55*67e74705SXin Li// expected-note@-1{{use nullability type specifier '_Nullable' to affect the innermost pointer type of 'NSFoo **'}} 56*67e74705SXin Li@property(null_unspecified,retain) NSFoo * _Nullable conflictingProperty2; // expected-error{{nullability specifier '_Nullable' conflicts with existing specifier '_Null_unspecified'}} 57*67e74705SXin Li@property(retain,nonnull) NSFoo * _Nonnull redundantProperty2; // expected-warning{{duplicate nullability specifier '_Nonnull'}} 58*67e74705SXin Li@end 59*67e74705SXin Li 60*67e74705SXin Livoid test_accepts_nonnull_null_pointer_literal(NSFoo *foo, _Nonnull NSBar *bar) { 61*67e74705SXin Li [foo methodTakingIntPtr: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 62*67e74705SXin Li [bar methodWithFoo: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 63*67e74705SXin Li bar.property1 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}} 64*67e74705SXin Li bar.property2 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}} 65*67e74705SXin Li [bar setProperty1: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 66*67e74705SXin Li [bar setProperty2: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 67*67e74705SXin Li int *ptr = bar.property1; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}} 68*67e74705SXin Li} 69*67e74705SXin Li 70*67e74705SXin Li// Check returning nil from a nonnull-returning method. 71*67e74705SXin Li@implementation NSBar 72*67e74705SXin Li- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo { 73*67e74705SXin Li return 0; // no warning 74*67e74705SXin Li} 75*67e74705SXin Li 76*67e74705SXin Li- (NSFoo **)invalidMethod1 { 77*67e74705SXin Li return 0; 78*67e74705SXin Li} 79*67e74705SXin Li 80*67e74705SXin Li- (NSFoo *)conflictingMethod1 { 81*67e74705SXin Li return 0; // no warning 82*67e74705SXin Li} 83*67e74705SXin Li- (NSFoo *)redundantMethod1 { 84*67e74705SXin Li int *ip = 0; 85*67e74705SXin Li return ip; // expected-warning{{result type 'NSFoo * _Nonnull'}} 86*67e74705SXin Li} 87*67e74705SXin Li@end 88*67e74705SXin Li 89*67e74705SXin Li__attribute__((objc_root_class)) 90*67e74705SXin Li@interface NSMerge 91*67e74705SXin Li- (nonnull NSFoo *)methodA:(nonnull NSFoo*)foo; 92*67e74705SXin Li- (nonnull NSFoo *)methodB:(nonnull NSFoo*)foo; 93*67e74705SXin Li- (NSFoo *)methodC:(NSFoo*)foo; 94*67e74705SXin Li@end 95*67e74705SXin Li 96*67e74705SXin Li@implementation NSMerge 97*67e74705SXin Li- (NSFoo *)methodA:(NSFoo*)foo { 98*67e74705SXin Li int *ptr = foo; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}} 99*67e74705SXin Li return ptr; // expected-warning{{result type 'NSFoo * _Nonnull'}} 100*67e74705SXin Li} 101*67e74705SXin Li 102*67e74705SXin Li- (nullable NSFoo *)methodB:(null_unspecified NSFoo*)foo { // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'nonnull'}} \ 103*67e74705SXin Li // expected-error{{nullability specifier 'null_unspecified' conflicts with existing specifier 'nonnull'}} 104*67e74705SXin Li return 0; 105*67e74705SXin Li} 106*67e74705SXin Li 107*67e74705SXin Li- (nonnull NSFoo *)methodC:(nullable NSFoo*)foo { 108*67e74705SXin Li int *ip = 0; 109*67e74705SXin Li return ip; // expected-warning{{result type 'NSFoo * _Nonnull'}} 110*67e74705SXin Li} 111*67e74705SXin Li@end 112*67e74705SXin Li 113*67e74705SXin Li// Checking merging of nullability when sending a message. 114*67e74705SXin Li@interface NSMergeReceiver 115*67e74705SXin Li- (id)returnsNone; 116*67e74705SXin Li- (nonnull id)returnsNonNull; 117*67e74705SXin Li- (nullable id)returnsNullable; 118*67e74705SXin Li- (null_unspecified id)returnsNullUnspecified; 119*67e74705SXin Li@end 120*67e74705SXin Li 121*67e74705SXin Livoid test_receiver_merge(NSMergeReceiver *none, 122*67e74705SXin Li _Nonnull NSMergeReceiver *nonnull, 123*67e74705SXin Li _Nullable NSMergeReceiver *nullable, 124*67e74705SXin Li _Null_unspecified NSMergeReceiver *null_unspecified) { 125*67e74705SXin Li int *ptr; 126*67e74705SXin Li 127*67e74705SXin Li ptr = [nullable returnsNullable]; // expected-warning{{'id _Nullable'}} 128*67e74705SXin Li ptr = [nullable returnsNullUnspecified]; // expected-warning{{'id _Nullable'}} 129*67e74705SXin Li ptr = [nullable returnsNonNull]; // expected-warning{{'id _Nullable'}} 130*67e74705SXin Li ptr = [nullable returnsNone]; // expected-warning{{'id _Nullable'}} 131*67e74705SXin Li 132*67e74705SXin Li ptr = [null_unspecified returnsNullable]; // expected-warning{{'id _Nullable'}} 133*67e74705SXin Li ptr = [null_unspecified returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}} 134*67e74705SXin Li ptr = [null_unspecified returnsNonNull]; // expected-warning{{'id _Null_unspecified'}} 135*67e74705SXin Li ptr = [null_unspecified returnsNone]; // expected-warning{{'id'}} 136*67e74705SXin Li 137*67e74705SXin Li ptr = [nonnull returnsNullable]; // expected-warning{{'id _Nullable'}} 138*67e74705SXin Li ptr = [nonnull returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}} 139*67e74705SXin Li ptr = [nonnull returnsNonNull]; // expected-warning{{'id _Nonnull'}} 140*67e74705SXin Li ptr = [nonnull returnsNone]; // expected-warning{{'id'}} 141*67e74705SXin Li 142*67e74705SXin Li ptr = [none returnsNullable]; // expected-warning{{'id _Nullable'}} 143*67e74705SXin Li ptr = [none returnsNullUnspecified]; // expected-warning{{'id'}} 144*67e74705SXin Li ptr = [none returnsNonNull]; // expected-warning{{'id'}} 145*67e74705SXin Li ptr = [none returnsNone]; // expected-warning{{'id'}} 146*67e74705SXin Li 147*67e74705SXin Li} 148*67e74705SXin Li 149*67e74705SXin Li// instancetype 150*67e74705SXin Li@protocol Initializable 151*67e74705SXin Li- (instancetype)initWithBlah:(id)blah; 152*67e74705SXin Li@end 153*67e74705SXin Li 154*67e74705SXin Li__attribute__((objc_root_class)) 155*67e74705SXin Li@interface InitializableClass <Initializable> 156*67e74705SXin Li- (nonnull instancetype)initWithBlah:(nonnull id)blah; 157*67e74705SXin Li- (nullable instancetype)returnMe; 158*67e74705SXin Li+ (nullable instancetype)returnInstanceOfMe; 159*67e74705SXin Li 160*67e74705SXin Li- (nonnull instancetype _Nullable)initWithBlah2:(nonnull id)blah; // expected-error {{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}} 161*67e74705SXin Li- (instancetype _Nullable)returnMe2; 162*67e74705SXin Li+ (_Nonnull instancetype)returnInstanceOfMe2; 163*67e74705SXin Li@end 164*67e74705SXin Li 165*67e74705SXin Livoid test_instancetype(InitializableClass * _Nonnull ic, id _Nonnull object) { 166*67e74705SXin Li int *ip = [ic returnMe]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'InitializableClass * _Nullable'}} 167*67e74705SXin Li ip = [InitializableClass returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}} 168*67e74705SXin Li ip = [InitializableClass returnInstanceOfMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}} 169*67e74705SXin Li ip = [object returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}} 170*67e74705SXin Li 171*67e74705SXin Li ip = [ic returnMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}} 172*67e74705SXin Li ip = [InitializableClass returnInstanceOfMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nonnull'}} 173*67e74705SXin Li} 174*67e74705SXin Li 175*67e74705SXin Li// Check null_resettable getters/setters. 176*67e74705SXin Li__attribute__((objc_root_class)) 177*67e74705SXin Li@interface NSResettable 178*67e74705SXin Li@property(null_resettable,retain) NSResettable *resettable1; // expected-note{{passing argument to parameter 'resettable1' here}} 179*67e74705SXin Li@property(null_resettable,retain,nonatomic) NSResettable *resettable2; 180*67e74705SXin Li@property(null_resettable,retain,nonatomic) NSResettable *resettable3; 181*67e74705SXin Li@property(null_resettable,retain,nonatomic) NSResettable *resettable4; 182*67e74705SXin Li@property(null_resettable,retain,nonatomic) NSResettable *resettable5; 183*67e74705SXin Li@property(null_resettable,retain,nonatomic) NSResettable *resettable6; 184*67e74705SXin Li@end 185*67e74705SXin Li 186*67e74705SXin Livoid test_null_resettable(NSResettable *r, int *ip) { 187*67e74705SXin Li [r setResettable1:ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'NSResettable * _Nullable'}} 188*67e74705SXin Li r.resettable1 = ip; // expected-warning{{incompatible pointer types assigning to 'NSResettable * _Nullable' from 'int *'}} 189*67e74705SXin Li} 190*67e74705SXin Li 191*67e74705SXin Li@implementation NSResettable // expected-warning{{synthesized setter 'setResettable4:' for null_resettable property 'resettable4' does not handle nil}} 192*67e74705SXin Li- (NSResettable *)resettable1 { 193*67e74705SXin Li int *ip = 0; 194*67e74705SXin Li return ip; // expected-warning{{result type 'NSResettable * _Nonnull'}} 195*67e74705SXin Li} 196*67e74705SXin Li 197*67e74705SXin Li- (void)setResettable1:(NSResettable *)param { 198*67e74705SXin Li} 199*67e74705SXin Li 200*67e74705SXin Li@synthesize resettable2; // no warning; not synthesized 201*67e74705SXin Li@synthesize resettable3; // expected-warning{{synthesized setter 'setResettable3:' for null_resettable property 'resettable3' does not handle nil}} 202*67e74705SXin Li 203*67e74705SXin Li- (void)setResettable2:(NSResettable *)param { 204*67e74705SXin Li} 205*67e74705SXin Li 206*67e74705SXin Li@dynamic resettable5; 207*67e74705SXin Li 208*67e74705SXin Li- (NSResettable *)resettable6 { 209*67e74705SXin Li return 0; // no warning 210*67e74705SXin Li} 211*67e74705SXin Li@end 212*67e74705SXin Li 213*67e74705SXin Li// rdar://problem/19814852 214*67e74705SXin Li@interface MultiProp 215*67e74705SXin Li@property (nullable, copy) id a, b, c; 216*67e74705SXin Li@property (nullable, copy) MultiProp *d, *(^e)(int); 217*67e74705SXin Li@end 218*67e74705SXin Li 219*67e74705SXin Livoid testMultiProp(MultiProp *foo) { 220*67e74705SXin Li int *ip; 221*67e74705SXin Li ip = foo.a; // expected-warning{{from 'id _Nullable'}} 222*67e74705SXin Li ip = foo.d; // expected-warning{{from 'MultiProp * _Nullable'}} 223*67e74705SXin Li ip = foo.e; // expected-error{{incompatible type 'MultiProp *(^ _Nullable)(int)'}} 224*67e74705SXin Li} 225*67e74705SXin Li 226*67e74705SXin Livoid testBlockLiterals() { 227*67e74705SXin Li (void)(^id(void) { return 0; }); 228*67e74705SXin Li (void)(^id _Nullable (void) { return 0; }); 229*67e74705SXin Li (void)(^ _Nullable id(void) { return 0; }); 230*67e74705SXin Li 231*67e74705SXin Li int *x = (^ _Nullable id(void) { return 0; })(); // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'id _Nullable'}} 232*67e74705SXin Li} 233