diff options
Diffstat (limited to 'test/Analysis/inlining/InlineObjCInstanceMethod.m')
-rw-r--r-- | test/Analysis/inlining/InlineObjCInstanceMethod.m | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/test/Analysis/inlining/InlineObjCInstanceMethod.m b/test/Analysis/inlining/InlineObjCInstanceMethod.m index 31b6d5b..f6aa50a 100644 --- a/test/Analysis/inlining/InlineObjCInstanceMethod.m +++ b/test/Analysis/inlining/InlineObjCInstanceMethod.m @@ -1,15 +1,32 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s +// RUN: %clang --analyze -Xanalyzer -analyzer-checker=osx.cocoa.IncompatibleMethodTypes,osx.coreFoundation.CFRetainRelease -Xclang -verify %s #include "InlineObjCInstanceMethod.h" +typedef const struct __CFString * CFStringRef; +typedef const void * CFTypeRef; +extern CFTypeRef CFRetain(CFTypeRef cf); +extern void CFRelease(CFTypeRef cf); +extern CFStringRef getString(void); + // Method is defined in the parent; called through self. @interface MyParent : NSObject - (int)getInt; +- (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained)); @end @implementation MyParent - (int)getInt { return 0; } + +- (CFStringRef) testCovariantReturnType __attribute__((cf_returns_retained)) { + CFStringRef Str = ((void*)0); + Str = getString(); + if (Str) { + CFRetain(Str); + } + return Str; +} + @end @interface MyClass : MyParent @@ -83,4 +100,49 @@ // Don't crash if we don't know the receiver's region. void randomlyMessageAnObject(MyClass *arr[], int i) { (void)[arr[i] getInt]; -}
\ No newline at end of file +} + + +@interface EvilChild : MyParent +- (id)getInt; +- (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained)); +@end + +@implementation EvilChild +- (id)getInt { // expected-warning {{types are incompatible}} + return self; +} +- (CFStringRef) testCovariantReturnType __attribute__((cf_returns_retained)) { + CFStringRef Str = ((void*)0); + Str = getString(); + if (Str) { + CFRetain(Str); + } + return Str; +} + +@end + +int testNonCovariantReturnType() { + MyParent *obj = [[EvilChild alloc] init]; + + // Devirtualization allows us to directly call -[EvilChild getInt], but + // that returns an id, not an int. There is an off-by-default warning for + // this, -Woverriding-method-mismatch, and an on-by-default analyzer warning, + // osx.cocoa.IncompatibleMethodTypes. This code would probably crash at + // runtime, but at least the analyzer shouldn't crash. + int x = 1 + [obj getInt]; + + [obj release]; + return 5/(x-1); // no-warning +} + +int testCovariantReturnTypeNoErrorSinceTypesMatch() { + MyParent *obj = [[EvilChild alloc] init]; + + CFStringRef S = ((void*)0); + S = [obj testCovariantReturnType]; + if (S) + CFRelease(S); + CFRelease(obj); +} |