summaryrefslogtreecommitdiffstats
path: root/test/Analysis/inlining/InlineObjCInstanceMethod.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/inlining/InlineObjCInstanceMethod.m')
-rw-r--r--test/Analysis/inlining/InlineObjCInstanceMethod.m66
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);
+}
OpenPOWER on IntegriCloud