diff options
Diffstat (limited to 'test/SemaObjC')
84 files changed, 2423 insertions, 291 deletions
diff --git a/test/SemaObjC/arc-decls.m b/test/SemaObjC/arc-decls.m index 903cea2a0e8a..7fcf576f7000 100644 --- a/test/SemaObjC/arc-decls.m +++ b/test/SemaObjC/arc-decls.m @@ -51,20 +51,28 @@ void func() } // rdar://9157348 +// rdar://15757510 @interface J -@property (retain) id newFoo; // expected-note {{property declared here}} -@property (strong) id copyBar; // expected-note {{property declared here}} -@property (copy) id allocBaz; // expected-note {{property declared here}} +@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 (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}} @end @implementation J -@synthesize newFoo; // expected-error {{property's synthesized getter follows Cocoa naming convention for returning}} -@synthesize copyBar; // expected-error {{property's synthesized getter follows Cocoa naming convention for returning}} -@synthesize allocBaz; // expected-error {{property's synthesized getter follows Cocoa naming convention for returning}} +@synthesize newFoo; +@synthesize copyBar; +@synthesize allocBaz; @synthesize new; - new {return 0; }; + +@dynamic newDFoo; +@dynamic copyDBar; +@dynamic allocDBaz; @end diff --git a/test/SemaObjC/arc-invalid.m b/test/SemaObjC/arc-invalid.m index c736ed4a167c..07b6480c1f9b 100644 --- a/test/SemaObjC/arc-invalid.m +++ b/test/SemaObjC/arc-invalid.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -verify %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -verify %s // rdar://problem/10982793 // [p foo] in ARC creates a cleanup. @@ -16,3 +16,29 @@ void test1(void) { __autoreleasing id p; // expected-note {{'p' declared here}} takeBlock(^{ (void) p; }); // expected-error {{cannot capture __autoreleasing variable in a block}} } + +// rdar://17024681 +@class WebFrame; +@interface WebView // expected-note {{previous definition is here}} +- (WebFrame *)mainFrame; +@end + +@interface WebView // expected-error {{duplicate interface definition for class 'WebView'}} +@property (nonatomic, readonly, strong) WebFrame *mainFrame; +@end + +@interface UIWebDocumentView +- (WebView *)webView; +@end + +@interface UIWebBrowserView : UIWebDocumentView +@end + +@interface StoreBanner @end + +@implementation StoreBanner ++ (void)readMetaTagContentForUIWebBrowserView:(UIWebBrowserView *)browserView +{ + [[browserView webView] mainFrame]; +} +@end diff --git a/test/SemaObjC/arc-jump-block.m b/test/SemaObjC/arc-jump-block.m index 26a1fc839d73..9b06c5a780cc 100644 --- a/test/SemaObjC/arc-jump-block.m +++ b/test/SemaObjC/arc-jump-block.m @@ -84,7 +84,7 @@ extern __attribute__((visibility("default"))) struct dispatch_queue_s _dispatch_ @end // Test 2. rdar://problem/11150919 -int test2(id obj, int state) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location +int test2(id obj, int state) { // expected-note {{jump enters lifetime of block}} FIXME: weird location switch (state) { case 0: (void) ^{ (void) obj; }; diff --git a/test/SemaObjC/arc-objcbridge-related-attribute.m b/test/SemaObjC/arc-objcbridge-related-attribute.m new file mode 100644 index 000000000000..59daef1ce64b --- /dev/null +++ b/test/SemaObjC/arc-objcbridge-related-attribute.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s +// rdar://15499111 + +typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 5 {{declared here}} +typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1; +typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2; + +@interface NSColor // expected-note 5 {{declared here}} ++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor; +- (CGColorRef)CGColor; +- (CGColorRef1)CGColor1; +@end + +@interface NSTextField +- (void)setBackgroundColor:(NSColor *)color; +- (NSColor *)backgroundColor; +@end + +void foo(NSColor*); // expected-note {{passing argument to parameter here}} + +NSColor * Test1(NSTextField *textField, CGColorRef newColor) { + foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} + textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *__strong'; use '+colorWithCGColor:' method for this conversion}} + return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} +} + +NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) { + foo(newColor); // expected-warning {{incompatible pointer types passing 'CGColorRef1' (aka 'struct CGColor1 *') to parameter of type 'NSColor *'}} + textField.backgroundColor = newColor; // expected-warning {{incompatible pointer types assigning to 'NSColor *__strong' from 'CGColorRef1' (aka 'struct CGColor1 *')}} + return newColor; // expected-warning {{incompatible pointer types returning 'CGColorRef1' (aka 'struct CGColor1 *') from a function with result type 'NSColor *'}} +} + +CGColorRef Test3(NSTextField *textField, CGColorRef newColor) { + newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} + return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} +} + +CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) { + newColor = textField.backgroundColor; // expected-warning {{incompatible pointer types assigning}} + return textField.backgroundColor; // expected-warning {{incompatible pointer types returning}} +} diff --git a/test/SemaObjC/arc-property-lifetime.m b/test/SemaObjC/arc-property-lifetime.m index ed72e8c7d811..4874ff3a35eb 100644 --- a/test/SemaObjC/arc-property-lifetime.m +++ b/test/SemaObjC/arc-property-lifetime.m @@ -154,7 +154,7 @@ @property id prop; @property __strong id strong_prop; @property (strong) id strong_attr_prop; -@property (strong) __strong id realy_strong_attr_prop; +@property (strong) __strong id really_strong_attr_prop; + (id) alloc; - (id) init; - (id) implicit; @@ -165,7 +165,7 @@ void foo(Baz *f) { f.prop = [[Baz alloc] init]; f.strong_prop = [[Baz alloc] init]; f.strong_attr_prop = [[Baz alloc] init]; - f.realy_strong_attr_prop = [[Baz alloc] init]; + f.really_strong_attr_prop = [[Baz alloc] init]; f.implicit = [[Baz alloc] init]; } diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m index eab5f2ca746e..82748027435e 100644 --- a/test/SemaObjC/arc-unavailable-for-weakref.m +++ b/test/SemaObjC/arc-unavailable-for-weakref.m @@ -90,3 +90,5 @@ __attribute__((objc_arc_weak_reference_unavailable)) __attribute__((objc_arc_weak_reference_unavailable(1))) // expected-error {{'objc_arc_weak_reference_unavailable' attribute takes no arguments}} @interface I3 @end + +int I4 __attribute__((objc_arc_weak_reference_unavailable)); // expected-error {{'objc_arc_weak_reference_unavailable' attribute only applies to Objective-C interfaces}} diff --git a/test/SemaObjC/arc-unavailable-system-function.m b/test/SemaObjC/arc-unavailable-system-function.m index b0b70db641cb..54ceaafbd699 100644 --- a/test/SemaObjC/arc-unavailable-system-function.m +++ b/test/SemaObjC/arc-unavailable-system-function.m @@ -3,7 +3,7 @@ # 1 "<command line>" # 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3 -id * foo(); // expected-note {{function has been explicitly marked unavailable here}} +id * foo(); // expected-note {{'foo' has been explicitly marked unavailable here}} # 1 "arc-unavailable-system-function.m" 2 void ret() { diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index 060af24fa0d9..ba7c09f4f9d7 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -285,7 +285,7 @@ void test11(id op, void *vp) { b = (nil == vp); b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} - b = (op == vp); // expected-error {{implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRelease call}} + b = (op == vp); } void test12(id collection) { @@ -782,3 +782,19 @@ void foo(NSArray *array) { } } } + +// rdar://16627903 +extern void abort(); +#define TKAssertEqual(a, b) do{\ + __typeof(a) a_res = (a);\ + __typeof(b) b_res = (b);\ + if ((a_res) != (b_res)) {\ + abort();\ + }\ +}while(0) + +int garf() { + id object; + TKAssertEqual(object, nil); + TKAssertEqual(object, (id)nil); +} diff --git a/test/SemaObjC/attr-availability.m b/test/SemaObjC/attr-availability.m index fddcd506d44d..7990b1202e8f 100644 --- a/test/SemaObjC/attr-availability.m +++ b/test/SemaObjC/attr-availability.m @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -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 {{method 'proto_method' declared here}} +- (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{'proto_method' has been explicitly marked deprecated here}} @end @interface A <P> -- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{method 'method' declared here}} +- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}} - (void)overridden __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}} - (void)overridden2 __attribute__((availability(macosx,introduced=10.3))); @@ -37,7 +37,7 @@ void f(A *a, B *b) { // using a deprecated method when that method is re-implemented in a // subclass where the redeclared method is not deprecated. @interface C -- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{method 'method' declared here}} +- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}} @end @interface D : C diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m index aa4b479e0022..ca30d0a27d88 100644 --- a/test/SemaObjC/attr-deprecated.m +++ b/test/SemaObjC/attr-deprecated.m @@ -2,10 +2,10 @@ // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s @interface A { - int X __attribute__((deprecated)); // expected-note 2 {{declared here}} + int X __attribute__((deprecated)); // expected-note 2 {{'X' has been explicitly marked deprecated here}} } -+ (void)F __attribute__((deprecated)); // expected-note 2 {{declared here}} -- (void)f __attribute__((deprecated)); // expected-note 4 {{declared here}} ++ (void)F __attribute__((deprecated)); // expected-note 2 {{'F' has been explicitly marked deprecated here}} +- (void)f __attribute__((deprecated)); // expected-note 4 {{'f' has been explicitly marked deprecated here}} @end @implementation A @@ -43,7 +43,7 @@ @end @protocol P -- (void)p __attribute__((deprecated)); // expected-note {{declared here}} +- (void)p __attribute__((deprecated)); // expected-note {{'p' has been explicitly marked deprecated here}} @end void t1(A *a) @@ -72,7 +72,7 @@ void t4(Class c) @interface Bar -@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{declared here}} +@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{'FooBar' has been explicitly marked deprecated here}} - (void) MySetter : (int) value; @end @@ -84,7 +84,7 @@ int t5() { __attribute ((deprecated)) -@interface DEPRECATED { // expected-note 2 {{declared here}} +@interface DEPRECATED { // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}} @public int ivar; DEPRECATED *ivar2; // no warning. } @@ -108,8 +108,8 @@ __attribute ((deprecated)) @interface Test2 -@property int test2 __attribute__((deprecated)); // expected-note 4 {{declared here}} \ - // expected-note 2 {{property 'test2' is declared deprecated here}} +@property int test2 __attribute__((deprecated)); // expected-note 2 {{property 'test2' is declared deprecated here}} expected-note 3 {{'test2' has been explicitly marked deprecated here}} \ + // expected-note {{'setTest2:' has been explicitly marked deprecated here}} @end void test(Test2 *foo) { @@ -127,7 +127,7 @@ __attribute__((deprecated)) typedef struct { int x; -} footype __attribute((deprecated)); // expected-note 2 {{declared here}} +} footype __attribute((deprecated)); // expected-note 2 {{'footype' has been explicitly marked deprecated here}} @interface foo { footype a; // expected-warning {{'footype' is deprecated}} @@ -142,7 +142,7 @@ typedef struct { +(void)cmeth; @end -typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' declared here}} +typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' has been explicitly marked deprecated here}} @interface SI : DeprI // expected-warning {{'DeprI' is deprecated: blah}} -(DeprI*)meth; // expected-warning {{'DeprI' is deprecated: blah}} @@ -154,3 +154,76 @@ typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'De return 0; } @end + +// <rdar://problem/15407366> and <rdar://problem/15466783>: +// - Using deprecated class name inside class should not warn about deprecation. +// - Implementations of deprecated classes should not result in deprecation warnings. +__attribute__((deprecated)) +@interface DeprecatedClassA +@end + +__attribute__((deprecated)) +@interface DeprecatedClassB +// The self-reference return value should not be +// flagged as the use of a deprecated declaration. ++ (DeprecatedClassB *)sharedInstance; // no-warning + +// Since this class is deprecated, returning a reference +// to another deprecated class is fine as they may +// have been deprecated together. From a user's +// perspective they are all deprecated. ++ (DeprecatedClassA *)somethingElse; // no-warning +@end + +@implementation DeprecatedClassB ++ (DeprecatedClassB *)sharedInstance +{ + // This self-reference should not + // be flagged as a use of a deprecated + // declaration. + static DeprecatedClassB *x; // no-warning + return x; +} ++ (DeprecatedClassA *)somethingElse { + // Since this class is deprecated, referencing + // another deprecated class is also OK. + static DeprecatedClassA *x; // no-warning + return x; +} + +@end + +// rdar://16068470 +@interface TestBase +@property (nonatomic, strong) id object __attribute__((deprecated("deprecated"))); // expected-note {{'object' has been explicitly marked deprecated here}} \ +expected-note {{property 'object' is declared deprecated here}} \ +expected-note {{'setObject:' has been explicitly marked deprecated here}} +@end + +@interface TestDerived : TestBase +@property (nonatomic, strong) id object; +@end + +@interface TestUse @end + +@implementation TestBase @end + +@implementation TestDerived @end + +@implementation TestUse + +- (void) use +{ + TestBase *base = (id)0; + TestDerived *derived = (id)0; + id object = (id)0; + + base.object = object; // expected-warning {{'object' is deprecated: deprecated}} + derived.object = object; + + [base setObject:object]; // expected-warning {{'setObject:' is deprecated: deprecated}} + [derived setObject:object]; +} + +@end + diff --git a/test/SemaObjC/attr-designated-init.m b/test/SemaObjC/attr-designated-init.m new file mode 100644 index 000000000000..535065769404 --- /dev/null +++ b/test/SemaObjC/attr-designated-init.m @@ -0,0 +1,412 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-incomplete-implementation -verify -fblocks %s + +#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) + +void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} + +@protocol P1 +-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} +@end + +__attribute__((objc_root_class)) +@interface I1 +-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} +-(id)init NS_DESIGNATED_INITIALIZER; ++(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} +@end + +@interface I1(cat) +-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}} +@end + +@interface I1() +-(id)init3 NS_DESIGNATED_INITIALIZER; +@end + +@implementation I1 +-(void)meth {} +-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}} ++(id)init { return 0; } +-(id)init3 { return 0; } +-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}} \ + // expected-warning {{convenience initializer missing a 'self' call to another initializer}} +@end + +__attribute__((objc_root_class)) +@interface B1 +-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}} +-(id)initB2; +@end + +@interface B1() +-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}} +@end; + +@implementation B1 +-(id)initB1 { return 0; } +-(id)initB2 { return 0; } // expected-warning {{convenience initializer missing a 'self' call to another initializer}} +-(id)initB3 { return 0; } +@end + +@interface S1 : B1 +-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}} +-(id)initS2 NS_DESIGNATED_INITIALIZER; +-(id)initS3 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}} +-(id)initB1; +@end + +@interface S1() +-(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}} +@end + +@implementation S1 +-(id)initS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return 0; +} +-(id)initS2 { + return [super initB1]; +} +-(id)initS3 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return [super initB2]; // expected-warning {{designated initializer invoked a non-designated initializer}} +} +-(id)initS4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}} +} +-(id)initB1 { + return [self initS1]; +} +-(id)initB3 { + return [self initS1]; +} +@end + +@interface S2 : B1 +-(id)initB1; +@end + +@interface SS2 : S2 +-(id)initSS1 NS_DESIGNATED_INITIALIZER; +@end + +@implementation SS2 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \ + // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}} +-(id)initSS1 { + return [super initB1]; +} +@end + +@interface S3 : B1 +-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}} +@end + +@interface SS3 : S3 +-(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}} +@end + +@implementation SS3 // expected-warning {{method override for the designated initializer of the superclass '-initS1' not found}} +-(id)initSS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return [super initB1]; // expected-warning {{designated initializer invoked a non-designated initializer}} +} +@end + +@interface S4 : B1 +-(id)initB1; +-(id)initB3; +@end + +@implementation S4 +-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return 0; +} +-(id)initB3 { + return [super initB3]; +} +@end + +@interface S5 : B1 +-(void)meth; +@end + +@implementation S5 +-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return 0; +} +-(id)initB3 { + [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}} + S5 *s; + [s initB1]; + [self meth]; + void (^blk)(void) = ^{ + [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}} + }; + return [super initB3]; +} +-(void)meth {} +@end + +@interface S6 : B1 +-(id)initS1 NS_DESIGNATED_INITIALIZER; +-(id)initS2; +-(id)initS3; +-(id)initS4; +@end + +@implementation S6 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \ + // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}} +-(id)initS1 { + return [super initB1]; +} +-(id)initS2 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}} + return [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}} +} +-(id)initS3 { + return [self initB1]; +} +-(id)initS4 { + return [self initS1]; +} +-(id)initS5 { + [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}} + void (^blk)(void) = ^{ + [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}} + }; + return [self initS1]; +} +-(id)initS6 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}} + S6 *s; + return [s initS1]; +} +@end + +@interface SS4 : S4 +-(id)initB1; +@end + +@implementation SS4 +-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return 0; +} +@end + +@interface S7 : B1 +-(id)initB1; +-(id)initB3; +-(id)initNewOne; +@end + +@interface SS7 : S7 +-(id)initB1; +@end + +@implementation SS7 +-(id)initB1 { + return 0; +} +@end + +__attribute__((objc_root_class)) +@interface B2 +-(id)init; +@end + +@interface S8: B2 +-(id)initS8 NS_DESIGNATED_INITIALIZER; +@end + +@implementation S8 +-(id)initS8 +{ + return [super init]; +} +@end + +@interface S9 : B1 +-(id)initB1; +-(id)initB3; +@end + +@interface S9(secondInit) +-(id)initNewOne; +@end + +@interface SS9 : S9 +-(id)initB1; +@end + +@implementation SS9 +-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return 0; +} +@end + +// rdar://16261494 +@class GEOPDAnalyticMetadata; // expected-note {{forward declaration of class here}} + +@implementation GEOPDAnalyticMetadata (PlaceCardExtras) // expected-error {{cannot find interface declaration for 'GEOPDAnalyticMetadata'}} +- (instancetype)initInProcess +{ + return ((void*)0); +} +@end + +// rdar://16305460 +__attribute__((objc_root_class)) +@interface MyObject +- (instancetype)initWithStuff:(id)stuff __attribute__((objc_designated_initializer)); +- (instancetype)init __attribute__((unavailable)); +@end + +@implementation MyObject +- (instancetype)init +{ + return ((void*)0); +} +@end + +// rdar://16323233 +__attribute__((objc_root_class)) +@interface B4 +-(id)initB4 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}} +-(id)initNonDI; +@end + +@interface rdar16323233 : B4 +-(id)initS4 NS_DESIGNATED_INITIALIZER; +@end + +@implementation rdar16323233 +-(id)initS4 { + static id sSharedObject = (void*)0; + (void)^(void) { + sSharedObject = [super initB4]; + }; + return 0; +} +-(id)initB4 { + return [self initS4]; +} +@end + +@interface S1B4 : B4 +@end +@implementation S1B4 +-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}} +} +@end + +@interface S2B4 : B4 +-(id)initB4; +@end +@implementation S2B4 +-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}} +} +@end + +@interface S3B4 : B4 +@end +@implementation S3B4 +-(id)initNew { + return [super initB4]; +} +-(id)initB4 { + return [self initNew]; +} +@end + +@interface S4B4 : B4 +-(id)initNew; +@end +@implementation S4B4 +-(id)initNew { + return [super initB4]; +} +-(id)initB4 { + return [self initNew]; +} +@end + +@interface S5B4 : B4 +-(id)initB4; +@end +@implementation S5B4 +-(id)initNew { + return [super initB4]; +} +-(id)initB4 { + return [self initNew]; +} +@end + +@interface S6B4 : B4 +-(id)initNew; +-(id)initB4; +@end +@implementation S6B4 +-(id)initNew { + return [super initB4]; +} +-(id)initB4 { + return [self initNew]; +} +@end + +__attribute__((objc_root_class)) +@interface NSObject +-(instancetype) init NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}} +@end + +@interface Test3 : NSObject +@end + +@implementation Test3 +-(instancetype) initWithBasePath:(id)path { + return [super init]; +} +-(instancetype) init { + return [self initWithBasePath:0]; +} +@end + +@interface Test1 : NSObject +-(instancetype) init NS_DESIGNATED_INITIALIZER; +@end +@implementation Test1 +-(instancetype) init { + return self; +} +@end + + +@interface Test2 : NSObject +@end +@interface SubTest2 : Test2 +@end +@implementation SubTest2 +-(instancetype) init { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}} + return self; +} +@end + +__attribute__((objc_root_class)) +@interface RootNoDI +-(id)init; +@end + +@interface Base : RootNoDI +@end + +@implementation Base +@end + +@interface Derived : Base +- (instancetype)initWithInt:(int)n NS_DESIGNATED_INITIALIZER; +@end + +@implementation Derived +- (instancetype)initWithInt:(int)n +{ + return [super init]; +} +@end diff --git a/test/SemaObjC/attr-ns-bridged.m b/test/SemaObjC/attr-ns-bridged.m deleted file mode 100644 index 1ab60a2b0d80..000000000000 --- a/test/SemaObjC/attr-ns-bridged.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -typedef struct __attribute__((ns_bridged)) test0s *test0ref; - -void test0func(void) __attribute__((ns_bridged)); // expected-error {{'ns_bridged' attribute only applies to structs}} - -union __attribute__((ns_bridged)) test0u; // expected-error {{'ns_bridged' attribute only applies to structs}} - -struct __attribute__((ns_bridged(Test1))) test1s; - -@class Test2; -struct __attribute__((ns_bridged(Test2))) test2s; - -void Test3(void); // expected-note {{declared here}} -struct __attribute__((ns_bridged(Test3))) test3s; // expected-error {{parameter of 'ns_bridged' attribute does not name an Objective-C class}} diff --git a/test/SemaObjC/block-type-safety.m b/test/SemaObjC/block-type-safety.m index 56342baae528..b2c4398dc3c5 100644 --- a/test/SemaObjC/block-type-safety.m +++ b/test/SemaObjC/block-type-safety.m @@ -23,6 +23,7 @@ void r1(Sub* (^f)()) { // expected-note{{passing argument to parameter 'f' here} } @protocol NSObject; +@class NSObject; void r2 (id<NSObject> (^f) (void)) { id o = f(); @@ -155,3 +156,45 @@ void f() { return NSOrderedSame; }]; } + +// rdar://16739120 +@protocol P1 @end +@protocol P2 @end + +void Test() { +void (^aBlock)(); +id anId = aBlock; // OK + +id<P1,P2> anQualId = aBlock; // expected-error {{initializing 'id<P1,P2>' with an expression of incompatible type 'void (^)()'}} + +NSArray* anArray = aBlock; // expected-error {{initializing 'NSArray *' with an expression of incompatible type 'void (^)()'}} + +aBlock = anId; // OK + +id<P1,P2> anQualId1; +aBlock = anQualId1; // expected-error {{assigning to 'void (^)()' from incompatible type 'id<P1,P2>'}} + +NSArray* anArray1; +aBlock = anArray1; // expected-error {{assigning to 'void (^)()' from incompatible type 'NSArray *'}} +} + +void Test2() { + void (^aBlock)(); + id<NSObject> anQualId1 = aBlock; // Ok + id<NSObject, NSCopying> anQualId2 = aBlock; // Ok + id<NSObject, NSCopying, NSObject, NSCopying> anQualId3 = aBlock; // Ok + id <P1> anQualId4 = aBlock; // expected-error {{initializing 'id<P1>' with an expression of incompatible type 'void (^)()'}} + id<NSObject, P1, NSCopying> anQualId5 = aBlock; // expected-error {{initializing 'id<NSObject,P1,NSCopying>' with an expression of incompatible type 'void (^)()'}} + id<NSCopying> anQualId6 = aBlock; // Ok +} + +void Test3() { + void (^aBlock)(); + NSObject *NSO = aBlock; // Ok + NSObject<NSObject> *NSO1 = aBlock; // Ok + NSObject<NSObject, NSCopying> *NSO2 = aBlock; // Ok + NSObject<NSObject, NSCopying, NSObject, NSCopying> *NSO3 = aBlock; // Ok + NSObject <P1> *NSO4 = aBlock; // expected-error {{initializing 'NSObject<P1> *' with an expression of incompatible type 'void (^)()'}} + NSObject<NSObject, P1, NSCopying> *NSO5 = aBlock; // expected-error {{initializing 'NSObject<NSObject,P1,NSCopying> *' with an expression of incompatible type 'void (^)()'}} + NSObject<NSCopying> *NSO6 = aBlock; // Ok +} diff --git a/test/SemaObjC/builtin_objc_lib_functions.m b/test/SemaObjC/builtin_objc_lib_functions.m index d8713ddfb416..2496bf2b1cf7 100644 --- a/test/SemaObjC/builtin_objc_lib_functions.m +++ b/test/SemaObjC/builtin_objc_lib_functions.m @@ -1,29 +1,29 @@ // RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify // rdar://8592641 Class f0() { return objc_getClass("a"); } // expected-warning {{implicitly declaring library function 'objc_getClass' with type 'id (const char *)'}} \ - // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getClass'}} + // expected-note {{include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getClass'}} // rdar://8735023 Class f1() { return objc_getMetaClass("a"); } // expected-warning {{implicitly declaring library function 'objc_getMetaClass' with type 'id (const char *)'}} \ - // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getMetaClass'}} + // expected-note {{include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getMetaClass'}} void f2(id val) { objc_enumerationMutation(val); } // expected-warning {{implicitly declaring library function 'objc_enumerationMutation' with type 'void (id)'}} \ - // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_enumerationMutation'}} + // expected-note {{include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_enumerationMutation'}} long double f3(id self, SEL op) { return objc_msgSend_fpret(self, op); } // expected-warning {{implicitly declaring library function 'objc_msgSend_fpret' with type 'long double (id, SEL, ...)'}} \ - // expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSend_fpret'}} + // expected-note {{include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSend_fpret'}} id f4(struct objc_super *super, SEL op) { // expected-warning {{declaration of 'struct objc_super' will not be visible outside of this function}} return objc_msgSendSuper(super, op); // expected-warning {{implicitly declaring library function 'objc_msgSendSuper' with type 'id (struct objc_super *, SEL, ...)'}} \ - // expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSendSuper'}} + // expected-note {{include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSendSuper'}} } id f5(id val, id *dest) { return objc_assign_strongCast(val, dest); // expected-warning {{implicitly declaring library function 'objc_assign_strongCast' with type 'id (id, id *)'}} \ - // expected-note {{please include the header <objc/objc-auto.h> or explicitly provide a declaration for 'objc_assign_strongCast'}} + // expected-note {{include the header <objc/objc-auto.h> or explicitly provide a declaration for 'objc_assign_strongCast'}} } int f6(Class exceptionClass, id exception) { return objc_exception_match(exceptionClass, exception); // expected-warning {{implicitly declaring library function 'objc_exception_match' with type 'int (id, id)'}} \ - // expected-note {{please include the header <objc/objc-exception.h> or explicitly provide a declaration for 'objc_exception_match'}} + // expected-note {{include the header <objc/objc-exception.h> or explicitly provide a declaration for 'objc_exception_match'}} } diff --git a/test/SemaObjC/builtin_objc_nslog.m b/test/SemaObjC/builtin_objc_nslog.m index c940b16cdc3a..cc6f194c898d 100644 --- a/test/SemaObjC/builtin_objc_nslog.m +++ b/test/SemaObjC/builtin_objc_nslog.m @@ -4,10 +4,10 @@ void f1(id arg) { NSLog(@"%@", arg); // expected-warning {{implicitly declaring library function 'NSLog' with type 'void (id, ...)'}} \ - // expected-note {{please include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLog'}} + // expected-note {{include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLog'}} } void f2(id str, va_list args) { NSLogv(@"%@", args); // expected-warning {{implicitly declaring library function 'NSLogv' with type }} \ - // expected-note {{please include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLogv'}} + // expected-note {{include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLogv'}} } diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index 18b872aa8b8a..89ac550578c5 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -2,7 +2,8 @@ @interface MyClass1 @end -@protocol p1,p2,p3; +@protocol p1,p2,p3; // expected-note {{protocol 'p1' has no definition}} \ + // expected-note {{protocol 'p2' has no definition}} @interface MyClass1 (Category1) <p1> // expected-warning {{cannot find protocol definition for 'p1'}} expected-note {{previous definition is here}} @end @@ -65,13 +66,13 @@ -(void) im0; // expected-note {{method 'im0' declared here}} @end -@interface MultipleCat_I @end // expected-note {{required for direct or indirect protocol 'MultipleCat_P'}} +@interface MultipleCat_I @end @interface MultipleCat_I() @end @interface MultipleCat_I() <MultipleCat_P> @end -@implementation MultipleCat_I // expected-warning {{method 'im0' in protocol not implemented}} +@implementation MultipleCat_I // expected-warning {{method 'im0' in protocol 'MultipleCat_P' not implemented}} @end // <rdar://problem/7680391> - Handle nameless categories with no name that refer diff --git a/test/SemaObjC/check-objcbridge-related-attribute-lookup.m b/test/SemaObjC/check-objcbridge-related-attribute-lookup.m new file mode 100644 index 000000000000..39b66bc8e88f --- /dev/null +++ b/test/SemaObjC/check-objcbridge-related-attribute-lookup.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -x objective-c -verify -Wno-objc-root-class %s +// rdar://15499111 + +typedef struct __attribute__((objc_bridge_related(NSColor,colorXWithCGColor:,CXGColor))) CGColor *CGColorRef; // expected-note 2 {{declared here}} + +typedef struct __attribute__((objc_bridge_related(XNSColor,colorWithCGColor:,CGColor))) CGColor1 *CGColorRef1; // expected-note 2 {{declared here}} + +typedef struct __attribute__((objc_bridge_related(PNsColor,colorWithCGColor:,CGColor))) CGColor2 *CGColorRef2; // expected-note 2 {{declared here}} + +@interface NSColor ++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor; +- (CGColorRef)CGColor; +@end + +@interface NSTextField +- (void)setBackgroundColor:(NSColor *)color; +- (NSColor *)backgroundColor; +@end + +typedef int PNsColor; // expected-note 2 {{declared here}} + +NSColor * Test1(NSTextField *textField, CGColorRef newColor) { + textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorXWithCGColor:' method for this conversion}} \ + // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef' (aka 'struct CGColor *')}} + newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CXGColor' method for this conversion}} \ + // expected-warning {{incompatible pointer types assigning to 'CGColorRef' (aka 'struct CGColor *') from 'NSColor *'}} +} +NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) { + textField.backgroundColor = newColor; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *'}} \ + // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef1' (aka 'struct CGColor1 *')}} + newColor = textField.backgroundColor ; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'NSColor *' to 'CGColorRef1' (aka 'struct CGColor1 *')}} \ + // expected-warning {{incompatible pointer types assigning to 'CGColorRef1' (aka 'struct CGColor1 *') from 'NSColor *'}} +} + +NSColor * Test3(NSTextField *textField, CGColorRef2 newColor) { + textField.backgroundColor = newColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'CGColorRef2' (aka 'struct CGColor2 *') to 'NSColor *'}} \ + // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef2' (aka 'struct CGColor2 *')}} + newColor = textField.backgroundColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *')}} \ + // expected-warning {{incompatible pointer types assigning to 'CGColorRef2' (aka 'struct CGColor2 *') from 'NSColor *'}} +} + diff --git a/test/SemaObjC/class-def-test-1.m b/test/SemaObjC/class-def-test-1.m index 7931cc3fdce4..98a887ecab1f 100644 --- a/test/SemaObjC/class-def-test-1.m +++ b/test/SemaObjC/class-def-test-1.m @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s -@protocol SUPER; +@protocol SUPER; // expected-note {{protocol 'SUPER' has no definition}} @interface SUPER <SUPER> @end // expected-warning {{cannot find protocol definition for 'SUPER'}} diff --git a/test/SemaObjC/class-extension-dup-methods.m b/test/SemaObjC/class-extension-dup-methods.m index 692ff8c68a0a..5f463aed168c 100644 --- a/test/SemaObjC/class-extension-dup-methods.m +++ b/test/SemaObjC/class-extension-dup-methods.m @@ -13,3 +13,16 @@ + (int) InstMeth; - (int) OK; @end + +// rdar://16312105 +@class NSObject; + +__attribute__((objc_root_class)) @interface AppDelegate ++ (void)someMethodWithArgument:(NSObject *)argument; ++ (void)someMethodWithArgument:(NSObject *)argument : (NSObject*) argument2; // expected-note {{previous declaration is here}} +@end + +@interface AppDelegate () +- (void)someMethodWithArgument:(float)argument; // OK. No warning to be issued here. ++ (void)someMethodWithArgument:(float)argument : (float)argument2; // expected-error {{duplicate declaration of method 'someMethodWithArgument::'}} +@end diff --git a/test/SemaObjC/class-property-access.m b/test/SemaObjC/class-property-access.m index 735b51a3c432..d57b986c3eac 100644 --- a/test/SemaObjC/class-property-access.m +++ b/test/SemaObjC/class-property-access.m @@ -11,3 +11,46 @@ int main () return Test.one.two; } +// rdar://16650575 +__attribute__((objc_root_class)) +@interface RootClass { + Class isa; +} + +@property int property; +-(int)method; +- (void) setMethod : (int)arg; ++(int)classMethod; +@end + +@interface Subclass : RootClass @end +void Test1() { + // now okay + (void)RootClass.property; + (void)Subclass.property; + (void)RootClass.method; + (void)Subclass.method; + + RootClass.property = 1; + Subclass.property = 2; + RootClass.method = 3; + Subclass.method = 4; + + // okay + (void)RootClass.classMethod; + (void)Subclass.classMethod; + + // also okay + (void)[RootClass property]; + (void)[Subclass property]; + [RootClass method]; + [Subclass method]; + [RootClass classMethod]; + [Subclass classMethod]; + + // also okay + [RootClass setProperty : 1]; + [Subclass setProperty : 2]; + [RootClass setMethod : 3]; + [Subclass setMethod : 4]; +} diff --git a/test/SemaObjC/class-proto-1.m b/test/SemaObjC/class-proto-1.m index 02c40aab6599..51a899341e31 100644 --- a/test/SemaObjC/class-proto-1.m +++ b/test/SemaObjC/class-proto-1.m @@ -2,7 +2,8 @@ @interface INTF1 @end -@protocol p1,p2,p3; +@protocol p1,p2,p3; // expected-note {{protocol 'p2' has no definition}} \ + // expected-note {{protocol 'p3' has no definition}} @protocol p1; @@ -34,3 +35,14 @@ @interface I4 : U2 <p1,p2> @end + +// rdar://16111182 +@interface NSObject @end + +@protocol UndefinedParentProtocol; // expected-note {{protocol 'UndefinedParentProtocol' has no definition}} + +@protocol UndefinedProtocol <UndefinedParentProtocol> +@end + +@interface SomeObject : NSObject <UndefinedProtocol> // expected-warning {{cannot find protocol definition for 'UndefinedProtocol'}} +@end diff --git a/test/SemaObjC/class-unavail-warning.m b/test/SemaObjC/class-unavail-warning.m index b2bd38831101..3ebf3e7815f3 100644 --- a/test/SemaObjC/class-unavail-warning.m +++ b/test/SemaObjC/class-unavail-warning.m @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -verify %s // rdar://9092208 __attribute__((unavailable("not available"))) -@interface MyClass { // expected-note 8 {{declaration has been explicitly marked unavailable here}} +@interface MyClass { // expected-note 8 {{'MyClass' has been explicitly marked unavailable here}} @public void *_test; MyClass *ivar; // no error. @@ -15,7 +15,7 @@ __attribute__((unavailable("not available"))) @end -@interface Foo { +@interface Gorf { MyClass *ivar; // expected-error {{unavailable}} } - (MyClass *)meth; // expected-error {{unavailable}} @@ -40,3 +40,30 @@ int main() { return 0; } + +// rdar://16681279 +@interface NSObject @end + +__attribute__((visibility("default"))) __attribute__((availability(macosx,unavailable))) +@interface Foo : NSObject @end // expected-note 3 {{'Foo' has been explicitly marked unavailable here}} +@interface AppDelegate : NSObject +@end + +@class Foo; + +@implementation AppDelegate +- (void) applicationDidFinishLaunching +{ + Foo *foo = 0; // expected-error {{'Foo' is unavailable}} +} +@end + +@class Foo; +Foo *g_foo = 0; // expected-error {{'Foo' is unavailable}} + +@class Foo; +@class Foo; +@class Foo; +Foo * f_func() { // expected-error {{'Foo' is unavailable}} + return 0; +} diff --git a/test/SemaObjC/cocoa.m b/test/SemaObjC/cocoa.m deleted file mode 100644 index a8cfb72e1ea8..000000000000 --- a/test/SemaObjC/cocoa.m +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %clang -arch x86_64 %s -fsyntax-only -Xclang -print-stats -#ifdef __APPLE__ -#include <Cocoa/Cocoa.h> -#endif - diff --git a/test/SemaObjC/compare-qualified-class.m b/test/SemaObjC/compare-qualified-class.m index 0f415b607dd7..60ef851e1f3f 100644 --- a/test/SemaObjC/compare-qualified-class.m +++ b/test/SemaObjC/compare-qualified-class.m @@ -25,6 +25,6 @@ int main () { return classA == classB || classA == classC || classC == classA || - classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol> *' and 'Class<SomeProtocol1> *')}} + classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol>' and 'Class<SomeProtocol1>')}} } diff --git a/test/SemaObjC/compare-qualified-id.m b/test/SemaObjC/compare-qualified-id.m index 02fa86ec8d9e..7da774957e58 100644 --- a/test/SemaObjC/compare-qualified-id.m +++ b/test/SemaObjC/compare-qualified-id.m @@ -15,7 +15,7 @@ typedef struct {} NSFastEnumerationState; @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; @end // expected-note {{receiver is instance of class declared here}} extern NSString * const NSTaskDidTerminateNotification; -@interface XCPropertyExpansionContext : NSObject <NSCopying> { // expected-note {{required for direct or indirect protocol 'NSCopying'}} +@interface XCPropertyExpansionContext : NSObject <NSCopying> { NSMutableDictionary * _propNamesToPropValuesCache; } @end @@ -23,7 +23,7 @@ extern NSString * const NSTaskDidTerminateNotification; - (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state; @end -@implementation XCPropertyExpansionContext // expected-warning {{method 'copyWithZone:' in protocol not implemented}} +@implementation XCPropertyExpansionContext // expected-warning {{method 'copyWithZone:' in protocol 'NSCopying' not implemented}} - (NSString *)expandedValueForProperty:(NSString *)property { id <XCPropertyValues> cachedValueNode = [_propNamesToPropValuesCache objectForKey:property]; // expected-warning {{method '-objectForKey:' not found (return type defaults to 'id')}} if (cachedValueNode == ((void *)0)) { } diff --git a/test/SemaObjC/comptypes-legal.m b/test/SemaObjC/comptypes-legal.m index d83d559ee64c..05f18977cc4e 100644 --- a/test/SemaObjC/comptypes-legal.m +++ b/test/SemaObjC/comptypes-legal.m @@ -35,3 +35,20 @@ void foo(void) // Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal. [Derived registerFunc: ExternFunc]; // expected-warning{{incompatible pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *'}} } + +// rdar://10751015 +@protocol NSCopying @end +@interface I +- (void) Meth : (id <NSCopying>)aKey; // expected-note {{passing argument to parameter 'aKey' here}} +@end + +@class ForwarClass; // expected-note 3 {{conformance of forward class ForwarClass to protocol NSCopying can not be confirmed}} + +ForwarClass *Test10751015 (I* pi, ForwarClass *ns_forward) { + + [pi Meth : ns_forward ]; // expected-warning {{sending 'ForwarClass *' to parameter of incompatible type 'id<NSCopying>'}} + + id <NSCopying> id_ns = ns_forward; // expected-warning {{initializing 'id<NSCopying>' with an expression of incompatible type 'ForwarClass *'}} + + return id_ns; // expected-warning {{returning 'id<NSCopying>' from a function with incompatible result type 'ForwarClass *'}} +} diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m index 049a095ce37c..d8862c584a0d 100644 --- a/test/SemaObjC/conditional-expr.m +++ b/test/SemaObjC/conditional-expr.m @@ -96,8 +96,8 @@ id f7(int a, id<P0> x, A* p) { return a ? x : p; } -void f8(int a, A<P0> *x, A *y) { - [ (a ? x : y ) intProp ]; +int f8(int a, A<P0> *x, A *y) { + return [ (a ? x : y ) intProp ]; } void f9(int a, A<P0> *x, A<P1> *y) { diff --git a/test/SemaObjC/continuation-class-property.m b/test/SemaObjC/continuation-class-property.m index 2a8e5085fe7f..83aa796309f5 100644 --- a/test/SemaObjC/continuation-class-property.m +++ b/test/SemaObjC/continuation-class-property.m @@ -61,3 +61,15 @@ struct S1; @property (nonatomic, readwrite, assign) struct S1 *httpRequest3; @property (nonatomic, readwrite, assign) struct S2 *httpRequest4; @end + +// rdar://15859862 +@protocol ADCameraJSO_Bindings +@property (nonatomic, readonly) NSString *currentPictureURI; +@end + +@interface ADCameraJSO +@end + +@interface ADCameraJSO() <ADCameraJSO_Bindings> +@property (nonatomic, copy) NSString *currentPictureURI; +@end diff --git a/test/SemaObjC/dealloc.m b/test/SemaObjC/dealloc.m index 59218d2d0733..c1bd0b5ed463 100644 --- a/test/SemaObjC/dealloc.m +++ b/test/SemaObjC/dealloc.m @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s -// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -Wdealloc-in-category -verify %s +// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -Wdealloc-in-category -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s // rdar://11987838 @protocol NSObject @@ -23,3 +23,33 @@ @end +// rdar://15397430 +@interface Base +- (void)dealloc; +@end + +@interface Subclass : Base +@end + +@interface Subclass (CAT) +- (void)dealloc; +@end + +@implementation Subclass (CAT) +- (void)dealloc { // expected-warning {{-dealloc is being overridden in a category}} +} +@end + +// rdar://15919775 +@interface NSObject @end +@interface NSError:NSObject +@end + +@interface NSError(CAT) +- (NSError *)MCCopyAsPrimaryError __attribute__((objc_method_family(new))); +@end +@implementation NSError(CAT) +- (NSError *)MCCopyAsPrimaryError { + return 0; +} +@end diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m index 1c32665a2dd7..c91597462d91 100644 --- a/test/SemaObjC/default-synthesize-3.m +++ b/test/SemaObjC/default-synthesize-3.m @@ -37,7 +37,7 @@ __attribute ((objc_requires_property_definitions)) @interface Deep(CAT) // expected-error {{attributes may not be specified on a category}} @end -__attribute ((objc_requires_property_definitions)) // expected-error {{objc_requires_property_definitions attribute may only be specified on a class}} +__attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}} @protocol P @end // rdar://13388503 @@ -172,12 +172,44 @@ typedef NSObject<Fooing> FooObject; @interface Okay : NSObject<Fooing> @end -@implementation Okay // expected-warning 2 {{auto property synthesis will not synthesize property declared in a protocol}} +@implementation Okay // expected-warning {{auto property synthesis will not synthesize property 'muahahaha' declared in protocol 'Fooing'}} expected-warning {{auto property synthesis will not synthesize property 'hoho' declared in protocol 'SubFooling'}} @end @interface Fail : FooObject @end -@implementation Fail // expected-warning 2 {{auto property synthesis will not synthesize property declared in a protocol}} +@implementation Fail // expected-warning {{auto property synthesis will not synthesize property 'muahahaha' declared in protocol 'Fooing'}} expected-warning {{auto property synthesis will not synthesize property 'hoho' declared in protocol 'SubFooling'}} @end +// rdar://16089191 +@class NSURL; + +@interface Root +- (void)setFileURL : (NSURL *) arg; +- (void)setFile : (NSURL *) arg; +- (NSURL *)fileSys; +- (void)setFileSys : (NSURL *) arg; +- (NSURL *)fileKerl; +@end + +@interface SuperClass : Root +- (NSURL *)fileURL; +- (NSURL *)file; +- (NSURL *)fileLog; +- (void)setFileLog : (NSURL *) arg; +- (void)setFileKerl : (NSURL *) arg; +@end + +@protocol r16089191Protocol +@property (readonly) NSURL *fileURL; +@property (copy) NSURL *file; +@property (copy) NSURL *fileSys; +@property (copy) NSURL *fileLog; +@property (copy) NSURL *fileKerl; +@end + +@interface SubClass : SuperClass <r16089191Protocol> +@end + +@implementation SubClass +@end diff --git a/test/SemaObjC/default-synthesize.m b/test/SemaObjC/default-synthesize.m index dd16c1361d89..9356b9f5b3a3 100644 --- a/test/SemaObjC/default-synthesize.m +++ b/test/SemaObjC/default-synthesize.m @@ -136,5 +136,5 @@ @interface MyClass <MyProtocol> @end -@implementation MyClass // expected-warning {{auto property synthesis will not synthesize property declared in a protocol}} +@implementation MyClass // expected-warning {{auto property synthesis will not synthesize property 'requiredString' declared in protocol 'MyProtocol'}} @end diff --git a/test/SemaObjC/deprecate_function_containers.m b/test/SemaObjC/deprecate_function_containers.m new file mode 100644 index 000000000000..531cf11d2704 --- /dev/null +++ b/test/SemaObjC/deprecate_function_containers.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify -Wno-objc-root-class %s +// rdar://10414277 + +@protocol P +void p_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}} +@end + +@interface I +void foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}} +inline void v_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}} +static int s_foo() {return 0; } // expected-warning {{function definition inside an Objective-C container is deprecated}} +static inline int si_val() { return 1; } // expected-warning {{function definition inside an Objective-C container is deprecated}} +@end + +@interface I(CAT) +void cat_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}} +@end + +@implementation I +inline void v_imp_foo() {} +@end + +@implementation I(CAT) +void cat_imp_foo() {} +@end + +// rdar://16859666 +@interface PrototypeState + +@property (strong, readwrite) id moin1; // expected-note {{property declared here}} + +static inline void prototype_observe_moin1(void (^callback)(id)) { // expected-warning {{function definition inside an Objective-C container is deprecated}} + (void)^(PrototypeState *prototypeState){ + callback(prototypeState.moin1); // expected-error {{use of Objective-C property in function nested in Objective-C container not supported, move function outside its container}} + }; +} +@end diff --git a/test/SemaObjC/encode-typeof-test.m b/test/SemaObjC/encode-typeof-test.m new file mode 100644 index 000000000000..2cda9739681b --- /dev/null +++ b/test/SemaObjC/encode-typeof-test.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://16655340 +@protocol X, Y, Z; +@class Foo; + +@protocol Proto +@end + +@interface Intf <Proto> +{ +id <X> IVAR_x; +id <X, Y> IVAR_xy; +id <X, Y, Z> IVAR_xyz; +Foo <X, Y, Z> *IVAR_Fooxyz; +Class <X> IVAR_Classx; +} +@end + +@implementation Intf +@end + +int main() +{ + int i; + typeof(@encode(typeof(i))) e = @encode(typeof(Intf)); // expected-warning {{initializer-string for char array is too long}} +} diff --git a/test/SemaObjC/error-missing-getter.m b/test/SemaObjC/error-missing-getter.m index 3dce858837aa..13dc8e5bb13f 100644 --- a/test/SemaObjC/error-missing-getter.m +++ b/test/SemaObjC/error-missing-getter.m @@ -27,7 +27,8 @@ int func2 (int arg) { if (TestClass.setterOnly) { // expected-error {{no getter method for read from property}} TestClass.setterOnly = 1; } - func(TestClass.setterOnly + 1, x); // expected-error {{no getter method for read from property}} + func(TestClass.setterOnly + 1, x); // expected-error {{no getter method for read from property}} \ + // expected-error {{use of undeclared identifier 'x'}} int i = TestClass.setterOnly + 1; // expected-error {{no getter method for read from property}} return TestClass.setterOnly + 1; // expected-error {{no getter method for read from property}} } diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m index e770373a055b..79f5656decc0 100644 --- a/test/SemaObjC/format-arg-attribute.m +++ b/test/SemaObjC/format-arg-attribute.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Werror -Wformat-nonliteral -verify -fsyntax-only %s +// RUN: %clang_cc1 -verify -fsyntax-only %s @class NSString; @@ -9,9 +9,9 @@ extern void fc1 (const NSString *) __attribute__((format_arg)); // expected-err extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{'format_arg' attribute takes one argument}} extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{'format_arg' attribute takes one argument}} -struct s1 { int i; } __attribute__((format_arg(1))); // expected-error {{'format_arg' attribute only applies to functions}} -union u1 { int i; } __attribute__((format_arg(1))); // expected-error {{'format_arg' attribute only applies to functions}} -enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-error {{'format_arg' attribute only applies to functions}} +struct s1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}} +union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}} +enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}} extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2))); extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{use of undeclared identifier 'foo'}} @@ -25,23 +25,3 @@ extern NSString *fi2 (NSString *) __attribute__((format_arg(1))); extern int fi3 (const NSString *) __attribute__((format_arg(1))); // expected-error {{function does not return NSString}} extern NSString *fi4 (const NSString *) __attribute__((format_arg(1))); extern NSString *fi5 (const NSString *) __attribute__((format_arg(1))); - -// rdar://15242010 -@interface NSString -+ (id)stringWithFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2))); -@end - -@interface NSBundle -- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName __attribute__ ((format_arg(1))); -+ (NSBundle *)mainBundle; -@end - - -NSString* localizedFormat(NSString* string) __attribute__ ((format_arg(1))); - -int main() -{ - [NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"foo %d" value:@"bar %d" table:0], 42]; - - [NSString stringWithFormat:localizedFormat(@"foo %d"), 42]; -} diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m index 2667e3047aae..49567a710c3a 100644 --- a/test/SemaObjC/format-strings-objc.m +++ b/test/SemaObjC/format-strings-objc.m @@ -116,6 +116,9 @@ NSString *test_literal_propagation(void) { NSLog(ns2); // expected-warning {{more '%' conversions than data arguments}} NSString * ns3 = ns1; NSLog(ns3); // expected-warning {{format string is not a string literal}}} + + NSString * const ns6 = @"split" " string " @"%s"; // expected-note {{format string is defined here}} + NSLog(ns6); // expected-warning {{more '%' conversions than data arguments}} } // Do not emit warnings when using NSLocalizedString diff --git a/test/SemaObjC/forward-protocol-incomplete-impl-warn.m b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m index c3efeba4f9ec..c235e32316a9 100644 --- a/test/SemaObjC/forward-protocol-incomplete-impl-warn.m +++ b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m @@ -12,9 +12,9 @@ @protocol DVTInvalidation; -@interface IBImageCatalogDocument : NSObject <DVTInvalidation> // expected-note {{required for direct or indirect protocol 'DVTInvalidation'}} +@interface IBImageCatalogDocument : NSObject <DVTInvalidation> @end -@implementation IBImageCatalogDocument // expected-warning {{auto property synthesis will not synthesize property declared in a protocol}} \ - // expected-warning {{method 'invalidate' in protocol not implemented}} +@implementation IBImageCatalogDocument // expected-warning {{auto property synthesis will not synthesize property 'Prop' declared in protocol 'DVTInvalidation'}} \ + // expected-warning {{method 'invalidate' in protocol 'DVTInvalidation' not implemented}} @end diff --git a/test/SemaObjC/ibaction.m b/test/SemaObjC/ibaction.m index 9c59d7aaec5b..43c927ce264f 100644 --- a/test/SemaObjC/ibaction.m +++ b/test/SemaObjC/ibaction.m @@ -4,12 +4,12 @@ { __attribute__((iboutlet)) id myoutlet; } -+ (void) __attribute__((ibaction)) myClassMethod:(id)msg; // expected-warning{{ibaction attribute can only be applied to Objective-C instance methods}} ++ (void) __attribute__((ibaction)) myClassMethod:(id)msg; // expected-warning{{'ibaction' attribute only applies to Objective-C instance methods}} - (void) __attribute__((ibaction)) myMessage:(id)msg; @end @implementation Foo -+ (void) __attribute__((ibaction)) myClassMethod:(id)msg {} // expected-warning{{ibaction attribute can only be applied to Objective-C instance methods}} ++ (void) __attribute__((ibaction)) myClassMethod:(id)msg {} // expected-warning{{'ibaction' attribute only applies to Objective-C instance methods}} // Normally attributes should not be attached to method definitions, but // we allow 'ibaction' to be attached because it can be expanded from // the IBAction macro. diff --git a/test/SemaObjC/iboutlet.m b/test/SemaObjC/iboutlet.m index 3c7f9581e663..63eac9af8a52 100644 --- a/test/SemaObjC/iboutlet.m +++ b/test/SemaObjC/iboutlet.m @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s -// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Wno-objc-root-class -verify %s +// 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 #define READONLY readonly @@ -40,3 +40,15 @@ @implementation RKTFHView @synthesize synthReadOnlyReadWrite=_synthReadOnlyReadWrite; @end + +// rdar://15885642 +@interface WeakOutlet +@property IBOutlet __weak WeakOutlet* WeakProp; +@end + +WeakOutlet* func() { + __weak WeakOutlet* pwi; + pwi.WeakProp = (WeakOutlet*)0; + pwi.WeakProp = pwi.WeakProp; + return pwi.WeakProp; +} diff --git a/test/SemaObjC/incomplete-implementation.m b/test/SemaObjC/incomplete-implementation.m index 4b8d600cb8b4..74dea2aa86b9 100644 --- a/test/SemaObjC/incomplete-implementation.m +++ b/test/SemaObjC/incomplete-implementation.m @@ -39,3 +39,29 @@ __attribute__((visibility("default"))) @end +// rdar://15580969 +typedef char BOOL; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@interface NSObject <NSObject> +@end + +@protocol NSApplicationDelegate <NSObject> +- (void)ImpleThisMethod; // expected-note {{method 'ImpleThisMethod' declared here}} +@end + +@interface AppDelegate : NSObject <NSApplicationDelegate> +@end + +@implementation AppDelegate (MRRCategory) + +- (BOOL)isEqual:(id)object +{ + return __objc_no; +} + +- (void)ImpleThisMethod {} // expected-warning {{category is implementing a method which will also be implemented by its primary class}} +@end diff --git a/test/SemaObjC/ivar-lookup-resolution-builtin.m b/test/SemaObjC/ivar-lookup-resolution-builtin.m index dd11b51459d7..94ed3256e8df 100644 --- a/test/SemaObjC/ivar-lookup-resolution-builtin.m +++ b/test/SemaObjC/ivar-lookup-resolution-builtin.m @@ -29,7 +29,7 @@ - (int) InstMethod { return index; // expected-warning {{implicitly declaring library function 'index'}} \ - // expected-note {{please include the header <strings.h> or explicitly provide a declaration for 'index'}} \ + // expected-note {{include the header <strings.h> or explicitly provide a declaration for 'index'}} \ // expected-warning {{incompatible pointer to integer conversion returning}} } + (int) ClassMethod diff --git a/test/SemaObjC/method-attributes.m b/test/SemaObjC/method-attributes.m index b402d52a42a1..1b0a900da81d 100644 --- a/test/SemaObjC/method-attributes.m +++ b/test/SemaObjC/method-attributes.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -verify -fsyntax-only -Wno-objc-root-class %s @class NSString; @@ -7,26 +7,28 @@ - (NSString *)stringByAppendingFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2))); -(void) m0 __attribute__((noreturn)); -(void) m1 __attribute__((unused)); +-(void) m2 __attribute__((stdcall)); +-(void) m3 __attribute__((optnone)); @end @interface INTF - (int) foo1: (int)arg1 __attribute__((deprecated)); -- (int) foo: (int)arg1; // expected-note {{method 'foo:' declared here}} +- (int) foo: (int)arg1; -- (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{method 'foo2:' declared here}} +- (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)); - (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self)); @end @implementation INTF -- (int) foo: (int)arg1 __attribute__((deprecated)){ // expected-warning {{attributes on method implementation and its declaration must match}} +- (int) foo: (int)arg1 __attribute__((deprecated)){ return 10; } - (int) foo1: (int)arg1 { return 10; } -- (int) foo2: (int)arg1 __attribute__((deprecated)) { // expected-warning {{attributes on method implementation and its declaration must match}} +- (int) foo2: (int)arg1 __attribute__((deprecated)) { return 10; } - (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self)) {return 0; } @@ -39,7 +41,7 @@ @interface Foo - (void)doSomething1:(id)sender; -- (void)doSomething2:(id)sender; // expected-note {{method 'doSomething2:' declared here}} +- (void)doSomething2:(id)sender; @end @implementation Foo @@ -52,7 +54,7 @@ @end @implementation Bar - (IBAction)doSomething1:(id)sender {} -- (IBAction)doSomething2:(id)sender {} // expected-warning {{attributes on method implementation and its declaration must match}} +- (IBAction)doSomething2:(id)sender {} - (IBAction)doSomething3:(id)sender {} @end @@ -63,7 +65,7 @@ -(id)method __attribute__((deprecated)); -(id)method1; -(id)method2 __attribute__((aligned(16))); -- (id) method3: (int)arg1 __attribute__((aligned(16))) __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{method 'method3:' declared here}} +- (id) method3: (int)arg1 __attribute__((aligned(16))) __attribute__((deprecated)) __attribute__((unavailable)); - (id) method4: (int)arg1 __attribute__((aligned(16))) __attribute__((deprecated)) __attribute__((unavailable)); @end @@ -77,10 +79,23 @@ -(id)method2 { return self; } -- (id) method3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) { // expected-warning {{attributes on method implementation and its declaration must match}} +- (id) method3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) { return self; } - (id) method4: (int)arg1 __attribute__((aligned(16))) __attribute__((deprecated)) __attribute__((unavailable)) { return self; } @end + +__attribute__((cdecl)) // expected-warning {{'cdecl' attribute only applies to functions and methods}} +@interface Complain +@end + +// rdar://15450637 +@interface rdar15450637 : NSObject +@property int p __attribute__((section("__TEXT,foo"))); + +- (id) IMethod :(int) count, ... __attribute__((section("__TEXT,foo"))); + ++ (void) CMethod : (id) Obj __attribute__((section("__TEXT,fee"))); +@end diff --git a/test/SemaObjC/method-sentinel-attr.m b/test/SemaObjC/method-sentinel-attr.m index d230be5805be..82ee373c2fef 100644 --- a/test/SemaObjC/method-sentinel-attr.m +++ b/test/SemaObjC/method-sentinel-attr.m @@ -13,7 +13,7 @@ - (void) foo8 : (int)x, ... __attribute__ ((__sentinel__("a"))); // expected-error {{'__sentinel__' attribute requires parameter 1 to be an integer constant}} - (void) foo9 : (int)x, ... __attribute__ ((__sentinel__(-1))); // expected-error {{'sentinel' parameter 1 less than zero}} - (void) foo10 : (int)x, ... __attribute__ ((__sentinel__(1,1))); -- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3))); // expected-error {{attribute takes no more than 2 arguments}} +- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3))); // expected-error {{'__sentinel__' attribute takes no more than 2 arguments}} - (void) foo12 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}} // rdar://7975788 diff --git a/test/SemaObjC/method-undef-category-warn-1.m b/test/SemaObjC/method-undef-category-warn-1.m index 98d732babb93..c951db2ca1a3 100644 --- a/test/SemaObjC/method-undef-category-warn-1.m +++ b/test/SemaObjC/method-undef-category-warn-1.m @@ -8,20 +8,20 @@ - (void) Pmeth1; // expected-note {{method 'Pmeth1' declared here}} @end -@interface MyClass1(CAT) <P> // expected-note {{required for direct or indirect protocol 'P'}} +@interface MyClass1(CAT) <P> - (void) meth2; // expected-note {{method 'meth2' declared here}} @end -@implementation MyClass1(CAT) // expected-warning {{method 'Pmeth' in protocol not implemented}} \ +@implementation MyClass1(CAT) // expected-warning {{method 'Pmeth' in protocol 'P' not implemented}} \ // expected-warning {{method definition for 'meth2' not found}} - (void) Pmeth1{} @end -@interface MyClass1(DOG) <P> // expected-note {{required for direct or indirect protocol 'P'}} +@interface MyClass1(DOG) <P> - (void)ppp; // expected-note {{method 'ppp' declared here}} @end -@implementation MyClass1(DOG) // expected-warning {{method 'Pmeth1' in protocol not implemented}} \ +@implementation MyClass1(DOG) // expected-warning {{method 'Pmeth1' in protocol 'P' not implemented}} \ // expected-warning {{method definition for 'ppp' not found}} - (void) Pmeth {} @end diff --git a/test/SemaObjC/method-undef-extension-warn-1.m b/test/SemaObjC/method-undef-extension-warn-1.m index fbc21bd39f6a..819d6ed86ff3 100644 --- a/test/SemaObjC/method-undef-extension-warn-1.m +++ b/test/SemaObjC/method-undef-extension-warn-1.m @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s -@interface MyClass // expected-note {{required for direct or indirect protocol 'P'}} +@interface MyClass @end @protocol P @@ -18,7 +18,7 @@ - (void)categoryMethod; @end -@implementation MyClass // expected-warning {{method 'Pmeth1' in protocol not implemented}} \ +@implementation MyClass // expected-warning {{method 'Pmeth1' in protocol 'P' not implemented}} \ // expected-warning {{method definition for 'meth2' not found}} - (void)Pmeth {} @end diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m index 902105b924dd..a345eddbf1e4 100644 --- a/test/SemaObjC/nonnull.m +++ b/test/SemaObjC/nonnull.m @@ -74,6 +74,9 @@ void func6(dispatch_object_t _head) { @interface NSObject - (void)doSomethingWithNonNullPointer:(void *)ptr :(int)iarg : (void*)ptr1 __attribute__((nonnull(1, 3))); + (void)doSomethingClassyWithNonNullPointer:(void *)ptr __attribute__((nonnull(1))); +- (void*)returnsCNonNull __attribute__((returns_nonnull)); // no-warning +- (id)returnsObjCNonNull __attribute__((returns_nonnull)); // no-warning +- (int)returnsIntNonNull __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}} @end extern void DoSomethingNotNull(void *db) __attribute__((nonnull(1))); @@ -82,6 +85,7 @@ extern void DoSomethingNotNull(void *db) __attribute__((nonnull(1))); { void * vp; } +- (void*) testRetNull __attribute__((returns_nonnull)); @end @implementation IMP @@ -93,5 +97,29 @@ extern void DoSomethingNotNull(void *db) __attribute__((nonnull(1))); DoSomethingNotNull(NULL); // expected-warning {{null passed to a callee which requires a non-null argument}} [object doSomethingWithNonNullPointer:vp:1:vp]; } +- (void*) testRetNull { + return 0; // expected-warning {{null returned from method that requires a non-null return value}} +} +@end + +__attribute__((objc_root_class)) +@interface TestNonNullParameters +- (void) doNotPassNullParameterNonPointerArg:(int)__attribute__((nonnull))x; // expected-warning {{'nonnull' attribute only applies to pointer arguments}} +- (void) doNotPassNullParameter:(id)__attribute__((nonnull))x; +- (void) doNotPassNullParameterArgIndex:(id)__attribute__((nonnull(1)))x; // expected-warning {{'nonnull' attribute when used on parameters takes no arguments}} +- (void) doNotPassNullOnMethod:(id)x __attribute__((nonnull(1))); @end +void test(TestNonNullParameters *f) { + [f doNotPassNullParameter:0]; // expected-warning {{null passed to a callee which requires a non-null argument}} + [f doNotPassNullParameterArgIndex:0]; // no-warning + [f doNotPassNullOnMethod:0]; // expected-warning {{null passed to a callee which requires a non-null argument}} +} + + +void PR18795(int (^g)(const char *h, ...) __attribute__((nonnull(1))) __attribute__((nonnull))) { + g(0); // expected-warning{{null passed to a callee which requires a non-null argument}} +} +void PR18795_helper() { + PR18795(0); // expected-warning{{null passed to a callee which requires a non-null argument}} +} diff --git a/test/SemaObjC/ns_returns_retained_block_return.m b/test/SemaObjC/ns_returns_retained_block_return.m new file mode 100644 index 000000000000..e5a96ca8af18 --- /dev/null +++ b/test/SemaObjC/ns_returns_retained_block_return.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fblocks -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fblocks -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s +// expected-no-diagnostics +// rdar://17259812 + +typedef void (^BT) (); + +BT foo() __attribute__((ns_returns_retained)); + +@interface I +BT foo() __attribute__((ns_returns_retained)); +- (BT) Meth __attribute__((ns_returns_retained)); ++ (BT) ClsMeth __attribute__((ns_returns_retained)); +@end + +@implementation I +BT foo() __attribute__((ns_returns_retained)) {return ^{}; } +- (BT) Meth {return ^{}; } ++ (BT) ClsMeth {return ^{}; } +@end diff --git a/test/SemaObjC/nsobject-attribute.m b/test/SemaObjC/nsobject-attribute.m index ead222c3310b..6bd2d5dabc4b 100644 --- a/test/SemaObjC/nsobject-attribute.m +++ b/test/SemaObjC/nsobject-attribute.m @@ -6,7 +6,7 @@ typedef struct CGColor * __attribute__((NSObject(12))) Illegal; // expected-err static int count; static CGColorRef tmp = 0; -typedef struct S1 __attribute__ ((NSObject)) CGColorRef1; // expected-error {{__attribute ((NSObject)) is for pointer types only}} +typedef struct S1 __attribute__ ((NSObject)) CGColorRef1; // expected-error {{'NSObject' attribute is for pointer types only}} typedef void * __attribute__ ((NSObject)) CGColorRef2; // no-warning typedef void * CFTypeRef; @@ -48,18 +48,18 @@ int main(int argc, char *argv[]) { // rdar://10453342 @interface I { - __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}} + __attribute__((NSObject)) void * color; // expected-warning {{'NSObject' attribute may be put on a typedef only; attribute is ignored}} } // <rdar://problem/10930507> @property (nonatomic, retain) __attribute__((NSObject)) CGColorRefNoNSObject color; // // no-warning @end void test_10453342() { - char* __attribute__((NSObject)) string2 = 0; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}} + char* __attribute__((NSObject)) string2 = 0; // expected-warning {{'NSObject' attribute may be put on a typedef only; attribute is ignored}} } // rdar://11569860 @interface A { int i; } -@property(retain) __attribute__((NSObject)) int i; // expected-error {{__attribute ((NSObject)) is for pointer types only}} \ +@property(retain) __attribute__((NSObject)) int i; // expected-error {{'NSObject' attribute is for pointer types only}} \ // expected-error {{property with 'retain (or strong)' attribute must be of object type}} @end diff --git a/test/SemaObjC/objc-asm-attribute-neg-test.m b/test/SemaObjC/objc-asm-attribute-neg-test.m new file mode 100644 index 000000000000..2fb6643adde4 --- /dev/null +++ b/test/SemaObjC/objc-asm-attribute-neg-test.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://16462586 + +__attribute__((objc_runtime_name)) // expected-error {{'objc_runtime_name' attribute takes one argument}} +@interface BInterface +@end + +__attribute__((objc_runtime_name(123))) // expected-error {{'objc_runtime_name' attribute requires a string}} +@protocol BProtocol1 +@end + +__attribute__((objc_runtime_name("MySecretNamespace.Protocol"))) +@protocol Protocol +@end + +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@interface Message <Protocol> { +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}} + id MyIVAR; +} +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}} + +- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}} + +- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}} + +@end + +__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass"))) +@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}} + +__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol"))) +@protocol ForwardProtocol; + +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}} +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +- (id) MyMethod { + return MyIVAR; +} +@end diff --git a/test/SemaObjC/objc-container-subscripting-attr.m b/test/SemaObjC/objc-container-subscripting-attr.m new file mode 100644 index 000000000000..17110c47576e --- /dev/null +++ b/test/SemaObjC/objc-container-subscripting-attr.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://16842487 +// pr19682 + +@interface Subscriptable +- (id)objectForKeyedSubscript:(id)sub __attribute__((unavailable)); // expected-note 2 {{'objectForKeyedSubscript:' has been explicitly marked unavailable here}} +- (void)setObject:(id)object forKeyedSubscript:(id)key __attribute__((unavailable)); // expected-note {{'setObject:forKeyedSubscript:' has been explicitly marked unavailable here}} +@end + +id test(Subscriptable *obj) { + obj[obj] = obj; // expected-error {{'setObject:forKeyedSubscript:' is unavailable}} + return obj[obj]; // expected-error {{'objectForKeyedSubscript:' is unavailable}} +} + +id control(Subscriptable *obj) { + return [obj objectForKeyedSubscript:obj]; // expected-error {{'objectForKeyedSubscript:' is unavailable}} +} + diff --git a/test/SemaObjC/objc-literal-nsnumber.m b/test/SemaObjC/objc-literal-nsnumber.m index 26bca189d1f6..a2d37282b716 100644 --- a/test/SemaObjC/objc-literal-nsnumber.m +++ b/test/SemaObjC/objc-literal-nsnumber.m @@ -1,10 +1,12 @@ -// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s +// RUN: %clang_cc1 -fsyntax-only -fblocks -triple x86_64-apple-darwin10 -verify %s // rdar://10111397 #if __LP64__ typedef unsigned long NSUInteger; +typedef long NSInteger; #else typedef unsigned int NSUInteger; +typedef int NSInteger; #endif @interface NSObject @@ -13,10 +15,23 @@ typedef unsigned int NSUInteger; @interface NSNumber : NSObject + (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; + (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; + (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithInteger:(NSInteger)value ; ++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; @end +// rdar://16417427 +int big = 1391126400; +int thousand = 1000; int main() { NSNumber * N = @3.1415926535; // expected-error {{declaration of 'numberWithDouble:' is missing in NSNumber class}} NSNumber *noNumber = @__objc_yes; // expected-error {{declaration of 'numberWithBool:' is missing in NSNumber class}} @@ -32,6 +47,9 @@ int main() { int five = 5; @-five; // expected-error{{@- must be followed by a number to form an NSNumber object}} @+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}} + NSNumber *av = @(1391126400000); + NSNumber *bv = @(1391126400 * 1000); // expected-warning {{overflow in expression; result is -443003904 with type 'int'}} + NSNumber *cv = @(big * thousand); } // Dictionary test diff --git a/test/SemaObjC/objc-mixed-bridge-attribute.m b/test/SemaObjC/objc-mixed-bridge-attribute.m new file mode 100644 index 000000000000..83fb4d3cc497 --- /dev/null +++ b/test/SemaObjC/objc-mixed-bridge-attribute.m @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// expected-no-diagnostics +// rdar://17238954 + +typedef const struct __attribute__((objc_bridge(NSAttributedString))) __CFAttributedString *CFAttributedStringRef; + +typedef struct __attribute__((objc_bridge_mutable(NSMutableAttributedString))) __CFAttributedString *CFMutableAttributedStringRef; + +@interface NSAttributedString +@end + +@interface NSMutableAttributedString +@end + +struct __CFAttributedString { +}; + +void Test1(CFAttributedStringRef attrStr, CFMutableAttributedStringRef mutable_attrStr) +{ + id x = (NSAttributedString *) attrStr; + id x1 =(NSAttributedString *) mutable_attrStr; + id x2 = (NSMutableAttributedString *) attrStr; + id x3 = (NSMutableAttributedString *) mutable_attrStr; +} + +void Test2(NSAttributedString *ns_attrStr, NSMutableAttributedString *ns_mutable_attr_Str) { + CFAttributedStringRef cfsr = (CFAttributedStringRef) ns_attrStr; + CFMutableAttributedStringRef cfsr1 = (CFMutableAttributedStringRef) ns_attrStr; + CFAttributedStringRef cfsr2 = (CFAttributedStringRef) ns_mutable_attr_Str; + CFMutableAttributedStringRef cfsr3 = (CFMutableAttributedStringRef) ns_mutable_attr_Str; +} + +// Tests with no definition declaration for struct __NDCFAttributedString. +typedef const struct __attribute__((objc_bridge(NSAttributedString))) __NDCFAttributedString *NDCFAttributedStringRef; + +typedef struct __attribute__((objc_bridge_mutable(NSMutableAttributedString))) __NDCFAttributedString *NDCFMutableAttributedStringRef; + +void Test3(NDCFAttributedStringRef attrStr, NDCFMutableAttributedStringRef mutable_attrStr) +{ + id x = (NSAttributedString *) attrStr; + id x1 =(NSAttributedString *) mutable_attrStr; + id x2 = (NSMutableAttributedString *) attrStr; + id x3 = (NSMutableAttributedString *) mutable_attrStr; +} + +void Test4(NSAttributedString *ns_attrStr, NSMutableAttributedString *ns_mutable_attr_Str) { + NDCFAttributedStringRef cfsr = (NDCFAttributedStringRef) ns_attrStr; + NDCFMutableAttributedStringRef cfsr1 = (NDCFMutableAttributedStringRef) ns_attrStr; + NDCFAttributedStringRef cfsr2 = (NDCFAttributedStringRef) ns_mutable_attr_Str; + NDCFMutableAttributedStringRef cfsr3 = (NDCFMutableAttributedStringRef) ns_mutable_attr_Str; +} diff --git a/test/SemaObjC/objcbridge-attribute-arc.m b/test/SemaObjC/objcbridge-attribute-arc.m new file mode 100644 index 000000000000..ee2bf07ed47e --- /dev/null +++ b/test/SemaObjC/objcbridge-attribute-arc.m @@ -0,0 +1,223 @@ +// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s +// rdar://15454846 + +typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}} + +typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}} + +typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}} + +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 * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute only applies to struct or union}} + +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 __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 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))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute only applies to struct or union}}; + +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}}; +} +@end + +@protocol NSTesting @end +@class NSString; + +typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}} + +id Test1(CFTestingRef cf) { + return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka 'struct __CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \ + // expected-error {{cast of C pointer type 'CFTestingRef' (aka 'struct __CFError *') to Objective-C pointer type 'NSString *' 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 'CFTestingRef' (aka 'struct __CFError *') into ARC}} +} + +typedef CFErrorRef CFErrorRef1; + +typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}} + +@protocol P1 @end +@protocol P2 @end +@protocol P3 @end +@protocol P4 @end +@protocol P5 @end + +@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}} + +@interface MyError : NSError // expected-note 1 {{declared here}} +@end + +@interface NSUColor @end + +@class NSString; + +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'}} \ + // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSString *' 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}} + (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSError *' 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 '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}} + (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}} + (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} \\ + // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} \\ + // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'Class' 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 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} + (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *}} \\ + // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} +} + + +void Test3(CFErrorRef cf, NSError *ns) { + (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id' 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 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}} + (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' 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 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}} + (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka 'struct __CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \ + // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' 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 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}} +} + +void Test4(CFMyErrorRef cf) { + (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id' 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 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}} + (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' 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 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}} + (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' 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 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}} + (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' 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 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}} + (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \ + // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' 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 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}} +} + +void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) { + (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}} +} + +void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) { + + (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}} + (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}} + (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}} + (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}} + (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}} +} + +typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}} + +@interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}} +@end + +void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) { + (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} + (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}} +} + +void Test8(CFMyPersonalErrorRef cf) { + (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id' 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 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}} + (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' 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 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}} + (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' 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 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}} + (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' 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 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}} + (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' 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 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}} + (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \ + // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' 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 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}} +} + +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 NSUColor *)cf2; // okay + (void)(__bridge CFErrorRef)ns; // okay + (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} + (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} +} diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m index 2db2ff4929e8..a268caef8a50 100644 --- a/test/SemaObjC/objcbridge-attribute.m +++ b/test/SemaObjC/objcbridge-attribute.m @@ -1,11 +1,13 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s // rdar://15454846 -typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 2 {{declared here}} +typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 3 {{declared here}} + +typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}} typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}} -typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}} +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}} @@ -15,7 +17,7 @@ typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLoc typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}} -typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; +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}}; @@ -43,11 +45,17 @@ id Test1(CFTestingRef cf) { typedef CFErrorRef CFErrorRef1; -typedef CFErrorRef1 CFErrorRef2; +typedef CFErrorRef1 CFErrorRef2; // expected-note {{declared here}} + +@protocol P1 @end +@protocol P2 @end +@protocol P3 @end +@protocol P4 @end +@protocol P5 @end -@interface NSError @end +@interface NSError<P1, P2, P3> @end // expected-note 3 {{declared here}} -@interface MyError : NSError +@interface MyError : NSError // expected-note 1 {{declared here}} @end @interface NSUColor @end @@ -64,3 +72,64 @@ void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2 (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} (void)(CFErrorRef)c; // expected-warning {{'Class' cannot bridge to 'CFErrorRef'}} } + + +void Test3(CFErrorRef cf, NSError *ns) { + (void)(id)cf; // okay + (void)(id<P1, P2>)cf; // okay + (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka 'struct __CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} +} + +void Test4(CFMyErrorRef cf) { + (void)(id)cf; // okay + (void)(id<P1, P2>)cf; // ok + (void)(id<P1, P2, P3>)cf; // ok + (void)(id<P2, P3>)cf; // ok + (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} +} + +void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) { + (void)(CFErrorRef)ID; // ok + (void)(CFErrorRef)P123; // ok + (void)(CFErrorRef)P1234; // ok + (void)(CFErrorRef)P12; // ok + (void)(CFErrorRef)P23; // ok +} + +void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) { + + (void)(CFMyErrorRef)ID; // ok + (void)(CFMyErrorRef)P123; // ok + (void)(CFMyErrorRef)P1234; // ok + (void)(CFMyErrorRef)P12; // ok + (void)(CFMyErrorRef)P23; // ok +} + +typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}} + +@interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}} +@end + +void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) { + (void)(CFMyPersonalErrorRef)ID; // ok + (void)(CFMyPersonalErrorRef)P123; // ok + (void)(CFMyPersonalErrorRef)P1234; // ok + (void)(CFMyPersonalErrorRef)P12; // ok + (void)(CFMyPersonalErrorRef)P23; // ok +} + +void Test8(CFMyPersonalErrorRef cf) { + (void)(id)cf; // ok + (void)(id<P1>)cf; // ok + (void)(id<P1, P2>)cf; // ok + (void)(id<P1, P2, P3>)cf; // ok + (void)(id<P1, P2, P3, P4>)cf; // ok + (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} +} + +CFDictionaryRef bar() __attribute__((cf_returns_not_retained)); +@class NSNumber; + +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}} +} diff --git a/test/SemaObjC/objcbridge-related-attribute.m b/test/SemaObjC/objcbridge-related-attribute.m new file mode 100644 index 000000000000..06c2e87c5b1f --- /dev/null +++ b/test/SemaObjC/objcbridge-related-attribute.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -x objective-c -verify -Wno-objc-root-class %s +// rdar://15499111 + +typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 5 {{declared here}} +typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1; +typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2; + +@interface NSColor // expected-note 5 {{declared here}} ++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor; +- (CGColorRef)CGColor; +- (CGColorRef1)CGColor1; +@end + +@interface NSTextField +- (void)setBackgroundColor:(NSColor *)color; +- (NSColor *)backgroundColor; +@end + +void foo(NSColor*); // expected-note {{passing argument to parameter here}} + +NSColor * Test1(NSTextField *textField, CGColorRef newColor) { + foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} + textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} + return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} +} + +NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) { + foo(newColor); // expected-warning {{incompatible pointer types passing 'CGColorRef1'}} + textField.backgroundColor = newColor; // expected-warning {{incompatible pointer types assigning}} + return newColor; // expected-warning {{incompatible pointer types returning}} +} + +CGColorRef Test3(NSTextField *textField, CGColorRef newColor) { + newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} + return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}} +} + +CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) { + newColor = textField.backgroundColor; // expected-warning {{incompatible pointer types assigning}} + return textField.backgroundColor; // expected-warning {{incompatible pointer types returning}} +} diff --git a/test/SemaObjC/objcbridgemutable-attribute.m b/test/SemaObjC/objcbridgemutable-attribute.m new file mode 100644 index 000000000000..4ec8de0b5488 --- /dev/null +++ b/test/SemaObjC/objcbridgemutable-attribute.m @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://15498044 + +typedef struct __attribute__((objc_bridge_mutable(NSMutableDictionary))) __CFDictionary * CFMutableDictionaryRef; // expected-note {{declared here}} + +typedef struct __attribute__((objc_bridge_mutable(12))) __CFDictionaryB1 * CFMutableDictionaryB1Ref; // expected-error {{parameter of 'objc_bridge_mutable' attribute must be a single name of an Objective-C class}} + +typedef struct __attribute__((objc_bridge_mutable(P))) __CFDictionaryB2 * CFMutableDictionaryB2Ref; // expected-note {{declared here}} + +typedef struct __attribute__((objc_bridge_mutable(NSMutableDictionary, Unknown))) __CFDictionaryB3 * CFMutableDictionaryB3Ref; // expected-error {{use of undeclared identifier 'Unknown'}} + +typedef struct __attribute__((objc_bridge_mutable)) __CFDictionaryB4 * CFMutableDictionaryB4Ref; // expected-error {{'objc_bridge_mutable' attribute takes one argument}} + +@interface NSDictionary +@end + +@interface NSMutableDictionary : NSDictionary +@end + +@protocol P @end + +void Test(NSMutableDictionary *md, NSDictionary *nd, CFMutableDictionaryRef mcf, CFMutableDictionaryB2Ref bmcf) { + + (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) (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/opaque-is-access-warn.m b/test/SemaObjC/opaque-is-access-warn.m new file mode 100644 index 000000000000..ac0f724df6f6 --- /dev/null +++ b/test/SemaObjC/opaque-is-access-warn.m @@ -0,0 +1,24 @@ +// RUN: %clang -target x86_64-apple-darwin -arch arm64 -mios-version-min=7 -fsyntax-only -Wdeprecated-objc-isa-usage %s -Xclang -verify +// RUN: %clang -target x86_64-apple-darwin -arch arm64 -mios-version-min=7 -fsyntax-only %s -Xclang -verify +// RUN: %clang -target x86_64-apple-darwin -mios-simulator-version-min=7 -fsyntax-only -Wdeprecated-objc-isa-usage %s -Xclang -verify +// rdar://10709102 + +typedef struct objc_object { + struct objc_class *isa; +} *id; + +@interface NSObject { + struct objc_class *isa; +} +@end +@interface Whatever : NSObject ++self; +@end + +static void func() { + + id x; + + [(*x).isa self]; // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} + [x->isa self]; // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} +} diff --git a/test/SemaObjC/opaque-is-access.m b/test/SemaObjC/opaque-is-access.m new file mode 100644 index 000000000000..89d91b356063 --- /dev/null +++ b/test/SemaObjC/opaque-is-access.m @@ -0,0 +1,23 @@ +// RUN: %clang -target x86_64-apple-darwin -arch arm64 -mios-version-min=7 -fsyntax-only %s -Xclang -verify +// RUN: %clang -target x86_64-apple-darwin -arch x86_64 -mios-simulator-version-min=7 -fsyntax-only %s -Xclang -verify +// rdar://10709102 + +typedef struct objc_object { + struct objc_class *isa; +} *id; + +@interface NSObject { + struct objc_class *isa; +} +@end +@interface Whatever : NSObject ++self; +@end + +static void func() { + + id x; + + [(*x).isa self]; // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} + [x->isa self]; // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}} +} diff --git a/test/SemaObjC/overriding-property-in-class-extension.m b/test/SemaObjC/overriding-property-in-class-extension.m index 8c0e1b98a572..77efd556928c 100644 --- a/test/SemaObjC/overriding-property-in-class-extension.m +++ b/test/SemaObjC/overriding-property-in-class-extension.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Weverything %s +// expected-no-diagnostics // rdar://12103434 @class NSString; @@ -7,7 +8,7 @@ @interface MyClass : NSObject -@property (nonatomic, copy, readonly) NSString* name; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property (nonatomic, copy, readonly) NSString* name; @end diff --git a/test/SemaObjC/property-10.m b/test/SemaObjC/property-10.m index 8cb8ec63a916..b2aaf2b1a180 100644 --- a/test/SemaObjC/property-10.m +++ b/test/SemaObjC/property-10.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s -fblocks +// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks // Check property attribute consistency. diff --git a/test/SemaObjC/property-12.m b/test/SemaObjC/property-12.m index c4a755555629..5fc311aa90ad 100644 --- a/test/SemaObjC/property-12.m +++ b/test/SemaObjC/property-12.m @@ -1,15 +1,15 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wreadonly-setter-attrs -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s @protocol P0 -@property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} +@property(readonly,assign) id X; @end @protocol P1 -@property(readonly,retain) id X; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}} +@property(readonly,retain) id X; @end @protocol P2 -@property(readonly,copy) id X; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property(readonly,copy) id X; @end @protocol P3 diff --git a/test/SemaObjC/property-deprecated-warning.m b/test/SemaObjC/property-deprecated-warning.m index 7e10356ac577..4beb23ada33a 100644 --- a/test/SemaObjC/property-deprecated-warning.m +++ b/test/SemaObjC/property-deprecated-warning.m @@ -5,7 +5,7 @@ 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 {{method 'ptarget' declared here}} +@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}} @end @protocol P1<P> @@ -14,7 +14,7 @@ typedef signed char BOOL; @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 {{method 'setTarget:' declared here}} +@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}} @end @interface PSTableCell : UITableViewCell @@ -22,9 +22,9 @@ typedef signed char BOOL; @end @interface UITableViewCell(UIDeprecated) -@property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{method 'dep_target' declared here}} \ +@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 {{method 'setDep_target:' declared here}} + // expected-note 2 {{'setDep_target:' has been explicitly marked deprecated here}} @end @implementation PSTableCell @@ -55,9 +55,9 @@ typedef signed char BOOL; @interface CustomAccessorNames -@property(getter=isEnabled,assign) BOOL enabled __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'isEnabled' declared here}} expected-note {{property 'enabled' is declared deprecated here}} +@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 {{method 'setNewDelegate:' declared here}} expected-note {{property 'delegate' 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}} @end void testCustomAccessorNames(CustomAccessorNames *obj) { @@ -78,3 +78,28 @@ id useDeprecatedProperty(ProtocolInCategory *obj, id<P> obj2, int flag) { return [obj ptarget]; // no-warning return [obj2 ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}} } + +// rdar://15951801 +@interface Foo +{ + int _x; +} +@property(nonatomic,readonly) int x; +- (void)setX:(int)x __attribute__ ((deprecated)); // expected-note 2 {{'setX:' has been explicitly marked deprecated here}} +- (int)x __attribute__ ((unavailable)); // expected-note {{'x' has been explicitly marked unavailable here}} +@end + +@implementation Foo +- (void)setX:(int)x { + _x = x; +} +- (int)x { + return _x; +} +@end + +void testUserAccessorAttributes(Foo *foo) { + [foo setX:5678]; // expected-warning {{'setX:' is deprecated}} + foo.x = foo.x; // expected-error {{property access is using 'x' method which is unavailable}} \ + // expected-warning {{property access is using 'setX:' method which is deprecated}} +} diff --git a/test/SemaObjC/property-in-class-extension-1.m b/test/SemaObjC/property-in-class-extension-1.m index 51837fd212ca..ab461ef6c191 100644 --- a/test/SemaObjC/property-in-class-extension-1.m +++ b/test/SemaObjC/property-in-class-extension-1.m @@ -8,20 +8,19 @@ @property (nonatomic, readonly) NSString* addingMemoryModel; -@property (nonatomic, copy, readonly) NSString* matchingMemoryModel; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property (nonatomic, copy, readonly) NSString* matchingMemoryModel; -@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}} +@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel; @property (readonly) NSString* none; @property (readonly) NSString* none1; -@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}} \ - // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} +@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}} @property (readonly) __weak id weak_prop; @property (readonly) __weak id weak_prop1; -@property (assign, readonly) NSString* assignProperty; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} +@property (assign, readonly) NSString* assignProperty; @property (readonly) NSString* readonlyProp; diff --git a/test/SemaObjC/property-inherited.m b/test/SemaObjC/property-inherited.m index f5f1b420c229..cd223ddd1ff3 100644 --- a/test/SemaObjC/property-inherited.m +++ b/test/SemaObjC/property-inherited.m @@ -44,3 +44,29 @@ @property(assign) Data *p_base; @property(assign) NSData *p_data; // expected-warning{{property type 'NSData *' is incompatible with type 'NSMutableData *' inherited from 'Base'}} @end + +// rdar://15967517 +@protocol P1 +@property (nonatomic) void* selected; +@end + +@protocol P2 +@property (nonatomic) void* selected; // expected-note {{property declared here}} +@end + +@interface MKAnnotationView <P1> +@property (nonatomic) void* selected; // expected-note {{property declared here}} +@property (nonatomic) char selected2; +@end + +@interface Parent : MKAnnotationView <P2> +@property (nonatomic) void* selected1; // expected-note {{property declared here}} +@property (nonatomic) char selected2; +@end + +@interface Child : Parent +@property (nonatomic) char selected; // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'MKAnnotationView'}} \ + // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'P2'}} +@property (nonatomic) char selected1; // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'Parent'}} +@property (nonatomic) char selected2; +@end diff --git a/test/SemaObjC/property-noninherited-availability-attr.m b/test/SemaObjC/property-noninherited-availability-attr.m index 0c2a5d385307..dfa72d1077ef 100644 --- a/test/SemaObjC/property-noninherited-availability-attr.m +++ b/test/SemaObjC/property-noninherited-availability-attr.m @@ -1,17 +1,16 @@ // RUN: %clang_cc1 -triple x86_64-apple-macosx10.8.0 -fsyntax-only -verify %s -// This test case shows that 'availablity' and 'deprecated' does not inherit +// This test case shows that 'availability' and 'deprecated' do not inherit // when a property is redeclared in a subclass. This is intentional. @interface NSObject @end @protocol myProtocol -@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{method 'myProtocolProperty' declared here}} \ +@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{'myProtocolProperty' has been explicitly marked deprecated here}} \ // expected-note {{property 'myProtocolProperty' is declared deprecated here}} @end @interface Foo : NSObject -@property int myProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{'myProperty' declared here}} \ - // expected-note {{method 'myProperty' declared here}} \ +@property int myProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note 2 {{'myProperty' has been explicitly marked deprecated here}} \ // expected-note {{property 'myProperty' is declared deprecated here}} @end @@ -22,13 +21,13 @@ void test(Foo *y, Bar *x, id<myProtocol> z) { y.myProperty = 0; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} - [y myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} + (void)[y myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} x.myProperty = 1; // no-warning - [x myProperty]; // no-warning + (void)[x myProperty]; // no-warning x.myProtocolProperty = 0; // no-warning - [x myProtocolProperty]; // no-warning - [z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}} + (void)[x myProtocolProperty]; // no-warning + (void)[z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}} } diff --git a/test/SemaObjC/property-typecheck-1.m b/test/SemaObjC/property-typecheck-1.m index 58d0f215cd92..5fb05c8bd384 100644 --- a/test/SemaObjC/property-typecheck-1.m +++ b/test/SemaObjC/property-typecheck-1.m @@ -93,7 +93,7 @@ typedef void (F)(void); return container.pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}} } -- (id)firstPeice +- (id)firstPiece { return container.first; } diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m index b2aecc209f1b..52bd44110fc9 100644 --- a/test/SemaObjC/protocol-attribute.m +++ b/test/SemaObjC/protocol-attribute.m @@ -6,7 +6,7 @@ __attribute ((unavailable)) Class <FwProto> cFw = 0; // expected-error {{'FwProto' is unavailable}} -__attribute ((deprecated)) @protocol MyProto1 // expected-note 7 {{declared here}} +__attribute ((deprecated)) @protocol MyProto1 // expected-note 7 {{'MyProto1' has been explicitly marked deprecated here}} @end @protocol Proto2 <MyProto1> // expected-warning {{'MyProto1' is deprecated}} diff --git a/test/SemaObjC/protocols-suppress-conformance.m b/test/SemaObjC/protocols-suppress-conformance.m new file mode 100644 index 000000000000..299e44e8074e --- /dev/null +++ b/test/SemaObjC/protocols-suppress-conformance.m @@ -0,0 +1,207 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class + +// Mark this protocol as requiring all of its methods and properties +// to be explicitly implemented in the adopting class. +__attribute__((objc_protocol_requires_explicit_implementation)) +@protocol Protocol +- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}} +@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}} +@end + +// In this example, ClassA adopts the protocol. We won't +// provide the implementation here, but this protocol will +// be adopted later by a subclass. +@interface ClassA <Protocol> +- (void) theBestOfTimes; +@property (readonly) id theWorstOfTimes; +@end + +// This class subclasses ClassA (which also adopts 'Protocol'). +@interface ClassB : ClassA <Protocol> +@end + +@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}} +@end + +@interface ClassB_Good : ClassA <Protocol> +@end + +@implementation ClassB_Good // no-warning +- (void) theBestOfTimes {} +@dynamic theWorstOfTimes; +@end + +@interface ClassB_AlsoGood : ClassA <Protocol> +@property (readonly) id theWorstOfTimes; +@end + +// Default synthesis acts as if @dynamic +// had been written for 'theWorstOfTimes' because +// it is declared in ClassA. This is okay, since +// the author of ClassB_AlsoGood needs explicitly +// write @property in the @interface. +@implementation ClassB_AlsoGood // no-warning +- (void) theBestOfTimes {} +@end + +// Test that inherited protocols do not get the explicit conformance requirement. +@protocol Inherited +- (void) fairIsFoul; +@end + +__attribute__((objc_protocol_requires_explicit_implementation)) +@protocol Derived <Inherited> +- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}} +@end + +@interface ClassC <Inherited> +@end + +@interface ClassD : ClassC <Derived> +@end + +@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}} +@end + +// Test that the attribute is used correctly. +__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}} +@protocol AnotherProtocol @end + +// Cannot put the attribute on classes or other non-protocol declarations. +__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}} +@interface AnotherClass @end + +__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}} +int x; + +// Test that inherited protocols with the attribute +// are treated properly. +__attribute__((objc_protocol_requires_explicit_implementation)) +@protocol ProtocolA +@required +- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}} +- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}} +@end + +@protocol ProtocolB <ProtocolA> +@required +- (void)dunwich; +- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}} +@end + +__attribute__((objc_protocol_requires_explicit_implementation)) +@protocol ProtocolB_Explicit <ProtocolA> +@required +- (void)dunwich; +- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}} +@end + +@protocol ProtocolC +@required +- (void)rlyeh; +- (void)innsmouth; +- (void)dunwich; +@end + +@interface MyObject <ProtocolC> @end + +// Provide two variants of a base class, one that adopts ProtocolA and +// one that does not. +@interface Lovecraft <ProtocolA> @end +@interface Lovecraft_2 @end + +// Provide two variants of a subclass that conform to ProtocolB. One +// subclasses from a class that conforms to ProtocolA, the other that +// does not. +// +// From those, provide two variants that conformat to ProtocolB_Explicit +// instead. +@interface Shoggoth : Lovecraft <ProtocolB> @end +@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end +@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end +@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end + +@implementation MyObject +- (void)innsmouth {} +- (void)rlyeh {} +- (void)dunwich {} +@end + +@implementation Lovecraft +- (void)innsmouth {} +- (void)rlyeh {} +@end + +@implementation Shoggoth +- (void)dunwich {} +@end + +@implementation Shoggoth_2 // expected-warning {{method 'innsmouth' in protocol 'ProtocolB' not implemented}}\ + // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\ + // expected-warning {{'innsmouth' in protocol 'ProtocolA' not implemented}} +- (void)dunwich {} +@end + +@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}} +- (void)dunwich {} +@end + +@implementation Shoggoth_2_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}\ + // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\ + // expected-warning {{method 'innsmouth' in protocol 'ProtocolA' not implemented}} +- (void)dunwich {} +@end + +// Categories adopting a protocol with explicit conformance need to implement that protocol. +@interface Parent +- (void) theBestOfTimes; +@property (readonly) id theWorstOfTimes; +@end + +@interface Derived : Parent +@end + +@interface Derived (MyCat) <Protocol> +@end + +@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}} +@end + +__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error{{attribute 'objc_protocol_requires_explicit_implementation' can only be applied to @protocol definitions, not forward declarations}} +@protocol NotDefined; + +// Another complete hierarchy. + __attribute__((objc_protocol_requires_explicit_implementation)) +@protocol Ex2FooBar +- (void)methodA; +@end + + __attribute__((objc_protocol_requires_explicit_implementation)) +@protocol Ex2ProtocolA +- (void)methodB; +@end + + __attribute__((objc_protocol_requires_explicit_implementation)) +@protocol Ex2ProtocolB <Ex2ProtocolA> +- (void)methodA; // expected-note {{method 'methodA' declared here}} +@end + +// NOT required +@protocol Ex2ProtocolC <Ex2ProtocolA> +- (void)methodB; +- (void)methodA; +@end + +@interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar> +@end +@implementation Ex2ClassA +- (void)methodB {} +- (void)methodA {} +@end + +@interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB> +@end + +@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}} +@end + diff --git a/test/SemaObjC/selector-1.m b/test/SemaObjC/selector-1.m index 186e19fead83..4efa0d711787 100644 --- a/test/SemaObjC/selector-1.m +++ b/test/SemaObjC/selector-1.m @@ -1,20 +1,31 @@ -// RUN: %clang_cc1 -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -Wselector-type-mismatch -verify %s @interface I -- (id) compare: (char) arg1; +- (id) compare: (char) arg1; // expected-note {{method 'compare:' declared here}} - length; @end @interface J -- (id) compare: (id) arg1; +- (id) compare: (id) arg1; // expected-note {{method 'compare:' declared here}} @end SEL func() { - return @selector(compare:); // Non warning on multiple selector found. + return @selector(compare:); // expected-warning {{several methods with selector 'compare:' of mismatched types are found for the @selector expression}} } +// rdar://16458579 +void Test16458579() { + SEL s = @selector((retain)); + SEL s1 = @selector((meth1:)); + SEL s2 = @selector((retainArgument::)); + SEL s3 = @selector((retainArgument:::::)); + SEL s4 = @selector((retainArgument:with:)); + SEL s5 = @selector((meth1:with:with:)); + SEL s6 = @selector((getEnum:enum:bool:)); + SEL s7 = @selector((char:float:double:unsigned:short:long:)); + SEL s9 = @selector((:enum:bool:)); +} int main() { SEL s = @selector(retain); SEL s1 = @selector(meth1:); @@ -27,3 +38,26 @@ int main() { SEL s9 = @selector(:enum:bool:); } + +// rdar://15794055 +@interface NSObject @end + +@class NSNumber; + +@interface XBRecipe : NSObject +@property (nonatomic, assign) float finalVolume; // expected-note {{method 'setFinalVolume:' declared here}} +@end + +@interface XBDocument : NSObject +@end + +@interface XBDocument () +- (void)setFinalVolume:(NSNumber *)finalVolumeNumber; // expected-note {{method 'setFinalVolume:' declared here}} +@end + +@implementation XBDocument +- (void)setFinalVolume:(NSNumber *)finalVolumeNumber +{ + (void)@selector(setFinalVolume:); // expected-warning {{several methods with selector 'setFinalVolume:' of mismatched types are found for the @selector expression}} +} +@end diff --git a/test/SemaObjC/selector-3.m b/test/SemaObjC/selector-3.m index d782c784f1de..dfd216a16fa9 100644 --- a/test/SemaObjC/selector-3.m +++ b/test/SemaObjC/selector-3.m @@ -14,7 +14,7 @@ - (void) foo { SEL a,b,c; - a = @selector(b1ar); // expected-warning {{creating selector for nonexistent method 'b1ar'}} + a = @selector(b1ar); b = @selector(bar); } @end @@ -25,7 +25,7 @@ SEL func() { - return @selector(length); // expected-warning {{creating selector for nonexistent method 'length'}} + return @selector(length); // expected-warning {{no method with selector 'length' is implemented in this translation unit}} } // rdar://9545564 @@ -69,7 +69,7 @@ extern SEL MySelector(SEL s); @implementation INTF - (void) Meth { - if( [cnx respondsToSelector:MySelector(@selector( _setQueue: ))] ) // expected-warning {{creating selector for nonexistent method '_setQueue:'}} + if( [cnx respondsToSelector:MySelector(@selector( _setQueue: ))] ) { } @@ -84,23 +84,23 @@ extern SEL MySelector(SEL s); // rdar://14007194 @interface UxTechTest : NSObject -- (int) invalidate : (id)Arg; // expected-warning {{multiple selectors named 'invalidate:' found}} -+ (int) C_invalidate : (int)arg; // expected-warning {{multiple selectors named 'C_invalidate:' found}} +- (int) invalidate : (id)Arg; ++ (int) C_invalidate : (int)arg; @end @interface UxTechTest(CAT) -- (char) invalidate : (int)arg; // expected-note {{also found}} -+ (int) C_invalidate : (char)arg; // expected-note {{also found}} +- (char) invalidate : (int)arg; ++ (int) C_invalidate : (char)arg; @end @interface NSPort : NSObject -- (double) invalidate : (void*)Arg1; // expected-note {{also found}} -+ (int) C_invalidate : (id*)arg; // expected-note {{also found}} +- (double) invalidate : (void*)Arg1; ++ (int) C_invalidate : (id*)arg; @end @interface USEText : NSPort -- (int) invalidate : (int)arg; // expected-note {{also found}} +- (int) invalidate : (int)arg; @end @implementation USEText @@ -110,3 +110,27 @@ extern SEL MySelector(SEL s); @interface USETextSub : USEText - (int) invalidate : (id)arg; @end + +// rdar://16428638 +@interface I16428638 +- (int) compare: (I16428638 *) arg1; // commenting out this line avoids the warning +@end + +@interface J16428638 +- (int) compare: (J16428638 *) arg1; +@end + +@implementation J16428638 +- (void)method { + SEL s = @selector(compare:); // spurious warning + (void)s; +} +- (int) compare: (J16428638 *) arg1 { + return 0; +} +@end + +void test16428638() { + SEL s = @selector(compare:); + (void)s; +} diff --git a/test/SemaObjC/selector-4.m b/test/SemaObjC/selector-4.m new file mode 100644 index 000000000000..59a8233f6bc1 --- /dev/null +++ b/test/SemaObjC/selector-4.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -Wselector -x objective-c %s -include %s -verify +// expected-no-diagnostics +// rdar://16600230 + +#ifndef INCLUDED +#define INCLUDED + +#pragma clang system_header + +@interface NSObject @end +@interface NSString @end + +@interface NSString (NSStringExtensionMethods) +- (void)compare:(NSString *)string; +@end + +@interface MyObject : NSObject +@end + +#else +int main() { + (void)@selector(compare:); +} + +@implementation MyObject + +@end +#endif diff --git a/test/SemaObjC/selector-overload.m b/test/SemaObjC/selector-overload.m index 53ba6f7e7e32..447607a1f754 100644 --- a/test/SemaObjC/selector-overload.m +++ b/test/SemaObjC/selector-overload.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -fsyntax-only +// FIXME: This test needs needs to be run with -verify @interface NSObject + alloc; diff --git a/test/SemaObjC/special-dep-unavail-warning.m b/test/SemaObjC/special-dep-unavail-warning.m index a179647ebccd..9e16b331c23c 100644 --- a/test/SemaObjC/special-dep-unavail-warning.m +++ b/test/SemaObjC/special-dep-unavail-warning.m @@ -4,48 +4,48 @@ @interface B - (void) depInA; - (void) unavailMeth __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} -- (void) depInA1 __attribute__((deprecated)); +- (void) depInA1 __attribute__((deprecated)); // expected-note {{'depInA1' has been explicitly marked deprecated here}} - (void) unavailMeth1; -- (void) depInA2 __attribute__((deprecated)); +- (void) depInA2 __attribute__((deprecated)); // expected-note {{'depInA2' has been explicitly marked deprecated here}} - (void) unavailMeth2 __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} - (void) depunavailInA; - (void) depunavailInA1 __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} -- (void)FuzzyMeth __attribute__((deprecated)); +- (void)FuzzyMeth __attribute__((deprecated)); // expected-note {{'FuzzyMeth' has been explicitly marked deprecated here}} - (void)FuzzyMeth1 __attribute__((unavailable)); @end @interface A - (void) unavailMeth1 __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} -- (void) depInA __attribute__((deprecated)); +- (void) depInA __attribute__((deprecated)); // expected-note {{'depInA' has been explicitly marked deprecated here}} - (void) depInA2 __attribute__((deprecated)); - (void) depInA1; - (void) unavailMeth2 __attribute__((unavailable)); - (void) depunavailInA __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}} - (void) depunavailInA1; - (void)FuzzyMeth __attribute__((unavailable)); -- (void)FuzzyMeth1 __attribute__((deprecated)); +- (void)FuzzyMeth1 __attribute__((deprecated)); // expected-note {{'FuzzyMeth1' has been explicitly marked deprecated here}} @end -@class C; // expected-note 5 {{forward declaration of class here}} +@class C; // expected-note 10 {{forward declaration of class here}} void test(C *c) { - [c depInA]; // expected-warning {{'depInA' maybe deprecated because receiver type is unknown}} - [c unavailMeth]; // expected-warning {{'unavailMeth' maybe unavailable because receiver type is unknown}} - [c depInA1]; // expected-warning {{'depInA1' maybe deprecated because receiver type is unknown}} - [c unavailMeth1]; // expected-warning {{'unavailMeth1' maybe unavailable because receiver type is unknown}} - [c depInA2]; // expected-warning {{'depInA2' maybe deprecated because receiver type is unknown}} - [c unavailMeth2]; // expected-warning {{'unavailMeth2' maybe unavailable because receiver type is unknown}} - [c depunavailInA]; // expected-warning {{'depunavailInA' maybe unavailable because receiver type is unknown}} - [c depunavailInA1];// expected-warning {{'depunavailInA1' maybe unavailable because receiver type is unknown}} - [c FuzzyMeth]; // expected-warning {{'FuzzyMeth' maybe deprecated because receiver type is unknown}} - [c FuzzyMeth1]; // expected-warning {{'FuzzyMeth1' maybe deprecated because receiver type is unknown}} + [c depInA]; // expected-warning {{'depInA' may be deprecated because the receiver type is unknown}} + [c unavailMeth]; // expected-warning {{'unavailMeth' may be unavailable because the receiver type is unknown}} + [c depInA1]; // expected-warning {{'depInA1' may be deprecated because the receiver type is unknown}} + [c unavailMeth1]; // expected-warning {{'unavailMeth1' may be unavailable because the receiver type is unknown}} + [c depInA2]; // expected-warning {{'depInA2' may be deprecated because the receiver type is unknown}} + [c unavailMeth2]; // expected-warning {{'unavailMeth2' may be unavailable because the receiver type is unknown}} + [c depunavailInA]; // expected-warning {{'depunavailInA' may be unavailable because the receiver type is unknown}} + [c depunavailInA1];// expected-warning {{'depunavailInA1' may be unavailable because the receiver type is unknown}} + [c FuzzyMeth]; // expected-warning {{'FuzzyMeth' may be deprecated because the receiver type is unknown}} + [c FuzzyMeth1]; // expected-warning {{'FuzzyMeth1' may be deprecated because the receiver type is unknown}} } // rdar://10268422 __attribute ((deprecated)) -@interface DEPRECATED // expected-note {{declared here}} +@interface DEPRECATED // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}} +(id)new; @end diff --git a/test/SemaObjC/tentative-property-decl.m b/test/SemaObjC/tentative-property-decl.m index aa7df5294a8a..a9649b644c31 100644 --- a/test/SemaObjC/tentative-property-decl.m +++ b/test/SemaObjC/tentative-property-decl.m @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -fsyntax-only -Weverything -verify %s +// expected-no-diagnostics // rdar://11656982 -/** Normally, a property cannot be both 'readonly' and having a "write" attribute +/** A property may not be both 'readonly' and having a memory management attribute (copy/retain/etc.). But, property declaration in primary class and protcols are tentative as they may be overridden into a 'readwrite' property in class - extensions. Postpone diagnosing such warnings until the class implementation - is seen. + extensions. So, do not issue any warning on 'readonly' and memory management + attributes in a property. */ @interface Super { @@ -14,8 +15,8 @@ @class NSString; @interface MyClass : Super -@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} -@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property(nonatomic, copy, readonly) NSString *prop; +@property(nonatomic, copy, readonly) id warnProp; @end @interface MyClass () @@ -29,8 +30,8 @@ @protocol P -@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} -@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@property(nonatomic, copy, readonly) NSString *prop; +@property(nonatomic, copy, readonly) id warnProp; @end @interface YourClass : Super <P> diff --git a/test/SemaObjC/undef-protocol-methods-1.m b/test/SemaObjC/undef-protocol-methods-1.m index 25b1dadb7cce..4858faf28031 100644 --- a/test/SemaObjC/undef-protocol-methods-1.m +++ b/test/SemaObjC/undef-protocol-methods-1.m @@ -22,13 +22,10 @@ + (void) cls_meth : (int) arg1; // expected-note {{method 'cls_meth:' declared here}} @end -@interface INTF <PROTO> // expected-note 3 {{required for direct or indirect protocol 'PROTO'}} \ - // expected-note 2 {{required for direct or indirect protocol 'P1'}} \ - // expected-note 2 {{required for direct or indirect protocol 'P3'}} \ - // expected-note 2 {{required for direct or indirect protocol 'P2'}} +@interface INTF <PROTO> @end -@implementation INTF // expected-warning 9 {{in protocol not implemented}} +@implementation INTF // expected-warning 9 {{in protocol '}} - (void) DefP1proto{} + (void) DefClsP3Proto{} @end diff --git a/test/SemaObjC/unsued-backing-ivar-warning.m b/test/SemaObjC/unsued-backing-ivar-warning.m deleted file mode 100644 index c07dea71a7e1..000000000000 --- a/test/SemaObjC/unsued-backing-ivar-warning.m +++ /dev/null @@ -1,76 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -Wunused-property-ivar -verify -Wno-objc-root-class %s -// rdar://14989999 - -@interface NSObject @end - -@interface Example : NSObject -@property (nonatomic, copy) id t; // expected-note {{property declared here}} -@property (nonatomic, copy) id u; // expected-note {{property declared here}} -@property (nonatomic, copy) id v; // expected-note {{property declared here}} -@property (nonatomic, copy) id w; -@property (nonatomic, copy) id x; // expected-note {{property declared here}} -@property (nonatomic, copy) id y; // expected-note {{property declared here}} -@property (nonatomic, copy) id z; -@property (nonatomic, copy) id ok; -@end - -@implementation Example -- (void) setX:(id)newX { // expected-warning {{ivar '_x' which backs the property is not referenced in this property's accessor}} - _y = newX; -} -- (id) y { // expected-warning {{ivar '_y' which backs the property is not referenced in this property's accessor}} - return _v; -} - -- (void) setV:(id)newV { // expected-warning {{ivar '_v' which backs the property is not referenced in this property's accessor}} - _y = newV; -} - -// No warning here because there is no backing ivar. -// both setter/getter are user defined. -- (void) setW:(id)newW { - _y = newW; -} -- (id) w { - return _v; -} - -- (id) u { // expected-warning {{ivar '_u' which backs the property is not referenced in this property's accessor}} - return _v; -} - -@synthesize ok = okIvar; -- (void) setOk:(id)newOk { - okIvar = newOk; -} - -@synthesize t = tIvar; -- (void) setT:(id)newT { // expected-warning {{ivar 'tIvar' which backs the property is not referenced in this property's accessor}} - okIvar = newT; -} -@end - -// rdar://15473432 -typedef char BOOL; -@interface CalDAVServerVersion { - BOOL _supportsTimeRangeFilterWithoutEndDate; -} -@property (nonatomic, readonly,nonatomic) BOOL supportsTimeRangeFilterWithoutEndDate; -@end - -@interface CalDAVConcreteServerVersion : CalDAVServerVersion { -} -@end - -@interface CalendarServerVersion : CalDAVConcreteServerVersion -@end - -@implementation CalDAVServerVersion -@synthesize supportsTimeRangeFilterWithoutEndDate=_supportsTimeRangeFilterWithoutEndDate; -@end - -@implementation CalendarServerVersion --(BOOL)supportsTimeRangeFilterWithoutEndDate { - return 0; -} -@end diff --git a/test/SemaObjC/unused-backing-ivar-warning.m b/test/SemaObjC/unused-backing-ivar-warning.m new file mode 100644 index 000000000000..52067c73d981 --- /dev/null +++ b/test/SemaObjC/unused-backing-ivar-warning.m @@ -0,0 +1,203 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-property-ivar -verify -Wno-objc-root-class %s +// rdar://14989999 + +@interface NSObject @end + +@interface Example : NSObject +@property (nonatomic, copy) id t; // expected-note {{property declared here}} +@property (nonatomic, copy) id u; // expected-note {{property declared here}} +@property (nonatomic, copy) id v; // expected-note {{property declared here}} +@property (nonatomic, copy) id w; +@property (nonatomic, copy) id x; // expected-note {{property declared here}} +@property (nonatomic, copy) id y; // expected-note {{property declared here}} +@property (nonatomic, copy) id z; +@property (nonatomic, copy) id ok; +@end + +@implementation Example +- (void) setX:(id)newX { // expected-warning {{ivar '_x' which backs the property is not referenced in this property's accessor}} + _y = newX; +} +- (id) y { // expected-warning {{ivar '_y' which backs the property is not referenced in this property's accessor}} + return _v; +} + +- (void) setV:(id)newV { // expected-warning {{ivar '_v' which backs the property is not referenced in this property's accessor}} + _y = newV; +} + +// No warning here because there is no backing ivar. +// both setter/getter are user defined. +- (void) setW:(id)newW { + _y = newW; +} +- (id) w { + return _v; +} + +- (id) u { // expected-warning {{ivar '_u' which backs the property is not referenced in this property's accessor}} + return _v; +} + +@synthesize ok = okIvar; +- (void) setOk:(id)newOk { + okIvar = newOk; +} + +@synthesize t = tIvar; +- (void) setT:(id)newT { // expected-warning {{ivar 'tIvar' which backs the property is not referenced in this property's accessor}} + okIvar = newT; +} +@end + +// rdar://15473432 +typedef char BOOL; +@interface CalDAVServerVersion { + BOOL _supportsTimeRangeFilterWithoutEndDate; +} +@property (nonatomic, readonly,nonatomic) BOOL supportsTimeRangeFilterWithoutEndDate; +@end + +@interface CalDAVConcreteServerVersion : CalDAVServerVersion { +} +@end + +@interface CalendarServerVersion : CalDAVConcreteServerVersion +@end + +@implementation CalDAVServerVersion +@synthesize supportsTimeRangeFilterWithoutEndDate=_supportsTimeRangeFilterWithoutEndDate; +@end + +@implementation CalendarServerVersion +-(BOOL)supportsTimeRangeFilterWithoutEndDate { + return 0; +} +@end + +// rdar://15630719 +@interface CDBModifyRecordsOperation : NSObject +@property (nonatomic, assign) BOOL atomic; +@end + +@class NSString; + +@implementation CDBModifyRecordsOperation +- (void)setAtomic:(BOOL)atomic { + if (atomic == __objc_yes) { + NSString *recordZoneID = 0; + } + _atomic = atomic; +} +@end + +// rdar://15728901 +@interface GATTOperation : NSObject { + long operation; +} +@property(assign) long operation; +@end + +@implementation GATTOperation +@synthesize operation; ++ (id) operation { + return 0; +} +@end + +// rdar://15727327 +@interface Radar15727327 : NSObject +@property (assign, readonly) long p; +@property (assign) long q; // expected-note 2 {{property declared here}} +@property (assign, readonly) long r; // expected-note {{property declared here}} +- (long)Meth; +@end + +@implementation Radar15727327 +@synthesize p; +@synthesize q; +@synthesize r; +- (long)Meth { return p; } +- (long) p { [self Meth]; return 0; } +- (long) q { return 0; } // expected-warning {{ivar 'q' which backs the property is not referenced in this property's accessor}} +- (void) setQ : (long) val { } // expected-warning {{ivar 'q' which backs the property is not referenced in this property's accessor}} +- (long) r { [self Meth]; return p; } // expected-warning {{ivar 'r' which backs the property is not referenced in this property's accessor}} +@end + +@interface I1 +@property (readonly) int p1; +@property (readonly) int p2; // expected-note {{property declared here}} +@end + +@implementation I1 +@synthesize p1=_p1; +@synthesize p2=_p2; + +-(int)p1 { + return [self getP1]; +} +-(int)getP1 { + return _p1; +} +-(int)getP2 { + return _p2; +} +-(int)p2 { // expected-warning {{ivar '_p2' which backs the property is not referenced in this property's accessor}} + Radar15727327 *o; + return [o Meth]; +} +@end + +// rdar://15873425 +@protocol MyProtocol +@property (nonatomic, readonly) int myProperty; +@end + +@interface MyFirstClass : NSObject <MyProtocol> +@end + +@interface MySecondClass : NSObject <MyProtocol> +@end + +@implementation MyFirstClass +@synthesize myProperty; +@end + +@implementation MySecondClass +@dynamic myProperty; +-(int)myProperty // should not warn; property is dynamic +{ + return 0; +} +@end + +// rdar://15890251 +@class NSURL; + +@protocol MCCIDURLProtocolDataProvider +@required +@property(strong, atomic, readonly) NSURL *cidURL; +@property(strong, atomic, readonly) NSURL *cidURL1; // expected-note {{property declared here}} +@end + +@interface UnrelatedClass : NSObject <MCCIDURLProtocolDataProvider> +@end + +@implementation UnrelatedClass +@synthesize cidURL = _cidURL; +@synthesize cidURL1 = _cidURL1; +@end + +@interface MUIWebAttachmentController : NSObject <MCCIDURLProtocolDataProvider> +@end + + +@implementation MUIWebAttachmentController +- (NSURL *)cidURL { + return 0; +} +@synthesize cidURL1 = _cidURL1; +- (NSURL *)cidURL1 { // expected-warning {{ivar '_cidURL1' which backs the property is not referenced in this property's accessor}} + return 0; +} +@end diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m index 3fd1cf04673f..6ea3fe8e00ab 100644 --- a/test/SemaObjC/unused.m +++ b/test/SemaObjC/unused.m @@ -72,3 +72,35 @@ static NSString *x = @"hi"; // expected-warning {{unused variable 'x'}} - (void) b {} - (void) a { [self b]; } @end + +// Test that objc_precise_lifetime suppresses +// unused variable warnings. +extern void rdar15596883_foo(void); +void rdar15596883(id x) { + __attribute__((objc_precise_lifetime)) id y = x; // no-warning + rdar15596883_foo(); +} + +@interface PropertyObject : NSObject +@property int length; +@end + +@protocol P +@property int property; +@end + +void test3(PropertyObject *o) +{ + [o length]; // expected-warning {{property access result unused - getters should not be used for side effects}} + (void)[o length]; +} + +void test4(id o) +{ + [o length]; // No warning. +} + +void test5(id <P> p) +{ + [p property]; // expected-warning {{property access result unused - getters should not be used for side effects}} +} diff --git a/test/SemaObjC/warn-deprecated-implementations.m b/test/SemaObjC/warn-deprecated-implementations.m index f63962f96180..6e208b5be795 100644 --- a/test/SemaObjC/warn-deprecated-implementations.m +++ b/test/SemaObjC/warn-deprecated-implementations.m @@ -11,13 +11,13 @@ @end @interface A() -- (void) E __attribute__((deprecated)); // expected-note {{method 'E' declared here}} +- (void) E __attribute__((deprecated)); @end @implementation A + (void)F { } // No warning, implementing its own deprecated method - (void) D {} // expected-warning {{Implementing deprecated method}} -- (void) E {} // expected-warning {{Implementing deprecated method}} +- (void) E {} // No warning, implementing deprecated method in its class extension. @end @interface A(CAT) @@ -29,7 +29,7 @@ @end __attribute__((deprecated)) -@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{declared here}} +@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{'CL' has been explicitly marked deprecated here}} @end @implementation CL // expected-warning {{Implementing deprecated class}} @@ -53,3 +53,15 @@ __attribute__((deprecated)) - (void) B {} // expected-warning {{Implementing deprecated method}} @end +@interface Test +@end + +@interface Test() +- (id)initSpecialInPrivateHeader __attribute__((deprecated)); +@end + +@implementation Test +- (id)initSpecialInPrivateHeader { + return (void *)0; +} +@end diff --git a/test/SemaObjC/warn-forward-class-attr-deprecated.m b/test/SemaObjC/warn-forward-class-attr-deprecated.m index 854ff699eed4..cb118c3caf4b 100644 --- a/test/SemaObjC/warn-forward-class-attr-deprecated.m +++ b/test/SemaObjC/warn-forward-class-attr-deprecated.m @@ -4,7 +4,7 @@ @class ABGroupImportFilesScope; // expected-note {{forward declaration of class here}} @interface I1 -- (id) filenames __attribute__((deprecated)); +- (id) filenames __attribute__((deprecated)); // expected-note {{'filenames' has been explicitly marked deprecated here}} @end @interface I2 @@ -16,7 +16,7 @@ @implementation I2 - (id) Meth : (ABGroupImportFilesScope*) scope { - id p = [self initWithAccount : 0 filenames :[scope filenames]]; // expected-warning {{'filenames' maybe deprecated because receiver type is unknown}} + id p = [self initWithAccount : 0 filenames :[scope filenames]]; // expected-warning {{'filenames' may be deprecated because the receiver type is unknown}} return 0; } - (id) filenames { return 0; } diff --git a/test/SemaObjC/warn-protocol-method-deprecated.m b/test/SemaObjC/warn-protocol-method-deprecated.m index 928694db2528..70dd394845ce 100644 --- a/test/SemaObjC/warn-protocol-method-deprecated.m +++ b/test/SemaObjC/warn-protocol-method-deprecated.m @@ -3,7 +3,7 @@ @protocol TestProtocol - (void)newProtocolMethod; -- (void)deprecatedProtocolMethod __attribute__((deprecated)); // expected-note 2 {{method 'deprecatedProtocolMethod' declared here}} +- (void)deprecatedProtocolMethod __attribute__((deprecated)); // expected-note 2 {{'deprecatedProtocolMethod' has been explicitly marked deprecated here}} @end @interface NSObject @end @@ -11,7 +11,7 @@ @interface TestClass : NSObject <TestProtocol> - (void)newInstanceMethod; -- (void)deprecatedInstanceMethod __attribute__((deprecated)); // expected-note {{method 'deprecatedInstanceMethod' declared here}} +- (void)deprecatedInstanceMethod __attribute__((deprecated)); // expected-note {{'deprecatedInstanceMethod' has been explicitly marked deprecated here}} @end diff --git a/test/SemaObjC/warn-retain-cycle.m b/test/SemaObjC/warn-retain-cycle.m index eb4e966c7726..4398d29e4a8c 100644 --- a/test/SemaObjC/warn-retain-cycle.m +++ b/test/SemaObjC/warn-retain-cycle.m @@ -122,8 +122,8 @@ void doSomething(unsigned v); // Sanity check that we are really whitelisting 'addOperationWithBlock:' and not doing // something funny. [myOperationQueue addSomethingElse:^() { // expected-note {{block will be retained by an object strongly retained by the captured object}} - if (count > 20) { // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}} - doSomething(count); + if (count > 20) { + doSomething(count); // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}} } }]; } @@ -184,3 +184,17 @@ void testCopying(Test0 *obj) { })]; } +// rdar://16944538 +void func(int someCondition) { + +__block void(^myBlock)(void) = ^{ + if (someCondition) { + doSomething(1); + myBlock(); + } + else { + myBlock = ((void*)0); + } + }; + +} diff --git a/test/SemaObjC/warn-thread-safety-analysis.m b/test/SemaObjC/warn-thread-safety-analysis.m new file mode 100644 index 000000000000..0e29ff253527 --- /dev/null +++ b/test/SemaObjC/warn-thread-safety-analysis.m @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s + +struct __attribute__ ((lockable)) Mutex {}; + +struct Mutex mu1; + +int Foo_fun1(int i) __attribute__ ((exclusive_locks_required((mu1)))) { + return i; +} + +@interface test +@end + +@implementation test +- (void) PR19541 { + Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}} +} + +@end diff --git a/test/SemaObjC/warn-unreachable.m b/test/SemaObjC/warn-unreachable.m index 832cbd23d27e..366767629d2d 100644 --- a/test/SemaObjC/warn-unreachable.m +++ b/test/SemaObjC/warn-unreachable.m @@ -1,4 +1,4 @@ -// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value -Wno-covered-switch-default +// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default // This previously triggered a warning from -Wunreachable-code because of // a busted CFG. @@ -15,3 +15,70 @@ void test_unreachable() { return; // expected-warning {{will never be executed}} } +#define NO __objc_no +#define YES __objc_yes +#define CONFIG NO + +// Test that 'NO' and 'YES' are not treated as configuration macros. +int test_NO() { + if (NO) + return 1; // expected-warning {{will never be executed}} + else + return 0; +} + +int test_YES() { + if (YES) + return 1; + else + return 0; // expected-warning {{will never be executed}} +} + +int test_CONFIG() { + if (CONFIG) + return 1; + else + return 0; +} + +// FIXME: This should at some point report a warning +// that the loop increment is unreachable. +void test_loop_increment(id container) { + for (id x in container) { // no-warning + break; + } +} + +void calledFun() {} + +// Test "silencing" with parentheses. +void test_with_paren_silencing(int x) { + if (NO) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}} + if ((NO)) calledFun(); // no-warning + + if (YES) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} + calledFun(); + else + calledFun(); // expected-warning {{will never be executed}} + + if ((YES)) + calledFun(); + else + calledFun(); // no-warning + + if (!YES) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} + calledFun(); // expected-warning {{code will never be executed}} + else + calledFun(); + + if ((!YES)) + calledFun(); // no-warning + else + calledFun(); + + if (!(YES)) + calledFun(); // no-warning + else + calledFun(); +} + |