brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.3 KiB · da53335 Raw
305 lines · plain
1// RUN: %clang_cc1 -fsyntax-only -fblocks -Woverriding-method-mismatch -Wno-nullability-declspec -Wnullable-to-nonnull-conversion %s -verify2 3__attribute__((objc_root_class))4@interface NSFoo5- (void)methodTakingIntPtr:(_Nonnull int *)ptr;6- (_Nonnull int *)methodReturningIntPtr;7@end8 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 NSFoo26- (void)methodTakingIntPtr:(_Nonnull int *)ptr { }27- (_Nonnull int *)methodReturningIntPtr {28  return 0; // no warning29}30@end31 32// Context-sensitive keywords and property attributes for nullability.33__attribute__((objc_root_class))34@interface NSBar35- (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@end51 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@end59 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-error{{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 NSBar72- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo {73  return 0; // no warning74}75 76- (NSFoo **)invalidMethod1 { 77  return 0; 78}79 80- (NSFoo *)conflictingMethod1 { 81  return 0; // no warning82}83- (NSFoo *)redundantMethod1 {84  int *ip = 0;85  return ip; // expected-error{{result type 'NSFoo * _Nonnull'}}86}87@end88 89__attribute__((objc_root_class))90@interface NSMerge91- (nonnull NSFoo *)methodA:(nonnull NSFoo*)foo;92- (nonnull NSFoo *)methodB:(nonnull NSFoo*)foo;93- (NSFoo *)methodC:(NSFoo*)foo;94@end95 96@implementation NSMerge97- (NSFoo *)methodA:(NSFoo*)foo {98  int *ptr = foo; // expected-error{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * _Nonnull'}}99  return ptr; // expected-error{{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-error{{result type 'NSFoo * _Nonnull'}}110}111@end112 113// Checking merging of nullability when sending a message.114@interface NSMergeReceiver115- (id)returnsNone;116- (nonnull id)returnsNonNull;117- (nullable id)returnsNullable;118- (null_unspecified id)returnsNullUnspecified;119- (_Nullable_result id)returnsNullableResult;120@end121 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-error{{'id _Nullable'}}130  ptr = [nullable returnsNullUnspecified]; // expected-error{{'id _Nullable'}}131  ptr = [nullable returnsNonNull]; // expected-error{{'id _Nullable'}}132  ptr = [nullable returnsNone]; // expected-error{{'id _Nullable'}}133 134  ptr = [nullable_result returnsNullable]; // expected-error{{'id _Nullable'}}135  ptr = [nullable_result returnsNullUnspecified]; // expected-error{{'id _Nullable'}}136  ptr = [nullable_result returnsNonNull]; // expected-error{{'id _Nullable'}}137  ptr = [nullable_result returnsNone]; // expected-error{{'id _Nullable'}}138  ptr = [nullable_result returnsNullableResult]; // expected-error{{'id _Nullable_result'}}139 140  ptr = [null_unspecified returnsNullable]; // expected-error{{'id _Nullable'}}141  ptr = [null_unspecified returnsNullUnspecified]; // expected-error{{'id _Null_unspecified'}}142  ptr = [null_unspecified returnsNonNull]; // expected-error{{'id _Null_unspecified'}}143  ptr = [null_unspecified returnsNone]; // expected-error{{'id'}}144 145  ptr = [nonnull returnsNullable]; // expected-error{{'id _Nullable'}}146  ptr = [nonnull returnsNullUnspecified]; // expected-error{{'id _Null_unspecified'}}147  ptr = [nonnull returnsNonNull]; // expected-error{{'id _Nonnull'}}148  ptr = [nonnull returnsNone]; // expected-error{{'id'}}149 150  ptr = [none returnsNullable]; // expected-error{{'id _Nullable'}}151  ptr = [none returnsNullUnspecified]; // expected-error{{'id'}}152  ptr = [none returnsNonNull]; // expected-error{{'id'}}153  ptr = [none returnsNone]; // expected-error{{'id'}}154  155}156 157// instancetype158@protocol Initializable159- (instancetype)initWithBlah:(id)blah;160@end161 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@end172 173void test_instancetype(InitializableClass * _Nonnull ic, id _Nonnull object) {174  int *ip = [ic returnMe]; // expected-error{{incompatible pointer types initializing 'int *' with an expression of type 'InitializableClass * _Nullable'}}175  ip = [InitializableClass returnMe]; // expected-error{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}}176  ip = [InitializableClass returnInstanceOfMe]; // expected-error{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}}177  ip = [object returnMe]; // expected-error{{incompatible pointer types assigning to 'int *' from 'id _Nullable'}}178 179  ip = [ic returnMe2]; // expected-error{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nullable'}}180  ip = [InitializableClass returnInstanceOfMe2]; // expected-error{{incompatible pointer types assigning to 'int *' from 'InitializableClass * _Nonnull'}}181}182 183// Check null_resettable getters/setters.184__attribute__((objc_root_class))185@interface NSResettable186@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@end193 194void test_null_resettable(NSResettable *r, int *ip) {195  [r setResettable1:ip]; // expected-error{{incompatible pointer types sending 'int *' to parameter of type 'NSResettable * _Nullable'}}196  r.resettable1 = ip; // expected-error{{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-error{{result type 'NSResettable * _Nonnull'}}203}204 205- (void)setResettable1:(NSResettable *)param {206}207 208@synthesize resettable2; // no warning; not synthesized209@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 warning218}219@end220 221@interface MultiProp222@property (nullable, copy) id a, b, c;223@property (nullable, copy) MultiProp *d, *(^e)(int);224@end225 226void testMultiProp(MultiProp *foo) {227  int *ip;228  ip = foo.a; // expected-error{{from 'id _Nullable'}}229  ip = foo.d; // expected-error{{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-error{{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 ArraysInMethods274- (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@end285 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 to296// the result type of a message send if the result type cannot have a297// nullability specifier.298@interface C0299-(int) count;300@end301 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