diff options
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Index/comment-objc-decls.m | 8 | ||||
| -rw-r--r-- | clang/test/SemaObjC/arc-property-decl-attrs.m | 8 | ||||
| -rw-r--r-- | clang/test/SemaObjC/arc-unavailable-for-weakref.m | 6 | ||||
| -rw-r--r-- | clang/test/SemaObjC/nullability.m | 151 | ||||
| -rw-r--r-- | clang/test/SemaObjC/nullable-weak-property.m | 18 | ||||
| -rw-r--r-- | clang/test/SemaObjC/override-nullability.m | 15 |
6 files changed, 196 insertions, 10 deletions
diff --git a/clang/test/Index/comment-objc-decls.m b/clang/test/Index/comment-objc-decls.m index ae3b0bbf415..d53757cbc3c 100644 --- a/clang/test/Index/comment-objc-decls.m +++ b/clang/test/Index/comment-objc-decls.m @@ -20,19 +20,19 @@ * \param[in] range output value is unsigned int * \result return index */ -- (unsigned int)MethodMyProto:(id)anObject inRange:(unsigned int)range; +- (unsigned int)MethodMyProto:(nullable id)anObject inRange:(unsigned int)range; /** * \brief PropertyMyProto - This is protocol's property. */ -@property (copy) id PropertyMyProto; +@property (copy, nonnull) id PropertyMyProto; /** * \brief ClassMethodMyProto */ + ClassMethodMyProto; @end // CHECK: <Declaration>@protocol MyProto\n@end</Declaration> -// CHECK: <Declaration>- (unsigned int)MethodMyProto:(id)anObject inRange:(unsigned int)range;</Declaration> -// CHECK: <Declaration>@optional\n@property(readwrite, copy, atomic) id PropertyMyProto;</Declaration> +// CHECK: <Declaration>- (unsigned int)MethodMyProto:(nullable id)anObject inRange:(unsigned int)range;</Declaration> +// CHECK: <Declaration>@optional\n@property(readwrite, copy, atomic, nonnull) id PropertyMyProto;</Declaration> // CHECK: <Declaration>+ (id)ClassMethodMyProto;</Declaration> /** diff --git a/clang/test/SemaObjC/arc-property-decl-attrs.m b/clang/test/SemaObjC/arc-property-decl-attrs.m index 283772c2279..e5b8f28e5ac 100644 --- a/clang/test/SemaObjC/arc-property-decl-attrs.m +++ b/clang/test/SemaObjC/arc-property-decl-attrs.m @@ -79,3 +79,11 @@ @property (readwrite) id frr; @end +// rdar://20152386 +@interface NSObject @end + +@interface rdar20152386_2: NSObject +@property(nonatomic, weak, nonnull) id delegate; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}} +@property(nonatomic, weak, nonnull, readonly) id ReadDelegate; // no warning +@end + diff --git a/clang/test/SemaObjC/arc-unavailable-for-weakref.m b/clang/test/SemaObjC/arc-unavailable-for-weakref.m index 82748027435..53ceaa15c28 100644 --- a/clang/test/SemaObjC/arc-unavailable-for-weakref.m +++ b/clang/test/SemaObjC/arc-unavailable-for-weakref.m @@ -56,7 +56,7 @@ __attribute__((objc_arc_weak_reference_unavailable)) @interface I { } -@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}} +@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * __nullable', which does not support weak references}} @end @implementation I // expected-note {{when implemented by class I}} @@ -65,7 +65,7 @@ __attribute__((objc_arc_weak_reference_unavailable)) // rdar://13676793 @protocol MyProtocol -@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}} +@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * __nullable', which does not support weak references}} @end @interface I1 <MyProtocol> @@ -76,7 +76,7 @@ __attribute__((objc_arc_weak_reference_unavailable)) @end @interface Super -@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}} +@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * __nullable', which does not support weak references}} @end diff --git a/clang/test/SemaObjC/nullability.m b/clang/test/SemaObjC/nullability.m index 0bcc0cb8faa..b852584758c 100644 --- a/clang/test/SemaObjC/nullability.m +++ b/clang/test/SemaObjC/nullability.m @@ -20,9 +20,6 @@ typedef __nonnull NSFoo * __nullable conflict_NSFoo_ptr_2; // expected-error{{'_ void testBlocksPrinting(NSFoo * __nullable (^bp)(int)) { int *ip = bp; // expected-error{{'NSFoo * __nullable (^)(int)'}} } -void test_accepts_nonnull_null_pointer_literal(NSFoo *foo) { - [foo methodTakingIntPtr: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} -} // Check returning nil from a __nonnull-returning method. @implementation NSFoo @@ -31,3 +28,151 @@ void test_accepts_nonnull_null_pointer_literal(NSFoo *foo) { return 0; // no warning } @end + +// Context-sensitive keywords and property attributes for nullability. +__attribute__((objc_root_class)) +@interface NSBar +- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo; + +- (nonnull NSFoo **)invalidMethod1; // expected-error{{nullability keyword 'nonnull' cannot be applied to multi-level pointer type 'NSFoo **'}} +// expected-note@-1{{use nullability type specifier '__nonnull' to affect the innermost pointer type of 'NSFoo **'}} +- (nonnull NSFoo * __nullable)conflictingMethod1; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__nonnull'}} +- (nonnull NSFoo * __nonnull)redundantMethod1; // expected-warning{{duplicate nullability specifier '__nonnull'}} + +@property(nonnull,retain) NSFoo *property1; +@property(nullable,assign) NSFoo ** invalidProperty1; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}} +// expected-note@-1{{use nullability type specifier '__nullable' to affect the innermost pointer type of 'NSFoo **'}} +@property(null_unspecified,retain) NSFoo * __nullable conflictingProperty1; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__null_unspecified'}} +@property(retain,nonnull) NSFoo * __nonnull redundantProperty1; // expected-warning{{duplicate nullability specifier '__nonnull'}} + +@property(null_unspecified,retain,nullable) NSFoo *conflictingProperty3; // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'null_unspecified'}} +@property(nullable,retain,nullable) NSFoo *redundantProperty3; // expected-warning{{duplicate nullability specifier 'nullable'}} +@end + +@interface NSBar () +@property(nonnull,retain) NSFoo *property2; +@property(nullable,assign) NSFoo ** invalidProperty2; // expected-error{{nullability keyword 'nullable' cannot be applied to multi-level pointer type 'NSFoo **'}} +// expected-note@-1{{use nullability type specifier '__nullable' to affect the innermost pointer type of 'NSFoo **'}} +@property(null_unspecified,retain) NSFoo * __nullable conflictingProperty2; // expected-error{{nullability specifier '__nullable' conflicts with existing specifier '__null_unspecified'}} +@property(retain,nonnull) NSFoo * __nonnull redundantProperty2; // expected-warning{{duplicate nullability specifier '__nonnull'}} +@end + +void test_accepts_nonnull_null_pointer_literal(NSFoo *foo, __nonnull NSBar *bar) { + [foo methodTakingIntPtr: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} + [bar methodWithFoo: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} + bar.property1 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}} + bar.property2 = 0; // expected-warning{{null passed to a callee that requires a non-null argument}} + [bar setProperty1: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} + [bar setProperty2: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}} + int *ptr = bar.property1; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * __nonnull'}} +} + +// Check returning nil from a nonnull-returning method. +@implementation NSBar +- (nonnull NSFoo *)methodWithFoo:(nonnull NSFoo *)foo { + return 0; // no warning +} + +- (NSFoo **)invalidMethod1 { + return 0; +} + +- (NSFoo *)conflictingMethod1 { + return 0; // no warning +} +- (NSFoo *)redundantMethod1 { + int *ip = 0; + return ip; // expected-warning{{result type 'NSFoo * __nonnull'}} +} +@end + +__attribute__((objc_root_class)) +@interface NSMerge +- (nonnull NSFoo *)methodA:(nonnull NSFoo*)foo; +- (nonnull NSFoo *)methodB:(nonnull NSFoo*)foo; +- (NSFoo *)methodC:(NSFoo*)foo; +@end + +@implementation NSMerge +- (NSFoo *)methodA:(NSFoo*)foo { + int *ptr = foo; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'NSFoo * __nonnull'}} + return ptr; // expected-warning{{result type 'NSFoo * __nonnull'}} +} + +- (nullable NSFoo *)methodB:(null_unspecified NSFoo*)foo { // expected-error{{nullability specifier 'nullable' conflicts with existing specifier 'nonnull'}} \ + // expected-error{{nullability specifier 'null_unspecified' conflicts with existing specifier 'nonnull'}} + return 0; +} + +- (nonnull NSFoo *)methodC:(nullable NSFoo*)foo { + int *ip = 0; + return ip; // expected-warning{{result type 'NSFoo * __nonnull'}} +} +@end + +// Checking merging of nullability when sending a message. +@interface NSMergeReceiver +- (id)returnsNone; +- (nonnull id)returnsNonNull; +- (nullable id)returnsNullable; +- (null_unspecified id)returnsNullUnspecified; +@end + +void test_receiver_merge(NSMergeReceiver *none, + __nonnull NSMergeReceiver *nonnull, + __nullable NSMergeReceiver *nullable, + __null_unspecified NSMergeReceiver *null_unspecified) { + int *ptr; + + ptr = [nullable returnsNullable]; // expected-warning{{'id __nullable'}} + ptr = [nullable returnsNullUnspecified]; // expected-warning{{'id __nullable'}} + ptr = [nullable returnsNonNull]; // expected-warning{{'id __nullable'}} + ptr = [nullable returnsNone]; // expected-warning{{'id __nullable'}} + + ptr = [null_unspecified returnsNullable]; // expected-warning{{'id __nullable'}} + ptr = [null_unspecified returnsNullUnspecified]; // expected-warning{{'id __null_unspecified'}} + ptr = [null_unspecified returnsNonNull]; // expected-warning{{'id __null_unspecified'}} + ptr = [null_unspecified returnsNone]; // expected-warning{{'id'}} + + ptr = [nonnull returnsNullable]; // expected-warning{{'id __nullable'}} + ptr = [nonnull returnsNullUnspecified]; // expected-warning{{'id __null_unspecified'}} + ptr = [nonnull returnsNonNull]; // expected-warning{{'id __nonnull'}} + ptr = [nonnull returnsNone]; // expected-warning{{'id'}} + + ptr = [none returnsNullable]; // expected-warning{{'id __nullable'}} + ptr = [none returnsNullUnspecified]; // expected-warning{{'id'}} + ptr = [none returnsNonNull]; // expected-warning{{'id'}} + ptr = [none returnsNone]; // expected-warning{{'id'}} + +} + +// instancetype +@protocol Initializable +- (instancetype)initWithBlah:(id)blah; +@end + +__attribute__((objc_root_class)) +@interface InitializableClass <Initializable> +- (nonnull instancetype)initWithBlah:(nonnull id)blah; +- (nullable instancetype)returnMe; ++ (nullable instancetype)returnInstanceOfMe; +@end + +void test_instancetype(InitializableClass * __nonnull ic, id __nonnull object) { + int *ip = [ic returnMe]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'InitializableClass * __nullable'}} + ip = [InitializableClass returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id __nullable'}} + ip = [InitializableClass returnInstanceOfMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * __nullable'}} + ip = [object returnMe]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'id __nullable'}} +} +// rdar://problem/19814852 +@interface MultiProp +@property (nullable, copy) id a, b, c; +@property (nullable, copy) MultiProp *d, *(^e)(int); +@end + +void testMultiProp(MultiProp *foo) { + int *ip; + ip = foo.a; // expected-warning{{from 'id __nullable'}} + ip = foo.d; // expected-warning{{from 'MultiProp * __nullable'}} + ip = foo.e; // expected-error{{incompatible type 'MultiProp *(^ __nullable)(int)'}} +} diff --git a/clang/test/SemaObjC/nullable-weak-property.m b/clang/test/SemaObjC/nullable-weak-property.m new file mode 100644 index 00000000000..617ff4ee5c6 --- /dev/null +++ b/clang/test/SemaObjC/nullable-weak-property.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -Wnullable-to-nonnull-conversion %s -verify + + +// rdar://19985330 +@interface NSObject @end + +@class NSFoo; +void foo (NSFoo * __nonnull); + +@interface NSBar : NSObject +@property(weak) NSFoo *property1; +@end + +@implementation NSBar +- (void) Meth { + foo (self.property1); // expected-warning {{implicit conversion from nullable pointer 'NSFoo * __nullable' to non-nullable pointer type 'NSFoo * __nonnull'}} +} +@end diff --git a/clang/test/SemaObjC/override-nullability.m b/clang/test/SemaObjC/override-nullability.m new file mode 100644 index 00000000000..8e29f915275 --- /dev/null +++ b/clang/test/SemaObjC/override-nullability.m @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -Wnonnull %s -verify +//rdar://19211059 + +@interface NSObject @end + +@interface Base : NSObject +- (nonnull id)bad:(nullable id)obj; // expected-note 2 {{previous declaration is here}} +- (nullable id)notAsBad:(nonnull id)obj; +@end + +@interface Sub : Base +- (nullable id)bad:(nonnull id)obj; // expected-warning {{conflicting nullability specifier on return types, 'nullable' conflicts with existing specifier 'nonnull'}} \ + // expected-warning {{conflicting nullability specifier on parameter types, 'nonnull' conflicts with existing specifier 'nullable'}} +- (nonnull id)notAsBad:(nullable id)obj; +@end |

