diff options
author | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-06-21 14:00:56 +0000 |
commit | 9dd834653b811ad20382e98a87dff824980c9916 (patch) | |
tree | a764184c2fc9486979b074250b013a0937ee64e5 /test/SemaObjC | |
parent | bb9760db9b86e93a638ed430d0a14785f7ff9064 (diff) | |
download | FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.zip FreeBSD-src-9dd834653b811ad20382e98a87dff824980c9916.tar.gz |
Vendor import of clang trunk r240225:
https://llvm.org/svn/llvm-project/cfe/trunk@240225
Diffstat (limited to 'test/SemaObjC')
-rw-r--r-- | test/SemaObjC/arc-property-decl-attrs.m | 26 | ||||
-rw-r--r-- | test/SemaObjC/arc-unavailable-for-weakref.m | 6 | ||||
-rw-r--r-- | test/SemaObjC/attr-cf_returns.m | 49 | ||||
-rw-r--r-- | test/SemaObjC/nullability-arc.m | 10 | ||||
-rw-r--r-- | test/SemaObjC/nullability.m | 232 | ||||
-rw-r--r-- | test/SemaObjC/nullable-weak-property.m | 18 | ||||
-rw-r--r-- | test/SemaObjC/override-nullability.m | 15 |
7 files changed, 353 insertions, 3 deletions
diff --git a/test/SemaObjC/arc-property-decl-attrs.m b/test/SemaObjC/arc-property-decl-attrs.m index 283772c..2d46917 100644 --- a/test/SemaObjC/arc-property-decl-attrs.m +++ b/test/SemaObjC/arc-property-decl-attrs.m @@ -79,3 +79,29 @@ @property (readwrite) id frr; @end +// rdar://20152386 +// rdar://20383235 + +@interface NSObject @end + +#pragma clang assume_nonnull begin +@interface I: NSObject +@property(nonatomic, weak) id delegate; // Do not warn, nullable is inferred. +@property(nonatomic, weak, readonly) id ROdelegate; // Do not warn, nullable is inferred. +@property(nonatomic, weak, nonnull) id NonNulldelete; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}} +@property(nonatomic, weak, nullable) id Nullabledelete; // do not warn + +// strong cases. +@property(nonatomic, strong) id stdelegate; // Do not warn +@property(nonatomic, readonly) id stROdelegate; // Do not warn +@property(nonatomic, strong, nonnull) id stNonNulldelete; // Do not warn +@property(nonatomic, nullable) id stNullabledelete; // do not warn +@end +#pragma clang assume_nonnull end + +@interface J: NSObject +@property(nonatomic, weak) id ddd; // Do not warn, nullable is inferred. +@property(nonatomic, weak, nonnull) id delegate; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}} +@property(nonatomic, weak, nonnull, readonly) id ROdelegate; // expected-error {{property attributes 'nonnull' and 'weak' are mutually exclusive}} +@end + diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m index 8274802..53ceaa1 100644 --- a/test/SemaObjC/arc-unavailable-for-weakref.m +++ b/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/test/SemaObjC/attr-cf_returns.m b/test/SemaObjC/attr-cf_returns.m new file mode 100644 index 0000000..560d40d --- /dev/null +++ b/test/SemaObjC/attr-cf_returns.m @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s + +#if __has_feature(attribute_cf_returns_on_parameters) +# error "okay!" +// expected-error@-1 {{okay!}} +#else +# error "uh-oh" +#endif + +#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) + +int x CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to functions, methods, and parameters}} +int y CF_RETURNS_NOT_RETAINED; // expected-warning{{'cf_returns_not_retained' attribute only applies to functions, methods, and parameters}} + +typedef struct __CFFoo *CFFooRef; + +int invalid1() CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to functions that return a pointer}} +void invalid2() CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to functions that return a pointer}} + +CFFooRef valid1() CF_RETURNS_RETAINED; +id valid2() CF_RETURNS_RETAINED; + +@interface Test +- (int)invalid1 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to methods that return a pointer}} +- (void)invalid2 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to methods that return a pointer}} + +- (CFFooRef)valid1 CF_RETURNS_RETAINED; +- (id)valid2 CF_RETURNS_RETAINED; + +@property int invalidProp1 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to properties that return a pointer}} +@property void invalidProp2 CF_RETURNS_RETAINED; // expected-warning{{'cf_returns_retained' attribute only applies to properties that return a pointer}} + +@property CFFooRef valid1 CF_RETURNS_RETAINED; +@property id valid2 CF_RETURNS_RETAINED; +@end + +void invalidParam(int a CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}} + int *b CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}} + id c CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}} + void *d CF_RETURNS_RETAINED, // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}} + CFFooRef e CF_RETURNS_RETAINED); // expected-warning{{'cf_returns_retained' attribute only applies to pointer-to-CF-pointer parameters}} + +void validParam(id *a CF_RETURNS_RETAINED, + CFFooRef *b CF_RETURNS_RETAINED, + void **c CF_RETURNS_RETAINED); +void validParam2(id *a CF_RETURNS_NOT_RETAINED, + CFFooRef *b CF_RETURNS_NOT_RETAINED, + void **c CF_RETURNS_NOT_RETAINED); diff --git a/test/SemaObjC/nullability-arc.m b/test/SemaObjC/nullability-arc.m new file mode 100644 index 0000000..917a808 --- /dev/null +++ b/test/SemaObjC/nullability-arc.m @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fobjc-arc -fsyntax-only -Woverriding-method-mismatch %s -verify + +__attribute__((objc_root_class)) +@interface NSFoo +@end + +// ARC qualifiers stacked with nullability. +void accepts_arc_qualified(NSFoo * __unsafe_unretained __nonnull obj) { + accepts_arc_qualified(0); // expected-warning{{null passed to a callee that requires a non-null argument}} +} diff --git a/test/SemaObjC/nullability.m b/test/SemaObjC/nullability.m new file mode 100644 index 0000000..ca8c2fc --- /dev/null +++ b/test/SemaObjC/nullability.m @@ -0,0 +1,232 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -Woverriding-method-mismatch -Wno-nullability-declspec %s -verify + +__attribute__((objc_root_class)) +@interface NSFoo +- (void)methodTakingIntPtr:(__nonnull int *)ptr; +- (__nonnull int *)methodReturningIntPtr; +@end + +// Nullability applies to all pointer types. +typedef NSFoo * __nonnull nonnull_NSFoo_ptr; +typedef id __nonnull nonnull_id; +typedef SEL __nonnull nonnull_SEL; + +// Nullability can move into Objective-C pointer types. +typedef __nonnull NSFoo * nonnull_NSFoo_ptr_2; + +// Conflicts from nullability moving into Objective-C pointer type. +typedef __nonnull NSFoo * __nullable conflict_NSFoo_ptr_2; // expected-error{{'__nonnull' cannot be applied to non-pointer type 'NSFoo'}} + +void testBlocksPrinting(NSFoo * __nullable (^bp)(int)) { + int *ip = bp; // expected-error{{'NSFoo * __nullable (^)(int)'}} +} + +// Check returning nil from a __nonnull-returning method. +@implementation NSFoo +- (void)methodTakingIntPtr:(__nonnull int *)ptr { } +- (__nonnull int *)methodReturningIntPtr { + 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; + +- (nonnull instancetype __nullable)initWithBlah2:(nonnull id)blah; // expected-error {{nullability specifier '__nullable' conflicts with existing specifier '__nonnull'}} +- (instancetype __nullable)returnMe2; ++ (__nonnull instancetype)returnInstanceOfMe2; +@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'}} + + ip = [ic returnMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * __nullable'}} + ip = [InitializableClass returnInstanceOfMe2]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'InitializableClass * __nonnull'}} +} + +// Check null_resettable getters/setters. +__attribute__((objc_root_class)) +@interface NSResettable +@property(null_resettable,retain) NSResettable *resettable1; // expected-note{{passing argument to parameter 'resettable1' here}} +@property(null_resettable,retain,nonatomic) NSResettable *resettable2; +@property(null_resettable,retain,nonatomic) NSResettable *resettable3; +@property(null_resettable,retain,nonatomic) NSResettable *resettable4; +@property(null_resettable,retain,nonatomic) NSResettable *resettable5; +@property(null_resettable,retain,nonatomic) NSResettable *resettable6; +@end + +void test_null_resettable(NSResettable *r, int *ip) { + [r setResettable1:ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'NSResettable * __nullable'}} + r.resettable1 = ip; // expected-warning{{incompatible pointer types assigning to 'NSResettable * __nullable' from 'int *'}} +} + +@implementation NSResettable // expected-warning{{synthesized setter 'setResettable4:' for null_resettable property 'resettable4' does not handle nil}} +- (NSResettable *)resettable1 { + int *ip = 0; + return ip; // expected-warning{{result type 'NSResettable * __nonnull'}} +} + +- (void)setResettable1:(NSResettable *)param { +} + +@synthesize resettable2; // no warning; not synthesized +@synthesize resettable3; // expected-warning{{synthesized setter 'setResettable3:' for null_resettable property 'resettable3' does not handle nil}} + +- (void)setResettable2:(NSResettable *)param { +} + +@dynamic resettable5; + +- (NSResettable *)resettable6 { + return 0; // no warning +} +@end + +// 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)'}} +} + +void testBlockLiterals() { + (void)(^id(void) { return 0; }); + (void)(^id __nullable (void) { return 0; }); + (void)(^ __nullable id(void) { return 0; }); + + int *x = (^ __nullable id(void) { return 0; })(); // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'id __nullable'}} +} diff --git a/test/SemaObjC/nullable-weak-property.m b/test/SemaObjC/nullable-weak-property.m new file mode 100644 index 0000000..617ff4e --- /dev/null +++ b/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/test/SemaObjC/override-nullability.m b/test/SemaObjC/override-nullability.m new file mode 100644 index 0000000..8e29f91 --- /dev/null +++ b/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 |