// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s #include "InlineObjCInstanceMethod.h" // Method is defined in the parent; called through self. @interface MyParent : NSObject - (int)getInt; @end @implementation MyParent - (int)getInt { return 0; } @end @interface MyClass : MyParent @end @implementation MyClass - (int)testDynDispatchSelf { int y = [self getInt]; return 5/y; // expected-warning {{Division by zero}} } // Get the dynamic type info from a cast (from id to MyClass*). + (int)testAllocInit { MyClass *a = [[self alloc] init]; return 5/[a getInt]; // expected-warning {{Division by zero}} } // Method is called on inited object. + (int)testAllocInit2 { MyClass *a = [[MyClass alloc] init]; return 5/[a getInt]; // expected-warning {{Division by zero}} } // Method is called on a parameter. + (int)testParam: (MyClass*) a { return 5/[a getInt]; // expected-warning {{Division by zero}} } // Method is called on a parameter of unnown type. + (int)testParamUnknownType: (id) a { return 5/[a getInt]; // no warning } @end // TODO: When method is inlined, the attribute reset should be visible. @interface TestSettingAnAttributeInCallee : NSObject { int _attribute; } - (void) method2; @end @implementation TestSettingAnAttributeInCallee - (int) method1 { [self method2]; return 5/_attribute; // expected-warning {{Division by zero}} } - (void) method2 { _attribute = 0; } @end @interface TestSettingAnAttributeInCaller : NSObject { int _attribute; } - (int) method2; @end @implementation TestSettingAnAttributeInCaller - (void) method1 { _attribute = 0; [self method2]; } - (int) method2 { return 5/_attribute; // expected-warning {{Division by zero}} } @end // Don't crash if we don't know the receiver's region. void randomlyMessageAnObject(MyClass *arr[], int i) { (void)[arr[i] getInt]; }