diff options
Diffstat (limited to 'test/SemaObjC')
-rw-r--r-- | test/SemaObjC/arc-peformselector.m | 12 | ||||
-rw-r--r-- | test/SemaObjC/arc-repeated-weak.mm | 21 | ||||
-rw-r--r-- | test/SemaObjC/arc-unavailable-for-weakref.m | 1 | ||||
-rw-r--r-- | test/SemaObjC/arc.m | 32 | ||||
-rw-r--r-- | test/SemaObjC/attr-deprecated.m | 12 | ||||
-rw-r--r-- | test/SemaObjC/category-attribute.m | 23 | ||||
-rw-r--r-- | test/SemaObjC/class-message-protocol-lookup.m | 27 | ||||
-rw-r--r-- | test/SemaObjC/default-synthesize-3.m | 4 | ||||
-rw-r--r-- | test/SemaObjC/objc-class-property.m | 9 | ||||
-rw-r--r-- | test/SemaObjC/property-typecheck-1.m | 5 | ||||
-rw-r--r-- | test/SemaObjC/special-dep-unavail-warning.m | 4 | ||||
-rw-r--r-- | test/SemaObjC/unsafe-perform-selector.m | 127 | ||||
-rw-r--r-- | test/SemaObjC/warn-deprecated-implementations.m | 11 |
13 files changed, 275 insertions, 13 deletions
diff --git a/test/SemaObjC/arc-peformselector.m b/test/SemaObjC/arc-peformselector.m index dec09e33ed68..a7e5d3e8239e 100644 --- a/test/SemaObjC/arc-peformselector.m +++ b/test/SemaObjC/arc-peformselector.m @@ -8,6 +8,7 @@ - (id) init __attribute__((ns_returns_not_retained)); - (id)PlusZero; - (id)PlusOne __attribute__((ns_returns_retained)); // expected-note {{method 'PlusOne' declared here}} +- (id)self; @end @interface I : NSObject @@ -17,6 +18,9 @@ - (id)performSelector:(SEL)aSelector; - (id)performSelector:(SEL)aSelector withObject:(id)object; - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; + +- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes; + @end @implementation I @@ -27,12 +31,20 @@ return [self performSelector : @selector(init)]; return [self performSelector : sel1]; // expected-warning {{performSelector may cause a leak because its selector is unknown}} \ // expected-note {{used here}} + return [self performSelector: (@selector(PlusZero))]; return [self performSelector : @selector(PlusZero)]; return [self performSelector : @selector(PlusOne)]; // expected-error {{performSelector names a selector which retains the object}} + + // Avoid the unkown selector warning for more complicated performSelector + // variations because it produces too many false positives. + [self performSelector: sel1 withObject:0 afterDelay:0 inModes:0]; + + return [self performSelector: @selector(self)]; // No error, -self is not +1! } - (id)performSelector:(SEL)aSelector { return 0; } - (id)performSelector:(SEL)aSelector withObject:(id)object { return 0; } - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2 { return 0; } +- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes { } @end diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm index 11161a0bf7fc..37b2123ec1c4 100644 --- a/test/SemaObjC/arc-repeated-weak.mm +++ b/test/SemaObjC/arc-repeated-weak.mm @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s @interface Test { @public @@ -445,8 +446,8 @@ void doubleLevelAccessIvar(Test *a, Test *b) { @class NSString; @interface NSBundle +(NSBundle *)foo; -@property (class) NSBundle *foo2; -@property NSString *prop; +@property (class, strong) NSBundle *foo2; +@property (strong) NSString *prop; @property(weak) NSString *weakProp; @end @@ -462,3 +463,19 @@ void foo() { use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}} } + +// This used to crash in the constructor of WeakObjectProfileTy when a +// DeclRefExpr was passed that didn't reference a VarDecl. + +typedef INTF * INTFPtrTy; + +enum E { + e1 +}; + +void foo1() { + INTFPtrTy tmp = (INTFPtrTy)e1; +#if __has_feature(objc_arc) +// expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}} +#endif +} diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m index 82748027435e..c59616819930 100644 --- a/test/SemaObjC/arc-unavailable-for-weakref.m +++ b/test/SemaObjC/arc-unavailable-for-weakref.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-weak -verify -Wno-objc-root-class %s // rdar://9693477 __attribute__((objc_arc_weak_reference_unavailable)) diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index f463bb03b075..e90d0a87e311 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class -Wblock-capture-autoreleasing %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s +// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s typedef unsigned long NSUInteger; typedef const void * CFTypeRef; @@ -809,9 +810,36 @@ int garf() { TKAssertEqual(object, (id)nil); } -void block_capture_autoreleasing(A * __autoreleasing *a, A **b) { // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} +void block_capture_autoreleasing(A * __autoreleasing *a, + A **b, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} + A * _Nullable *c, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} + A * _Nullable __autoreleasing *d, + A ** _Nullable e, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} + A * __autoreleasing * _Nullable f, + id __autoreleasing *g, + id *h, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} + id _Nullable *i, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} + id _Nullable __autoreleasing *j, + id * _Nullable k, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}} + id __autoreleasing * _Nullable l) { + // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:37-[[@LINE-11]]:37}:" __autoreleasing " + // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:47-[[@LINE-11]]:47}:" __autoreleasing" + // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:37-[[@LINE-10]]:37}:" __autoreleasing " + // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:36-[[@LINE-8]]:36}:" __autoreleasing" + // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:46-[[@LINE-8]]:46}:" __autoreleasing" + // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:36-[[@LINE-7]]:36}:" __autoreleasing" ^{ (void)*a; (void)*b; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} + (void)*c; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} + (void)*d; + (void)*e; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} + (void)*f; + (void)*g; + (void)*h; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} + (void)*i; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} + (void)*j; + (void)*k; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}} + (void)*l; }(); } diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m index 59087bdf1154..b0613851ddaa 100644 --- a/test/SemaObjC/attr-deprecated.m +++ b/test/SemaObjC/attr-deprecated.m @@ -83,8 +83,8 @@ int t5() { } -__attribute ((deprecated)) -@interface DEPRECATED { // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}} +__attribute ((deprecated)) // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}} +@interface DEPRECATED { @public int ivar; DEPRECATED *ivar2; // no warning. } @@ -121,9 +121,15 @@ void test(Test2 *foo) { } __attribute__((deprecated)) -@interface A(Blah) // expected-error{{attributes may not be specified on a category}} +@interface A(Blah) // no warning +- (A*)getA; @end +@implementation A(Blah) // Don't warn by default +- (A*)getA { + return self; +} +@end typedef struct { int x; diff --git a/test/SemaObjC/category-attribute.m b/test/SemaObjC/category-attribute.m new file mode 100644 index 000000000000..7efe3df00ec8 --- /dev/null +++ b/test/SemaObjC/category-attribute.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +__attribute__ ((external_source_symbol(language= "Swift", defined_in="A"))) +@interface TestInterface +@end +// CHECK: ObjCInterfaceDecl {{.*}} TestInterface +// CHECK-NEXT: ExternalSourceSymbolAttr + +__attribute__ ((external_source_symbol(language= "Swift", defined_in="B"))) +@interface TestInterface () +@end +// CHECK: ObjCCategoryDecl +// CHECK-NEXT: ObjCInterface +// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "B" + +__attribute__ ((external_source_symbol(language= "Swift", defined_in="C"))) +@interface TestInterface (Category) +@end +// CHECK: ObjCCategoryDecl +// CHECK-NEXT: ObjCInterface +// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "C" diff --git a/test/SemaObjC/class-message-protocol-lookup.m b/test/SemaObjC/class-message-protocol-lookup.m index 37df7a641673..d9f954dc473d 100644 --- a/test/SemaObjC/class-message-protocol-lookup.m +++ b/test/SemaObjC/class-message-protocol-lookup.m @@ -32,3 +32,30 @@ int main () Class<Test2Protocol> c2 = [c2 alloc]; // ok return 0; } + +// rdar://22812517 + +@protocol NSObject + +- (int)respondsToSelector:(SEL)aSelector; + +@end + +__attribute__((objc_root_class)) +@interface NSObject <NSObject> + +@end + +@protocol OtherProto + +- (void)otherInstanceMethod; // expected-note {{method 'otherInstanceMethod' declared here}} + +@end + +@protocol MyProto <NSObject, OtherProto> +@end + +void allowInstanceMethodsFromRootProtocols(Class<MyProto> c) { + [c respondsToSelector: @selector(instanceMethod)]; // no warning + [c otherInstanceMethod]; // expected-warning {{instance method 'otherInstanceMethod' found instead of class method 'otherInstanceMethod'}} +} diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m index dce9edabb90d..fe2b35f61523 100644 --- a/test/SemaObjC/default-synthesize-3.m +++ b/test/SemaObjC/default-synthesize-3.m @@ -33,8 +33,8 @@ __attribute ((objc_requires_property_definitions)) // redundant, just for testi - (id) DeepMustSynthProperty { return 0; } @end -__attribute ((objc_requires_property_definitions)) -@interface Deep(CAT) // expected-error {{attributes may not be specified on a category}} +__attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}} +@interface Deep(CAT) @end __attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}} diff --git a/test/SemaObjC/objc-class-property.m b/test/SemaObjC/objc-class-property.m index 56285976e194..f8d49112766d 100644 --- a/test/SemaObjC/objc-class-property.m +++ b/test/SemaObjC/objc-class-property.m @@ -21,6 +21,8 @@ @property (class) int c2; // expected-note {{property declared here}} \ // expected-note {{property declared here}} @property (class) int x; +@property (class, setter=customSet:) int customSetterProperty; +@property (class, getter=customGet) int customGetterProperty; @end @implementation A // expected-warning {{class property 'c2' requires method 'c2' to be defined}} \ @@ -29,6 +31,8 @@ @dynamic (class) x; // refers to the class property @synthesize z, c2; // expected-error {{@synthesize not allowed on a class property 'c2'}} @dynamic c; // refers to the class property +@dynamic customSetterProperty; +@dynamic customGetterProperty; @end int test() { @@ -37,6 +41,11 @@ int test() { return a.x + A.c; } +void customSelectors() { + A.customSetterProperty = 1; + (void)A.customGetterProperty; +} + void message_id(id me) { [me y]; } diff --git a/test/SemaObjC/property-typecheck-1.m b/test/SemaObjC/property-typecheck-1.m index 5fb05c8bd384..85e8d4624be1 100644 --- a/test/SemaObjC/property-typecheck-1.m +++ b/test/SemaObjC/property-typecheck-1.m @@ -78,6 +78,11 @@ typedef void (F)(void); - (NSMutableArray*) pieces; // expected-note 2 {{declared here}} - (NSArray*) first; + +// Don't warn about setter-like methods for readonly properties. +- (void)setFirst:(char)val; +- (void)setPieces:(char)val; + @end @interface Class2 { diff --git a/test/SemaObjC/special-dep-unavail-warning.m b/test/SemaObjC/special-dep-unavail-warning.m index 9e16b331c23c..b667c3c51c9d 100644 --- a/test/SemaObjC/special-dep-unavail-warning.m +++ b/test/SemaObjC/special-dep-unavail-warning.m @@ -44,8 +44,8 @@ void test(C *c) { } // rdar://10268422 -__attribute ((deprecated)) -@interface DEPRECATED // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}} +__attribute ((deprecated)) // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}} +@interface DEPRECATED +(id)new; @end diff --git a/test/SemaObjC/unsafe-perform-selector.m b/test/SemaObjC/unsafe-perform-selector.m new file mode 100644 index 000000000000..661ff363603f --- /dev/null +++ b/test/SemaObjC/unsafe-perform-selector.m @@ -0,0 +1,127 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s +// rdar://12056271 + +@class Thread; + +__attribute__((objc_root_class)) +@interface NSObject + +- (id)performSelector:(SEL)sel; +- (void)performSelectorInBackground:(SEL)sel withObject:(id)arg; +- (void)performSelectorOnMainThread:(SEL)sel; + +- (void)performSelectorOnMainThread:(SEL)aSelector + onThread:(Thread *)thread + withObject:(id)arg + waitUntilDone:(int)wait + modes:(id *)array; + +@end + +typedef struct { int x; int y; int width; int height; } Rectangle; + +struct Struct { Rectangle r; }; + +typedef union { int x; float f; } Union; + +@interface Base : NSObject + +- (struct Struct)returnsStruct2; // expected-note {{method 'returnsStruct2' that returns 'struct Struct' declared here}} +- (Union)returnsId; + +@end + +@protocol IP + +- (Union)returnsUnion; // expected-note 2 {{method 'returnsUnion' that returns 'Union' declared here}} + +@end + +typedef __attribute__((__ext_vector_type__(3))) float float3; +typedef int int4 __attribute__ ((vector_size (16))); + +@interface I : Base<IP> + +- (Rectangle)returnsStruct; // expected-note 4 {{method 'returnsStruct' that returns 'Rectangle' declared here}} +- (id)returnsId; // shadows base 'returnsId' +- (int)returnsInt; +- (I *)returnPtr; +- (float3)returnsExtVector; // expected-note {{method 'returnsExtVector' that returns 'float3' (vector of 3 'float' values) declared here}} +- (int4)returnsVector; // expected-note {{method 'returnsVector' that returns 'int4' (vector of 4 'int' values) declared here}} + ++ (Rectangle)returnsStructClass; // expected-note 2 {{method 'returnsStructClass' that returns 'Rectangle' declared here}} ++ (void)returnsUnion; // Not really + +@end + +void foo(I *i) { + [i performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} + [i performSelectorInBackground: @selector(returnsStruct) withObject:0]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a struct type}} + [i performSelector: ((@selector(returnsUnion)))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a union type}} + [i performSelectorOnMainThread: @selector(returnsStruct2)]; // expected-warning {{'performSelectorOnMainThread:' is incompatible with selectors that return a struct type}} + [I performSelector: (@selector(returnsStructClass))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} + + [i performSelector: @selector(returnsId)]; + [i performSelector: @selector(returnsInt)]; + [i performSelector: @selector(returnsPtr)]; + [I performSelector: @selector(returnsUnion)]; // No warning expected + + id obj = i; + [obj performSelector: @selector(returnsId)]; + [obj performSelector: @selector(returnsStruct)]; +} + +@interface SubClass: I + +@end + +@interface SubClass () +- (struct Struct)returnsSubStructExt; // expected-note {{method 'returnsSubStructExt' that returns 'struct Struct' declared here}} expected-note {{method 'returnsSubStructExt' declared here}} +@end + +@implementation SubClass // expected-warning {{method definition for 'returnsSubStructExt' not found}} + +- (struct Struct)returnsSubStructImpl { // expected-note {{method 'returnsSubStructImpl' that returns 'struct Struct' declared here}} + struct Struct Result; + return Result; +} + +- (void)checkPrivateCalls { + [self performSelector: @selector(returnsSubStructExt)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} + [self performSelector: @selector(returnsSubStructImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} +} + +- (void)checkSuperCalls { + [super performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} + [super performSelectorInBackground: @selector(returnsUnion) withObject: self]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a union type}} + [super performSelector: @selector(returnsId)]; +} + ++ (struct Struct)returnsSubStructClassImpl { // expected-note {{method 'returnsSubStructClassImpl' that returns 'struct Struct' declared here}} + struct Struct Result; + return Result; +} + ++ (void)checkClassPrivateCalls { + [self performSelector: @selector(returnsSubStructClassImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} +} + ++ (void)checkClassSuperCalls { + [super performSelector: @selector(returnsStructClass)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}} + [super performSelector: @selector(returnsUnion)]; // No warning expected +} + +@end + +@implementation I (LongPerformSelectors) + +- (void)checkLongCallsFromCategory { + [self performSelectorOnMainThread: @selector(returnsStruct) onThread:0 withObject:self waitUntilDone:1 modes:0]; // expected-warning {{'performSelectorOnMainThread:onThread:withObject:waitUntilDone:modes:' is incompatible with selectors that return a struct type}} +} + +- (void)checkVectorReturn { + [self performSelector: @selector(returnsExtVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}} + [self performSelector: @selector(returnsVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}} +} + +@end diff --git a/test/SemaObjC/warn-deprecated-implementations.m b/test/SemaObjC/warn-deprecated-implementations.m index 6e208b5be795..0c341165b0f0 100644 --- a/test/SemaObjC/warn-deprecated-implementations.m +++ b/test/SemaObjC/warn-deprecated-implementations.m @@ -28,8 +28,8 @@ - (void) G {} // No warning, implementing its own deprecated method @end -__attribute__((deprecated)) -@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{'CL' has been explicitly marked deprecated here}} +__attribute__((deprecated)) // expected-note 2 {{'CL' has been explicitly marked deprecated here}} +@interface CL // expected-note 2 {{class declared here}} @end @implementation CL // expected-warning {{Implementing deprecated class}} @@ -65,3 +65,10 @@ __attribute__((deprecated)) return (void *)0; } @end + +__attribute__((deprecated)) +@interface Test(DeprecatedCategory) // expected-note {{category declared here}} +@end + +@implementation Test(DeprecatedCategory) // expected-warning {{Implementing deprecated category}} +@end |