1 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -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. 84 void randomlyMessageAnObject(MyClass *arr[], int i) { 85 (void)[arr[i] getInt]; 86 }