diff options
Diffstat (limited to 'test/SemaObjC')
72 files changed, 1180 insertions, 116 deletions
diff --git a/test/SemaObjC/arc-bridged-cast.m b/test/SemaObjC/arc-bridged-cast.m index 56efe81..b5ec36a 100644 --- a/test/SemaObjC/arc-bridged-cast.m +++ b/test/SemaObjC/arc-bridged-cast.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s typedef const void *CFTypeRef; CFTypeRef CFBridgingRetain(id X); @@ -32,13 +33,32 @@ void to_cf(id obj) { // rdar://problem/9629566 - temporary workaround CFTypeRef cf5 = (__bridge_retain CFTypeRef)CreateSomething(); // expected-error {{unknown cast annotation __bridge_retain; did you mean __bridge_retained?}} + // CHECK: fix-it:"{{.*}}":{35:20-35:35}:"__bridge_retained" } -void fixits() { +CFTypeRef fixits() { id obj1 = (id)CFCreateSomething(); // expected-error{{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} + // expected-note{{use __bridge to convert directly (no change in ownership)}} expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} + // CHECK: fix-it:"{{.*}}":{40:17-40:17}:"CFBridgingRelease(" + // CHECK: fix-it:"{{.*}}":{40:36-40:36}:")" + CFTypeRef cf1 = (CFTypeRef)CreateSomething(); // expected-error{{cast of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \ // expected-note{{use __bridge to convert directly (no change in ownership)}} \ // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}} + // CHECK: fix-it:"{{.*}}":{45:30-45:30}:"CFBridgingRetain(" + // CHECK: fix-it:"{{.*}}":{45:47-45:47}:")" + + return (obj1); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}} + // CHECK: fix-it:"{{.*}}":{51:10-51:10}:"(__bridge CFTypeRef)" + // CHECK: fix-it:"{{.*}}":{51:10-51:10}:"CFBridgingRetain" +} + +CFTypeRef fixitsWithSpace(id obj) { + return(obj); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \ + // expected-note{{use __bridge to convert directly (no change in ownership)}} \ + // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}} + // CHECK: fix-it:"{{.*}}":{59:9-59:9}:"(__bridge CFTypeRef)" + // CHECK: fix-it:"{{.*}}":{59:9-59:9}:" CFBridgingRetain" } diff --git a/test/SemaObjC/arc-cf.m b/test/SemaObjC/arc-cf.m index 69662ea..5754720 100644 --- a/test/SemaObjC/arc-cf.m +++ b/test/SemaObjC/arc-cf.m @@ -10,11 +10,13 @@ id CFBridgingRelease(CFTypeRef); typedef const struct __CFString *CFStringRef; extern CFStringRef CFMakeString0(void); +#pragma clang arc_cf_code_audited begin extern CFStringRef CFCreateString0(void); +#pragma clang arc_cf_code_audited end void test0() { id x; x = (id) CFMakeString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} - x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} + x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}} } extern CFStringRef CFMakeString1(void) __attribute__((cf_returns_not_retained)); @@ -22,7 +24,7 @@ extern CFStringRef CFCreateString1(void) __attribute__((cf_returns_retained)); void test1() { id x; x = (id) CFMakeString1(); - x = (id) CFCreateString1(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} + x = (id) CFCreateString1(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}} } #define CF_AUDIT_BEGIN _Pragma("clang arc_cf_code_audited begin") @@ -40,6 +42,6 @@ void test2() { id x; x = (id) CFMakeString2(); x = (id) CFCreateString2(); - x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} - x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}} + x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}} + x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}} } diff --git a/test/SemaObjC/arc-dict-bridged-cast.m b/test/SemaObjC/arc-dict-bridged-cast.m new file mode 100644 index 0000000..ea64840 --- /dev/null +++ b/test/SemaObjC/arc-dict-bridged-cast.m @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// rdar://11913153 + +typedef const struct __CFString * CFStringRef; +typedef struct __CFString * CFMutableStringRef; +typedef signed long CFIndex; +typedef const struct __CFAllocator * CFAllocatorRef; + +extern const CFStringRef kCFBundleNameKey; + +@protocol NSCopying @end + +@interface NSDictionary +- (id)objectForKeyedSubscript:(id<NSCopying>)key; +@end + +#pragma clang arc_cf_code_audited begin +extern +CFMutableStringRef CFStringCreateMutable(CFAllocatorRef alloc, CFIndex maxLength); +#pragma clang arc_cf_code_audited end + +typedef const void * CFTypeRef; + +id CFBridgingRelease(CFTypeRef __attribute__((cf_consumed)) X); + +@interface NSMutableString @end + +NSMutableString *test() { + NSDictionary *infoDictionary; + infoDictionary[kCFBundleNameKey] = 0; // expected-error {{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} \ + // expected-error {{implicit conversion of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' requires a bridged cast}} \ + // expected-note {{use __bridge to convert directly (no change in ownership)}} \ + // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} + return infoDictionary[CFStringCreateMutable(((void*)0), 100)]; // expected-error {{indexing expression is invalid because subscript type 'CFMutableStringRef' (aka 'struct __CFString *') is not an integral or Objective-C pointer type}} \ + // expected-error {{implicit conversion of C pointer type 'CFMutableStringRef' (aka 'struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' requires a bridged cast}} \ + // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFMutableStringRef' (aka 'struct __CFString *') into ARC}} + +} + +// CHECK: fix-it:"{{.*}}":{31:18-31:18}:"(__bridge __strong id<NSCopying>)(" +// CHECK: fix-it:"{{.*}}":{31:34-31:34}:")" +// CHECK: fix-it:"{{.*}}":{31:18-31:18}:"CFBridgingRelease(" +// CHECK: fix-it:"{{.*}}":{31:34-31:34}:")" +// CHECK: fix-it:"{{.*}}":{35:25-35:25}:"CFBridgingRelease(" +// CHECK: fix-it:"{{.*}}":{35:63-35:63}:")" diff --git a/test/SemaObjC/arc-no-runtime.m b/test/SemaObjC/arc-no-runtime.m index b75064f..c5820d4 100644 --- a/test/SemaObjC/arc-no-runtime.m +++ b/test/SemaObjC/arc-no-runtime.m @@ -3,7 +3,7 @@ // rdar://problem/9150784 void test(void) { __weak id x; // expected-error {{the current deployment target does not support automated __weak references}} - __weak void *v; // expected-warning {{'__weak' only applies to objective-c object or block pointer types}} + __weak void *v; // expected-warning {{'__weak' only applies to Objective-C object or block pointer types}} } @interface A diff --git a/test/SemaObjC/arc-property-lifetime.m b/test/SemaObjC/arc-property-lifetime.m index fad37cc..bd393e0 100644 --- a/test/SemaObjC/arc-property-lifetime.m +++ b/test/SemaObjC/arc-property-lifetime.m @@ -168,3 +168,8 @@ void foo(Baz *f) { f.realy_strong_attr_prop = [[Baz alloc] init]; f.implicit = [[Baz alloc] init]; } + +// rdar://11253688 +@interface Boom +@property (readonly) const void * innerPointer __attribute__((objc_returns_inner_pointer)); // expected-error {{'objc_returns_inner_pointer' attribute only applies to methods}} +@end diff --git a/test/SemaObjC/arc-property.m b/test/SemaObjC/arc-property.m index 2599fb9..41d8e87 100644 --- a/test/SemaObjC/arc-property.m +++ b/test/SemaObjC/arc-property.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -fobjc-exceptions -verify -Wno-objc-root-class %s // rdar://9309489 @interface MyClass { @@ -55,3 +55,11 @@ @implementation Test2 @synthesize test2; @end + +// rdar://problem/11144407 +@interface Test3 +@property (strong) id exception; +@end +void test3(Test3 *t3) { + @throw t3.exception; +} diff --git a/test/SemaObjC/arc-unbridged-cast.m b/test/SemaObjC/arc-unbridged-cast.m index 7d5a6b0..6a39e70 100644 --- a/test/SemaObjC/arc-unbridged-cast.m +++ b/test/SemaObjC/arc-unbridged-cast.m @@ -44,10 +44,10 @@ void test1(int cond) { x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} - x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} - x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} - x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} - x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}} + x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}} + x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}} x = (id) [object property]; x = (id) (cond ? [object property] : (void*) 0); diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index 9c3b298..bd30715 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -641,7 +641,7 @@ void test35(void) { test36_helper(&y); ^{ test36_helper(&y); }(); - __strong int non_objc_type; // expected-warning {{'__strong' only applies to objective-c object or block pointer types}} + __strong int non_objc_type; // expected-warning {{'__strong' only applies to Objective-C object or block pointer types}} } void test36(int first, ...) { @@ -696,3 +696,24 @@ void _NSCalcBeze(NSColor* color, NSColor* bezelColors[]); // expected-error {{mu } @end +// rdar://11814185 +@interface Radar11814185 +@property (nonatomic, weak) Radar11814185* picker1; ++ alloc; +- init; +@end + +@implementation Radar11814185 + +@synthesize picker1; + +- (void)viewDidLoad +{ + picker1 = [[Radar11814185 alloc] init]; // expected-warning {{assigning retained object to weak variable; object will be released after assignment}} + self.picker1 = [[Radar11814185 alloc] init]; // expected-warning {{assigning retained object to weak property; object will be released after assignment}} +} + ++ alloc { return 0; } +- init { return 0; } +@end + diff --git a/test/SemaObjC/assign-rvalue-message.m b/test/SemaObjC/assign-rvalue-message.m index 1105d5e..a90cc50 100644 --- a/test/SemaObjC/assign-rvalue-message.m +++ b/test/SemaObjC/assign-rvalue-message.m @@ -19,6 +19,6 @@ struct Bar { - (void)baz { bar.x = 0; - [self bar].x = 10; // expected-error {{assigning to 'readonly' return result of an objective-c message not allowed}} + [self bar].x = 10; // expected-error {{assigning to 'readonly' return result of an Objective-C message not allowed}} } @end diff --git a/test/SemaObjC/at-defs.m b/test/SemaObjC/at-defs.m index 4c0c586f..73316ca 100644 --- a/test/SemaObjC/at-defs.m +++ b/test/SemaObjC/at-defs.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown -fobjc-fragile-abi %s -fsyntax-only +// RUN: %clang_cc1 -triple i386-unknown-unknown -fobjc-runtime=macosx-fragile-10.5 %s -fsyntax-only @interface Test { double a; diff --git a/test/SemaObjC/attr-availability.m b/test/SemaObjC/attr-availability.m index d857bda..7c9ff0f 100644 --- a/test/SemaObjC/attr-availability.m +++ b/test/SemaObjC/attr-availability.m @@ -1,13 +1,21 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s -@interface A -- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); + +@protocol P +- (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{method 'proto_method' declared here}} +@end + +@interface A <P> +- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{method 'method' declared here}} @end +// rdar://11475360 @interface B : A -- (void)method; +- (void)method; // expected-note {{method 'method' declared here}} @end void f(A *a, B *b) { [a method]; // expected-warning{{'method' is deprecated: first deprecated in Mac OS X 10.2}} - [b method]; + [b method]; // expected-warning {{'method' is deprecated: first deprecated in Mac OS X 10.2}} + [a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in Mac OS X 10.2}} + [b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in Mac OS X 10.2}} } diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m index db0b958..260462a 100644 --- a/test/SemaObjC/attr-deprecated.m +++ b/test/SemaObjC/attr-deprecated.m @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s @interface A { - int X __attribute__((deprecated)); + int X __attribute__((deprecated)); // expected-note 2 {{declared here}} } -+ (void)F __attribute__((deprecated)); -- (void)f __attribute__((deprecated)); ++ (void)F __attribute__((deprecated)); // expected-note 2 {{declared here}} +- (void)f __attribute__((deprecated)); // expected-note 4 {{declared here}} @end @implementation A @@ -42,7 +42,7 @@ @end @protocol P -- (void)p __attribute__((deprecated)); +- (void)p __attribute__((deprecated)); // expected-note {{declared here}} @end void t1(A *a) @@ -71,7 +71,7 @@ void t4(Class c) @interface Bar -@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); +@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{declared here}} - (void) MySetter : (int) value; @end @@ -83,7 +83,7 @@ int t5() { __attribute ((deprecated)) -@interface DEPRECATED { +@interface DEPRECATED { // expected-note 2 {{declared here}} @public int ivar; DEPRECATED *ivar2; // no warning. } @@ -107,7 +107,7 @@ __attribute ((deprecated)) @interface Test2 -@property int test2 __attribute__((deprecated)); +@property int test2 __attribute__((deprecated)); // expected-note 4 {{declared here}} @end void test(Test2 *foo) { @@ -121,3 +121,16 @@ void test(Test2 *foo) { __attribute__((deprecated)) @interface A(Blah) // expected-error{{attributes may not be specified on a category}} @end + + +typedef struct { + int x; +} footype __attribute((deprecated)); // expected-note 2 {{declared here}} + +@interface foo { + footype a; // expected-warning {{'footype' is deprecated}} + footype b __attribute((deprecated)); +} +@property footype c; // expected-warning {{'footype' is deprecated}} +@property footype d __attribute((deprecated)); +@end diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m index 7beec19..9926b08 100644 --- a/test/SemaObjC/blocks.m +++ b/test/SemaObjC/blocks.m @@ -73,3 +73,124 @@ void foo10() { NSLog(@"%@", myBlock); } + +// In C, enum constants have the type of the underlying integer type, not the +// enumeration they are part of. We pretend the constants have enum type when +// they are mixed with other expressions of enum type. +enum CStyleEnum { + CSE_Value = 1 +}; +enum CStyleEnum getCSE(); +typedef enum CStyleEnum (^cse_block_t)(); + +void testCStyleEnumInference(bool arg) { + cse_block_t a; + + // No warnings here. + a = ^{ return getCSE(); }; + + a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} + return 1; + }; + a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} + return CSE_Value; + }; + + // No warnings here. + a = ^{ if (arg) return CSE_Value; else return getCSE(); }; + a = ^{ if (arg) return getCSE(); else return CSE_Value; }; + + // These two blocks actually return 'int' + a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} + if (arg) + return 1; + else + return CSE_Value; + }; + + a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} + if (arg) + return CSE_Value; + else + return 1; + }; +} + + +enum FixedTypeEnum : unsigned { + FTE_Value = 1U +}; +enum FixedTypeEnum getFTE(); +typedef enum FixedTypeEnum (^fte_block_t)(); + +void testFixedTypeEnumInference(bool arg) { + fte_block_t a; + + // No warnings here. + a = ^{ return getFTE(); }; + + // Since we fixed the underlying type of the enum, this is considered a + // compatible block type. + a = ^{ + return 1U; + }; + a = ^{ + return FTE_Value; + }; + + // No warnings here. + a = ^{ if (arg) return FTE_Value; else return FTE_Value; }; + a = ^{ if (arg) return getFTE(); else return getFTE(); }; + a = ^{ if (arg) return FTE_Value; else return getFTE(); }; + a = ^{ if (arg) return getFTE(); else return FTE_Value; }; + + // These two blocks actually return 'unsigned'. + a = ^{ + if (arg) + return 1U; + else + return FTE_Value; + }; + + a = ^{ + if (arg) + return FTE_Value; + else + return 1U; + }; +} + + +enum { + AnonymousValue = 1 +}; + +enum : short { + FixedAnonymousValue = 1 +}; + +typedef enum { + TDE_Value +} TypeDefEnum; +TypeDefEnum getTDE(); + +typedef enum : short { + TDFTE_Value +} TypeDefFixedTypeEnum; +TypeDefFixedTypeEnum getTDFTE(); + +typedef int (^int_block_t)(); +typedef short (^short_block_t)(); +void testAnonymousEnumTypes(int arg) { + int_block_t IB; + IB = ^{ return AnonymousValue; }; + IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; // expected-error {{incompatible block pointer}} + IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; // expected-error {{incompatible block pointer}} + + // Since we fixed the underlying type of the enum, these are considered + // compatible block types anyway. + short_block_t SB; + SB = ^{ return FixedAnonymousValue; }; + SB = ^{ if (arg) return TDFTE_Value; else return getTDFTE(); }; + SB = ^{ if (arg) return getTDFTE(); else return TDFTE_Value; }; +} diff --git a/test/SemaObjC/boxing-illegal-types.m b/test/SemaObjC/boxing-illegal-types.m new file mode 100644 index 0000000..ad45b11 --- /dev/null +++ b/test/SemaObjC/boxing-illegal-types.m @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wattributes %s + +typedef long NSInteger; +typedef unsigned long NSUInteger; +typedef signed char BOOL; + +@interface NSNumber +@end +@interface NSNumber (NSNumberCreation) ++ (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 *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; ++ (NSNumber *)numberWithInteger:(NSInteger)value; ++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; +@end + +typedef struct { + int x, y, z; +} point; + +void testStruct() { + point p = { 0, 0, 0 }; + id boxed = @(p); // expected-error {{illegal type 'point' used in a boxed expression}} +} + +void testPointers() { + void *null = 0; + id boxed_null = @(null); // expected-error {{illegal type 'void *' used in a boxed expression}} + int numbers[] = { 0, 1, 2 }; + id boxed_numbers = @(numbers); // expected-error {{illegal type 'int *' used in a boxed expression}} +} + +void testInvalid() { + @(not_defined); // expected-error {{use of undeclared identifier 'not_defined'}} +} + +enum MyEnum { + ME_foo +}; + +enum ForwE; + +void testEnum(void *p) { + enum MyEnum myen; + id box = @(myen); + box = @(ME_foo); + box = @(*(enum ForwE*)p); // expected-error {{incomplete type 'enum ForwE' used in a boxed expression}} +} diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m index f842278..a7e6965 100644 --- a/test/SemaObjC/category-1.m +++ b/test/SemaObjC/category-1.m @@ -99,3 +99,12 @@ @class I; // expected-note {{forward declaration}} @implementation I(cat) // expected-error{{cannot find interface declaration}} @end + +// <rdar://problem/11478173> +@interface Unrelated +- foo; +@end + +@interface Blah (Blarg) // expected-error{{cannot find interface declaration for 'Blah'}} +- foo; +@end diff --git a/test/SemaObjC/class-bitfield.m b/test/SemaObjC/class-bitfield.m index ae12e04..4b13d9a 100644 --- a/test/SemaObjC/class-bitfield.m +++ b/test/SemaObjC/class-bitfield.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fobjc-fragile-abi -fsyntax-only -verify +// RUN: %clang_cc1 %s -fobjc-runtime=macosx-fragile-10.5 -fsyntax-only -verify @interface X { diff --git a/test/SemaObjC/cocoa-api-usage.m b/test/SemaObjC/cocoa-api-usage.m index 85e2115..bed7ecd 100644 --- a/test/SemaObjC/cocoa-api-usage.m +++ b/test/SemaObjC/cocoa-api-usage.m @@ -1,9 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only -// RUN: cp %s %t.m -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api -// RUN: diff %s.fixed %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -x objective-c %s.fixed -fsyntax-only // RUN: cp %s %t.m // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api // RUN: diff %s.fixed %t.m @@ -82,7 +78,7 @@ typedef signed char BOOL; void foo() { NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} - str = [[NSString alloc] initWithString:@"foo"]; + str = [[NSString alloc] initWithString:@"foo"]; // expected-warning {{redundant}} NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} } diff --git a/test/SemaObjC/cocoa-api-usage.m.fixed b/test/SemaObjC/cocoa-api-usage.m.fixed index 55e060a..f472cf1 100644 --- a/test/SemaObjC/cocoa-api-usage.m.fixed +++ b/test/SemaObjC/cocoa-api-usage.m.fixed @@ -1,9 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only -// RUN: cp %s %t.m -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api -// RUN: diff %s.fixed %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -x objective-c %s.fixed -fsyntax-only // RUN: cp %s %t.m // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api // RUN: diff %s.fixed %t.m @@ -82,7 +78,7 @@ typedef signed char BOOL; void foo() { NSString *str = M(@"foo"); // expected-warning {{redundant}} - str = [[NSString alloc] initWithString:@"foo"]; + str = @"foo"; // expected-warning {{redundant}} NSArray *arr = @[str]; // expected-warning {{redundant}} NSDictionary *dict = @{str: arr}; // expected-warning {{redundant}} } diff --git a/test/SemaObjC/conflicting-ivar-test-1.m b/test/SemaObjC/conflicting-ivar-test-1.m index a7c1d35..a5c09d8 100644 --- a/test/SemaObjC/conflicting-ivar-test-1.m +++ b/test/SemaObjC/conflicting-ivar-test-1.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fobjc-fragile-abi -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.5 -fsyntax-only -verify -Wno-objc-root-class %s @interface INTF { diff --git a/test/SemaObjC/continuation-class-err.m b/test/SemaObjC/continuation-class-err.m index d691f12..ceb8ee9 100644 --- a/test/SemaObjC/continuation-class-err.m +++ b/test/SemaObjC/continuation-class-err.m @@ -11,9 +11,9 @@ @end @interface ReadOnly () -@property(readwrite, copy) id object; // expected-warning {{property attribute in continuation class does not match the primary class}} -@property(readonly) id object1; // expected-error {{illegal redeclaration of property in continuation class 'ReadOnly' (attribute must be 'readwrite', while its primary must be 'readonly')}} -@property (readwrite, assign) int indentLevel; // OK. assign the the default in any case. +@property(readwrite, copy) id object; // expected-warning {{property attribute in class extension does not match the primary class}} +@property(readonly) id object1; // expected-error {{illegal redeclaration of property in class extension 'ReadOnly' (attribute must be 'readwrite', while its primary must be 'readonly')}} +@property (readwrite, assign) int indentLevel; // OK. assign the default in any case. @end @protocol Proto @@ -31,8 +31,8 @@ @end @interface Bar () -@property (copy) id foo; // expected-error {{illegal redeclaration of property in continuation class 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}} -@property (copy) id fee; // expected-error {{illegal redeclaration of property in continuation class 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}} +@property (copy) id foo; // expected-error {{illegal redeclaration of property in class extension 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}} +@property (copy) id fee; // expected-error {{illegal redeclaration of property in class extension 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}} @end @implementation Bar diff --git a/test/SemaObjC/continuation-class-property.m b/test/SemaObjC/continuation-class-property.m index 7d95424..2a8e508 100644 --- a/test/SemaObjC/continuation-class-property.m +++ b/test/SemaObjC/continuation-class-property.m @@ -38,8 +38,8 @@ typedef struct { @end @interface MyClass () -@property (readwrite) NSString *foo; // expected-error {{type of property 'NSString *' in continuation class does not match property type in primary class}} -@property (readwrite, strong) NSRect bar; // expected-error {{type of property 'NSRect' in continuation class does not match property type in primary class}} +@property (readwrite) NSString *foo; // expected-error {{type of property 'NSString *' in class extension does not match property type in primary class}} +@property (readwrite, strong) NSRect bar; // expected-error {{type of property 'NSRect' in class extension does not match property type in primary class}} @end // rdar://10655530 diff --git a/test/SemaObjC/dealloc.m b/test/SemaObjC/dealloc.m new file mode 100644 index 0000000..feafafd --- /dev/null +++ b/test/SemaObjC/dealloc.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// rdar://11987838 + +@protocol NSObject +- dealloc; // expected-error {{return type must be correctly specified as 'void' under ARC, instead of 'id'}} +// CHECK: fix-it:"{{.*}}":{6:3-6:3}:"(void)" +@end + +@protocol Foo <NSObject> @end + +@interface Root <Foo> +@end + +@interface Baz : Root { +} +@end + +@implementation Baz +- (id) dealloc { // expected-error {{return type must be correctly specified as 'void' under ARC, instead of 'id'}} +// CHECK: fix-it:"{{.*}}":{20:5-20:7}:"void" +} + +@end + diff --git a/test/SemaObjC/default-synthesize-1.m b/test/SemaObjC/default-synthesize-1.m index c201e74..5aaca9a 100644 --- a/test/SemaObjC/default-synthesize-1.m +++ b/test/SemaObjC/default-synthesize-1.m @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -Wobjc-missing-property-synthesis -verify -Wno-objc-root-class %s +// rdar://11295716 @interface NSObject - (void) release; @@ -7,21 +8,21 @@ @class NSString; @interface SynthItAll : NSObject -@property int howMany; -@property (retain) NSString* what; +@property int howMany; // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}} +@property (retain) NSString* what; // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}} @end -@implementation SynthItAll +@implementation SynthItAll // expected-note 2 {{detected while default synthesizing properties in class implementation}} //@synthesize howMany, what; @end @interface SynthSetter : NSObject -@property (nonatomic) int howMany; // REM: nonatomic to avoid warnings about only implementing one of the pair -@property (nonatomic, retain) NSString* what; +@property (nonatomic) int howMany; // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}} +@property (nonatomic, retain) NSString* what; // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}} @end -@implementation SynthSetter +@implementation SynthSetter // expected-note 2 {{detected while default synthesizing properties in class implementation}} //@synthesize howMany, what; - (int) howMany { @@ -37,11 +38,11 @@ @interface SynthGetter : NSObject -@property (nonatomic) int howMany; // REM: nonatomic to avoid warnings about only implementing one of the pair -@property (nonatomic, retain) NSString* what; +@property (nonatomic) int howMany; // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}} +@property (nonatomic, retain) NSString* what; // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}} @end -@implementation SynthGetter +@implementation SynthGetter // expected-note 2 {{detected while default synthesizing properties in class implementation}} //@synthesize howMany, what; // - (int) howMany @@ -114,3 +115,12 @@ } @end +@interface rdar11333367 +@property enum A x; // expected-note {{forward declaration of 'enum A'}} expected-note {{property declared here}} +@property struct B y; // expected-note {{forward declaration of 'struct B'}} expected-note {{property declared here}} \ + // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}} +@end +@implementation rdar11333367 // expected-error {{cannot synthesize property 'y' with incomplete type 'struct B'}} \ + // expected-note {{detected while default synthesizing properties in class implementation}} +@synthesize x; // expected-error {{cannot synthesize property 'x' with incomplete type 'enum A'}} +@end diff --git a/test/SemaObjC/default-synthesize-2.m b/test/SemaObjC/default-synthesize-2.m index b95f263..3756413 100644 --- a/test/SemaObjC/default-synthesize-2.m +++ b/test/SemaObjC/default-synthesize-2.m @@ -41,12 +41,13 @@ // Test3 @interface Test3 { - id uid; + id uid; // expected-note {{ivar is declared here}} } -@property (readwrite, assign) id uid; +@property (readwrite, assign) id uid; // expected-note {{property declared here}} @end -@implementation Test3 +// rdar://11671080 +@implementation Test3 // expected-warning {{autosynthesized property 'uid' will use synthesized instance variable '_uid', not existing instance variable 'uid'}} // Oops, forgot to write @synthesize! will be default synthesized - (void) myMethod { self.uid = 0; // Use of the “setter” @@ -114,3 +115,15 @@ int* _object; } @end +// rdar://11671080 +@interface Test8 +{ + id _y; + id y; // expected-note {{ivar is declared here}} +} +@property(copy) id y; // expected-note {{property declared here}} +@end + + +@implementation Test8 @end // expected-warning {{autosynthesized property 'y' will use instance variable '_y', not existing instance variable 'y'}} + diff --git a/test/SemaObjC/delay-parsing-cfunctions.m b/test/SemaObjC/delay-parsing-cfunctions.m new file mode 100644 index 0000000..a6f66fe --- /dev/null +++ b/test/SemaObjC/delay-parsing-cfunctions.m @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -Werror -verify -Wno-objc-root-class %s +// rdar://10387088 + +@interface MyClass +- (void)someMethod; +@end + +@implementation MyClass +- (void)someMethod { + [self privateMethod]; // clang already does not warn here +} + +int bar(MyClass * myObject) { + [myObject privateMethod]; + return gorfbar(myObject); +} +- (void)privateMethod { } + +int gorfbar(MyClass * myObject) { + [myObject privateMethod]; + [myObject privateMethod1]; + return getMe + bar(myObject); +} + +int KR(myObject) +MyClass * myObject; +{ + [myObject privateMethod]; + [myObject privateMethod1]; + return getMe + bar(myObject); +} + +- (void)privateMethod1 { + getMe = getMe+1; +} + +static int getMe; + +static int test() { + return 0; +} + +@end diff --git a/test/SemaObjC/direct-synthesized-ivar-access.m b/test/SemaObjC/direct-synthesized-ivar-access.m index 54b7110..dc14911 100644 --- a/test/SemaObjC/direct-synthesized-ivar-access.m +++ b/test/SemaObjC/direct-synthesized-ivar-access.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wnonfragile-abi2 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify -Wno-objc-root-class %s // rdar://8673791 // rdar://9943851 diff --git a/test/SemaObjC/duplicate-property-class-extension.m b/test/SemaObjC/duplicate-property-class-extension.m index bf48ed6..696768d 100644 --- a/test/SemaObjC/duplicate-property-class-extension.m +++ b/test/SemaObjC/duplicate-property-class-extension.m @@ -9,7 +9,7 @@ @interface Foo () @property (readwrite) char foo; // expected-note 2 {{property declared here}} @property (readwrite) char NewProperty; // expected-note 2 {{property declared here}} -@property (readwrite) char bar; // expected-error{{illegal redeclaration of 'readwrite' property in continuation class 'Foo' (perhaps you intended this to be a 'readwrite' redeclaration of a 'readonly' public property?)}} +@property (readwrite) char bar; // expected-error{{illegal redeclaration of 'readwrite' property in class extension 'Foo' (perhaps you intended this to be a 'readwrite' redeclaration of a 'readonly' public property?)}} @end @interface Foo () diff --git a/test/SemaObjC/error-implicit-property.m b/test/SemaObjC/error-implicit-property.m index ea0587a..7e795c7 100644 --- a/test/SemaObjC/error-implicit-property.m +++ b/test/SemaObjC/error-implicit-property.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -Wno-objc-root-class -verify %s // rdar://11273060 @interface I diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m index 987889b..7faa995 100644 --- a/test/SemaObjC/format-strings-objc.m +++ b/test/SemaObjC/format-strings-objc.m @@ -31,6 +31,12 @@ extern void *_NSConstantStringClassReference; typedef const struct __CFString * CFStringRef; extern void CFStringCreateWithFormat(CFStringRef format, ...) __attribute__((format(CFString, 1, 2))); +#define CFSTR(cStr) ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr "")) + +// This function is used instead of the builtin if -fno-constant-cfstrings. +// The definition on Mac OS X is NOT annotated with format_arg as of 10.8, +// but clang will implicitly add the attribute if it's not written. +extern CFStringRef __CFStringMakeConstantString(const char *); int printf(const char * restrict, ...) ; @@ -52,6 +58,7 @@ void rdar_7068334() { long long test = 500; printf("%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}} NSLog(@"%i ",test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}} + CFStringCreateWithFormat(CFSTR("%i"),test); // expected-warning{{format specifies type 'int' but the argument has type 'long long'}} } // <rdar://problem/7697748> @@ -72,7 +79,7 @@ extern void MyCFStringCreateWithFormat(CFStringRef format, ...) __attribute__((f void check_mylog() { MyNSLog(@"%@"); // expected-warning {{more '%' conversions than data arguments}} - // FIXME: find a way to test CFString too, but I don't know how to create constant CFString. + MyCFStringCreateWithFormat(CFSTR("%@")); // expected-warning {{more '%' conversions than data arguments}} } // PR 10275 - format function attribute isn't checked in Objective-C methods @@ -111,11 +118,20 @@ NSString *test_literal_propagation(void) { } // Do not emit warnings when using NSLocalizedString -extern NSString *GetLocalizedString(NSString *str); -#define NSLocalizedString(key) GetLocalizedString(key) +#include "format-strings-system.h" + +// Test it inhibits diag only for macros in system headers +#define MyNSLocalizedString(key) GetLocalizedString(key) +#define MyNSAssert(fmt, arg) NSLog(fmt, arg, 0, 0) void check_NSLocalizedString() { [Foo fooWithFormat:NSLocalizedString(@"format"), @"arg"]; // no-warning + [Foo fooWithFormat:MyNSLocalizedString(@"format"), @"arg"]; // expected-warning {{format string is not a string literal}}} +} + +void check_NSAssert() { + NSAssert(@"Hello %@", @"World"); // no-warning + MyNSAssert(@"Hello %@", @"World"); // expected-warning {{data argument not used by format string}} } typedef __WCHAR_TYPE__ wchar_t; @@ -150,8 +166,12 @@ void test_percent_C() { } // Test that %@ works with toll-free bridging (<rdar://problem/10814120>). -void test_toll_free_bridging(CFStringRef x) { +void test_toll_free_bridging(CFStringRef x, id y) { NSLog(@"%@", x); // no-warning + CFStringCreateWithFormat(CFSTR("%@"), x); // no-warning + + NSLog(@"%@", y); // no-warning + CFStringCreateWithFormat(CFSTR("%@"), y); // no-warning } @interface Bar @@ -186,3 +206,32 @@ int rdar11049844() { printf("%p", x); // no-warning } +void test_nonBuiltinCFStrings() { + CFStringCreateWithFormat(__CFStringMakeConstantString("%@"), 1); // expected-warning{{format specifies type 'id' but the argument has type 'int'}} +} + + +// Don't crash on an invalid argument expression. +// <rdar://problem/11890818> +@interface NSDictionary : NSObject +- (id)objectForKeyedSubscript:(id)key; +@end + +void testInvalidFormatArgument(NSDictionary *dict) { + NSLog(@"no specifiers", dict[CFSTR("abc")]); // expected-error{{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} + NSLog(@"%@", dict[CFSTR("abc")]); // expected-error{{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} + NSLog(@"%@ %@", dict[CFSTR("abc")]); // expected-error{{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} + + [Foo fooWithFormat:@"no specifiers", dict[CFSTR("abc")]]; // expected-error{{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} + [Foo fooWithFormat:@"%@", dict[CFSTR("abc")]]; // expected-error{{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} + [Foo fooWithFormat:@"%@ %@", dict[CFSTR("abc")]]; // expected-error{{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} expected-warning{{more '%' conversions than data arguments}} +} + + +// <rdar://problem/11825593> +void testByValueObjectInFormat(Foo *obj) { + printf("%d %d %d", 1L, *obj, 1L); // expected-error {{cannot pass object with interface type 'Foo' by value to variadic function; expected type from format string was 'int'}} expected-warning 2 {{format specifies type 'int' but the argument has type 'long'}} + + [Bar log2:@"%d", *obj]; // expected-error {{cannot pass object with interface type 'Foo' by value to variadic method; expected type from format string was 'int'}} +} + diff --git a/test/SemaObjC/format-strings-system.h b/test/SemaObjC/format-strings-system.h new file mode 100644 index 0000000..73b7768 --- /dev/null +++ b/test/SemaObjC/format-strings-system.h @@ -0,0 +1,10 @@ + +#pragma clang system_header + +@class NSString; + +// Do not emit warnings when using NSLocalizedString +extern NSString *GetLocalizedString(NSString *str); +#define NSLocalizedString(key) GetLocalizedString(key) + +#define NSAssert(fmt, arg) NSLog(fmt, arg, 0, 0) diff --git a/test/SemaObjC/getter-setter-defined-in-category-of-parent.m b/test/SemaObjC/getter-setter-defined-in-category-of-parent.m new file mode 100644 index 0000000..71c3237 --- /dev/null +++ b/test/SemaObjC/getter-setter-defined-in-category-of-parent.m @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s + +@interface MyParent { + int X; +} +@end +@implementation MyParent +@end + +@interface MyParent(AA) { +} +@end +@implementation MyParent (AA) +- (void) setX: (int)in {X = in - 2;} +- (int) X {return X;} +@end + +@interface MyClass : MyParent +@end +@implementation MyClass +@end + +int foo(MyClass *o) { + o.X = 2; + return o.X; +}
\ No newline at end of file diff --git a/test/SemaObjC/iboutlet.m b/test/SemaObjC/iboutlet.m new file mode 100644 index 0000000..a29915c --- /dev/null +++ b/test/SemaObjC/iboutlet.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -Wno-objc-root-class -verify %s +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-default-synthesize-properties -Wno-objc-root-class -verify %s +// rdar://11448209 + +#define READONLY readonly + +@class NSView; + +#define IBOutlet __attribute__((iboutlet)) + +@interface I +@property (getter = MyGetter, readonly, assign) IBOutlet NSView *myView; // expected-note {{property declared here}} \ + // expected-note {{readonly IBOutlet property should be changed to be readwrite}} + +@property (readonly) IBOutlet NSView *myView1; // expected-note {{readonly IBOutlet property should be changed to be readwrite}} \ + // expected-note {{property declared here}} + +@property (getter = MyGetter, READONLY) IBOutlet NSView *myView2; // expected-note {{property declared here}} + +@end + +@implementation I // expected-warning 3 {{readonly IBOutlet property when auto-synthesized may not work correctly with 'nib' loader}} +@end diff --git a/test/SemaObjC/id.m b/test/SemaObjC/id.m index 27b84de..ced406e 100644 --- a/test/SemaObjC/id.m +++ b/test/SemaObjC/id.m @@ -16,6 +16,16 @@ void foo() { } // Test attempt to redefine 'id' in an incompatible fashion. -typedef int id; // FIXME: Decide how we want to deal with this (now that 'id' is more of a built-in type). +// rdar://11356439 +typedef int id; // expected-error {{typedef redefinition with different types ('int' vs 'id')}} id b; +typedef double id; // expected-error {{typedef redefinition with different types ('double' vs 'id')}} + +typedef char *id; // expected-error {{typedef redefinition with different types ('char *' vs 'id')}} + +typedef union U{ int iu; } *id; // expected-error {{typedef redefinition with different types ('union U *' vs 'id')}} + +void test11356439(id o) { + o->x; // expected-error {{member reference base type 'id' is not a structure or union}} +} diff --git a/test/SemaObjC/interface-1.m b/test/SemaObjC/interface-1.m index 87c2307..79fbad8 100644 --- a/test/SemaObjC/interface-1.m +++ b/test/SemaObjC/interface-1.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-fragile-abi %s -fsyntax-only -verify +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 %s -fsyntax-only -verify // rdar://5957506 @interface NSWhatever : diff --git a/test/SemaObjC/interface-layout.m b/test/SemaObjC/interface-layout.m index a8a93f0..336605a 100644 --- a/test/SemaObjC/interface-layout.m +++ b/test/SemaObjC/interface-layout.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -triple i386-apple-darwin9 -fobjc-fragile-abi +// RUN: %clang_cc1 %s -fsyntax-only -verify -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 typedef struct objc_object {} *id; typedef signed char BOOL; typedef unsigned int NSUInteger; diff --git a/test/SemaObjC/ivar-in-class-extension-error.m b/test/SemaObjC/ivar-in-class-extension-error.m index cecaa33..b22b798 100644 --- a/test/SemaObjC/ivar-in-class-extension-error.m +++ b/test/SemaObjC/ivar-in-class-extension-error.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fobjc-fragile-abi -fsyntax-only -verify %s +// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.5 -fsyntax-only -verify %s // rdar://6812436 @interface A @end diff --git a/test/SemaObjC/method-bad-param.m b/test/SemaObjC/method-bad-param.m index 9505cb4..d44b536 100644 --- a/test/SemaObjC/method-bad-param.m +++ b/test/SemaObjC/method-bad-param.m @@ -26,7 +26,7 @@ foo somefunc2() {} // expected-error {{interface type 'foo' cannot be returned b // rdar://6780761 void f0(foo *a0) { extern void g0(int x, ...); - g0(1, *(foo*)a0); // expected-error {{cannot pass object with interface type 'foo' by-value through variadic function}} + g0(1, *(foo*)a0); // expected-error {{cannot pass object with interface type 'foo' by value through variadic function}} } // rdar://8421082 diff --git a/test/SemaObjC/method-prototype-scope.m b/test/SemaObjC/method-prototype-scope.m index 0bebd9b..c581500 100644 --- a/test/SemaObjC/method-prototype-scope.m +++ b/test/SemaObjC/method-prototype-scope.m @@ -7,7 +7,7 @@ int object; @class NSString, NSArray; @interface Test -- Func:(int)XXXX, id object; +- Func:(int)XXXX, id object; // expected-warning {{use of C-style parameters in Objective-C method declarations is deprecated}} - doSomethingElseWith:(id)object; @@ -23,7 +23,7 @@ int object; return object; // expected-warning {{incompatible pointer types returning 'NSArray *' from a function with result type 'NSString *'}} } -- Func:(int)XXXX, id object { return object; } +- Func:(int)XXXX, id object { return object; } // expected-warning {{use of C-style parameters in Objective-C method declarations is deprecated}} - doSomethingElseWith:(id)object { return object; } diff --git a/test/SemaObjC/mismatched-undefined-method.m b/test/SemaObjC/mismatched-undefined-method.m new file mode 100644 index 0000000..c41d142 --- /dev/null +++ b/test/SemaObjC/mismatched-undefined-method.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated-declarations -verify %s +// rdar://11460990 + +typedef unsigned int CGDirectDisplayID; + +@interface NSObject @end + +@interface BrightnessAssistant : NSObject {} +- (void)BrightnessAssistantUnregisterForNotifications:(void*) observer; // expected-note {{previous definition is here}} +@end +@implementation BrightnessAssistant // expected-note {{implementation started here}} +- (void)BrightnessAssistantUnregisterForNotifications:(CGDirectDisplayID) displayID, void* observer // expected-warning {{conflicting parameter types in implementation of 'BrightnessAssistantUnregisterForNotifications:': 'void *' vs 'CGDirectDisplayID'}} +@end // expected-error {{expected method body}} // expected-error {{missing '@end'}} diff --git a/test/SemaObjC/narrow-property-type-in-cont-class.m b/test/SemaObjC/narrow-property-type-in-cont-class.m index 3ba848f..0f73b1e 100644 --- a/test/SemaObjC/narrow-property-type-in-cont-class.m +++ b/test/SemaObjC/narrow-property-type-in-cont-class.m @@ -14,6 +14,6 @@ @interface GKTurnBasedMatchMakerKVO () @property(nonatomic,readwrite,retain) NSMutableArray* outline; -@property(nonatomic,readwrite,retain) NSArray* err_outline; // expected-error {{type of property 'NSArray *' in continuation class does not match property type in primary class}} +@property(nonatomic,readwrite,retain) NSArray* err_outline; // expected-error {{type of property 'NSArray *' in class extension does not match property type in primary class}} @end diff --git a/test/SemaObjC/no-ivar-in-interface-block.m b/test/SemaObjC/no-ivar-in-interface-block.m new file mode 100644 index 0000000..215db61 --- /dev/null +++ b/test/SemaObjC/no-ivar-in-interface-block.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class -Wobjc-interface-ivars %s +// rdar://10763173 + +@interface I +{ + @protected int P_IVAR; // expected-warning {{declaration of ivars in the interface is deprecated}} + + @public int PU_IVAR; // expected-warning {{declaration of ivars in the interface is deprecated}} + + @private int PRV_IVAR; // expected-warning {{declaration of ivars in the interface is deprecated}} +} +@end + +@interface I() +{ + int I1; + int I2; +} +@end + +@interface I() +{ + int I3, I4; +} +@end + +@implementation I +{ + int I5; + int I6; +} +@end diff --git a/test/SemaObjC/nowarn-superclass-method-mismatch.m b/test/SemaObjC/nowarn-superclass-method-mismatch.m new file mode 100644 index 0000000..b211cde --- /dev/null +++ b/test/SemaObjC/nowarn-superclass-method-mismatch.m @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -Wsuper-class-method-mismatch -verify %s +// rdar://11793793 + +@class NSString; + +@interface Super +@property (nonatomic) NSString *thingy; +@property () __weak id PROP; +@end + +@interface Sub : Super +@end + +@implementation Sub +- (void)setThingy:(NSString *)val +{ + [super setThingy:val]; +} +@synthesize PROP; +@end diff --git a/test/SemaObjC/nsobject-attribute.m b/test/SemaObjC/nsobject-attribute.m index f41df89..e3f2874 100644 --- a/test/SemaObjC/nsobject-attribute.m +++ b/test/SemaObjC/nsobject-attribute.m @@ -46,9 +46,19 @@ int main(int argc, char *argv[]) { __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}} } // <rdar://problem/10930507> -@property (nonatomic, retain) __attribute__((NSObject)) void * color; // // no-warning +@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}} } +// rdar://11569860 +@interface A { int i; } +@property(retain) __attribute__((NSObject)) int i; // expected-error {{__attribute ((NSObject)) is for pointer types only}} \ + // expected-error {{property with 'retain (or strong)' attribute must be of object type}} +@end + +@implementation A +@synthesize i; +@end + diff --git a/test/SemaObjC/objc-container-subscripting-2.m b/test/SemaObjC/objc-container-subscripting-2.m index 3c0081b..62320fc 100644 --- a/test/SemaObjC/objc-container-subscripting-2.m +++ b/test/SemaObjC/objc-container-subscripting-2.m @@ -16,8 +16,8 @@ typedef unsigned int size_t; id func() { NSMutableArray *array; float f; - array[f] = array; // expected-error {{indexing expression is invalid because subscript type 'float' is not an integral or objective-C pointer type}} - return array[3.14]; // expected-error {{indexing expression is invalid because subscript type 'double' is not an integral or objective-C pointer type}} + array[f] = array; // expected-error {{indexing expression is invalid because subscript type 'float' is not an integral or Objective-C pointer type}} + return array[3.14]; // expected-error {{indexing expression is invalid because subscript type 'double' is not an integral or Objective-C pointer type}} } void test_unused() { diff --git a/test/SemaObjC/objc-container-subscripting-3.m b/test/SemaObjC/objc-container-subscripting-3.m index 5fd1a10..2f716d6 100644 --- a/test/SemaObjC/objc-container-subscripting-3.m +++ b/test/SemaObjC/objc-container-subscripting-3.m @@ -14,7 +14,7 @@ int main() { Test *array; int i = array[10]; // expected-error {{method for accessing array element must have Objective-C object return type instead of 'int'}} - array[2] = i; // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'int' is not an objective-C pointer type}} + array[2] = i; // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'int' is not an Objective-C pointer type}} NSMutableDictionary *dict; id key, val; diff --git a/test/SemaObjC/objc-container-subscripting.m b/test/SemaObjC/objc-container-subscripting.m index 4125bc6..3bbd7d4 100644 --- a/test/SemaObjC/objc-container-subscripting.m +++ b/test/SemaObjC/objc-container-subscripting.m @@ -14,15 +14,15 @@ int main() { NSMutableArray<P> * array; id oldObject = array[10]; // expected-error {{method index parameter type 'double' is not integral type}} array[3] = 0; // expected-error {{method index parameter type 'void *' is not integral type}} \ - // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'id *' is not an objective-C pointer type}} + // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'id *' is not an Objective-C pointer type}} I* iarray; iarray[3] = 0; // expected-error {{expected method to write array element not found on object of type 'I *'}} I* p = iarray[4]; // expected-error {{expected method to read array element not found on object of type 'I *'}} - oldObject = array[10]++; // expected-error {{illegal operation on objective-c container subscripting}} - oldObject = array[10]--; // expected-error {{illegal operation on objective-c container subscripting}} - oldObject = --array[10]; // expected-error {{illegal operation on objective-c container subscripting}} + oldObject = array[10]++; // expected-error {{illegal operation on Objective-C container subscripting}} + oldObject = array[10]--; // expected-error {{illegal operation on Objective-C container subscripting}} + oldObject = --array[10]; // expected-error {{illegal operation on Objective-C container subscripting}} } @interface NSMutableDictionary diff --git a/test/SemaObjC/objc-cstyle-args-in-methods.m b/test/SemaObjC/objc-cstyle-args-in-methods.m index d37b589..ebc7192 100644 --- a/test/SemaObjC/objc-cstyle-args-in-methods.m +++ b/test/SemaObjC/objc-cstyle-args-in-methods.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated-declarations -verify -Wno-objc-root-class %s @interface Foo - (id)test:(id)one, id two; diff --git a/test/SemaObjC/objc-dictionary-literal.m b/test/SemaObjC/objc-dictionary-literal.m index 2acbc39..0b6da4a 100644 --- a/test/SemaObjC/objc-dictionary-literal.m +++ b/test/SemaObjC/objc-dictionary-literal.m @@ -27,7 +27,7 @@ int main() { NSDictionary *dict = @{ @"name":@666 }; dict[@"name"] = @666; - dict["name"] = @666; // expected-error {{indexing expression is invalid because subscript type 'char *' is not an objective-C pointer}} + dict["name"] = @666; // expected-error {{indexing expression is invalid because subscript type 'char *' is not an Objective-C pointer}} return 0; } diff --git a/test/SemaObjC/objc-literal-comparison.m b/test/SemaObjC/objc-literal-comparison.m new file mode 100644 index 0000000..f1aa8ec --- /dev/null +++ b/test/SemaObjC/objc-literal-comparison.m @@ -0,0 +1,96 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=((id)0)" -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=(id)0" -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=0" -verify %s + +// (test the warning flag as well) + +typedef signed char BOOL; + +@interface BaseObject ++ (instancetype)new; +@end + +@interface NSObject : BaseObject +- (BOOL)isEqual:(id)other; +@end + +@interface NSNumber : NSObject ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; +@end + +@interface NSArray : NSObject ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +@interface NSDictionary : NSObject ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +@end + +@interface NSString : NSObject +@end + +void testComparisonsWithFixits(id obj) { + if (obj == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (obj != @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@"" == obj) return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@"" == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + + if (@[] == obj) return; // expected-warning{{direct comparison of an array literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@{} == obj) return; // expected-warning{{direct comparison of a dictionary literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@12 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@1.0 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@__objc_yes == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@(1+1) == obj) return; // expected-warning{{direct comparison of a boxed expression has undefined behavior}} expected-note{{use 'isEqual:' instead}} +} + + +@interface BadEqualReturnString : NSString +- (void)isEqual:(id)other; +@end + +@interface BadEqualArgString : NSString +- (BOOL)isEqual:(int)other; +@end + + +void testComparisonsWithoutFixits() { + if ([BaseObject new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} + + if ([BadEqualReturnString new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} + if ([BadEqualArgString new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} + + if (@"" < @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} + if (@"" > @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} + if (@"" <= @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} + if (@"" >= @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} +} + + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-string-compare" + +void testWarningFlags(id obj) { + if (obj == @"") return; // no-warning + if (@"" == obj) return; // no-warning + + if (obj == @1) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} + if (@1 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} +} + +#pragma clang diagnostic pop + + +void testNilComparison() { + // Don't warn when comparing to nil in a macro. +#define RETURN_IF_NIL(x) if (x == nil || nil == x) return + RETURN_IF_NIL(@""); + RETURN_IF_NIL(@1); + RETURN_IF_NIL(@1.0); + RETURN_IF_NIL(@[]); + RETURN_IF_NIL(@{}); + RETURN_IF_NIL(@__objc_yes); + RETURN_IF_NIL(@(1+1)); +} + diff --git a/test/SemaObjC/objc-literal-nsnumber.m b/test/SemaObjC/objc-literal-nsnumber.m index 6635bea..26bca18 100644 --- a/test/SemaObjC/objc-literal-nsnumber.m +++ b/test/SemaObjC/objc-literal-nsnumber.m @@ -83,3 +83,7 @@ typedef float BOOL; BOOL radar11231426() { return __objc_yes; } + +id stringBoxingNoSuchMethod(const char *str) { + return @(str); // expected-error {{declaration of 'stringWithUTF8String:' is missing in NSString class}} +} diff --git a/test/SemaObjC/objc-literal-sig.m b/test/SemaObjC/objc-literal-sig.m index fb5c79f..86f42d3 100644 --- a/test/SemaObjC/objc-literal-sig.m +++ b/test/SemaObjC/objc-literal-sig.m @@ -16,25 +16,36 @@ typedef _Bool BOOL; + (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; + (NSNumber *)numberWithFloat:(float)value; + (NSNumber *)numberWithDouble:(double)value; -+ (int)numberWithBool:(BOOL)value; // expected-note{{method returns unexpected type 'int' (should be an object type)}} ++ (int)numberWithBool:(BOOL)value; // expected-note 2 {{method returns unexpected type 'int' (should be an object type)}} +@end + +@interface NSString ++ (char)stringWithUTF8String:(const char *)value; // expected-note 2 {{method returns unexpected type 'char' (should be an object type)}} @end @interface NSArray @end @interface NSArray (NSArrayCreation) -+ (id)arrayWithObjects:(const int [])objects // expected-note{{first parameter has unexpected type 'const int *' (should be 'const id *')}} ++ (id)arrayWithObjects:(const int [])objects // expected-note 2 {{first parameter has unexpected type 'const int *' (should be 'const id *')}} count:(unsigned long)cnt; @end @interface NSDictionary + (id)dictionaryWithObjects:(const id [])objects - forKeys:(const int [])keys // expected-note{{second parameter has unexpected type 'const int *' (should be 'const id *')}} + forKeys:(const int [])keys // expected-note 2 {{second parameter has unexpected type 'const int *' (should be 'const id *')}} count:(unsigned long)cnt; @end +// All tests are doubled to make sure that a bad method is not saved +// and then used un-checked. void test_sig() { (void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}} + (void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}} id array = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}} + id array2 = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}} id dict = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}} + id dict2 = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}} + id str = @("hello"); // expected-error{{literal construction method 'stringWithUTF8String:' has incompatible signature}} + id str2 = @("hello"); // expected-error{{literal construction method 'stringWithUTF8String:' has incompatible signature}} } diff --git a/test/SemaObjC/property-10.m b/test/SemaObjC/property-10.m index 51eb39c..8cb8ec6 100644 --- a/test/SemaObjC/property-10.m +++ b/test/SemaObjC/property-10.m @@ -24,7 +24,7 @@ @property(unsafe_unretained, copy, retain) id p4_3; // expected-error {{property attributes 'unsafe_unretained' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'unsafe_unretained' and 'retain' are mutually exclusive}} @property(unsafe_unretained, copy, strong) id s4_3; // expected-error {{property attributes 'unsafe_unretained' and 'copy' are mutually exclusive}}, expected-error {{property attributes 'unsafe_unretained' and 'strong' are mutually exclusive}} -@property id p4; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}} +@property id p4; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-GC object}} @property(nonatomic,copy) int (^includeMailboxCondition)(); @property(nonatomic,copy) int (*includeMailboxCondition2)(); // expected-error {{property with 'copy' attribute must be of object type}} diff --git a/test/SemaObjC/property-12.m b/test/SemaObjC/property-12.m index cd0fccf..c4a7555 100644 --- a/test/SemaObjC/property-12.m +++ b/test/SemaObjC/property-12.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wreadonly-setter-attrs -verify %s @protocol P0 @property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}} @@ -29,4 +29,39 @@ @end +// rdar://11656982 +@interface I0 <P0> @end +@implementation I0 +@synthesize X; +@end + +@interface I1 <P1> @end +@implementation I1 +@synthesize X; +@end + +@interface I2 <P2> @end +@implementation I2 +@synthesize X; +@end + +@interface I3 <P3> @end +@implementation I3 +@synthesize X; +@end + +@interface I4 <P4> @end +@implementation I4 +@synthesize X; +@end + +@interface I5 <P5> @end +@implementation I5 +@synthesize X; +@end + +@interface I6 <P6> @end +@implementation I6 +@synthesize X; +@end diff --git a/test/SemaObjC/property-impl-misuse.m b/test/SemaObjC/property-impl-misuse.m index c3cedb0..939909e 100644 --- a/test/SemaObjC/property-impl-misuse.m +++ b/test/SemaObjC/property-impl-misuse.m @@ -30,7 +30,20 @@ @synthesize gradientStyle = _gradientStyle; - (void)setGradientStyle:(id)value { } -+ (void)_componentCellWithRepresentedObject { - self.gradientStyle; // expected-error {{property 'gradientStyle' not found on object of type 'Class'}} ++ (id)_componentCellWithRepresentedObject { + return self.gradientStyle; } @end + +// rdar://11054153 +@interface rdar11054153 +@property int P; // expected-error {{type of property 'P' ('int') does not match type of accessor 'P' ('void')}} +- (void)P; // expected-note {{declared here}} + +@property int P1; // expected-warning {{type of property 'P1' does not match type of accessor 'P1'}} +- (double) P1; // expected-note {{declared here}} + +@property int P2; // expected-error {{type of property 'P2' ('int') does not match type of accessor 'P2' ('double *')}} +- (double*)P2; // expected-note {{declared here}} + +@end diff --git a/test/SemaObjC/property-ivar-mismatch.m b/test/SemaObjC/property-ivar-mismatch.m index 6abd6e6..a0d1c9d 100644 --- a/test/SemaObjC/property-ivar-mismatch.m +++ b/test/SemaObjC/property-ivar-mismatch.m @@ -12,3 +12,15 @@ @synthesize prop = ivar; // expected-error {{type of property 'prop' ('int') does not match type of ivar 'ivar' ('char')}} @end + +@interface Test5 +{ + void * _P; // expected-note {{ivar is declared here}} +} +@property int P; +@end + +@implementation Test5 +@synthesize P=_P; // expected-error {{ype of property 'P' ('int') does not match type of ivar '_P' ('void *')}} +@end + diff --git a/test/SemaObjC/property-typecheck-1.m b/test/SemaObjC/property-typecheck-1.m index f71e4a0..58d0f21 100644 --- a/test/SemaObjC/property-typecheck-1.m +++ b/test/SemaObjC/property-typecheck-1.m @@ -73,10 +73,10 @@ typedef void (F)(void); NSArray* first; } -@property (readonly) NSArray* pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}} -@property (readonly) NSMutableArray* first; +@property (readonly) NSArray* pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}} +@property (readonly) NSMutableArray* first; -- (NSMutableArray*) pieces; // expected-note {{declared here}} // expected-note {{declared here}} +- (NSMutableArray*) pieces; // expected-note 2 {{declared here}} - (NSArray*) first; @end @@ -95,7 +95,7 @@ typedef void (F)(void); - (id)firstPeice { - return container.first; + return container.first; } @end diff --git a/test/SemaObjC/property-user-setter.m b/test/SemaObjC/property-user-setter.m index 7d4e544..9ebad60 100644 --- a/test/SemaObjC/property-user-setter.m +++ b/test/SemaObjC/property-user-setter.m @@ -102,3 +102,55 @@ int main (void) { abort (); return 0; } + +// rdar://11363363 +@interface rdar11363363 +{ + id R; +} +@property (copy) id p; +@property (copy) id r; +@property (copy) id Q; +@property (copy) id t; // expected-note 2 {{property declared here}} +@property (copy) id T; // expected-note 2 {{property declared here}} +@property (copy) id Pxyz; // expected-note 2 {{property declared here}} +@property (copy) id pxyz; // expected-note 2 {{property declared here}} +@end + +@implementation rdar11363363 +@synthesize p; +@synthesize r; +@synthesize Q; +@synthesize t, T; +@synthesize Pxyz, pxyz; +- (id) Meth { + self.P = 0; + self.q = 0; +// rdar://11528439 + self.t = 0; // expected-error {{synthesized properties 't' and 'T' both claim setter 'setT:'}} + self.T = 0; // expected-error {{synthesized properties 'T' and 't' both claim setter 'setT:'}} + self.Pxyz = 0; // expected-error {{synthesized properties 'Pxyz' and 'pxyz' both claim setter 'setPxyz:'}} + self.pxyz = 0; // expected-error {{synthesized properties 'pxyz' and 'Pxyz' both claim setter 'setPxyz:'}} + self.R = 0; + return self.R; // expected-error {{expected getter method not found on object of type 'rdar11363363 *'}} +} +@end + +// rdar://11499742 +@class BridgeFormatter; + +@interface FMXBridgeFormatter + +@property(assign, readwrite, getter=formatter, setter=setFormatter:) BridgeFormatter* cppFormatter; + +@end + +@implementation FMXBridgeFormatter +@synthesize cppFormatter; + +- (void) dealloc +{ + self.formatter = 0; +} +@end + diff --git a/test/SemaObjC/property.m b/test/SemaObjC/property.m index a948741..d6495b4 100644 --- a/test/SemaObjC/property.m +++ b/test/SemaObjC/property.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-fragile-abi -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -fsyntax-only -verify -Wno-objc-root-class %s @interface I { @@ -6,7 +6,7 @@ int name; } @property int d1; -@property id prop_id; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-gc object}} +@property id prop_id; // expected-warning {{no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed}}, expected-warning {{default property attribute 'assign' not appropriate for non-GC object}} @property int name; @end diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m index 178774c..b2aecc2 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 +__attribute ((deprecated)) @protocol MyProto1 // expected-note 7 {{declared here}} @end @protocol Proto2 <MyProto1> // expected-warning {{'MyProto1' is deprecated}} diff --git a/test/SemaObjC/protocols.m b/test/SemaObjC/protocols.m index ca38f20..eb27341 100644 --- a/test/SemaObjC/protocols.m +++ b/test/SemaObjC/protocols.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated-declarations -verify %s @interface INTF1 @required // expected-error {{directive may only be specified in protocols only}} diff --git a/test/SemaObjC/provisional-ivar-lookup.m b/test/SemaObjC/provisional-ivar-lookup.m index 2ec23a5..7460fc2 100644 --- a/test/SemaObjC/provisional-ivar-lookup.m +++ b/test/SemaObjC/provisional-ivar-lookup.m @@ -36,7 +36,7 @@ @synthesize PROP=PROP; - (void)setPROP:(int)value { - PROP = PROP; // OK + PROP = value; // OK } @end diff --git a/test/SemaObjC/related-result-type-inference.m b/test/SemaObjC/related-result-type-inference.m index 124767c..b1d77dc 100644 --- a/test/SemaObjC/related-result-type-inference.m +++ b/test/SemaObjC/related-result-type-inference.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -Wno-deprecated-declarations -Wno-objc-root-class %s @interface Unrelated @end @@ -178,3 +178,9 @@ void test_inference() { return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}} } @end + +// <rdar://problem/11460990> + +@interface WeirdNSString : NSString +- (id)initWithCString:(const char*)string, void *blah; +@end diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m index 7304b6c..db765b7 100644 --- a/test/SemaObjC/sizeof-interface.m +++ b/test/SemaObjC/sizeof-interface.m @@ -23,7 +23,7 @@ void *g3(I0 *P) { @end // size == 4 -int g1[ sizeof(I0) // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}} +int g1[ sizeof(I0) // expected-error {{application of 'sizeof' to interface 'I0' is not supported on this architecture and platform}} == 4 ? 1 : -1]; @implementation I0 @@ -32,7 +32,7 @@ int g1[ sizeof(I0) // expected-error {{invalid application of 'sizeof' to in // size == 4 (we do not include extended properties in the // sizeof). -int g2[ sizeof(I0) // expected-error {{invalid application of 'sizeof' to interface 'I0' in non-fragile ABI}} +int g2[ sizeof(I0) // expected-error {{application of 'sizeof' to interface 'I0' is not supported on this architecture and platform}} == 4 ? 1 : -1]; @interface I1 @@ -43,7 +43,7 @@ int g2[ sizeof(I0) // expected-error {{invalid application of 'sizeof' to inte @synthesize p0 = _p0; @end -typedef struct { @defs(I1); } I1_defs; // expected-error {{invalid application of @defs in non-fragile ABI}} +typedef struct { @defs(I1); } I1_defs; // expected-error {{use of @defs is not supported on this architecture and platform}} // FIXME: This is currently broken due to the way the record layout we // create is tied to whether we have seen synthesized properties. Ugh. @@ -51,9 +51,9 @@ typedef struct { @defs(I1); } I1_defs; // expected-error {{invalid application o // rdar://6821047 int bar(I0 *P) { - P = P+5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} - P = 5+P; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} - P = P-5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} + P = P+5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size for this architecture and platform}} + P = 5+P; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size for this architecture and platform}} + P = P-5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size for this architecture and platform}} return P[4].x[2]; // expected-error {{expected method to read array element not found on object of type 'I0 *'}} } @@ -64,7 +64,7 @@ int bar(I0 *P) { @interface XCAttributeRunDirectNode { @public - unsigned long attributeRuns[1024 + sizeof(I)]; // expected-error {{invalid application of 'sizeof' to interface 'I' in non-fragile ABI}} + unsigned long attributeRuns[1024 + sizeof(I)]; // expected-error {{application of 'sizeof' to interface 'I' is not supported on this architecture and platform}} int i; } @end @@ -85,6 +85,6 @@ int foo() Foo *f; // Both of these crash clang nicely - ++f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}} - --f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size in non-fragile ABI}} + ++f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size for this architecture and platform}} + --f; // expected-error {{arithmetic on pointer to interface 'Foo', which is not a constant size for this architecture and platform}} } diff --git a/test/SemaObjC/special-dep-unavail-warning.m b/test/SemaObjC/special-dep-unavail-warning.m index 754bf5f..a179647 100644 --- a/test/SemaObjC/special-dep-unavail-warning.m +++ b/test/SemaObjC/special-dep-unavail-warning.m @@ -45,7 +45,7 @@ void test(C *c) { // rdar://10268422 __attribute ((deprecated)) -@interface DEPRECATED +@interface DEPRECATED // expected-note {{declared here}} +(id)new; @end diff --git a/test/SemaObjC/tentative-property-decl.m b/test/SemaObjC/tentative-property-decl.m new file mode 100644 index 0000000..f69ac6d --- /dev/null +++ b/test/SemaObjC/tentative-property-decl.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -Weverything -verify %s +// rdar://11656982 +/** Normally, a property cannot be both 'readonly' and having a "write" 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. +*/ + +@interface Super { +} +@end + +@class NSString; + +@interface MyClass : Super +@property(nonatomic, copy, readonly) NSString *prop; +@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@end + +@interface MyClass () +@property(nonatomic, copy, readwrite) NSString *prop; +@end + +@implementation MyClass +@synthesize prop; +@synthesize warnProp; +@end + + +@protocol P +@property(nonatomic, copy, readonly) NSString *prop; +@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}} +@end + +@interface YourClass : Super <P> +@end + +@interface YourClass () +@property(nonatomic, copy, readwrite) NSString *prop; +@end + +@implementation YourClass +@synthesize prop; +@synthesize warnProp; +@end + diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m index 975b9a9..5c7542b 100644 --- a/test/SemaObjC/unused.m +++ b/test/SemaObjC/unused.m @@ -51,3 +51,5 @@ void test2() { } @end +// rdar://10777111 +static NSString *x = @"hi"; // expected-warning {{unused variable 'x'}} diff --git a/test/SemaObjC/warn-deprecated-implementations.m b/test/SemaObjC/warn-deprecated-implementations.m index 919b221..5f7c2fd 100644 --- a/test/SemaObjC/warn-deprecated-implementations.m +++ b/test/SemaObjC/warn-deprecated-implementations.m @@ -20,7 +20,7 @@ @end __attribute__((deprecated)) -@interface CL // expected-note 2 {{class declared here}} +@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{declared here}} @end @implementation CL // expected-warning {{Implementing deprecated class}} diff --git a/test/SemaObjC/warn-direct-ivar-access.m b/test/SemaObjC/warn-direct-ivar-access.m new file mode 100644 index 0000000..d2295f4 --- /dev/null +++ b/test/SemaObjC/warn-direct-ivar-access.m @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -Wdirect-ivar-access -verify -Wno-objc-root-class %s +// rdar://6505197 + +__attribute__((objc_root_class)) @interface MyObject { +@public + id _myMaster; + id _isTickledPink; + int _myIntProp; +} +@property(retain) id myMaster; +@property(assign) id isTickledPink; // expected-note {{property declared here}} +@property int myIntProp; +@end + +@implementation MyObject + +@synthesize myMaster = _myMaster; +@synthesize isTickledPink = _isTickledPink; // expected-error {{existing ivar '_isTickledPink' for property 'isTickledPink'}} +@synthesize myIntProp = _myIntProp; + +- (void) doSomething { + _myMaster = _isTickledPink; // expected-warning {{instance variable '_myMaster' is being directly accessed}} \ + // expected-warning {{instance variable '_isTickledPink' is being directly accessed}} +} + +- (id) init { + _myMaster=0; + return _myMaster; +} +- (void) dealloc { _myMaster = 0; } +@end + +MyObject * foo () +{ + MyObject* p=0; + p.isTickledPink = p.myMaster; // ok + p->_isTickledPink = (*p)._myMaster; // expected-warning {{instance variable '_isTickledPink' is being directly accessed}} \ + // expected-warning {{instance variable '_myMaster' is being directly accessed}} + if (p->_myIntProp) // expected-warning {{instance variable '_myIntProp' is being directly accessed}} + p->_myIntProp = 0; // expected-warning {{instance variable '_myIntProp' is being directly accessed}} + return p->_isTickledPink; // expected-warning {{instance variable '_isTickledPink' is being directly accessed}} +} + +@interface ITest32 { +@public + id ivar; +} +@end + +id Test32(__weak ITest32 *x) { + __weak ITest32 *y; + x->ivar = 0; // expected-error {{dereferencing a __weak pointer is not allowed}} + return y ? y->ivar // expected-error {{dereferencing a __weak pointer is not allowed}} + : (*x).ivar; // expected-error {{dereferencing a __weak pointer is not allowed}} +} + diff --git a/test/SemaObjC/id-isa-ref.m b/test/SemaObjC/warn-isa-ref.m index c2debb0..1932a02 100644 --- a/test/SemaObjC/id-isa-ref.m +++ b/test/SemaObjC/warn-isa-ref.m @@ -5,6 +5,7 @@ typedef struct objc_object { } *id; @interface NSObject { + id firstobj; struct objc_class *isa; } @end @@ -33,3 +34,50 @@ static void func() { expected-warning{{receiver type 'struct objc_class *' is not 'id' or interface pointer, consider casting it to 'id'}} \ expected-warning{{method '-self' not found (return type defaults to 'id')}} } + +// rdar://11702488 +// If an ivar is (1) the first ivar in a root class and (2) named `isa`, +// then it should get the same warnings that id->isa gets. + +@interface BaseClass { +@public + Class isa; // expected-note 3 {{ivar is declared here}} +} +@end + +@interface OtherClass { +@public + id firstIvar; + Class isa; // note, not first ivar; +} +@end + +@interface Subclass : BaseClass @end + +@interface SiblingClass : BaseClass @end + +@interface Root @end + +@interface hasIsa : Root { +@public + Class isa; // note, isa is not in root class +} +@end + +@implementation Subclass +-(void)method { + hasIsa *u; + id v; + BaseClass *w; + Subclass *x; + SiblingClass *y; + OtherClass *z; + (void)v->isa; // expected-warning {{direct access to objective-c's isa is deprecated}} + (void)w->isa; // expected-warning {{direct access to objective-c's isa is deprecated}} + (void)x->isa; // expected-warning {{direct access to objective-c's isa is deprecated}} + (void)y->isa; // expected-warning {{direct access to objective-c's isa is deprecated}} + (void)z->isa; + (void)u->isa; +} +@end + diff --git a/test/SemaObjC/warn-protocol-method-deprecated.m b/test/SemaObjC/warn-protocol-method-deprecated.m new file mode 100644 index 0000000..928694d --- /dev/null +++ b/test/SemaObjC/warn-protocol-method-deprecated.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s +// rdar://11618852 + +@protocol TestProtocol +- (void)newProtocolMethod; +- (void)deprecatedProtocolMethod __attribute__((deprecated)); // expected-note 2 {{method 'deprecatedProtocolMethod' declared here}} +@end + +@interface NSObject @end + +@interface TestClass : NSObject <TestProtocol> + +- (void)newInstanceMethod; +- (void)deprecatedInstanceMethod __attribute__((deprecated)); // expected-note {{method 'deprecatedInstanceMethod' declared here}} + +@end + +int main(int argc, const char * argv[]) +{ + + TestClass *testObj = (TestClass*)0; + [testObj newInstanceMethod]; + [testObj deprecatedInstanceMethod]; // expected-warning {{'deprecatedInstanceMethod' is deprecated}} + + [testObj newProtocolMethod]; + [testObj deprecatedProtocolMethod]; // expected-warning {{'deprecatedProtocolMethod' is deprecated}} + + id <TestProtocol> testProto = testObj; + [testProto newProtocolMethod]; + [testProto deprecatedProtocolMethod]; // expected-warning {{'deprecatedProtocolMethod' is deprecated}} + return 0; +} diff --git a/test/SemaObjC/arc-retain-block-property.m b/test/SemaObjC/warn-retain-block-property.m index 3b66d14..3a54baf 100644 --- a/test/SemaObjC/arc-retain-block-property.m +++ b/test/SemaObjC/warn-retain-block-property.m @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -fblocks -fobjc-arc -verify -Wno-objc-root-class %s // rdar://9829425 +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify -Wno-objc-root-class %s +// rdar://11761511 extern void doSomething(); diff --git a/test/SemaObjC/weak-receiver-warn.m b/test/SemaObjC/weak-receiver-warn.m index f3955da..547f008 100644 --- a/test/SemaObjC/weak-receiver-warn.m +++ b/test/SemaObjC/weak-receiver-warn.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wreceiver-is-weak -verify %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Wreceiver-is-weak -verify %s // rdar://10225276 @interface Test0 @@ -15,5 +15,66 @@ void test0(Test0 *x) { [weakx addBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} [weakx setBlock: ^{ [x actNow]; }]; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} - weakx.block = ^{ [x actNow]; }; + weakx.block = ^{ [x actNow]; }; // expected-warning {{weak receiver may be unpredictably null in ARC mode}} } + +@interface Test +{ + __weak Test* weak_prop; +} +- (void) Meth; +@property __weak Test* weak_prop; // expected-note {{property declared here}} +@property (weak, atomic) id weak_atomic_prop; // expected-note {{property declared here}} +- (__weak id) P; // expected-note {{method 'P' declared here}} +@end + +@implementation Test +- (void) Meth { + if (self.weak_prop) { + self.weak_prop = 0; + } + if (self.weak_atomic_prop) { + self.weak_atomic_prop = 0; + } + [self.weak_prop Meth]; // expected-warning {{weak property may be unpredictably null in ARC mode}} + id pi = self.P; + + [self.weak_atomic_prop Meth]; // expected-warning {{weak property may be unpredictably null in ARC mode}} + + [self.P Meth]; // expected-warning {{weak implicit property may be unpredictably null in ARC mode}} +} + +- (__weak id) P { return 0; } +@dynamic weak_prop, weak_atomic_prop; +@end + + +@interface MyClass { + __weak MyClass *_parent; +} +@property (weak) MyClass *parent; // expected-note 2 {{property declared here}} +@end + +@implementation MyClass +@synthesize parent = _parent; + +- (void)doSomething +{ + [[self parent] doSomething]; // expected-warning {{weak property may be unpredictably null in ARC mode}} + + (void)self.parent.doSomething; // expected-warning {{weak property may be unpredictably null in ARC mode}} +} + +@end + + +// Weak properties on protocols can be synthesized by an adopting class. +@protocol MyProtocol +@property (weak) id object; // expected-note 2 {{property declared here}} +@end + +void testProtocol(id <MyProtocol> input) { + [[input object] Meth]; // expected-warning {{weak property may be unpredictably null in ARC mode}} + [input.object Meth]; // expected-warning {{weak property may be unpredictably null in ARC mode}} +} + |