diff options
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Analysis/retain-release-arc.m | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/clang/test/Analysis/retain-release-arc.m b/clang/test/Analysis/retain-release-arc.m index e27f519ea69..616e00917fd 100644 --- a/clang/test/Analysis/retain-release-arc.m +++ b/clang/test/Analysis/retain-release-arc.m @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fobjc-arc -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text +typedef __typeof(sizeof(int)) size_t; + #define HAS_ARC __has_feature(objc_arc) typedef unsigned long long CFOptionFlags; @@ -45,6 +47,41 @@ typedef struct _NSZone NSZone; @interface NSDictionary : NSObject @end +#define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__)) +#define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED + +@protocol OS_dispatch_object +@end +@protocol OS_dispatch_data <OS_dispatch_object> +@end +@protocol OS_dispatch_queue <OS_dispatch_object> +@end + +typedef NSObject<OS_dispatch_object> *dispatch_object_t; +typedef NSObject<OS_dispatch_data> *dispatch_data_t; +typedef NSObject<OS_dispatch_queue> *dispatch_queue_t; + +typedef void (^dispatch_block_t)(void); + +dispatch_queue_t dispatch_get_main_queue(void); + +DISPATCH_RETURNS_RETAINED dispatch_data_t +dispatch_data_create(const void *buffer, size_t size, + dispatch_queue_t _Nullable queue, + dispatch_block_t _Nullable destructor); + +void _dispatch_object_validate(dispatch_object_t object); + +#define dispatch_retain(object) \ + __extension__({ dispatch_object_t _o = (object); \ + _dispatch_object_validate(_o); \ + (void)[_o retain]; }) +#define dispatch_release(object) \ + __extension__({ dispatch_object_t _o = (object); \ + _dispatch_object_validate(_o); \ + [_o release]; }) + + @interface SomeClass @end @@ -84,3 +121,46 @@ typedef struct _NSZone NSZone; } @end +int buf[1024]; + +void libdispatch_leaked_data() { + dispatch_data_t data = dispatch_data_create(buf, 1024, + dispatch_get_main_queue(), ^{}); +} +#if !HAS_ARC + // expected-warning@-2{{Potential leak of an object stored into 'data'}} + // expected-note@-5{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}} + // expected-note@-4{{Object leaked: object allocated and stored into 'data' is not referenced later in this execution path and has a retain count of +1}} +#endif + +void libdispatch_dispatch_released_data() { + dispatch_data_t data = dispatch_data_create(buf, 1024, + dispatch_get_main_queue(), ^{}); +#if !HAS_ARC + dispatch_release(data); // no-warning +#endif +} + +void libdispatch_objc_released_data() { + dispatch_data_t data = dispatch_data_create(buf, 1024, + dispatch_get_main_queue(), ^{}); +#if !HAS_ARC + [data release]; // no-warning +#endif +} + +void libdispatch_leaked_retained_data() { + dispatch_data_t data = dispatch_data_create(buf, 1024, + dispatch_get_main_queue(), ^{}); +#if !HAS_ARC + dispatch_retain(data); + [data release]; +#endif +} +#if !HAS_ARC +// expected-warning@-2{{Potential leak of an object stored into 'data'}} +// expected-note@-9{{Call to function 'dispatch_data_create' returns an Objective-C object with a +1 retain count}} +// expected-note@-7{{Reference count incremented. The object now has a +2 retain count}} +// expected-note@-7{{Reference count decremented. The object now has a +1 retain count}} +// expected-note@-6{{Object leaked: object allocated and stored into 'data' is not referenced later in this execution path and has a retain count of +1}} +#endif |

