diff options
| author | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 | 
|---|---|---|
| committer | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 | 
| commit | be1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch) | |
| tree | 1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/test/ARCMT/checking.m | |
| parent | c4626a62754862d20b41e8a46a3574264ea80e6d (diff) | |
| parent | f1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff) | |
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/test/ARCMT/checking.m')
| -rw-r--r-- | clang/test/ARCMT/checking.m | 327 | 
1 files changed, 327 insertions, 0 deletions
diff --git a/clang/test/ARCMT/checking.m b/clang/test/ARCMT/checking.m new file mode 100644 index 0000000..cf71611 --- /dev/null +++ b/clang/test/ARCMT/checking.m @@ -0,0 +1,327 @@ +// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 %s +// DISABLE: mingw32 + +#if __has_feature(objc_arc) +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) +#else +#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE +#endif + +typedef const void * CFTypeRef; +CFTypeRef CFBridgingRetain(id X); +id CFBridgingRelease(CFTypeRef); + +typedef int BOOL; +typedef unsigned NSUInteger; + +@protocol NSObject +- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; +@end + +@interface NSObject <NSObject> {} +- (id)init; + ++ (id)new; ++ (id)alloc; +- (void)dealloc; + +- (void)finalize; + +- (id)copy; +- (id)mutableCopy; +@end + +typedef const struct __CFString * CFStringRef; +extern const CFStringRef kUTTypePlainText; +extern const CFStringRef kUTTypeRTF; +@class NSString; +@class A; + +struct UnsafeS { +  A *__unsafe_unretained unsafeObj; +}; + +@interface A : NSObject +- (id)retain; +- (id)retainCount; +- (id)autorelease; +- (id)init; +- (oneway void)release; +- (void)dealloc; +-(void)test; +-(id)delegate; +@end + +@implementation A +-(void)test { +  [super dealloc]; +} +-(void)dealloc { +  [super dealloc]; +} + +- (id)retain { return self; } // expected-error {{ARC forbids implementation}} +- (id)retainCount { return self; } // expected-error {{ARC forbids implementation}} +- (id)autorelease { return self; } // expected-error {{ARC forbids implementation}} +- (oneway void)release { } // expected-error {{ARC forbids implementation}} + +-(id)delegate { return self; } +@end + +id global_foo; + +void test1(A *a, BOOL b, struct UnsafeS *unsafeS) { +  [[a delegate] release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ +                          // expected-error {{ARC forbids explicit message send}} +  [a.delegate release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ +                        // expected-error {{ARC forbids explicit message send}} +  [unsafeS->unsafeObj retain]; // expected-error {{it is not safe to remove 'retain' message on an __unsafe_unretained type}} \ +                               // expected-error {{ARC forbids explicit message send}} +  id foo = [unsafeS->unsafeObj retain]; // no warning. +  [global_foo retain]; // expected-error {{it is not safe to remove 'retain' message on a global variable}} \ +                       // expected-error {{ARC forbids explicit message send}} +  [global_foo release]; // expected-error {{it is not safe to remove 'release' message on a global variable}} \ +                        // expected-error {{ARC forbids explicit message send}} +  [a dealloc]; +  [a retain]; +  [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} +  [a release]; +  [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ +                   // expected-error {{ARC forbids explicit message send}} + +  CFStringRef cfstr; +  NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' 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}} \ +  str = (NSString *)kUTTypePlainText; +  str = b ? kUTTypeRTF : kUTTypePlainText; +  str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); +  str = (NSString *)a; // no change. + +  SEL s = @selector(retain);  // expected-error {{ARC forbids use of 'retain' in a @selector}} +  s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} +  s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} +  s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} + +  static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}} +} + +struct S { +  A* a; // expected-error {{ARC forbids Objective-C objects in structs or unions}} +}; + +@interface B +-(id)alloc; +- (id)initWithInt: (int) i; +@end + +void rdar8861761() { +  B *o1 = [[B alloc] initWithInt:0]; +  B *o2 = [B alloc]; +  [o2 initWithInt:0]; +} + +@interface Test13 +- (id) init0; +- (void) noninit; +@end +@implementation Test13 +- (id) init0 { +  self = 0; +} +- (void) noninit { +  self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} + +  for (id x in collection) { // expected-error {{use of undeclared identifier 'collection'}} +    x = 0; +  } +} +@end + +void * cvt(id arg) +{ +  void* voidp_val; +  (void)(int*)arg; // expected-error {{disallowed}} +  (void)(id)arg; +  (void)(__autoreleasing id*)arg; // expected-error {{disallowed}} +  (void)(id*)arg; // expected-error {{disallowed}} + +  (void)(__autoreleasing id**)voidp_val; +  (void)(void*)voidp_val; +  (void)(void**)arg; // expected-error {{disallowed}} +  cvt((void*)arg); // expected-error 2 {{requires a bridged cast}} \ +                   // expected-note 2 {{use __bridge to}} expected-note {{use CFBridgingRelease call}} expected-note {{use CFBridgingRetain call}} +  cvt(0); +  (void)(__strong id**)(0); +  return arg; // expected-error {{requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} +} + + +void test12(id collection) { +  for (id x in collection) { +    x = 0; +  } + +  for (__strong id x in collection) { +    x = 0; +  } +} + +void test6(unsigned cond) { +  // FIXME: Fix this automatically ? +  switch (cond) { +  case 0: +    ; +    id x; // expected-note {{jump bypasses initialization of retaining variable}} + +  case 1: // expected-error {{switch case is in protected scope}} +    break; +  } +} + +@class Test8_incomplete; +@interface Test8_complete @end; +@interface Test8_super @end; +@interface Test8 : Test8_super +- (id) init00; +- (id) init01; // expected-note {{declaration in interface}} +- (id) init02; +- (id) init03; // covariance +- (id) init04; // covariance +- (id) init05; + +- (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init11; +- (void) init12; +- (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} +- (void) init15; + +// These should be invalid to actually call. +- (Test8_incomplete*) init20; +- (Test8_incomplete*) init21; // expected-note {{declaration in interface}} +- (Test8_incomplete*) init22; +- (Test8_incomplete*) init23; +- (Test8_incomplete*) init24; +- (Test8_incomplete*) init25; + +- (Test8_super*) init30; // id exception to covariance +- (Test8_super*) init31; // expected-note {{declaration in interface}} +- (Test8_super*) init32; +- (Test8_super*) init33; +- (Test8_super*) init34; // covariance +- (Test8_super*) init35; + +- (Test8*) init40; // id exception to covariance +- (Test8*) init41; // expected-note {{declaration in interface}} +- (Test8*) init42; +- (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing +- (Test8*) init44; +- (Test8*) init45; + +- (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} +@end +@implementation Test8 +- (id) init00 { return 0; } +- (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (id) init20 { return 0; } +- (id) init30 { return 0; } +- (id) init40 { return 0; } +- (id) init50 { return 0; } + +- (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init11 {} +- (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} +- (void) init51 {} + +- (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} + +- (Test8_super*) init03 { return 0; } +- (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8_super*) init23 { return 0; } +- (Test8_super*) init33 { return 0; } +- (Test8_super*) init43 { return 0; } +- (Test8_super*) init53 { return 0; } + +- (Test8*) init04 { return 0; } +- (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} +- (Test8*) init24 { return 0; } +- (Test8*) init34 { return 0; } +- (Test8*) init44 { return 0; } +- (Test8*) init54 { return 0; } + +- (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +- (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} +@end + +@class Test9_incomplete; +@interface Test9 +- (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} +- (Test9_incomplete*) init2; +@end +id test9(Test9 *v) { +  return [v init1]; +} + +// rdar://9491791 +void rdar9491791(int p) { +  switch (p) { +  case 3:; +    NSObject *o = [[NSObject alloc] init]; // expected-note {{jump bypasses initialization of retaining variable}} +    [o release]; +    break; +  default: // expected-error {{switch case is in protected scope}} +    break; +  } +} + +#define RELEASE_MACRO(x) do { [x release]; } while(1) + +// rdar://9504750 +void rdar9504750(id p) { +  RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} +} + +// rdar://8939557 +@interface TestReadonlyProperty : NSObject +@property(assign,readonly) NSObject *value; +@end + +@implementation TestReadonlyProperty +@synthesize value; +- (void)viewDidLoad { +  value = [NSObject new]; // expected-error {{assigning retained object}} +} +@end + +// rdar://9601437 +@interface I9601437 { +  __unsafe_unretained id x; +} +-(void)Meth; +@end + +@implementation I9601437 +-(void)Meth { +  self->x = [NSObject new]; // expected-error {{assigning retained object}} +} +@end  | 
