1// RUN: %clang_cc1 -fsyntax-only -fblocks -Woverriding-method-mismatch -Wno-nullability-declspec %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 '_Nullable' conflicts with existing specifier '_Nonnull'}} 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 '_Nullable' conflicts with existing specifier '_Null_unspecified'}} 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 '_Nullable' conflicts with existing specifier '_Null_unspecified'}} 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@end 120 121void test_receiver_merge(NSMergeReceiver *none, 122 _Nonnull NSMergeReceiver *nonnull, 123 _Nullable NSMergeReceiver *nullable, 124 _Null_unspecified NSMergeReceiver *null_unspecified) { 125 int *ptr; 126 127 ptr = [nullable returnsNullable]; // expected-warning{{'id _Nullable'}} 128 ptr = [nullable returnsNullUnspecified]; // expected-warning{{'id _Nullable'}} 129 ptr = [nullable returnsNonNull]; // expected-warning{{'id _Nullable'}} 130 ptr = [nullable returnsNone]; // expected-warning{{'id _Nullable'}} 131 132 ptr = [null_unspecified returnsNullable]; // expected-warning{{'id _Nullable'}} 133 ptr = [null_unspecified returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}} 134 ptr = [null_unspecified returnsNonNull]; // expected-warning{{'id _Null_unspecified'}} 135 ptr = [null_unspecified returnsNone]; // expected-warning{{'id'}} 136 137 ptr = [nonnull returnsNullable]; // expected-warning{{'id _Nullable'}} 138 ptr = [nonnull returnsNullUnspecified]; // expected-warning{{'id _Null_unspecified'}} 139 ptr = [nonnull returnsNonNull]; // expected-warning{{'id _Nonnull'}} 140 ptr = [nonnull returnsNone]; // expected-warning{{'id'}} 141 142 ptr = [none returnsNullable]; // expected-warning{{'id _Nullable'}} 143 ptr = [none returnsNullUnspecified]; // expected-warning{{'id'}} 144 ptr = [none returnsNonNull]; // expected-warning{{'id'}} 145 ptr = [none returnsNone]; // expected-warning{{'id'}} 146 147} 148 149// instancetype 150@protocol Initializable 151- (instancetype)initWithBlah:(id)blah; 152@end 153 154__attribute__((objc_root_class)) 155@interface InitializableClass <Initializable> 156- (nonnull instancetype)initWithBlah:(nonnull id)blah; 157- (nullable instancetype)returnMe; 158+ (nullable instancetype)returnInstanceOfMe; 159 160- (nonnull instancetype _Nullable)initWithBlah2:(nonnull id)blah; // expected-error {{nullability specifier '_Nullable' conflicts with existing specifier '_Nonnull'}} 161- (instancetype _Nullable)returnMe2; 162+ (_Nonnull instancetype)returnInstanceOfMe2; 163@end 164 165void test_instancetype(InitializableClass * _Nonnull ic, id _Nonnull object) { 166 int *ip = [ic returnMe]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'InitializableClass * _Nullable'}} 167 ip = [InitializableClass returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}} 168 ip = [InitializableClass returnInstanceOfMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}} 169 ip = [object returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}} 170 171 ip = [ic returnMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}} 172 ip = [InitializableClass returnInstanceOfMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nonnull'}} 173} 174 175// Check null_resettable getters/setters. 176__attribute__((objc_root_class)) 177@interface NSResettable 178@property(null_resettable,retain) NSResettable *resettable1; // expected-note{{passing argument to parameter 'resettable1' here}} 179@property(null_resettable,retain,nonatomic) NSResettable *resettable2; 180@property(null_resettable,retain,nonatomic) NSResettable *resettable3; 181@property(null_resettable,retain,nonatomic) NSResettable *resettable4; 182@property(null_resettable,retain,nonatomic) NSResettable *resettable5; 183@property(null_resettable,retain,nonatomic) NSResettable *resettable6; 184@end 185 186void test_null_resettable(NSResettable *r, int *ip) { 187 [r setResettable1:ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'NSResettable * _Nullable'}} 188 r.resettable1 = ip; // expected-warning{{incompatible pointer types assigning to 'NSResettable * _Nullable' from 'int *'}} 189} 190 191@implementation NSResettable // expected-warning{{synthesized setter 'setResettable4:' for null_resettable property 'resettable4' does not handle nil}} 192- (NSResettable *)resettable1 { 193 int *ip = 0; 194 return ip; // expected-warning{{result type 'NSResettable * _Nonnull'}} 195} 196 197- (void)setResettable1:(NSResettable *)param { 198} 199 200@synthesize resettable2; // no warning; not synthesized 201@synthesize resettable3; // expected-warning{{synthesized setter 'setResettable3:' for null_resettable property 'resettable3' does not handle nil}} 202 203- (void)setResettable2:(NSResettable *)param { 204} 205 206@dynamic resettable5; 207 208- (NSResettable *)resettable6 { 209 return 0; // no warning 210} 211@end 212 213// rdar://problem/19814852 214@interface MultiProp 215@property (nullable, copy) id a, b, c; 216@property (nullable, copy) MultiProp *d, *(^e)(int); 217@end 218 219void testMultiProp(MultiProp *foo) { 220 int *ip; 221 ip = foo.a; // expected-warning{{from 'id _Nullable'}} 222 ip = foo.d; // expected-warning{{from 'MultiProp * _Nullable'}} 223 ip = foo.e; // expected-error{{incompatible type 'MultiProp *(^ _Nullable)(int)'}} 224} 225 226void testBlockLiterals() { 227 (void)(^id(void) { return 0; }); 228 (void)(^id _Nullable (void) { return 0; }); 229 (void)(^ _Nullable id(void) { return 0; }); 230 231 int *x = (^ _Nullable id(void) { return 0; })(); // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'id _Nullable'}} 232} 233