]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/inlining/DynDispatchBifurcate.m
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
[FreeBSD/FreeBSD.git] / test / Analysis / inlining / DynDispatchBifurcate.m
1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-ipa=dynamic-bifurcate -verify %s
2
3 #include "InlineObjCInstanceMethod.h"
4
5 @interface MyParent : NSObject
6 - (int)getZero;
7 @end
8 @implementation MyParent
9 - (int)getZero {
10     return 0;
11 }
12 @end
13
14 @interface PublicClass () {
15    int value2;
16 }
17 @property (readwrite) int value1;
18 - (void)setValue2:(int)newValue2;
19 @end
20
21 @implementation PublicClass
22
23 - (int)getZeroPublic {
24     return 0;
25 }
26
27 @synthesize value1;
28
29 - (int)value2 {
30     return value2;
31
32 - (void)setValue2:(int)newValue {
33     value2 = newValue;
34 }
35
36 - (int)value3 {
37     return value3;
38
39 - (void)setValue3:(int)newValue {
40     value3 = newValue;
41 }
42
43 @end
44
45 @interface MyClassWithPublicParent : PublicClass
46 - (int)getZeroPublic;
47 @end
48 @implementation MyClassWithPublicParent
49 - (int)getZeroPublic {
50     return 0;
51 }
52 @end
53
54 // Category overrides a public method.
55 @interface PublicSubClass (PrvateCat)
56   - (int) getZeroPublic;
57 @end
58 @implementation PublicSubClass (PrvateCat)
59 - (int)getZeroPublic {
60     return 0;
61 }
62 @end
63
64
65 @interface MyClass : MyParent {
66   int value;
67 }
68 - (int)getZero;
69 @property int value;
70 @end
71
72 // Since class is private, we assume that it cannot be subclassed.
73 // False negative: this class is "privately subclassed". this is very rare 
74 // in practice.
75 @implementation MyClass
76 + (int) testTypeFromParam:(MyParent*) p {
77   int m = 0;
78   int z = [p getZero];
79   if (z)
80     return 5/m; // false negative
81   return 5/[p getZero];// expected-warning {{Division by zero}}
82 }
83
84 // Here only one definition is possible, since the declaration is not visible 
85 // from outside. 
86 + (int) testTypeFromParamPrivateChild:(MyClass*) c {
87   int m = 0;
88   int z = [c getZero]; // MyClass overrides getZero to return '1'.
89   if (z)
90     return 5/m; // expected-warning {{Division by zero}}
91   return 5/[c getZero];//no warning
92 }
93
94 - (int)getZero {
95     return 1;
96 }
97
98 - (int)value {
99   return value;
100 }
101  
102 - (void)setValue:(int)newValue {
103   value = newValue;
104 }
105
106 // Test ivar access.
107 - (int) testIvarInSelf {
108   value = 0;
109   return 5/value; // expected-warning {{Division by zero}}
110 }
111
112 + (int) testIvar: (MyClass*) p {
113   p.value = 0;
114   return 5/p.value; // expected-warning {{Division by zero}}
115 }
116
117 // Test simple property access.
118 + (int) testProperty: (MyClass*) p {
119   int x= 0;
120   [p setValue:0];
121   return 5/[p value]; // expected-warning {{Division by zero}}  
122 }
123
124 @end
125
126 // The class is prvate and is not subclassed.
127 int testCallToPublicAPIInParent(MyClassWithPublicParent *p) {
128   int m = 0;
129   int z = [p getZeroPublic];
130   if (z)
131     return 5/m; // no warning
132   return 5/[p getZeroPublic];// expected-warning {{Division by zero}}  
133 }
134
135 // When the called method is public (due to it being defined outside of main file),
136 // split the path and analyze both branches.
137 // In this case, p can be either the object of type MyParent* or MyClass*:
138 // - If it's MyParent*, getZero returns 0.
139 // - If it's MyClass*, getZero returns 1 and 'return 5/m' is reachable.
140 // Declaration is provate, but p can be a subclass (MyClass*).
141 int testCallToPublicAPI(PublicClass *p) {
142   int m = 0;
143   int z = [p getZeroPublic];
144   if (z)
145     return 5/m; // expected-warning {{Division by zero}}
146   return 5/[p getZeroPublic];// expected-warning {{Division by zero}}  
147 }
148
149 // Even though the method is privately declared in the category, the parent 
150 // declares the method as public. Assume the instance can be subclassed.
151 int testCallToPublicAPICat(PublicSubClass *p) {
152   int m = 0;
153   int z = [p getZeroPublic];
154   if (z)
155     return 5/m; // expected-warning {{Division by zero}}
156   return 5/[p getZeroPublic];// expected-warning {{Division by zero}}  
157 }
158
159 // Test public property - properties should always be inlined, regardless 
160 // weither they are "public" or private. 
161 int testPublicProperty(PublicClass *p) {
162   int x = 0;
163   p.value3 = 0;
164   if (p.value3 != 0)
165     return 5/x; 
166   return 5/p.value3;// expected-warning {{Division by zero}}
167 }
168
169 int testExtension(PublicClass *p) {
170   int x = 0;
171   [p setValue2:0];
172   if ([p value2] != 0)
173     return 5/x; // expected-warning {{Division by zero}}
174   return 5/[p value2]; // expected-warning {{Division by zero}}
175 }
176
177 // TODO: we do not handle synthesized properties yet.
178 int testPropertySynthesized(PublicClass *p) {
179   [p setValue1:0];
180   return 5/[p value1];  
181 }
182
183 // Test definition not available edge case.
184 @interface DefNotAvailClass : NSObject
185 @end
186 id testDefNotAvailableInlined(DefNotAvailClass *C) {
187   return [C mem]; // expected-warning {{instance method '-mem' not found}}
188 }
189 id testDefNotAvailable(DefNotAvailClass *C) {
190   return testDefNotAvailableInlined(C);
191 }