InlineObjCInstanceMethod.m revision 70e5b575e187beb10f4a10667d9f4f5227131c40
1// RUN: %clang --analyze -Xanalyzer -analyzer-checker=core -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}