1 // RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero,core.DynamicTypePropagation,osx.cocoa.IncompatibleMethodTypes -w -verify %s
3 #include "InlineObjCInstanceMethod.h"
5 typedef const struct __CFString * CFStringRef;
6 typedef const void * CFTypeRef;
7 extern CFTypeRef CFRetain(CFTypeRef cf);
8 extern void CFRelease(CFTypeRef cf);
9 extern CFStringRef getString(void);
11 // Method is defined in the parent; called through self.
12 @interface MyParent : NSObject
14 - (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained));
16 @implementation MyParent
21 - (CFStringRef) testCovariantReturnType __attribute__((cf_returns_retained)) {
22 CFStringRef Str = ((void*)0);
32 @interface MyClass : MyParent
34 @implementation MyClass
35 - (int)testDynDispatchSelf {
36 int y = [self getInt];
37 return 5/y; // expected-warning {{Division by zero}}
40 // Get the dynamic type info from a cast (from id to MyClass*).
41 + (int)testAllocInit {
42 MyClass *a = [[self alloc] init];
43 return 5/[a getInt]; // expected-warning {{Division by zero}}
46 // Method is called on inited object.
47 + (int)testAllocInit2 {
48 MyClass *a = [[MyClass alloc] init];
49 return 5/[a getInt]; // expected-warning {{Division by zero}}
52 // Method is called on a parameter.
53 + (int)testParam: (MyClass*) a {
54 return 5/[a getInt]; // expected-warning {{Division by zero}}
57 // Method is called on a parameter of unnown type.
58 + (int)testParamUnknownType: (id) a {
59 return 5/[a getInt]; // no warning
64 // TODO: When method is inlined, the attribute reset should be visible.
65 @interface TestSettingAnAttributeInCallee : NSObject {
71 @implementation TestSettingAnAttributeInCallee
74 return 5/_attribute; // expected-warning {{Division by zero}}
82 @interface TestSettingAnAttributeInCaller : NSObject {
88 @implementation TestSettingAnAttributeInCaller
95 return 5/_attribute; // expected-warning {{Division by zero}}
100 // Don't crash if we don't know the receiver's region.
101 void randomlyMessageAnObject(MyClass *arr[], int i) {
102 (void)[arr[i] getInt];
106 @interface EvilChild : MyParent
108 - (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained));
111 @implementation EvilChild
112 - (id)getInt { // expected-warning {{types are incompatible}}
115 - (CFStringRef) testCovariantReturnType __attribute__((cf_returns_retained)) {
116 CFStringRef Str = ((void*)0);
126 int testNonCovariantReturnType(void) {
127 MyParent *obj = [[EvilChild alloc] init];
129 // Devirtualization allows us to directly call -[EvilChild getInt], but
130 // that returns an id, not an int. There is an off-by-default warning for
131 // this, -Woverriding-method-mismatch, and an on-by-default analyzer warning,
132 // osx.cocoa.IncompatibleMethodTypes. This code would probably crash at
133 // runtime, but at least the analyzer shouldn't crash.
134 int x = 1 + [obj getInt];
137 return 5/(x-1); // no-warning
140 int testCovariantReturnTypeNoErrorSinceTypesMatch(void) {
141 MyParent *obj = [[EvilChild alloc] init];
143 CFStringRef S = ((void*)0);
144 S = [obj testCovariantReturnType];