1// RUN: %clang_cc1 -fsyntax-only -fblocks -Woverriding-method-mismatch -Wno-nullability-declspec -Wnullable-to-nonnull-conversion %s -verify 2 3__attribute__((objc_root_class)) 4@interface NSFoo 5- (void)methodTakingIntPtr:(_Nonnull int *)ptr; 6- (_Nonnull int *)methodReturningIntPtr; 7@end 8 9// Nullability applies to all pointer types. 10typedef NSFoo * _Nonnull nonnull_NSFoo_ptr; 11typedef id _Nonnull nonnull_id; 12typedef SEL _Nonnull nonnull_SEL; 13 14// Nullability can move into Objective-C pointer types. 15typedef _Nonnull NSFoo * nonnull_NSFoo_ptr_2; 16 17// Conflicts from nullability moving into Objective-C pointer type. 18typedef _Nonnull NSFoo * _Nullable conflict_NSFoo_ptr_2; // expected-error{{'_Nonnull' cannot be applied to non-pointer type 'NSFoo'}} 19 20void testBlocksPrinting(NSFoo * _Nullable (^bp)(int)) { 21 int *ip = bp; // expected-error{{'NSFoo * _Nullable (^)(int)'}} 22} 23 24// Check returning nil from a _Nonnull-returning method. 25@implementation NSFoo 26- (void)methodTakingIntPtr:(_Nonnull int *)ptr { } 27- (_Nonnull int *)methodReturningIntPtr { 28 return 0; // no warning 29} 30@end 31 32// Context-sensitive keywords and property attributes for nullability. 33__attribute__((objc_root_class)) 34@interface NSBar 35- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo; 36 37- (nonnull NSFoo **)invalidMethod1; // expected-error{{nullability keyword 'nonnull' cannot be applied to multi-level pointer type 'NSFoo **'}} 38// expected-note@-1{{use nullability type specifier '_Nonnull' to affect the innermost pointer type of 'NSFoo **'}} 39- (nonnull NSFoo * _Nullable)conflictingMethod1; // expected-error{{nullability specifier 'nonnull' conflicts with existing specifier '_Nullable'}} 40- (nonnull NSFoo * _Nonnull)redundantMethod1; // expected-warning{{duplicate nullability specifier 'nonnull'}} 41 42@property(nonnull,retain) NSFoo *property1; 43@property(nullable,assign) NSFoo ** invalidProperty1; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}} 44// expected-note@-1{{use nullability type specifier '_Nullable' to affect the innermost pointer type of 'NSFoo **'}} 45@property(null_unspecified,retain) NSFoo * _Nullable conflictingProperty1; // expected-error{{nullability specifier 'null_unspecified' conflicts with existing specifier '_Nullable'}} 46@property(retain,nonnull) NSFoo * _Nonnull redundantProperty1; // expected-warning{{duplicate nullability specifier 'nonnull'}} 47 48@property(null_unspecified,retain,nullable) NSFoo *conflictingProperty3; // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'null_unspecified'}} 49@property(nullable,retain,nullable) NSFoo *redundantProperty3; // expected-warning{{duplicate nullability specifier 'nullable'}} 50@end 51 52@interface NSBar () 53@property(nonnull,retain) NSFoo *property2; 54@property(nullable,assign) NSFoo ** invalidProperty2; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}} 55// expected-note@-1{{use nullability type specifier '_Nullable' to affect the innermost pointer type of 'NSFoo **'}} 56@property(null_unspecified,retain) NSFoo * _Nullable conflictingProperty2; // expected-error{{nullability specifier 'null_unspecified' conflicts with existing specifier '_Nullable'}} 57@property(retain,nonnull) NSFoo * _Nonnull redundantProperty2; // expected-warning{{duplicate nullability specifier 'nonnull'}} 58@end 59 60void test_accepts_nonnull_null_pointer_literal(NSFoo *foo, _Nonnull NSBar *bar) { 61 [foo methodTakingIntPtr: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 62 [bar methodWithFoo: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 63 bar.property1 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}} 64 bar.property2 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}} 65 [bar setProperty1: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 66 [bar setProperty2: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} 67 int *ptr = bar.property1; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}} 68} 69 70// Check returning nil from a nonnull-returning method. 71@implementation NSBar 72- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo { 73 return 0; // no warning 74} 75 76- (NSFoo **)invalidMethod1 { 77 return 0; 78} 79 80- (NSFoo *)conflictingMethod1 { 81 return 0; // no warning 82} 83- (NSFoo *)redundantMethod1 { 84 int *ip = 0; 85 return ip; // expected-warning{{result type 'NSFoo * _Nonnull'}} 86} 87@end 88 89__attribute__((objc_root_class)) 90@interface NSMerge 91- (nonnull NSFoo *)methodA:(nonnull NSFoo*)foo; 92- (nonnull NSFoo *)methodB:(nonnull NSFoo*)foo; 93- (NSFoo *)methodC:(NSFoo*)foo; 94@end 95 96@implementation NSMerge 97- (NSFoo *)methodA:(NSFoo*)foo { 98 int *ptr = foo; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}} 99 return ptr; // expected-warning{{result type 'NSFoo * _Nonnull'}} 100} 101 102- (nullable NSFoo *)methodB:(null_unspecified NSFoo*)foo { // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'nonnull'}} \ 103 // expected-error{{nullability specifier 'null_unspecified' conflicts with existing specifier 'nonnull'}} 104 return 0; 105} 106 107- (nonnull NSFoo *)methodC:(nullable NSFoo*)foo { 108 int *ip = 0; 109 return ip; // expected-warning{{result type 'NSFoo * _Nonnull'}} 110} 111@end 112 113// Checking merging of nullability when sending a message. 114@interface NSMergeReceiver 115- (id)returnsNone; 116- (nonnull id)returnsNonNull; 117- (nullable id)returnsNullable; 118- (null_unspecified id)returnsNullUnspecified; 119- (_Nullable_result id)returnsNullableResult; 120@end 121 122void test_receiver_merge(NSMergeReceiver *none, 123 _Nonnull NSMergeReceiver *nonnull, 124 _Nullable NSMergeReceiver *nullable, 125 _Nullable_result NSMergeReceiver *nullable_result, 126 _Null_unspecified NSMergeReceiver *null_unspecified) { 127 int *ptr; 128 129 ptr = [nullable returnsNullable]; // expected-warning{{'id _Nullable'}} 130 ptr = [nullable returnsNullUnspecified]; // expected-warning{{'id _Nullable'}} 131 ptr = [nullable returnsNonNull]; // expected-warning{{'id _Nullable'}} 132 ptr = [nullable returnsNone]; // expected-warning{{'id _Nullable'}} 133 134 ptr = [nullable_result returnsNullable]; // expected-warning{{'id _Nullable'}} 135 ptr = [nullable_result returnsNullUnspecified]; // expected-warning{{'id _Nullable'}} 136 ptr = [nullable_result returnsNonNull]; // expected-warning{{'id _Nullable'}} 137 ptr = [nullable_result returnsNone]; // expected-warning{{'id _Nullable'}} 138 ptr = [nullable_result returnsNullableResult]; // expected-warning{{'id _Nullable_result'}} 139 140 ptr = [null_unspecified returnsNullable]; // expected-warning{{'id _Nullable'}} 141 ptr = [null_unspecified returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}} 142 ptr = [null_unspecified returnsNonNull]; // expected-warning{{'id _Null_unspecified'}} 143 ptr = [null_unspecified returnsNone]; // expected-warning{{'id'}} 144 145 ptr = [nonnull returnsNullable]; // expected-warning{{'id _Nullable'}} 146 ptr = [nonnull returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}} 147 ptr = [nonnull returnsNonNull]; // expected-warning{{'id _Nonnull'}} 148 ptr = [nonnull returnsNone]; // expected-warning{{'id'}} 149 150 ptr = [none returnsNullable]; // expected-warning{{'id _Nullable'}} 151 ptr = [none returnsNullUnspecified]; // expected-warning{{'id'}} 152 ptr = [none returnsNonNull]; // expected-warning{{'id'}} 153 ptr = [none returnsNone]; // expected-warning{{'id'}} 154 155} 156 157// instancetype 158@protocol Initializable 159- (instancetype)initWithBlah:(id)blah; 160@end 161 162__attribute__((objc_root_class)) 163@interface InitializableClass <Initializable> 164- (nonnull instancetype)initWithBlah:(nonnull id)blah; 165- (nullable instancetype)returnMe; 166+ (nullable instancetype)returnInstanceOfMe; 167 168- (nonnull instancetype _Nullable)initWithBlah2:(nonnull id)blah; // expected-error {{nullability specifier 'nonnull' conflicts with existing specifier '_Nullable'}} 169- (instancetype _Nullable)returnMe2; 170+ (_Nonnull instancetype)returnInstanceOfMe2; 171@end 172 173void test_instancetype(InitializableClass * _Nonnull ic, id _Nonnull object) { 174 int *ip = [ic returnMe]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'InitializableClass * _Nullable'}} 175 ip = [InitializableClass returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}} 176 ip = [InitializableClass returnInstanceOfMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}} 177 ip = [object returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}} 178 179 ip = [ic returnMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}} 180 ip = [InitializableClass returnInstanceOfMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nonnull'}} 181} 182 183// Check null_resettable getters/setters. 184__attribute__((objc_root_class)) 185@interface NSResettable 186@property(null_resettable,retain) NSResettable *resettable1; // expected-note{{passing argument to parameter 'resettable1' here}} 187@property(null_resettable,retain,nonatomic) NSResettable *resettable2; 188@property(null_resettable,retain,nonatomic) NSResettable *resettable3; 189@property(null_resettable,retain,nonatomic) NSResettable *resettable4; 190@property(null_resettable,retain,nonatomic) NSResettable *resettable5; 191@property(null_resettable,retain,nonatomic) NSResettable *resettable6; 192@end 193 194void test_null_resettable(NSResettable *r, int *ip) { 195 [r setResettable1:ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'NSResettable * _Nullable'}} 196 r.resettable1 = ip; // expected-warning{{incompatible pointer types assigning to 'NSResettable * _Nullable' from 'int *'}} 197} 198 199@implementation NSResettable // expected-warning{{synthesized setter 'setResettable4:' for null_resettable property 'resettable4' does not handle nil}} 200- (NSResettable *)resettable1 { 201 int *ip = 0; 202 return ip; // expected-warning{{result type 'NSResettable * _Nonnull'}} 203} 204 205- (void)setResettable1:(NSResettable *)param { 206} 207 208@synthesize resettable2; // no warning; not synthesized 209@synthesize resettable3; // expected-warning{{synthesized setter 'setResettable3:' for null_resettable property 'resettable3' does not handle nil}} 210 211- (void)setResettable2:(NSResettable *)param { 212} 213 214@dynamic resettable5; 215 216- (NSResettable *)resettable6 { 217 return 0; // no warning 218} 219@end 220 221@interface MultiProp 222@property (nullable, copy) id a, b, c; 223@property (nullable, copy) MultiProp *d, *(^e)(int); 224@end 225 226void testMultiProp(MultiProp *foo) { 227 int *ip; 228 ip = foo.a; // expected-warning{{from 'id _Nullable'}} 229 ip = foo.d; // expected-warning{{from 'MultiProp * _Nullable'}} 230 ip = foo.e; // expected-error{{incompatible type 'MultiProp *(^ _Nullable)(int)'}} 231} 232 233void testBlockLiterals(void) { 234 (void)(^id(void) { return 0; }); 235 (void)(^id _Nullable (void) { return 0; }); 236 (void)(^ _Nullable id(void) { return 0; }); 237 238 int *x = (^ _Nullable id(void) { return 0; })(); // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'id _Nullable'}} 239} 240 241// Check nullability of conditional expressions. 242void conditional_expr(int c) { 243 NSFoo * _Nonnull p; 244 NSFoo * _Nonnull nonnullP; 245 NSFoo * _Nullable nullableP; 246 NSFoo * _Null_unspecified unspecifiedP; 247 NSFoo * _Nullable_result nullableResultP; 248 NSFoo *noneP; 249 250 p = c ? nonnullP : nonnullP; 251 p = c ? nonnullP : nullableP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 252 p = c ? nonnullP : unspecifiedP; 253 p = c ? nonnullP : noneP; 254 p = c ? nullableP : nonnullP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 255 p = c ? nullableP : nullableP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 256 p = c ? nullableP : unspecifiedP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 257 p = c ? nullableP : noneP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 258 p = c ? unspecifiedP : nonnullP; 259 p = c ? unspecifiedP : nullableP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 260 p = c ? unspecifiedP : unspecifiedP; 261 p = c ? unspecifiedP : noneP; 262 p = c ? noneP : nonnullP; 263 p = c ? noneP : nullableP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 264 p = c ? noneP : unspecifiedP; 265 p = c ? noneP : noneP; 266 p = c ? noneP : nullableResultP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 267 p = c ? nonnullP : nullableResultP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 268 p = c ? nullableP : nullableResultP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}} 269 p = c ? nullableResultP : nullableResultP; // expected-warning{{implicit conversion from nullable pointer 'NSFoo * _Nullable_result' to non-nullable pointer type 'NSFoo * _Nonnull'}} 270} 271 272typedef int INTS[4]; 273@interface ArraysInMethods 274- (void)simple:(int [_Nonnull 2])x; 275- (void)nested:(void *_Nullable [_Nonnull 2])x; 276- (void)nestedBad:(int [2][_Nonnull 2])x; // expected-error {{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'int[2]'}} 277 278- (void)withTypedef:(INTS _Nonnull)x; 279- (void)withTypedefBad:(INTS _Nonnull[2])x; // expected-error{{nullability specifier '_Nonnull' cannot be applied to non-pointer type 'INTS' (aka 'int[4]')}} 280 281- (void)simpleSugar:(nonnull int [2])x; 282- (void)nestedSugar:(nonnull void *_Nullable [2])x; // expected-error {{nullability keyword 'nonnull' cannot be applied to multi-level pointer type 'void * _Nullable[2]'}} expected-note {{use nullability type specifier '_Nonnull' to affect the innermost pointer type of 'void * _Nullable[2]'}} 283- (void)sugarWithTypedef:(nonnull INTS)x; 284@end 285 286void test(ArraysInMethods *obj) { 287 [obj simple:0]; // expected-warning {{null passed to a callee that requires a non-null argument}} 288 [obj nested:0]; // expected-warning {{null passed to a callee that requires a non-null argument}} 289 [obj withTypedef:0]; // expected-warning {{null passed to a callee that requires a non-null argument}} 290 291 [obj simpleSugar:0]; // expected-warning {{null passed to a callee that requires a non-null argument}} 292 [obj sugarWithTypedef:0]; // expected-warning {{null passed to a callee that requires a non-null argument}} 293} 294 295// Check that we don't propagate the nullability specifier on the receiver to 296// the result type of a message send if the result type cannot have a 297// nullability specifier. 298@interface C0 299-(int) count; 300@end 301 302void testMessageSendResultType(C0 * _Nullable c0) { 303 int *p = [c0 count]; // expected-error {{incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int'}} 304} 305