diff options
Diffstat (limited to 'test/SemaObjC')
32 files changed, 795 insertions, 152 deletions
diff --git a/test/SemaObjC/arc-bridged-cast.m b/test/SemaObjC/arc-bridged-cast.m index 439d3821165d..0ba7792146c6 100644 --- a/test/SemaObjC/arc-bridged-cast.m +++ b/test/SemaObjC/arc-bridged-cast.m @@ -62,3 +62,30 @@ CFTypeRef fixitsWithSpace(id obj) { // CHECK: fix-it:"{{.*}}":{59:9-59:9}:"(__bridge CFTypeRef)" // CHECK: fix-it:"{{.*}}":{59:9-59:9}:" CFBridgingRetain" } + +// rdar://problem/20107345 +typedef const struct __attribute__((objc_bridge(id))) __CFAnnotatedObject *CFAnnotatedObjectRef; +CFAnnotatedObjectRef CFGetAnnotated(); + +void testObjCBridgeId() { + id obj; + obj = (__bridge id)CFGetAnnotated(); + obj = (__bridge NSString*)CFGetAnnotated(); + obj = (__bridge_transfer id)CFGetAnnotated(); + obj = (__bridge_transfer NSString*)CFGetAnnotated(); + + CFAnnotatedObjectRef ref; + ref = (__bridge CFAnnotatedObjectRef) CreateSomething(); + ref = (__bridge CFAnnotatedObjectRef) CreateNSString(); + ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething(); + ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString(); +} + +// rdar://20113785 +typedef const struct __attribute__((objc_bridge(UIFont))) __CTFont * CTFontRef; + +id testObjCBridgeUnknownTypeToId(CTFontRef font) { + id x = (__bridge id)font; + return x; +} + diff --git a/test/SemaObjC/arc-decls.m b/test/SemaObjC/arc-decls.m index 7fcf576f7000..c1c319d95e3c 100644 --- a/test/SemaObjC/arc-decls.m +++ b/test/SemaObjC/arc-decls.m @@ -54,13 +54,13 @@ void func() // rdar://15757510 @interface J -@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} -@property (strong) id copyBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} -@property (copy) id allocBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} +@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-newFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} +@property (strong) id copyBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-copyBar' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} +@property (copy) id allocBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-allocBaz' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} @property (copy, nonatomic) id new; -@property (retain) id newDFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} -@property (strong) id copyDBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} -@property (copy) id allocDBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} +@property (retain) id newDFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-newDFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} +@property (strong) id copyDBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-copyDBar' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} +@property (copy) id allocDBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note{{explicitly declare getter '-allocDBaz' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} @end @implementation J @@ -76,6 +76,29 @@ void func() @end +@interface MethodFamilyDiags +@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} +- (id)newFoo; // expected-note {{explicitly declare getter '-newFoo' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} + +#define OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none))) +- (id)newBar; // expected-note {{explicitly declare getter '-newBar' with 'OBJC_METHOD_FAMILY_NONE' to return an 'unowned' object}} +@property (retain) id newBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} + +@property (retain) id newBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note {{explicitly declare getter '-newBaz' with 'OBJC_METHOD_FAMILY_NONE' to return an 'unowned' object}} +#undef OBJC_METHOD_FAMILY_NONE + +@property (retain, readonly) id newGarply; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}} expected-note {{explicitly declare getter '-newGarply' with '__attribute__((objc_method_family(none)))' to return an 'unowned' object}} +@end + +@interface MethodFamilyDiags (Redeclarations) +- (id)newGarply; // no note here +@end + +@implementation MethodFamilyDiags +@synthesize newGarply; +@end + + // rdar://10187884 @interface Super - (void)bar:(id)b; // expected-note {{parameter declared here}} diff --git a/test/SemaObjC/arc-dict-bridged-cast.m b/test/SemaObjC/arc-dict-bridged-cast.m index e00c47fca393..e683343cd07a 100644 --- a/test/SemaObjC/arc-dict-bridged-cast.m +++ b/test/SemaObjC/arc-dict-bridged-cast.m @@ -28,19 +28,12 @@ id CFBridgingRelease(CFTypeRef __attribute__((cf_consumed)) X); NSMutableString *test() { NSDictionary *infoDictionary; - infoDictionary[kCFBundleNameKey] = 0; // expected-error {{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} \ - // expected-error {{implicit conversion of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} + infoDictionary[kCFBundleNameKey] = 0; // expected-error {{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} return infoDictionary[CFStringCreateMutable(((void*)0), 100)]; // expected-error {{indexing expression is invalid because subscript type 'CFMutableStringRef' (aka 'struct __CFString *') is not an integral or Objective-C pointer type}} \ // expected-error {{implicit conversion of C pointer type 'CFMutableStringRef' (aka 'struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' requires a bridged cast}} \ // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFMutableStringRef' (aka 'struct __CFString *') into ARC}} } -// CHECK: fix-it:"{{.*}}":{31:18-31:18}:"(__bridge __strong id<NSCopying>)(" -// CHECK: fix-it:"{{.*}}":{31:34-31:34}:")" -// CHECK: fix-it:"{{.*}}":{31:18-31:18}:"CFBridgingRelease(" -// CHECK: fix-it:"{{.*}}":{31:34-31:34}:")" -// CHECK: fix-it:"{{.*}}":{35:25-35:25}:"CFBridgingRelease(" -// CHECK: fix-it:"{{.*}}":{35:63-35:63}:")" +// CHECK: fix-it:"{{.*}}":{32:25-32:25}:"CFBridgingRelease(" +// CHECK: fix-it:"{{.*}}":{32:63-32:63}:")" diff --git a/test/SemaObjC/arc-unbridged-cast.m b/test/SemaObjC/arc-unbridged-cast.m index 6a39e707717e..3c0e3f288540 100644 --- a/test/SemaObjC/arc-unbridged-cast.m +++ b/test/SemaObjC/arc-unbridged-cast.m @@ -32,15 +32,20 @@ CFStringRef auditedString(void); CFStringRef auditedCreateString(void); #pragma clang arc_cf_code_audited end +extern const CFStringRef kUserConst; + void test1(int cond) { id x; x = (id) auditedString(); + x = (id) kUserConst; x = (id) (cond ? auditedString() : (void*) 0); x = (id) (cond ? (void*) 0 : auditedString()); x = (id) (cond ? (CFStringRef) @"help" : auditedString()); + x = (id) (cond ? (CFStringRef) @"help" : kUserConst); x = (id) unauditedString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} x = (id) (cond ? unauditedString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? unauditedString() : kUserConst); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} @@ -68,11 +73,13 @@ void test1(int cond) { x = (id) (cond ? [object makeString] : (void*) 0); x = (id) (cond ? (void*) 0 : [object makeString]); x = (id) (cond ? (CFStringRef) @"help" : [object makeString]); + x = (id) (cond ? kUserConst : [object makeString]); x = (id) [object newString]; x = (id) (cond ? [object newString] : (void*) 0); x = (id) (cond ? (void*) 0 : [object newString]); x = (id) (cond ? (CFStringRef) @"help" : [object newString]); // a bit questionable + x = (id) (cond ? kUserConst : [object newString]); // expected-error{{requires a bridged cast}} expected-note{{use __bridge to}} expected-note{{use CFBridgingRelease call to}} } // rdar://problem/10246264 diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index 54a7db7b11b1..60bd6735dbf5 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -293,8 +293,8 @@ void test12(id collection) { x = 0; // expected-error {{fast enumeration variables can't be modified in ARC by default; declare the variable __strong to allow this}} } - for (const id x in collection) { - x = 0; // expected-error {{read-only variable is not assignable}} + for (const id x in collection) { // expected-note {{variable 'x' declared const here}} + x = 0; // expected-error {{cannot assign to variable 'x' with const-qualified type 'const __strong id'}} } for (__strong id x in collection) { diff --git a/test/SemaObjC/attr-availability.m b/test/SemaObjC/attr-availability.m index c455bc7acce6..ea97e0e472d3 100644 --- a/test/SemaObjC/attr-availability.m +++ b/test/SemaObjC/attr-availability.m @@ -1,11 +1,21 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s +// RUN: %clang_cc1 -D WARN_PARTIAL -Wpartial-availability -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s @protocol P - (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{'proto_method' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) + // expected-note@+2 2 {{'partial_proto_method' has been explicitly marked partial here}} +#endif +- (void)partial_proto_method __attribute__((availability(macosx,introduced=10.8))); @end @interface A <P> - (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}} +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'partialMethod' has been explicitly marked partial here}} +#endif +- (void)partialMethod __attribute__((availability(macosx,introduced=10.8))); - (void)overridden __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}} - (void)overridden2 __attribute__((availability(macosx,introduced=10.3))); @@ -18,6 +28,7 @@ // rdar://11475360 @interface B : A - (void)method; // NOTE: we expect 'method' to *not* inherit availability. +- (void)partialMethod; // Likewise. - (void)overridden __attribute__((availability(macosx,introduced=10.4))); // expected-warning{{overriding method introduced after overridden method on OS X (10.4 vs. 10.3)}} - (void)overridden2 __attribute__((availability(macosx,introduced=10.2))); - (void)overridden3 __attribute__((availability(macosx,deprecated=10.4))); @@ -31,6 +42,32 @@ void f(A *a, B *b) { [b method]; // no-warning [a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}} [b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}} + +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partialMethod' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'partialMethod' to silence this warning}} +#endif + [a partialMethod]; + [b partialMethod]; // no warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_proto_method' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'partial_proto_method' to silence this warning}} +#endif + [a partial_proto_method]; +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_proto_method' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'partial_proto_method' to silence this warning}} +#endif + [b partial_proto_method]; +} + +@interface A (NewAPI) +- (void)partialMethod; +- (void)partial_proto_method; +@end + +void f_after_redecl(A *a, B *b) { + [a partialMethod]; // no warning + [b partialMethod]; // no warning + [a partial_proto_method]; // no warning + [b partial_proto_method]; // no warning } // Test case for <rdar://problem/11627873>. Warn about @@ -87,3 +124,85 @@ id NSNibOwner, topNibObjects; } @end + +@protocol PartialProt +- (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8))); ++ (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface PartialI <PartialProt> +- (void)partialMethod __attribute__((availability(macosx,introduced=10.8))); ++ (void)partialMethod __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface PartialI () +- (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8))); +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'ipartialMethod2' has been explicitly marked partial here}} +#endif +- (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8))); ++ (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8))); +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'ipartialMethod2' has been explicitly marked partial here}} +#endif ++ (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface PartialI (Redecls) +- (void)partialMethod; +- (void)ipartialMethod1; +- (void)ppartialMethod; ++ (void)partialMethod; ++ (void)ipartialMethod1; ++ (void)ppartialMethod; +@end + +void partialfun(PartialI* a) { + [a partialMethod]; // no warning + [a ipartialMethod1]; // no warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'ipartialMethod2' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'ipartialMethod2' to silence this warning}} +#endif + [a ipartialMethod2]; + [a ppartialMethod]; // no warning + [PartialI partialMethod]; // no warning + [PartialI ipartialMethod1]; // no warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'ipartialMethod2' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'ipartialMethod2' to silence this warning}} +#endif + [PartialI ipartialMethod2]; + [PartialI ppartialMethod]; // no warning +} + +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'PartialI2' has been explicitly marked partial here}} +#endif +__attribute__((availability(macosx, introduced = 10.8))) @interface PartialI2 +@end + +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'PartialI2' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'PartialI2' to silence this warning}} +#endif +void partialinter1(PartialI2* p) { +} + +@class PartialI2; + +void partialinter2(PartialI2* p) { // no warning +} + + +// Test that both the use of the 'typedef' and the enum constant +// produces an error. rdar://problem/20903588 +#define UNAVAILABLE __attribute__((unavailable("not available"))) + +typedef enum MyEnum : int MyEnum; +enum MyEnum : int { // expected-note {{'MyEnum' has been explicitly marked unavailable here}} + MyEnum_Blah UNAVAILABLE, // expected-note {{'MyEnum_Blah' has been explicitly marked unavailable here}} +} UNAVAILABLE; + +void use_myEnum() { + // expected-error@+2 {{'MyEnum' is unavailable: not available}} + // expected-error@+1 {{MyEnum_Blah' is unavailable: not available}} + MyEnum e = MyEnum_Blah; +} diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m index 13ba68db58e6..14d33d376051 100644 --- a/test/SemaObjC/attr-deprecated.m +++ b/test/SemaObjC/attr-deprecated.m @@ -284,3 +284,14 @@ void f(id a) { void g(id a) { [a anotherPartiallyUnavailableMethod]; // no warning, `a` could be an InterfaceWithImplementation. } + +typedef struct {} S1 __attribute__((unavailable)); // expected-note2{{marked unavailable here}} +typedef struct {} S2 __attribute__((deprecated)); // expected-note2{{marked deprecated here}} +@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}} +- (void)method1:(S1) x; // expected-error{{is unavailable}} +- (void)method2:(S2) x; // expected-warning{{is deprecated}} +@end +@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}} +- (void)method1:(S1) x; // expected-error{{is unavailable}} +- (void)method2:(S2) x; // expected-warning{{is deprecated}} +@end diff --git a/test/SemaObjC/attr-designated-init.m b/test/SemaObjC/attr-designated-init.m index 535065769404..a8673e1b0191 100644 --- a/test/SemaObjC/attr-designated-init.m +++ b/test/SemaObjC/attr-designated-init.m @@ -410,3 +410,11 @@ __attribute__((objc_root_class)) return [super init]; } @end + +@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}} +- (instancetype)init NS_DESIGNATED_INITIALIZER; +@end + +@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}} +- (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}} +@end diff --git a/test/SemaObjC/attr-malloc.m b/test/SemaObjC/attr-malloc.m index a504b333b51f..0874a476806c 100644 --- a/test/SemaObjC/attr-malloc.m +++ b/test/SemaObjC/attr-malloc.m @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -verify -fsyntax-only -fblocks %s @interface TestAttrMallocOnMethods {} -- (id) test1 __attribute((malloc)); // expected-warning {{functions returning a pointer type}} -- (int) test2 __attribute((malloc)); // expected-warning {{functions returning a pointer type}} +- (id) test1 __attribute((malloc)); // expected-warning {{attribute only applies to functions}} +- (int) test2 __attribute((malloc)); // expected-warning {{attribute only applies to functions}} @end id bar(void) __attribute((malloc)); // no-warning @@ -10,7 +10,7 @@ id bar(void) __attribute((malloc)); // no-warning typedef void (^bptr)(void); bptr baz(void) __attribute((malloc)); // no-warning -__attribute((malloc)) id (*f)(); // expected-warning {{functions returning a pointer type}} -__attribute((malloc)) bptr (*g)(); // expected-warning {{functions returning a pointer type}} -__attribute((malloc)) void *(^h)(); // expected-warning {{functions returning a pointer type}} +__attribute((malloc)) id (*f)(); // expected-warning {{attribute only applies to functions}} +__attribute((malloc)) bptr (*g)(); // expected-warning {{attribute only applies to functions}} +__attribute((malloc)) void *(^h)(); // expected-warning {{attribute only applies to functions}} diff --git a/test/SemaObjC/circular-container.m b/test/SemaObjC/circular-container.m new file mode 100644 index 000000000000..1a2a24e8985a --- /dev/null +++ b/test/SemaObjC/circular-container.m @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s + +typedef long int NSUInteger; +#define nil 0 +@class NSString; + +@interface NSMutableArray + +- (void)addObject:(id)object; +- (void)insertObject:(id)object atIndex:(NSUInteger)index; +- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)object; +- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index; + +@end + +@interface NSMutableDictionary + +- (void)setObject:(id)object forKey:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +- (void)setValue:(id)value forKey:(NSString *)key; + +@end + +@interface NSMutableSet + +- (void)addObject:(id)object; + +@end + +@interface NSCountedSet : NSMutableSet + +@end + +@interface NSMutableOrderedSet + +- (void)addObject:(id)object; +- (void)insertObject:(id)object atIndex:(NSUInteger)index; +- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index; +- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)object; +- (void)setObject:(id)object atIndex:(NSUInteger)index; + +@end + +@interface SelfRefClass +{ + NSMutableArray *_array; // expected-note {{'_array' declared here}} + NSMutableDictionary *_dictionary; // expected-note {{'_dictionary' declared here}} + NSMutableSet *_set; // expected-note {{'_set' declared here}} + NSCountedSet *_countedSet; // expected-note {{'_countedSet' declared here}} + NSMutableOrderedSet *_orderedSet; // expected-note {{'_orderedSet' declared here}} +} +@end + +@implementation SelfRefClass + +- (void)check { + [_array addObject:_array]; // expected-warning {{adding '_array' to '_array' might cause circular dependency in container}} + [_dictionary setObject:_dictionary forKey:@"key"]; // expected-warning {{adding '_dictionary' to '_dictionary' might cause circular dependency in container}} + [_set addObject:_set]; // expected-warning {{adding '_set' to '_set' might cause circular dependency in container}} + [_countedSet addObject:_countedSet]; // expected-warning {{adding '_countedSet' to '_countedSet' might cause circular dependency in container}} + [_orderedSet addObject:_orderedSet]; // expected-warning {{adding '_orderedSet' to '_orderedSet' might cause circular dependency in container}} +} + +- (void)checkNSMutableArray:(NSMutableArray *)a { // expected-note {{'a' declared here}} + [a addObject:a]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} +} + +- (void)checkNSMutableDictionary:(NSMutableDictionary *)d { // expected-note {{'d' declared here}} + [d setObject:d forKey:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} +} + +- (void)checkNSMutableSet:(NSMutableSet *)s { // expected-note {{'s' declared here}} + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +- (void)checkNSCountedSet:(NSCountedSet *)s { // expected-note {{'s' declared here}} + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +- (void)checkNSMutableOrderedSet:(NSMutableOrderedSet *)s { // expected-note {{'s' declared here}} + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +@end + +void checkNSMutableArrayParam(NSMutableArray *a) { // expected-note {{'a' declared here}} + [a addObject:a]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} +} + +void checkNSMutableDictionaryParam(NSMutableDictionary *d) { // expected-note {{'d' declared here}} + [d setObject:d forKey:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} +} + +void checkNSMutableSetParam(NSMutableSet *s) { // expected-note {{'s' declared here}} + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +void checkNSCountedSetParam(NSCountedSet *s) { // expected-note {{'s' declared here}} + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +void checkNSMutableOrderedSetParam(NSMutableOrderedSet *s) { // expected-note {{'s' declared here}} + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +void checkNSMutableArray() { + NSMutableArray *a = nil; // expected-note 5 {{'a' declared here}} 5 + + [a addObject:a]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + [a insertObject:a atIndex:0]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + [a replaceObjectAtIndex:0 withObject:a]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + [a setObject:a atIndexedSubscript:0]; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} + a[0] = a; // expected-warning {{adding 'a' to 'a' might cause circular dependency in container}} +} + +void checkNSMutableDictionary() { + NSMutableDictionary *d = nil; // expected-note 4 {{'d' declared here}} + + [d setObject:d forKey:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} + [d setObject:d forKeyedSubscript:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} + [d setValue:d forKey:@"key"]; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} + d[@"key"] = d; // expected-warning {{adding 'd' to 'd' might cause circular dependency in container}} +} + +void checkNSMutableSet() { + NSMutableSet *s = nil; // expected-note {{'s' declared here}} + + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +void checkNSCountedSet() { + NSCountedSet *s = nil; // expected-note {{'s' declared here}} + + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + +void checkNSMutableOrderedSet() { + NSMutableOrderedSet *s = nil; // expected-note 5 {{'s' declared here}} + + [s addObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} + [s insertObject:s atIndex:0]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} + [s setObject:s atIndex:0]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} + [s setObject:s atIndexedSubscript:0]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} + [s replaceObjectAtIndex:0 withObject:s]; // expected-warning {{adding 's' to 's' might cause circular dependency in container}} +} + diff --git a/test/SemaObjC/class-unavail-warning.m b/test/SemaObjC/class-unavail-warning.m index 3ebf3e7815f3..6a683dd349c2 100644 --- a/test/SemaObjC/class-unavail-warning.m +++ b/test/SemaObjC/class-unavail-warning.m @@ -67,3 +67,34 @@ Foo *g_foo = 0; // expected-error {{'Foo' is unavailable}} Foo * f_func() { // expected-error {{'Foo' is unavailable}} return 0; } + +#define UNAVAILABLE __attribute__((unavailable("not available"))) + +UNAVAILABLE +@interface Base // expected-note {{unavailable here}} +@end + +UNAVAILABLE +@protocol SomeProto // expected-note 4 {{unavailable here}} +@end + +@interface Sub : Base<SomeProto> // expected-error 2 {{unavailable}} +@end +@interface IP<SomeProto> // expected-error {{unavailable}} +@end +@protocol SubProt<SomeProto> // expected-error {{unavailable}} +@end +@interface Sub(cat)<SomeProto> // expected-error {{unavailable}} +@end + +UNAVAILABLE +@interface UnavailSub : Base<SomeProto> // no error +@end +UNAVAILABLE +@interface UnavailIP<SomeProto> // no error +@end +UNAVAILABLE +@protocol UnavailProt<SomeProto> // no error +@end +@interface UnavailSub(cat)<SomeProto> // no error +@end diff --git a/test/SemaObjC/debugger-support.m b/test/SemaObjC/debugger-support.m index 5dbc3eebfa2c..b67353f6f71c 100644 --- a/test/SemaObjC/debugger-support.m +++ b/test/SemaObjC/debugger-support.m @@ -8,7 +8,7 @@ void test0(id x) { // CHECK: [[X:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[RESULT:%.*]] = alloca [[A:%.*]], align 4 // CHECK-NEXT: store i8* {{%.*}}, i8** [[X]], - // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]], - // CHECK-NEXT: [[T1:%.*]] = load i8** @OBJC_SELECTOR_REFERENCES_ + // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], + // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T2:%.*]] = call { i64, i64 } bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to { i64, i64 } (i8*, i8*)*)(i8* [[T0]], i8* [[T1]]) } diff --git a/test/SemaObjC/format-ostrace-warning.m b/test/SemaObjC/format-ostrace-warning.m new file mode 100644 index 000000000000..c749881c7a8d --- /dev/null +++ b/test/SemaObjC/format-ostrace-warning.m @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -Wcstring-format-directive -verify -fsyntax-only %s +// rdar://19904147 + +typedef __builtin_va_list __darwin_va_list; +typedef __builtin_va_list va_list; + +va_list argList; + +typedef const struct __CFString * CFStringRef; +typedef struct __CFString * CFMutableStringRef; +typedef const struct __CFAllocator * CFAllocatorRef; + + +typedef const struct __CFDictionary * CFDictionaryRef; + +CFStringRef CFSTR ( const char *cStr ); + + +extern +CFStringRef CStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, const char* format, ...) __attribute__((format(os_trace, 3, 4))); + +extern +CFStringRef CStringCreateWithFormatAndArguments(CFAllocatorRef alloc, CFDictionaryRef formatOptions, const char* format, va_list arguments) __attribute__((format(os_trace, 3, 0))); + +extern +void CStringAppendFormat(CFMutableStringRef theString, CFDictionaryRef formatOptions, const char* format, ...) __attribute__((format(os_trace, 3, 4))); + +extern +void CStringAppendFormatAndArguments(CFMutableStringRef theString, CFDictionaryRef formatOptions, const char* format, va_list arguments) __attribute__((format(os_trace, 3, 0))); + +void Test1(va_list argList) { + CFAllocatorRef alloc; + CStringCreateWithFormatAndArguments (alloc, 0, "%s\n", argList); + CStringAppendFormatAndArguments ((CFMutableStringRef)@"AAAA", 0, "Hello %s there %d\n", argList); + CStringCreateWithFormatAndArguments (alloc, 0, "%c\n", argList); + CStringAppendFormatAndArguments ((CFMutableStringRef)@"AAAA", 0, "%d\n", argList); +} + +extern void MyOSLog(const char* format, ...) __attribute__((format(os_trace, 1, 2))); +extern void MyFStringCreateWithFormat(const char *format, ...) __attribute__((format(os_trace, 1, 2))); +extern void XMyOSLog(int, const char* format, ...) __attribute__((format(os_trace, 2, 3))); +extern void os_trace(const char *format, ...) __attribute__((format(os_trace, 1, 2))); + +void Test2() { + MyOSLog("%s\n", "Hello"); + + MyFStringCreateWithFormat("%s", "Hello"); + XMyOSLog(4, "%s\n", "Hello"); + + os_trace("testing %@, %s, %d, %@, %m", CFSTR("object"), "string", 3, "it"); // expected-warning {{format specifies type 'id' but the argument has type 'char *'}} + + os_trace("testing %@, %s, %d, %@, %m", CFSTR("object"), "string", 3, @"ok"); +} + diff --git a/test/SemaObjC/iboutlet.m b/test/SemaObjC/iboutlet.m index 7d656a51684a..597c4e462872 100644 --- a/test/SemaObjC/iboutlet.m +++ b/test/SemaObjC/iboutlet.m @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s // rdar://11448209 +// rdar://20259376 #define READONLY readonly diff --git a/test/SemaObjC/multiple-method-names.m b/test/SemaObjC/multiple-method-names.m new file mode 100644 index 000000000000..9fd83b208ab7 --- /dev/null +++ b/test/SemaObjC/multiple-method-names.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -Wobjc-multiple-method-names -x objective-c %s -verify +// PR22047 + +@interface Face0 +- (void)foo:(float)i; // expected-note {{using}} +@end + +@interface Face1 +- (void)foo:(int)i __attribute__((unavailable)); +@end + +@interface Face2 +- (void)foo:(char)i; // expected-note {{also found}} +@end + +void f(id i) { + [i foo:4.0f]; // expected-warning {{multiple methods named 'foo:' found}} +} + diff --git a/test/SemaObjC/multiple-property-deprecated-decl.m b/test/SemaObjC/multiple-property-deprecated-decl.m new file mode 100644 index 000000000000..d7dbd458a419 --- /dev/null +++ b/test/SemaObjC/multiple-property-deprecated-decl.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.11 -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple x86_64-apple-macosx10.11 -verify -Wno-objc-root-class %s +// expected-no-diagnostics +// rdar://20408445 + +@protocol NSFileManagerDelegate @end + +@interface NSFileManager +@property (assign) id <NSFileManagerDelegate> delegate; +@end + +@interface NSFontManager +@property (assign) id delegate __attribute__((availability(macosx,introduced=10.0 ,deprecated=10.11,message="" "NSFontManager doesn't have any delegate method. This property should not be used."))); + +@end + +id Test20408445(id p) { + return [p delegate]; +} diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m index cacca07240f6..e1f31937a510 100644 --- a/test/SemaObjC/nonnull.m +++ b/test/SemaObjC/nonnull.m @@ -123,3 +123,5 @@ void PR18795(int (^g)(const char *h, ...) __attribute__((nonnull(1))) __attribut void PR18795_helper() { PR18795(0); // expected-warning{{null passed to a callee that requires a non-null argument}} } + +void (^PR23117)(int *) = ^(int *p1) __attribute__((nonnull(1))) {}; diff --git a/test/SemaObjC/objc-array-literal.m b/test/SemaObjC/objc-array-literal.m index 706207df7482..2971fcc45399 100644 --- a/test/SemaObjC/objc-array-literal.m +++ b/test/SemaObjC/objc-array-literal.m @@ -9,6 +9,18 @@ typedef unsigned long NSUInteger; typedef unsigned int NSUInteger; #endif +void checkNSArrayUnavailableDiagnostic() { + id obj; + id arr = @[obj]; // expected-error {{NSArray must be available to use Objective-C array literals}} +} + +@class NSArray; + +void checkNSArrayFDDiagnostic() { + id obj; + id arr = @[obj]; // expected-error {{declaration of 'arrayWithObjects:count:' is missing in NSArray class}} +} + @class NSString; extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); diff --git a/test/SemaObjC/objc-dictionary-literal.m b/test/SemaObjC/objc-dictionary-literal.m index f9fd57f2dae2..87f127f9281e 100644 --- a/test/SemaObjC/objc-dictionary-literal.m +++ b/test/SemaObjC/objc-dictionary-literal.m @@ -5,6 +5,20 @@ #define nil ((void *)0) +void checkNSDictionaryUnavailableDiagnostic() { + id key; + id value; + id dict = @{ key : value }; // expected-error {{NSDictionary must be available to use Objective-C dictionary literals}} +} + +@class NSDictionary; + +void checkNSDictionaryFDDiagnostic() { + id key; + id value; + id dic = @{ key : value }; // expected-error {{declaration of 'dictionaryWithObjects:forKeys:count:' is missing in NSDictionary class}} +} + @interface NSNumber + (NSNumber *)numberWithChar:(char)value; + (NSNumber *)numberWithInt:(int)value; diff --git a/test/SemaObjC/objc-independent-class-attribute.m b/test/SemaObjC/objc-independent-class-attribute.m new file mode 100644 index 000000000000..2fc13f0cf141 --- /dev/null +++ b/test/SemaObjC/objc-independent-class-attribute.m @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://20255473 + +@interface NSObject @end + +typedef NSObject * __attribute__((objc_independent_class))dispatch_queue_t; + +typedef struct S {int ii; } * __attribute__((objc_independent_class))dispatch_queue_t_2; // expected-warning {{Objective-C object}} + +typedef struct { // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} + NSObject *__attribute__((objc_independent_class)) ns; // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} +} __attribute__((objc_independent_class)) T; + +dispatch_queue_t dispatch_queue_create(); + +@interface DispatchQPointerCastIssue : NSObject { + NSObject *__attribute__((objc_independent_class)) Ivar; // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} +} + +@property (copy) NSObject *__attribute__((objc_independent_class)) Prop; // expected-warning {{'objc_independent_class' attribute may be put on a typedef only; attribute is ignored}} + +typedef NSObject * __attribute__((objc_independent_class))dispatch_queue_t_1; + +@end + +@implementation DispatchQPointerCastIssue ++ (dispatch_queue_t) newDispatchQueue { + return dispatch_queue_create(); +} +@end + +NSObject *get_nsobject() { + typedef NSObject * __attribute__((objc_independent_class))dispatch_queue_t; + dispatch_queue_t dt; + return dt; +} diff --git a/test/SemaObjC/objc-literal-nsnumber.m b/test/SemaObjC/objc-literal-nsnumber.m index a2d37282b716..57bc07b139e9 100644 --- a/test/SemaObjC/objc-literal-nsnumber.m +++ b/test/SemaObjC/objc-literal-nsnumber.m @@ -9,6 +9,24 @@ typedef unsigned int NSUInteger; typedef int NSInteger; #endif +void checkNSNumberUnavailableDiagnostic() { + id num = @1000; // expected-error {{NSNumber must be available to use Objective-C literals}} + + int x = 1000; + id num1 = @(x); // expected-error {{NSNumber must be available to use Objective-C literals}}\ + // expected-error {{illegal type 'int' used in a boxed expression}} +} + +@class NSNumber; + +void checkNSNumberFDDiagnostic() { + id num = @1000; // expected-error {{NSNumber must be available to use Objective-C literals}} + + int x = 1000; + id num1 = @(x); // expected-error {{declaration of 'numberWithInt:' is missing in NSNumber class}}\ + // expected-error {{illegal type 'int' used in a boxed expression}} +} + @interface NSObject + (NSObject*)nsobject; @end diff --git a/test/SemaObjC/objcbridge-attribute-arc.m b/test/SemaObjC/objcbridge-attribute-arc.m index ab8cab8d1919..3bcfdf48e794 100644 --- a/test/SemaObjC/objcbridge-attribute-arc.m +++ b/test/SemaObjC/objcbridge-attribute-arc.m @@ -9,28 +9,30 @@ typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // e typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}} -typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}} -typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; -typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} + +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX; typedef XXX *CFUColor2Ref; @interface I { - __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; + __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}}; } @end @@ -75,7 +77,8 @@ void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2 // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \ // expected-note {{__bridge to convert directly (no change in ownership)}} \ - // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} + // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} \ + // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \ // expected-note {{use __bridge to convert directly (no change in ownership)}} \ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') into ARC}} @@ -214,7 +217,7 @@ void Test8(CFMyPersonalErrorRef cf) { void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) { (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} (void)(__bridge NSError *)cf; // okay - (void)(__bridge MyError*)cf; // okay, + (void)(__bridge MyError*)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(__bridge NSUColor *)cf2; // okay (void)(__bridge CFErrorRef)ns; // okay (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m index a268caef8a50..9cab64ec6b28 100644 --- a/test/SemaObjC/objcbridge-attribute.m +++ b/test/SemaObjC/objcbridge-attribute.m @@ -9,28 +9,36 @@ typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // e typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}} -typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}} -typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} +typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; // expected-note {{declared here}} -typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} -typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{parameter of 'objc_bridge' attribute must be 'id' when used on a typedef}} typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX; typedef XXX *CFUColor2Ref; +typedef const void *ConstVoidRef __attribute__((objc_bridge(id))); +typedef void *VoidRef __attribute__((objc_bridge(id))); +typedef struct Opaque *OpaqueRef __attribute__((objc_bridge(id))); // expected-error {{'objc_bridge(id)' is only allowed on structs and typedefs of void pointers}} + +#if !__has_feature(objc_bridge_id_on_typedefs) +#error objc_bridge(id) on typedefs feature not found! +#endif + @interface I { - __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; + __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}}; } @end @@ -65,7 +73,7 @@ typedef CFErrorRef1 CFErrorRef2; // expected-note {{declared here}} void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) { (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} (void)(NSError *)cf; // okay - (void)(MyError*)cf; // okay, + (void)(MyError*)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}} (void)(NSUColor *)cf2; // okay (void)(CFErrorRef)ns; // okay (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} @@ -133,3 +141,14 @@ CFDictionaryRef bar() __attribute__((cf_returns_not_retained)); void Test9() { NSNumber *w2 = (NSNumber*) bar(); // expected-error {{CF object of type 'CFDictionaryRef' (aka 'struct __CFDictionary *') is bridged to 'NSDictionary', which is not an Objective-C class}} } + +// rdar://18311183 +@interface NSObject @end + +@interface NSFont : NSObject @end + +typedef struct __attribute__ ((objc_bridge(NSFont))) __CFFontRef * CFFontRef; + +void Test10(CFFontRef cf) { + (void)(__bridge NSObject *)cf; +} diff --git a/test/SemaObjC/objcbridgemutable-attribute.m b/test/SemaObjC/objcbridgemutable-attribute.m index 4ec8de0b5488..524e6868fa70 100644 --- a/test/SemaObjC/objcbridgemutable-attribute.m +++ b/test/SemaObjC/objcbridgemutable-attribute.m @@ -23,7 +23,8 @@ void Test(NSMutableDictionary *md, NSDictionary *nd, CFMutableDictionaryRef mcf, (void) (CFMutableDictionaryRef)md; (void) (CFMutableDictionaryRef)nd; // expected-warning {{'NSDictionary' cannot bridge to 'CFMutableDictionaryRef' (aka 'struct __CFDictionary *')}} - (void) (NSDictionary *)mcf; // expected-warning {{'CFMutableDictionaryRef' (aka 'struct __CFDictionary *') bridges to NSMutableDictionary, not 'NSDictionary'}} + (void) (NSDictionary *)mcf; // ok, bridgt_type NSMutableDictionary can be type-cast to its super class. + NSDictionary *nsdobj = (NSMutableDictionary*)0; (void) (NSMutableDictionary *)mcf; // ok; (void) (NSMutableDictionary *)bmcf; // expected-error {{CF object of type 'CFMutableDictionaryB2Ref' (aka 'struct __CFDictionaryB2 *') is bridged to 'P', which is not an Objective-C class}} diff --git a/test/SemaObjC/property-9.m b/test/SemaObjC/property-9.m index 4bed8751b6a8..623143d54967 100644 --- a/test/SemaObjC/property-9.m +++ b/test/SemaObjC/property-9.m @@ -106,3 +106,18 @@ id f0(MDATestDocument *d) { return d.instance.path; // expected-error {{property 'path' cannot be found in forward class object 'MDAInstance'}} } +// rdar://20469452 +@interface UIView @end + +@interface FRFakeBannerView : UIView +@end + +@interface FRAdCollectionViewCell +@property (nonatomic, weak, readonly) UIView *bannerView; +@end + +@interface FRAdCollectionViewCell () + +@property (nonatomic, weak, readwrite) FRFakeBannerView *bannerView; + +@end diff --git a/test/SemaObjC/property-deprecated-warning.m b/test/SemaObjC/property-deprecated-warning.m index 4beb23ada33a..cec376838def 100644 --- a/test/SemaObjC/property-deprecated-warning.m +++ b/test/SemaObjC/property-deprecated-warning.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -triple thumbv6-apple-ios3.0 -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -D WARN_PARTIAL -Wpartial-availability -fsyntax-only -triple thumbv6-apple-ios3.0 -verify -Wno-objc-root-class %s // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple thumbv6-apple-ios3.0 -verify -Wno-objc-root-class %s // rdar://12324295 @@ -6,29 +7,47 @@ typedef signed char BOOL; @protocol P @property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{'ptarget' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialPtarget' is declared partial here}} expected-note@+2 {{'partialPtarget' has been explicitly marked partial here}} +#endif +@property(nonatomic,assign) id partialPtarget __attribute__((availability(ios,introduced=5.0))); @end @protocol P1<P> - (void)setPtarget:(id)arg; +- (void)setPartialPtarget:(id)arg; @end @interface UITableViewCell<P1> @property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} expected-note {{'setTarget:' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialTarget' is declared partial here}} expected-note@+2 {{'setPartialTarget:' has been explicitly marked partial here}} +#endif +@property(nonatomic,assign) id partialTarget __attribute__((availability(ios,introduced=5.0))); @end @interface PSTableCell : UITableViewCell - (void)setTarget:(id)target; + - (void)setPartialTarget:(id)target; @end @interface UITableViewCell(UIDeprecated) @property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{'dep_target' has been explicitly marked deprecated here}} \ // expected-note 4 {{property 'dep_target' is declared deprecated here}} \ // expected-note 2 {{'setDep_target:' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 4 {{property 'partial_dep_target' is declared partial here}} expected-note@+2 2 {{'partial_dep_target' has been explicitly marked partial here}} expected-note@+2 2 {{'setPartial_dep_target:' has been explicitly marked partial here}} +#endif +@property(nonatomic,assign) id partial_dep_target __attribute__((availability(ios,introduced=5.0))); @end @implementation PSTableCell - (void)setTarget:(id)target {}; +- (void)setPartialTarget:(id)target {}; - (void)setPtarget:(id)val {}; - (void) Meth { [self setTarget: (id)0]; // no-warning @@ -36,20 +55,41 @@ typedef signed char BOOL; // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}} [self setPtarget: (id)0]; // no-warning + [self setPartialTarget: (id)0]; // no-warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_dep_target' is partial: introduced in iOS 5.0}} expected-warning@+2 {{'setPartial_dep_target:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partial_dep_target' to silence this warning}} expected-note@+2 {{explicitly redeclare 'setPartial_dep_target:' to silence this warning}} +#endif + [self setPartial_dep_target: [self partial_dep_target]]; + + [self setPartialPtarget: (id)0]; // no-warning } @end @implementation UITableViewCell @synthesize target; +@synthesize partialTarget; @synthesize ptarget; +@synthesize partialPtarget; - (void)setPtarget:(id)val {}; +- (void)setPartialPtarget:(id)val {}; - (void)setTarget:(id)target {}; +- (void)setPartialTarget:(id)target {}; - (void) Meth { [self setTarget: (id)0]; // expected-warning {{'setTarget:' is deprecated: first deprecated in iOS 3.0}} [self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \ // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}} - + [self setPtarget: (id)0]; // no-warning + +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'setPartialTarget:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'setPartialTarget:' to silence this warning}} +#endif + [self setPartialTarget: (id)0]; +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_dep_target' is partial: introduced in iOS 5.0}} expected-warning@+2 {{'setPartial_dep_target:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partial_dep_target' to silence this warning}} expected-note@+2 {{explicitly redeclare 'setPartial_dep_target:' to silence this warning}} +#endif + [self setPartial_dep_target: [self partial_dep_target]]; + [self setPartialPtarget: (id)0]; // no-warning } @end @@ -58,11 +98,27 @@ typedef signed char BOOL; @property(getter=isEnabled,assign) BOOL enabled __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'isEnabled' has been explicitly marked deprecated here}} expected-note {{property 'enabled' is declared deprecated here}} @property(setter=setNewDelegate:,assign) id delegate __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'setNewDelegate:' has been explicitly marked deprecated here}} expected-note {{property 'delegate' is declared deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialEnabled' is declared partial here}} expected-note@+2 {{'partialIsEnabled' has been explicitly marked partial here}} +#endif +@property(getter=partialIsEnabled,assign) BOOL partialEnabled __attribute__((availability(ios,introduced=5.0))); + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialDelegate' is declared partial here}} expected-note@+2 {{'partialSetNewDelegate:' has been explicitly marked partial here}} +#endif +@property(setter=partialSetNewDelegate:,assign) id partialDelegate __attribute__((availability(ios,introduced=5.0))); @end void testCustomAccessorNames(CustomAccessorNames *obj) { if ([obj isEnabled]) // expected-warning {{'isEnabled' is deprecated: first deprecated in iOS 3.0}} [obj setNewDelegate:0]; // expected-warning {{'setNewDelegate:' is deprecated: first deprecated in iOS 3.0}} + +#if defined(WARN_PARTIAL) +// expected-warning@+2 {{'partialIsEnabled' is partial: introduced in iOS 5.0}} expected-warning@+3 {{'partialSetNewDelegate:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partialIsEnabled' to silence this warning}} expected-note@+3 {{explicitly redeclare 'partialSetNewDelegate:' to silence this warning}} +#endif + if ([obj partialIsEnabled]) + [obj partialSetNewDelegate:0]; } @@ -71,12 +127,20 @@ void testCustomAccessorNames(CustomAccessorNames *obj) { @interface ProtocolInCategory (TheCategory) <P1> - (id)ptarget; +- (id)partialPtarget; @end id useDeprecatedProperty(ProtocolInCategory *obj, id<P> obj2, int flag) { if (flag) return [obj ptarget]; // no-warning return [obj2 ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}} + + if (flag) + return [obj partialPtarget]; // no-warning +#if defined(WARN_PARTIAL) +// expected-warning@+2 {{'partialPtarget' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partialPtarget' to silence this warning}} +#endif + return [obj2 partialPtarget]; } // rdar://15951801 diff --git a/test/SemaObjC/selector-3.m b/test/SemaObjC/selector-3.m index dfd216a16fa9..80332ec0d474 100644 --- a/test/SemaObjC/selector-3.m +++ b/test/SemaObjC/selector-3.m @@ -134,3 +134,24 @@ void test16428638() { SEL s = @selector(compare:); (void)s; } + +// rdar://16607480 +@class NSString; +@interface SELCanary : NSObject +@property (readonly, nonatomic) NSString *name; +@property (nonatomic, getter = isHidden) char hidden; +@property (nonatomic, copy, getter = hasFish, setter = setFish:) NSString *ridiculousFish; +@end + +@implementation SELCanary +- (void) Meth { + SEL properties[] = { + @selector(name), + @selector(isHidden), + @selector(setHidden:), + @selector(hasFish), + @selector(setFish:) + }; +} +@end + diff --git a/test/SemaObjC/super-property-notation.m b/test/SemaObjC/super-property-notation.m index 2b13a5c0f87c..7d7b84deb7cd 100644 --- a/test/SemaObjC/super-property-notation.m +++ b/test/SemaObjC/super-property-notation.m @@ -50,3 +50,9 @@ __attribute__((objc_root_class)) @interface ClassBase [super setFoo:foo]; // works with no warning } @end + +@implementation IFaceNotFound (Foo) // expected-error {{cannot find interface declaration for 'IFaceNotFound'}} +-(int) foo { + return super.foo; // expected-error {{expected identifier or '('}} +} +@end diff --git a/test/SemaObjC/undef-arg-super-method-call.m b/test/SemaObjC/undef-arg-super-method-call.m new file mode 100644 index 000000000000..6a27acb6304a --- /dev/null +++ b/test/SemaObjC/undef-arg-super-method-call.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://20350364 + +@interface NSObject @end + +@interface DBGViewDebuggerSupport : NSObject ++ (void)addViewLayerInfo:(id)view; +- (void)addInstViewLayerInfo:(id)view; +@end + +@interface DBGViewDebuggerSupport_iOS : DBGViewDebuggerSupport +@end + +@implementation DBGViewDebuggerSupport_iOS ++ (void)addViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}} +{ + [super addViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}} +} +- (void)addInstViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}} +{ + [super addInstViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}} +} +@end diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m index 6ea3fe8e00ab..f31e4709f534 100644 --- a/test/SemaObjC/unused.m +++ b/test/SemaObjC/unused.m @@ -91,8 +91,7 @@ void rdar15596883(id x) { void test3(PropertyObject *o) { - [o length]; // expected-warning {{property access result unused - getters should not be used for side effects}} - (void)[o length]; + [o length]; // No warning. property name used in direct method call. } void test4(id o) @@ -102,5 +101,30 @@ void test4(id o) void test5(id <P> p) { - [p property]; // expected-warning {{property access result unused - getters should not be used for side effects}} + [p property]; // No warning. property name used in direct method call. } + +// rdar://19773512 +@interface Model +@property (nonatomic, retain, setter=setOrCreateGroup:, getter=getOrCreateGroup) id group; +@end + +@implementation Model { + id _group; +} +- (void)method { + [self getOrCreateGroup]; + self.getOrCreateGroup; // expected-warning {{property access result unused - getters should not be used for side effects}} + self.group; // expected-warning {{property access result unused - getters should not be used for side effects}} + self.group = (void*)0; + [self setOrCreateGroup : ((void*)0)]; + +} +- (id)getOrCreateGroup { + if (!_group) { + _group = @"group"; + } + return _group; +} +@end + diff --git a/test/SemaObjC/warn-strict-selector-match.m b/test/SemaObjC/warn-strict-selector-match.m index 9f22e73edc69..13e9bac462fc 100644 --- a/test/SemaObjC/warn-strict-selector-match.m +++ b/test/SemaObjC/warn-strict-selector-match.m @@ -13,23 +13,24 @@ int main() { [(id)0 method]; } // expected-warning {{multiple methods named 'met @interface Object @end @interface Class1 -- (void)setWindow:(Object *)wdw; // expected-note {{using}} +- (void)setWindow:(Object *)wdw; // expected-note 2 {{using}} @end @interface Class2 -- (void)setWindow:(Class1 *)window; // expected-note {{also found}} +- (void)setWindow:(Class1 *)window; // expected-note 2 {{also found}} @end id foo(void) { Object *obj = 0; id obj2 = obj; - [obj setWindow:0]; // expected-warning {{Object' may not respond to 'setWindow:'}} + [obj setWindow:0]; // expected-warning {{Object' may not respond to 'setWindow:'}} \ + // expected-warning {{multiple methods named 'setWindow:' found}} [obj2 setWindow:0]; // expected-warning {{multiple methods named 'setWindow:' found}} return obj; } @protocol MyObject -- (id)initWithData:(Object *)data; // expected-note {{using}} +- (id)initWithData:(Object *)data; // expected-note {{also found}} @end @protocol SomeOther @@ -37,7 +38,7 @@ id foo(void) { @end @protocol MyCoding -- (id)initWithData:(id<MyObject, MyCoding>)data; // expected-note {{also found}} +- (id)initWithData:(id<MyObject, MyCoding>)data; // expected-note {{using}} @end @interface NTGridDataObject: Object <MyCoding> @@ -71,3 +72,29 @@ void foo1(void) { [(Class)0 port]; // OK - gcc issues warning but there is only one Class method so no ambiguity to warn } +// rdar://19265430 +@interface NSObject +- (id)class; +- (id) alloc; +@end + +@class NSString; + +@interface A : NSObject +- (instancetype)initWithType:(NSString *)whatever; // expected-note {{also found}} +@end + +@interface Test : NSObject +@end + +@implementation Test ++ (instancetype)foo +{ + return [[[self class] alloc] initWithType:3]; // expected-warning {{multiple methods named 'initWithType:'}} +} + +- (instancetype)initWithType:(unsigned int)whatever // expected-note {{using}} +{ + return 0; +} +@end diff --git a/test/SemaObjC/weak-receiver-warn.m b/test/SemaObjC/weak-receiver-warn.m deleted file mode 100644 index 88b867ed0d04..000000000000 --- a/test/SemaObjC/weak-receiver-warn.m +++ /dev/null @@ -1,100 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Wreceiver-is-weak -verify %s -// rdar://10225276 - -@interface Test0 -- (void) setBlock: (void(^)(void)) block; -- (void) addBlock: (void(^)(void)) block; -- (void) actNow; -@end - -void test0(Test0 *x) { - __weak Test0 *weakx = x; - [x addBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - [x setBlock: ^{ [weakx actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - x.block = ^{ [weakx actNow]; }; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - - [weakx addBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - [weakx setBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - weakx.block = ^{ [x actNow]; }; // expected-warning {{weak receiver may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} -} - -@interface Test -{ - __weak Test* weak_prop; -} -- (void) Meth; -@property __weak Test* weak_prop; // expected-note {{property declared here}} -@property (weak, atomic) id weak_atomic_prop; // expected-note {{property declared here}} -- (__weak id) P; // expected-note {{method 'P' declared here}} -@end - -@implementation Test -- (void) Meth { - if (self.weak_prop) { - self.weak_prop = 0; - } - if (self.weak_atomic_prop) { - self.weak_atomic_prop = 0; - } - [self.weak_prop Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - id pi = self.P; - - [self.weak_atomic_prop Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - - [self.P Meth]; // expected-warning {{weak implicit property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} -} - -- (__weak id) P { return 0; } -@dynamic weak_prop, weak_atomic_prop; -@end - - -@interface MyClass { - __weak MyClass *_parent; -} -@property (weak) MyClass *parent; // expected-note 4 {{property declared here}} -@end - -@implementation MyClass -@synthesize parent = _parent; - -- (void)doSomething -{ - [[self parent] doSomething]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - - (void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} -} - -@end - - -// Weak properties on protocols can be synthesized by an adopting class. -@protocol MyProtocol -@property (weak) id object; // expected-note 2 {{property declared here}} -@end - -void testProtocol(id <MyProtocol> input) { - [[input object] Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - [input.object Meth]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} -} - - -@interface Subclass : MyClass -// Unnecessarily redeclare -parent. -- (id)parent; -@end - -@implementation Subclass - -- (id)parent { - return [super parent]; -} - -- (void)doSomethingElse { - [[self parent] doSomething]; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} - - (void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably set to nil}} expected-note {{assign the value to a strong variable to keep the object alive during use}} -} - -@end - |
