InlineObjCInstanceMethod.m revision ff63227817217cd33c587e054d4892285b8e00c6
1// RUN: %clang --analyze -Xanalyzer -analyzer-checker=osx.cocoa.IncompatibleMethodTypes -Xclang -verify %s 2 3#include "InlineObjCInstanceMethod.h" 4 5// Method is defined in the parent; called through self. 6@interface MyParent : NSObject 7- (int)getInt; 8@end 9@implementation MyParent 10- (int)getInt { 11 return 0; 12} 13@end 14 15@interface MyClass : MyParent 16@end 17@implementation MyClass 18- (int)testDynDispatchSelf { 19 int y = [self getInt]; 20 return 5/y; // expected-warning {{Division by zero}} 21} 22 23// Get the dynamic type info from a cast (from id to MyClass*). 24+ (int)testAllocInit { 25 MyClass *a = [[self alloc] init]; 26 return 5/[a getInt]; // expected-warning {{Division by zero}} 27} 28 29// Method is called on inited object. 30+ (int)testAllocInit2 { 31 MyClass *a = [[MyClass alloc] init]; 32 return 5/[a getInt]; // expected-warning {{Division by zero}} 33} 34 35// Method is called on a parameter. 36+ (int)testParam: (MyClass*) a { 37 return 5/[a getInt]; // expected-warning {{Division by zero}} 38} 39 40// Method is called on a parameter of unnown type. 41+ (int)testParamUnknownType: (id) a { 42 return 5/[a getInt]; // no warning 43} 44 45@end 46 47// TODO: When method is inlined, the attribute reset should be visible. 48@interface TestSettingAnAttributeInCallee : NSObject { 49 int _attribute; 50} 51 - (void) method2; 52@end 53 54@implementation TestSettingAnAttributeInCallee 55- (int) method1 { 56 [self method2]; 57 return 5/_attribute; // expected-warning {{Division by zero}} 58} 59 60- (void) method2 { 61 _attribute = 0; 62} 63@end 64 65@interface TestSettingAnAttributeInCaller : NSObject { 66 int _attribute; 67} 68 - (int) method2; 69@end 70 71@implementation TestSettingAnAttributeInCaller 72- (void) method1 { 73 _attribute = 0; 74 [self method2]; 75} 76 77- (int) method2 { 78 return 5/_attribute; // expected-warning {{Division by zero}} 79} 80@end 81 82 83// Don't crash if we don't know the receiver's region. 84void randomlyMessageAnObject(MyClass *arr[], int i) { 85 (void)[arr[i] getInt]; 86} 87 88 89@interface EvilChild : MyParent 90- (id)getInt; 91@end 92 93@implementation EvilChild 94- (id)getInt { // expected-warning {{types are incompatible}} 95 return self; 96} 97@end 98 99int testNonCovariantReturnType() { 100 MyParent *obj = [[EvilChild alloc] init]; 101 102 // Devirtualization allows us to directly call -[EvilChild getInt], but 103 // that returns an id, not an int. There is an off-by-default warning for 104 // this, -Woverriding-method-mismatch, and an on-by-default analyzer warning, 105 // osx.cocoa.IncompatibleMethodTypes. This code would probably crash at 106 // runtime, but at least the analyzer shouldn't crash. 107 int x = 1 + [obj getInt]; 108 109 [obj release]; 110 return 5/(x-1); // no-warning 111} 112