Lines 12-2538
Link Here
|
12 |
|
12 |
|
13 |
import java.util.Map; |
13 |
import java.util.Map; |
14 |
|
14 |
|
|
|
15 |
import org.eclipse.jdt.internal.compiler.flow.FlowInfo; |
16 |
import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo; |
15 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
17 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
|
|
18 |
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; |
19 |
import org.eclipse.jdt.internal.core.Assert.AssertionFailedException; |
16 |
|
20 |
|
|
|
21 |
import junit.framework.AssertionFailedError; |
17 |
import junit.framework.Test; |
22 |
import junit.framework.Test; |
18 |
|
23 |
|
19 |
public class NullReferenceTest extends AbstractRegressionTest { |
24 |
public class NullReferenceTest extends AbstractRegressionTest { |
20 |
|
25 |
|
21 |
public NullReferenceTest(String name) { |
26 |
public NullReferenceTest(String name) { |
22 |
super(name); |
27 |
super(name); |
23 |
} |
28 |
} |
24 |
|
29 |
|
25 |
// Static initializer to specify tests subset using TESTS_* static variables |
30 |
// Static initializer to specify tests subset using TESTS_* static variables |
26 |
// All specified tests which does not belong to the class are skipped... |
31 |
// All specified tests which does not belong to the class are skipped... |
27 |
// Only the highest compliance level is run; add the VM argument |
32 |
// Only the highest compliance level is run; add the VM argument |
28 |
// -Dcompliance=1.4 (for example) to lower it if needed |
33 |
// -Dcompliance=1.4 (for example) to lower it if needed |
29 |
static { |
34 |
static { |
30 |
// TESTS_NAMES = new String[] { "test011" }; |
35 |
// TESTS_NAMES = new String[] { "test011" }; |
31 |
// TESTS_NUMBERS = new int[] { 2 }; |
36 |
// TESTS_NUMBERS = new int[] { 729 }; |
32 |
// TESTS_RANGE = new int[] { 231, 240 }; |
37 |
// TESTS_NUMBERS = new int[] { 2999 }; |
33 |
} |
38 |
// TESTS_RANGE = new int[] { 2050, -1 }; |
34 |
public static Test suite() { |
39 |
// TESTS_RANGE = new int[] { 1, 2049 }; |
35 |
return buildTestSuite(testClass()); |
40 |
// TESTS_RANGE = new int[] { 449, 451 }; |
36 |
} |
41 |
// TESTS_RANGE = new int[] { 900, 999 }; |
37 |
|
42 |
} |
38 |
public static Class testClass() { |
|
|
39 |
return NullReferenceTest.class; |
40 |
} |
41 |
|
43 |
|
42 |
// Augment problem detection settings |
44 |
public static Test suite() { |
43 |
protected Map getCompilerOptions() { |
45 |
return buildTestSuite(testClass()); |
44 |
Map defaultOptions = super.getCompilerOptions(); |
46 |
} |
45 |
defaultOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.WARNING); |
47 |
|
46 |
defaultOptions.put(CompilerOptions.OPTION_ReportNoEffectAssignment, CompilerOptions.WARNING); |
48 |
public static Class testClass() { |
47 |
return defaultOptions; |
49 |
return NullReferenceTest.class; |
48 |
} |
50 |
} |
49 |
|
51 |
|
50 |
// null analysis -- simple case for local |
52 |
// Augment problem detection settings |
51 |
public void test0001_simple_local() { |
53 |
protected Map getCompilerOptions() { |
52 |
this.runNegativeTest( |
54 |
Map defaultOptions = super.getCompilerOptions(); |
53 |
new String[] { |
55 |
// defaultOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.WARNING); |
54 |
"X.java", |
56 |
defaultOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); |
55 |
"public class X {\n" + |
57 |
// defaultOptions.put(CompilerOptions.OPTION_ReportNoEffectAssignment, CompilerOptions.WARNING); |
56 |
" void foo() {\n" + |
58 |
return defaultOptions; |
57 |
" Object o = null;\n" + |
59 |
} |
58 |
" o.toString();\n" + |
60 |
|
59 |
" }\n" + |
61 |
// null analysis -- simple case for local |
60 |
"}\n"}, |
62 |
public void test0001_simple_local() { |
61 |
"----------\n" + |
63 |
this.runNegativeTest( |
62 |
"1. WARNING in X.java (at line 4)\n" + |
64 |
new String[] { |
63 |
" o.toString();\n" + |
65 |
"X.java", |
64 |
" ^\n" + |
66 |
"public class X {\n" + |
65 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
67 |
" void foo() {\n" + |
66 |
"----------\n" |
68 |
" Object o = null;\n" + |
67 |
); |
69 |
" o.toString();\n" + |
68 |
} |
70 |
" }\n" + |
69 |
|
71 |
"}\n"}, |
70 |
// null analysis -- simple case for field |
72 |
"----------\n" + |
71 |
// despite the fact that a separate thread may update the field, |
73 |
"1. ERROR in X.java (at line 4)\n" + |
72 |
// a comprehensive warning policy could point this case as potentially |
74 |
" o.toString();\n" + |
73 |
// harmful -- this is not the current design, thow; it takes a |
75 |
" ^\n" + |
74 |
// conservative approach and leaves fields out of the analysis altogether |
76 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
75 |
// TODO (maxime) reset diagnostic once supported |
77 |
"----------\n"); |
76 |
public void test0002_simple_field() { |
78 |
} |
77 |
this.runNegativeTest( |
79 |
|
78 |
new String[] { |
80 |
// null analysis -- simple case for field |
79 |
"X.java", |
81 |
// the current design leaves fields out of the analysis altogether |
80 |
"public class X {\n" + |
82 |
public void test0002_simple_field() { |
81 |
" Object o;\n" + |
83 |
this.runNegativeTest( |
82 |
" void foo() {\n" + |
84 |
new String[] { |
83 |
" o = null;\n" + |
85 |
"X.java", |
84 |
" o.toString();\n" + |
86 |
"public class X {\n" + |
85 |
" }\n" + |
87 |
" Object o;\n" + |
86 |
"}\n"}, |
88 |
" void foo() {\n" + |
|
|
89 |
" o = null;\n" + |
90 |
" o.toString();\n" + |
91 |
" }\n" + |
92 |
"}\n"}, |
93 |
"" |
94 |
// "----------\n" + |
95 |
// "1. ERROR in X.java (at line 5)\n" + |
96 |
// " o.toString();\n" + |
97 |
// " ^\n" + |
98 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
99 |
// "----------\n" |
100 |
); |
101 |
} |
102 |
|
103 |
// null analysis -- simple case for parameter |
104 |
public void test0003_simple_parameter() { |
105 |
this.runNegativeTest( |
106 |
new String[] { |
107 |
"X.java", |
108 |
"public class X {\n" + |
109 |
" void foo(Object o) {\n" + |
110 |
" o = null;\n" + |
111 |
" o.toString();\n" + |
112 |
" }\n" + |
113 |
"}\n"}, |
114 |
"----------\n" + |
115 |
"1. ERROR in X.java (at line 4)\n" + |
116 |
" o.toString();\n" + |
117 |
" ^\n" + |
118 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
119 |
"----------\n"); |
120 |
} |
121 |
|
122 |
// null analysis -- final local |
123 |
public void test0004_final_local() { |
124 |
this.runNegativeTest( |
125 |
new String[] { |
126 |
"X.java", |
127 |
"public class X {\n" + |
128 |
" void foo() {\n" + |
129 |
" final Object o = null;\n" + |
130 |
" o.toString();\n" + |
131 |
" }\n" + |
132 |
"}\n"}, |
133 |
"----------\n" + |
134 |
"1. ERROR in X.java (at line 4)\n" + |
135 |
" o.toString();\n" + |
136 |
" ^\n" + |
137 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
138 |
"----------\n"); |
139 |
} |
140 |
|
141 |
// null analysis -- final local |
142 |
public void test0005_final_local() { |
143 |
this.runNegativeTest( |
144 |
new String[] { |
145 |
"X.java", |
146 |
"public class X {\n" + |
147 |
" void foo() {\n" + |
148 |
" final Object o;\n" + |
149 |
" o.toString();\n" + |
150 |
" }\n" + |
151 |
"}\n"}, |
152 |
"----------\n" + |
153 |
"1. ERROR in X.java (at line 4)\n" + |
154 |
" o.toString();\n" + |
155 |
" ^\n" + |
156 |
"The local variable o may not have been initialized\n" + |
157 |
// hides the null related message, but complains once, which is good |
158 |
"----------\n"); |
159 |
} |
160 |
|
161 |
// null analysis -- final local |
162 |
public void test0006_final_local() { |
163 |
this.runNegativeTest( |
164 |
new String[] { |
165 |
"X.java", |
166 |
"public class X {\n" + |
167 |
" void foo() {\n" + |
168 |
" final Object o = null;\n" + |
169 |
" if (o != null) { /* */ }\n" + // complain |
170 |
" }\n" + |
171 |
"}\n"}, |
172 |
"----------\n" + |
173 |
"1. ERROR in X.java (at line 4)\n" + |
174 |
" if (o != null) { /* */ }\n" + |
175 |
" ^\n" + |
176 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
177 |
"----------\n"); |
178 |
} |
179 |
|
180 |
// null analysis -- local with member |
181 |
public void test0007_local_with_member() { |
182 |
this.runNegativeTest( |
183 |
new String[] { |
184 |
"X.java", |
185 |
"public class X {\n" + |
186 |
" Object m;\n" + |
187 |
" void foo() {\n" + |
188 |
" X x = null;\n" + |
189 |
" x.m.toString();\n" + // complain |
190 |
" }\n" + |
191 |
"}\n"}, |
192 |
"----------\n" + |
193 |
"1. ERROR in X.java (at line 5)\n" + |
194 |
" x.m.toString();\n" + |
195 |
" ^^^\n" + |
196 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
197 |
"----------\n"); |
198 |
} |
199 |
|
200 |
// null analysis -- local with member |
201 |
// REVIEW le diagnostic montre x.m au lieu de x ; noter que c'est aussi le cas pour |
202 |
// REVIEW le message "n'a pas été initialisé" ; ouvrir un bug dédié ? |
203 |
// REVIEW la cause est que QualifiedNameReference est l'ASTNode concerné, et que l'on |
204 |
// REVIEW n'a pas de support pour en montrer une sous-partie |
205 |
public void test0008_local_with_member() { |
206 |
this.runNegativeTest( |
207 |
new String[] { |
208 |
"X.java", |
209 |
"public class X {\n" + |
210 |
" Object m;\n" + |
211 |
" void foo() {\n" + |
212 |
" X x = null;\n" + |
213 |
" System.out.println(x.m);\n" + // complain |
214 |
" }\n" + |
215 |
"}\n"}, |
216 |
"----------\n" + |
217 |
"1. ERROR in X.java (at line 5)\n" + |
218 |
" System.out.println(x.m);\n" + |
219 |
" ^^^\n" + |
220 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
221 |
"----------\n"); |
222 |
} |
223 |
|
224 |
// null analysis -- local with member |
225 |
public void test0009_local_with_member() { |
226 |
this.runConformTest( |
227 |
new String[] { |
228 |
"X.java", |
229 |
"public class X {\n" + |
230 |
" Object m;\n" + |
231 |
" void foo(X x) {\n" + |
232 |
" x.m.toString();\n" + // quiet |
233 |
" }\n" + |
234 |
"}\n"}, |
235 |
""); |
236 |
} |
237 |
|
238 |
// null analysis -- field |
239 |
public void test0010_field_with_method_call() { |
240 |
this.runConformTest( |
241 |
new String[] { |
242 |
"X.java", |
243 |
"public class X {\n" + |
244 |
" Object o;\n" + |
245 |
" void foo() {\n" + |
246 |
" o = null;\n" + |
247 |
" bar();\n" + // defuses null by side effect |
248 |
" o.toString();\n" + |
249 |
" }\n" + |
250 |
" void bar() {\n" + |
251 |
" }\n" + |
252 |
"}\n"}, |
253 |
""); |
254 |
} |
255 |
|
256 |
// null analysis -- field |
257 |
public void test0011_field_with_method_call() { |
258 |
this.runConformTest( |
259 |
new String[] { |
260 |
"X.java", |
261 |
"public class X {\n" + |
262 |
" static Object o;\n" + |
263 |
" void foo() {\n" + |
264 |
" o = null;\n" + |
265 |
" bar();\n" + // defuses null by side effect |
266 |
" o.toString();\n" + |
267 |
" }\n" + |
268 |
" static void bar() {\n" + |
269 |
" }\n" + |
270 |
"}\n"}, |
271 |
""); |
272 |
} |
273 |
|
274 |
// null analysis -- field |
275 |
public void test0012_field_with_method_call() { |
276 |
this.runConformTest( |
277 |
new String[] { |
278 |
"X.java", |
279 |
"public class X {\n" + |
280 |
" Object o;\n" + |
281 |
" void foo() {\n" + |
282 |
" o = null;\n" + |
283 |
" bar();\n" + |
284 |
" o.toString();\n" + |
285 |
" }\n" + |
286 |
" static void bar() {\n" + |
287 |
" }\n" + |
288 |
"}\n"}, |
289 |
"" // still ok because the class may hold a pointer to this |
290 |
); |
291 |
} |
292 |
|
293 |
// null analysis -- field |
294 |
public void test0013_field_with_method_call() { |
295 |
this.runConformTest( |
296 |
new String[] { |
297 |
"X.java", |
298 |
"public class X {\n" + |
299 |
" static Object o;\n" + |
300 |
" void foo() {\n" + |
301 |
" o = null;\n" + |
302 |
" bar();\n" + |
303 |
" o.toString();\n" + |
304 |
" }\n" + |
305 |
" void bar() {\n" + |
306 |
" }\n" + |
307 |
"}\n"}, |
308 |
"" // still ok because this may place a static call upon X |
309 |
); |
310 |
} |
311 |
|
312 |
// null analysis -- field |
313 |
public void test0014_field_with_explicit_this_access() { |
314 |
this.runNegativeTest( |
315 |
new String[] { |
316 |
"X.java", |
317 |
"public class X {\n" + |
318 |
" Object o;\n" + |
319 |
" void foo() {\n" + |
320 |
" o = null;\n" + |
321 |
" this.o.toString();\n" + |
322 |
" }\n" + |
323 |
"}\n"}, |
87 |
"" |
324 |
"" |
88 |
// "----------\n" + |
325 |
// "----------\n" + |
89 |
// "1. WARNING in X.java (at line 5)\n" + |
326 |
// "1. ERROR in X.java (at line 5)\n" + |
90 |
// " o.toString();\n" + |
327 |
// " this.o.toString();\n" + |
91 |
// " ^\n" + |
328 |
// " ^^^^^^\n" + |
92 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
329 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
93 |
// "----------\n" |
330 |
// "----------\n" |
94 |
); |
331 |
); |
95 |
} |
332 |
} |
96 |
|
333 |
|
97 |
// null analysis -- simple case for parameter |
334 |
// null analysis -- field |
98 |
public void test0003_simple_parameter() { |
335 |
public void test0015_field_with_explicit_this_access() { |
99 |
this.runNegativeTest( |
336 |
this.runNegativeTest( |
100 |
new String[] { |
337 |
new String[] { |
101 |
"X.java", |
338 |
"X.java", |
102 |
"public class X {\n" + |
339 |
"public class X {\n" + |
103 |
" void foo(Object o) {\n" + |
340 |
" Object o;\n" + |
104 |
" o = null;\n" + |
341 |
" void foo() {\n" + |
105 |
" o.toString();\n" + |
342 |
" this.o = null;\n" + |
106 |
" }\n" + |
343 |
" o.toString();\n" + |
107 |
"}\n"}, |
344 |
" }\n" + |
108 |
"----------\n" + |
345 |
"}\n"}, |
109 |
"1. WARNING in X.java (at line 4)\n" + |
346 |
"" |
110 |
" o.toString();\n" + |
347 |
// "----------\n" + |
111 |
" ^\n" + |
348 |
// "1. ERROR in X.java (at line 5)\n" + |
112 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
349 |
// " o.toString();\n" + |
113 |
"----------\n" |
350 |
// " ^\n" + |
114 |
); |
351 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
115 |
} |
352 |
// "----------\n" |
|
|
353 |
); |
354 |
} |
116 |
|
355 |
|
117 |
// null analysis -- field |
356 |
// null analysis -- field |
118 |
public void test0004_field_with_method_call() { |
357 |
public void test0016_field_of_another_object() { |
119 |
this.runNegativeTest( |
358 |
this.runConformTest( |
120 |
new String[] { |
359 |
new String[] { |
121 |
"X.java", |
360 |
"X.java", |
122 |
"public class X {\n" + |
361 |
"public class X {\n" + |
123 |
" Object o;\n" + |
362 |
" Object o;\n" + |
124 |
" void foo() {\n" + |
363 |
" void foo() {\n" + |
125 |
" o = null;\n" + |
364 |
" X other = new X();\n" + |
126 |
" bar();\n" + // defuses null by side effect |
365 |
" other.o = null;\n" + |
127 |
" o.toString();\n" + |
366 |
" other.o.toString();\n" + |
128 |
" }\n" + |
367 |
" }\n" + |
129 |
" void bar() {\n" + |
368 |
"}\n"}, |
130 |
" }\n" + |
369 |
""); |
131 |
"}\n"}, |
370 |
} |
132 |
"" |
|
|
133 |
); |
134 |
} |
135 |
|
371 |
|
136 |
// null analysis -- field |
372 |
// null analysis -- field |
137 |
public void test0005_field_with_method_call() { |
373 |
public void test0017_field_of_another_object() { |
138 |
this.runNegativeTest( |
374 |
this.runConformTest( |
139 |
new String[] { |
375 |
new String[] { |
140 |
"X.java", |
376 |
"X.java", |
141 |
"public class X {\n" + |
377 |
"public class X {\n" + |
142 |
" static Object o;\n" + |
378 |
" Object o;\n" + |
143 |
" void foo() {\n" + |
379 |
" void foo() {\n" + |
144 |
" o = null;\n" + |
380 |
" X other = this;\n" + |
145 |
" bar();\n" + // defuses null by side effect |
381 |
" o = null;\n" + |
146 |
" o.toString();\n" + |
382 |
" other.o.toString();\n" + |
147 |
" }\n" + |
383 |
" }\n" + |
148 |
" static void bar() {\n" + |
384 |
"}\n"}, |
149 |
" }\n" + |
385 |
""); |
150 |
"}\n"}, |
386 |
} |
151 |
"" |
|
|
152 |
); |
153 |
} |
154 |
|
387 |
|
155 |
// null analysis -- field |
388 |
// null analysis -- field |
156 |
public void test0006_field_with_method_call() { |
389 |
public void test0018_field_of_enclosing_object() { |
157 |
this.runNegativeTest( |
390 |
this.runNegativeTest( |
158 |
new String[] { |
391 |
new String[] { |
159 |
"X.java", |
392 |
"X.java", |
160 |
"public class X {\n" + |
393 |
"public class X {\n" + |
161 |
" Object o;\n" + |
394 |
" Object o;\n" + |
162 |
" void foo() {\n" + |
395 |
" public class Y {\n" + |
163 |
" o = null;\n" + |
396 |
" void foo() {\n" + |
164 |
" bar();\n" + |
397 |
" X.this.o = null;\n" + |
165 |
" o.toString();\n" + |
398 |
" X.this.o.toString();\n" + // complain |
166 |
" }\n" + |
399 |
" }\n" + |
167 |
" static void bar() {\n" + |
400 |
" }\n" + |
168 |
" }\n" + |
401 |
"}\n"}, |
169 |
"}\n"}, |
402 |
"" |
170 |
"" // still ok because the class may hold a pointer to this |
403 |
// "----------\n" + |
171 |
); |
404 |
// "1. ERROR in X.java (at line 6)\n" + |
172 |
} |
405 |
// " X.this.o.toString();\n" + |
|
|
406 |
// " ^^^^^^^^\n" + |
407 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
408 |
// "----------\n" |
409 |
); |
410 |
} |
173 |
|
411 |
|
174 |
// null analysis -- field |
412 |
// null analysis -- fields |
175 |
public void test0007_field_with_method_call() { |
413 |
// check that fields that are protected against concurrent access |
176 |
this.runNegativeTest( |
414 |
// behave as locals when no call to further methods can affect them |
177 |
new String[] { |
415 |
public void test0019_field_synchronized() { |
178 |
"X.java", |
416 |
this.runNegativeTest( |
179 |
"public class X {\n" + |
417 |
new String[] { |
180 |
" static Object o;\n" + |
418 |
"X.java", |
181 |
" void foo() {\n" + |
419 |
"public class X {\n" + |
182 |
" o = null;\n" + |
420 |
" Object o;\n" + |
183 |
" bar();\n" + |
421 |
" public synchronized void foo() {\n" + |
184 |
" o.toString();\n" + |
422 |
" o = null;\n" + |
185 |
" }\n" + |
423 |
" o.toString();\n" + |
186 |
" void bar() {\n" + |
424 |
" }\n" + |
187 |
" }\n" + |
425 |
" void bar() {/* */}\n" + |
188 |
"}\n"}, |
426 |
"}\n"}, |
189 |
"" // still ok because this may place a static call upon X |
427 |
"" |
190 |
); |
428 |
// "----------\n" + |
191 |
} |
429 |
// "1. ERROR in X.java (at line 5)\n" + |
192 |
|
430 |
// " o.toString();\n" + |
193 |
// null analysis -- field |
431 |
// " ^\n" + |
194 |
// TODO (maxime) reset diagnostic once supported |
432 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
195 |
public void test0008_field_with_explicit_this_access() { |
433 |
// "----------\n" |
196 |
this.runNegativeTest( |
434 |
); |
197 |
new String[] { |
435 |
} |
198 |
"X.java", |
|
|
199 |
"public class X {\n" + |
200 |
" Object o;\n" + |
201 |
" void foo() {\n" + |
202 |
" o = null;\n" + |
203 |
" this.o.toString();\n" + |
204 |
" }\n" + |
205 |
"}\n"}, |
206 |
"" |
207 |
// "----------\n" + |
208 |
// "1. WARNING in X.java (at line 5)\n" + |
209 |
// " this.o.toString();\n" + |
210 |
// " ^^^^^^\n" + |
211 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
212 |
// "----------\n" |
213 |
); |
214 |
} |
215 |
|
436 |
|
216 |
// null analysis -- field |
437 |
// null analysis -- field |
217 |
// TODO (maxime) reset diagnostic once supported |
438 |
// check that final fields behave as locals despite calls to further |
218 |
public void test0009_field_with_explicit_this_access() { |
439 |
// methods |
219 |
this.runNegativeTest( |
440 |
public void test0020_final_field() { |
220 |
new String[] { |
441 |
this.runNegativeTest( |
221 |
"X.java", |
442 |
new String[] { |
222 |
"public class X {\n" + |
443 |
"X.java", |
223 |
" Object o;\n" + |
444 |
"public class X {\n" + |
224 |
" void foo() {\n" + |
445 |
" final Object o = null;\n" + |
225 |
" this.o = null;\n" + |
446 |
" public synchronized void foo() {\n" + |
226 |
" o.toString();\n" + |
447 |
" bar();\n" + |
227 |
" }\n" + |
448 |
" o.toString();\n" + |
228 |
"}\n"}, |
449 |
" }\n" + |
229 |
"" |
450 |
" void bar() {/* */}\n" + |
230 |
// "----------\n" + |
451 |
"}\n"}, |
231 |
// "1. WARNING in X.java (at line 5)\n" + |
452 |
"" |
232 |
// " o.toString();\n" + |
453 |
// "----------\n" + |
233 |
// " ^\n" + |
454 |
// "1. ERROR in X.java (at line 5)\n" + |
234 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
455 |
// " o.toString();\n" + |
235 |
// "----------\n" |
456 |
// " ^\n" + |
236 |
); |
457 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
237 |
} |
458 |
// "----------\n" |
|
|
459 |
); |
460 |
} |
238 |
|
461 |
|
239 |
// null analysis -- field |
462 |
// null analysis -- field |
240 |
public void test0010_field_of_another_object() { |
463 |
public void test0021_final_field() { |
241 |
this.runNegativeTest( |
464 |
this.runNegativeTest( |
242 |
new String[] { |
465 |
new String[] { |
243 |
"X.java", |
466 |
"X.java", |
244 |
"public class X {\n" + |
467 |
"public class X {\n" + |
245 |
" Object o;\n" + |
468 |
" final Object o = null;\n" + |
246 |
" void foo() {\n" + |
469 |
" X () {\n" + |
247 |
" X other = new X();\n" + |
470 |
" bar();\n" + |
248 |
" other.o = null;\n" + |
471 |
" o.toString();\n" + |
249 |
" other.o.toString();\n" + |
472 |
" }\n" + |
250 |
" }\n" + |
473 |
" void bar() {/* */}\n" + |
251 |
"}\n"}, |
474 |
"}\n"}, |
252 |
"" |
475 |
"" |
253 |
); |
476 |
// "----------\n" + |
254 |
} |
477 |
// "1. ERROR in X.java (at line 5)\n" + |
255 |
|
478 |
// " o.toString();\n" + |
256 |
// null analysis -- field |
479 |
// " ^\n" + |
257 |
public void test0011_field_of_another_object() { |
480 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
258 |
this.runNegativeTest( |
481 |
// "----------\n" |
259 |
new String[] { |
482 |
); |
260 |
"X.java", |
483 |
} |
261 |
"public class X {\n" + |
|
|
262 |
" Object o;\n" + |
263 |
" void foo() {\n" + |
264 |
" X other = this;\n" + |
265 |
" o = null;\n" + |
266 |
" other.o.toString();\n" + |
267 |
" }\n" + |
268 |
"}\n"}, |
269 |
"" |
270 |
); |
271 |
} |
272 |
|
484 |
|
273 |
// null analysis -- field |
485 |
// null analysis -- field |
274 |
// TODO (maxime) reset diagnostic once supported |
486 |
public void test0022_final_field() { |
275 |
public void test0012_field_of_enclosing_object() { |
487 |
this.runNegativeTest( |
276 |
this.runNegativeTest( |
488 |
new String[] { |
|
|
489 |
"X.java", |
490 |
"public class X {\n" + |
491 |
" final Object o = new Object();\n" + |
492 |
" X () {\n" + |
493 |
" bar();\n" + |
494 |
" if (o == null) { /* empty */ }\n" + |
495 |
" }\n" + |
496 |
" void bar() {/* */}\n" + |
497 |
"}\n"}, |
498 |
"" |
499 |
// "----------\n" + |
500 |
// "1. ERROR in X.java (at line 5)\n" + |
501 |
// " if (o == null) { /* empty */ }\n" + |
502 |
// " ^\n" + |
503 |
// "The field o is likely non null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
504 |
// "----------\n" |
505 |
); |
506 |
} |
507 |
|
508 |
// null analysis -- field |
509 |
public void test0023_field_assignment() { |
510 |
this.runConformTest( |
511 |
new String[] { |
512 |
"X.java", |
513 |
"public class X {\n" + |
514 |
" Object m;\n" + |
515 |
" void foo(X x) {\n" + |
516 |
" Object o = x.m;\n" + |
517 |
" if (o == null) { /* */ };\n" + |
518 |
" }\n" + |
519 |
"}\n"}, |
520 |
""); |
521 |
} |
522 |
|
523 |
// null analysis -- field |
524 |
public void test0024_field_cast_assignment() { |
525 |
this.runConformTest( |
526 |
new String[] { |
527 |
"X.java", |
528 |
"public class X {\n" + |
529 |
" Object m;\n" + |
530 |
" void foo(Object x) {\n" + |
531 |
" Object o = ((X) x).m;\n" + |
532 |
" if (o == null) { /* */ };\n" + |
533 |
" }\n" + |
534 |
"}\n"}, |
535 |
""); |
536 |
} |
537 |
|
538 |
// null analysis -- parameter |
539 |
public void test0025_parameter() { |
540 |
this.runConformTest( |
541 |
new String[] { |
542 |
"X.java", |
543 |
"public class X {\n" + |
544 |
" void foo(Object o) {\n" + |
545 |
" o.toString();\n" + // quiet: parameters have unknown value |
546 |
" }\n" + |
547 |
"}\n"}, |
548 |
""); |
549 |
} |
550 |
|
551 |
// null analysis -- suppress warnings |
552 |
public void test0026_suppress_warnings() { |
553 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
554 |
Map compilerOptions = getCompilerOptions(); |
555 |
compilerOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.WARNING); |
556 |
this.runConformTest( |
277 |
new String[] { |
557 |
new String[] { |
278 |
"X.java", |
558 |
"X.java", |
279 |
"public class X {\n" + |
559 |
"@SuppressWarnings(\"null\")\n" + |
280 |
" Object o;\n" + |
560 |
"public class X {\n" + |
281 |
" public class Y {\n" + |
561 |
" void foo() {\n" + |
282 |
" void foo() {\n" + |
562 |
" Object o = null;\n" + |
283 |
" X.this.o = null;\n" + |
563 |
" o.toString();\n" + |
284 |
" X.this.o.toString();\n" + // complain |
|
|
285 |
" }\n" + |
286 |
" }\n" + |
564 |
" }\n" + |
287 |
"}\n"}, |
565 |
"}\n"}, |
288 |
"" |
566 |
"", null, true, null, compilerOptions, null); |
289 |
// "----------\n" + |
|
|
290 |
// "1. WARNING in X.java (at line 6)\n" + |
291 |
// " X.this.o.toString();\n" + |
292 |
// " ^^^^^^^^\n" + |
293 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
294 |
// "----------\n" |
295 |
); |
296 |
} |
297 |
|
298 |
// null analysis -- fields |
299 |
// check that fields that are protected against concurrent access |
300 |
// behave as locals when no call to further methods can affect them |
301 |
// TODO (maxime) reset diagnostic once supported |
302 |
public void test0013_field_synchronized() { |
303 |
this.runNegativeTest( |
304 |
new String[] { |
305 |
"X.java", |
306 |
"public class X {\n" + |
307 |
" Object o;\n" + |
308 |
" public synchronized void foo() {\n" + |
309 |
" o = null;\n" + |
310 |
" o.toString();\n" + |
311 |
" }\n" + |
312 |
" void bar() {/* */}\n" + |
313 |
"}\n"}, |
314 |
"" |
315 |
// "----------\n" + |
316 |
// "1. WARNING in X.java (at line 5)\n" + |
317 |
// " o.toString();\n" + |
318 |
// " ^\n" + |
319 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
320 |
// "----------\n" |
321 |
); |
322 |
} |
567 |
} |
|
|
568 |
} |
323 |
|
569 |
|
324 |
// null analysis -- field |
570 |
// null analysis -- embedded comparison |
325 |
// check that final fields behave as locals despite calls to further |
571 |
public void test0027_embedded_comparison() { |
326 |
// methods |
572 |
this.runNegativeTest( |
327 |
// TODO (maxime) reset diagnostic once supported |
573 |
new String[] { |
328 |
public void test0014_final_field() { |
574 |
"X.java", |
329 |
this.runNegativeTest( |
575 |
"public class X {\n" + |
330 |
new String[] { |
576 |
" void foo(Object o) {\n" + |
331 |
"X.java", |
577 |
" boolean b = o != null;\n" + // shades doubts upon o |
332 |
"public class X {\n" + |
578 |
" if (b) { /* */ }\n" + |
333 |
" final Object o = null;\n" + |
579 |
" o.toString();\n" + // complain |
334 |
" public synchronized void foo() {\n" + |
580 |
" }\n" + |
335 |
" bar();\n" + |
581 |
"}\n"}, |
336 |
" o.toString();\n" + |
582 |
"----------\n" + |
337 |
" }\n" + |
583 |
"1. ERROR in X.java (at line 5)\n" + |
338 |
" void bar() {/* */}\n" + |
584 |
" o.toString();\n" + |
339 |
"}\n"}, |
585 |
" ^\n" + |
340 |
"" |
586 |
"The variable o may be null\n" + |
341 |
// "----------\n" + |
587 |
"----------\n"); |
342 |
// "1. WARNING in X.java (at line 5)\n" + |
588 |
} |
343 |
// " o.toString();\n" + |
|
|
344 |
// " ^\n" + |
345 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
346 |
// "----------\n" |
347 |
); |
348 |
} |
349 |
|
589 |
|
350 |
// null analysis -- field |
590 |
// null analysis -- field |
351 |
// TODO (maxime) reset diagnostic once supported |
591 |
public void test0028_field_as_initializer() { |
352 |
public void test0015_final_field() { |
592 |
this.runConformTest( |
353 |
this.runNegativeTest( |
593 |
new String[] { |
354 |
new String[] { |
594 |
"X.java", |
355 |
"X.java", |
595 |
"public class X {\n" + |
356 |
"public class X {\n" + |
596 |
" X f;\n" + |
357 |
" final Object o = null;\n" + |
597 |
" void foo() {\n" + |
358 |
" X () {\n" + |
598 |
" X x = f;\n" + |
359 |
" bar();\n" + |
599 |
" if (x == null) { /* */ }\n" + |
360 |
" o.toString();\n" + |
600 |
" }\n" + |
361 |
" }\n" + |
601 |
"}\n"}, |
362 |
" void bar() {/* */}\n" + |
602 |
""); |
363 |
"}\n"}, |
603 |
} |
364 |
"" |
|
|
365 |
// "----------\n" + |
366 |
// "1. WARNING in X.java (at line 5)\n" + |
367 |
// " o.toString();\n" + |
368 |
// " ^\n" + |
369 |
// "The field o is likely null; it was either set to null or checked for null when last used\n" + |
370 |
// "----------\n" |
371 |
); |
372 |
} |
373 |
|
604 |
|
374 |
// null analysis -- field |
605 |
// null analysis -- field |
375 |
// TODO (maxime) reset diagnostic once supported |
606 |
public void test0029_field_assignment() { |
376 |
public void test0016_final_field() { |
607 |
this.runNegativeTest( |
377 |
this.runNegativeTest( |
608 |
new String[] { |
378 |
new String[] { |
609 |
"X.java", |
379 |
"X.java", |
610 |
"public class X {\n" + |
380 |
"public class X {\n" + |
611 |
" Object m;\n" + |
381 |
" final Object o = new Object();\n" + |
612 |
" void foo() {\n" + |
382 |
" X () {\n" + |
613 |
" X x = null;\n" + |
383 |
" bar();\n" + |
614 |
" x.m = new Object();\n" + |
384 |
" if (o == null) { /* empty */ }\n" + |
615 |
" }\n" + |
385 |
" }\n" + |
616 |
"}\n"}, |
386 |
" void bar() {/* */}\n" + |
617 |
"----------\n" + |
387 |
"}\n"}, |
618 |
"1. ERROR in X.java (at line 5)\n" + |
388 |
"" |
619 |
" x.m = new Object();\n" + |
389 |
// "----------\n" + |
620 |
" ^^^\n" + |
390 |
// "1. WARNING in X.java (at line 5)\n" + |
621 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
391 |
// " if (o == null) { /* empty */ }\n" + |
622 |
"----------\n"); |
392 |
// " ^\n" + |
623 |
} |
393 |
// "The field o is likely non null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
|
|
394 |
// "----------\n" |
395 |
); |
396 |
} |
397 |
|
624 |
|
398 |
// null analysis -- parameter |
625 |
// null analysis -- conditional expression |
399 |
public void test0017_parameter() { |
626 |
public void test0030_conditional_expression() { |
400 |
this.runNegativeTest( |
627 |
this.runNegativeTest( |
401 |
new String[] { |
628 |
new String[] { |
402 |
"X.java", |
629 |
"X.java", |
403 |
"public class X {\n" + |
630 |
"public class X {\n" + |
404 |
" void foo(Object o) {\n" + |
631 |
" void foo() {\n" + |
405 |
" o.toString();\n" + // quiet: parameters have unknown value |
632 |
" Object o = true ? null : null;\n" + |
406 |
" }\n" + |
633 |
" o.toString();\n" + |
407 |
"}\n"}, |
634 |
" }\n" + |
408 |
"" |
635 |
"}\n"}, |
409 |
); |
636 |
"----------\n" + |
410 |
} |
637 |
"1. ERROR in X.java (at line 4)\n" + |
|
|
638 |
" o.toString();\n" + |
639 |
" ^\n" + |
640 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
641 |
"----------\n"); |
642 |
} |
643 |
|
644 |
// null analysis -- conditional expression |
645 |
public void test0031_conditional_expression() { |
646 |
this.runNegativeTest( |
647 |
new String[] { |
648 |
"X.java", |
649 |
"public class X {\n" + |
650 |
" void foo() {\n" + |
651 |
" Object o = true ? null : new Object();\n" + |
652 |
" o.toString();\n" + |
653 |
" }\n" + |
654 |
"}\n"}, |
655 |
"----------\n" + |
656 |
"1. ERROR in X.java (at line 4)\n" + |
657 |
" o.toString();\n" + |
658 |
" ^\n" + |
659 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
660 |
"----------\n"); |
661 |
} |
662 |
|
663 |
// null analysis -- conditional expression |
664 |
public void test0032_conditional_expression() { |
665 |
this.runConformTest( |
666 |
new String[] { |
667 |
"X.java", |
668 |
"public class X {\n" + |
669 |
" void foo() {\n" + |
670 |
" Object o = false ? null : new Object();\n" + |
671 |
" o.toString();\n" + |
672 |
" }\n" + |
673 |
"}\n"}, |
674 |
""); |
675 |
} |
676 |
|
677 |
// null analysis -- conditional expression |
678 |
public void test0033_conditional_expression() { |
679 |
this.runNegativeTest( |
680 |
new String[] { |
681 |
"X.java", |
682 |
"public class X {\n" + |
683 |
" void foo() {\n" + |
684 |
" Object o = (1 == 1) ? null : new Object();\n" + |
685 |
" o.toString();\n" + |
686 |
" }\n" + |
687 |
"}\n"}, |
688 |
"----------\n" + |
689 |
"1. ERROR in X.java (at line 4)\n" + |
690 |
" o.toString();\n" + |
691 |
" ^\n" + |
692 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
693 |
"----------\n"); |
694 |
} |
411 |
|
695 |
|
412 |
// null analysis -- conditional expression |
696 |
// null analysis -- conditional expression |
413 |
// TODO (maxime) fix |
697 |
// TODO (maxime) fix - may consider simultaneous computation of expression null status |
414 |
public void _test0020_conditional_expression() { |
698 |
// this case is one of those which raise the need for the simultaneous calculation of |
|
|
699 |
// the null status of an expression and the code analysis of the said expression; this |
700 |
// case is simplistic: we need a value (here, potentially null), that is *not* carried |
701 |
// by the current embodiment of the flow info; other cases are less trivial in which |
702 |
// side effects on variables could introduce errors into after the facts evaluations; |
703 |
// one possible trick would be to add a slot for this |
704 |
// other path: use a tainted unknown expression status; does not seem to cope well |
705 |
// with o = (o == null ? new Object() : o) |
706 |
public void _test0034_conditional_expression() { |
707 |
this.runNegativeTest( |
708 |
new String[] { |
709 |
"X.java", |
710 |
"public class X {\n" + |
711 |
" boolean b;\n" + |
712 |
" void foo() {\n" + |
713 |
" Object o = b ? null : new Object();\n" + |
714 |
" o.toString();\n" + |
715 |
" }\n" + |
716 |
"}\n"}, |
717 |
"----------\n" + |
718 |
"1. ERROR in X.java (at line 4)\n" + |
719 |
" o.toString();\n" + |
720 |
" ^\n" + |
721 |
"The variable o may be null\n" + |
722 |
"----------\n"); |
723 |
} |
724 |
|
725 |
// null analysis -- conditional expression |
726 |
public void test0035_conditional_expression() { |
727 |
this.runConformTest( |
728 |
new String[] { |
729 |
"X.java", |
730 |
"public class X {\n" + |
731 |
" boolean b;\n" + |
732 |
" void foo() {\n" + |
733 |
" Object o = b ? null : new Object();\n" + |
734 |
" if (o == null) { /* */ }\n" + |
735 |
" }\n" + |
736 |
"}\n"}, |
737 |
""); |
738 |
} |
739 |
|
740 |
// null analysis -- conditional expression |
741 |
public void test0036_conditional_expression() { |
742 |
this.runNegativeTest( |
743 |
new String[] { |
744 |
"X.java", |
745 |
"public class X {\n" + |
746 |
" boolean b;\n" + |
747 |
" void foo() {\n" + |
748 |
" Object o = b ? null : null;\n" + |
749 |
" if (o == null) { /* */ }\n" + |
750 |
" }\n" + |
751 |
"}\n"}, |
752 |
"----------\n" + |
753 |
"1. ERROR in X.java (at line 5)\n" + |
754 |
" if (o == null) { /* */ }\n" + |
755 |
" ^\n" + |
756 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
757 |
"----------\n"); |
758 |
} |
759 |
|
760 |
// null analysis -- autoboxing |
761 |
public void test0040_autoboxing_compound_assignment() { |
762 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
415 |
this.runNegativeTest( |
763 |
this.runNegativeTest( |
416 |
new String[] { |
764 |
new String[] { |
417 |
"X.java", |
765 |
"X.java", |
418 |
"public class X {\n" + |
766 |
"public class X {\n" + |
419 |
" void foo() {\n" + |
767 |
" void foo() {\n" + |
420 |
" Object o = true ? null : null;\n" + |
768 |
" Integer i = null;\n" + |
421 |
" o.toString();\n" + |
769 |
" i += 1;\n" + |
422 |
" }\n" + |
770 |
" }\n" + |
423 |
"}\n"}, |
771 |
"}\n"}, |
424 |
"----------\n" + |
772 |
"----------\n" + |
425 |
"1. WARNING in X.java (at line 4)\n" + |
773 |
"1. ERROR in X.java (at line 4)\n" + |
426 |
" o.toString();\n" + |
774 |
" i += 1;\n" + |
427 |
" ^\n" + |
775 |
" ^\n" + |
428 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
776 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
429 |
"----------\n" |
777 |
"----------\n"); |
430 |
); |
|
|
431 |
} |
778 |
} |
|
|
779 |
} |
432 |
|
780 |
|
433 |
// null analysis -- conditional expression |
781 |
// null analysis -- autoboxing |
434 |
// TODO (maxime) fix |
782 |
public void test0041_autoboxing_increment_operator() { |
435 |
public void _test0021_conditional_expression() { |
783 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
436 |
this.runNegativeTest( |
784 |
this.runNegativeTest( |
437 |
new String[] { |
785 |
new String[] { |
438 |
"X.java", |
786 |
"X.java", |
439 |
"public class X {\n" + |
787 |
"public class X {\n" + |
440 |
" void foo() {\n" + |
788 |
" void foo() {\n" + |
441 |
" Object o = true ? null : new Object();\n" + |
789 |
" Integer i = null;\n" + |
442 |
" o.toString();\n" + |
790 |
" i++;\n" + // complain: this is null |
443 |
" }\n" + |
791 |
" ++i;\n" + // quiet (because previous step guards it) |
|
|
792 |
" }\n" + |
444 |
"}\n"}, |
793 |
"}\n"}, |
445 |
"----------\n" + |
794 |
"----------\n" + |
446 |
"1. WARNING in X.java (at line 4)\n" + |
795 |
"1. ERROR in X.java (at line 4)\n" + |
447 |
" o.toString();\n" + |
796 |
" i++;\n" + |
448 |
" ^\n" + |
797 |
" ^\n" + |
449 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
798 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
450 |
"----------\n" |
799 |
"----------\n"); |
451 |
); |
|
|
452 |
} |
800 |
} |
|
|
801 |
} |
453 |
|
802 |
|
454 |
// null analysis -- conditional expression |
803 |
// null analysis -- autoboxing |
455 |
public void test0022_conditional_expression() { |
804 |
public void test0042_autoboxing_literal() { |
|
|
805 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
456 |
this.runNegativeTest( |
806 |
this.runNegativeTest( |
457 |
new String[] { |
807 |
new String[] { |
458 |
"X.java", |
808 |
"X.java", |
459 |
"public class X {\n" + |
809 |
"public class X {\n" + |
460 |
" void foo() {\n" + |
810 |
" void foo() {\n" + |
461 |
" Object o = false ? null : new Object();\n" + |
811 |
" Integer i = 0;\n" + |
462 |
" o.toString();\n" + |
812 |
" if (i == null) {};\n" + // complain: this is non null |
463 |
" }\n" + |
813 |
" }\n" + |
464 |
"}\n"}, |
814 |
"}\n"}, |
465 |
"" |
815 |
"----------\n" + |
466 |
); |
816 |
"1. ERROR in X.java (at line 4)\n" + |
|
|
817 |
" if (i == null) {};\n" + |
818 |
" ^\n" + |
819 |
"The variable i cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
820 |
"----------\n"); |
467 |
} |
821 |
} |
|
|
822 |
} |
468 |
|
823 |
|
469 |
// null analysis -- conditional expression |
824 |
// null analysis -- autoboxing |
470 |
// TODO (maxime) fix |
825 |
public void test0043_autoboxing_literal() { |
471 |
public void _test0023_conditional_expression() { |
826 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
472 |
this.runNegativeTest( |
827 |
this.runNegativeTest( |
473 |
new String[] { |
828 |
new String[] { |
474 |
"X.java", |
829 |
"X.java", |
475 |
"public class X {\n" + |
830 |
"public class X {\n" + |
476 |
" void foo() {\n" + |
831 |
" void foo() {\n" + |
477 |
" Object o = (1 == 1) ? null : new Object();\n" + |
832 |
" Integer i = null;\n" + |
478 |
" o.toString();\n" + |
833 |
" System.out.println(i + 4);\n" + // complain: this is null |
479 |
" }\n" + |
834 |
" }\n" + |
480 |
"}\n"}, |
835 |
"}\n"}, |
481 |
"----------\n" + |
836 |
"----------\n" + |
482 |
"1. WARNING in X.java (at line 4)\n" + |
837 |
"1. ERROR in X.java (at line 4)\n" + |
483 |
" o.toString();\n" + |
838 |
" System.out.println(i + 4);\n" + |
484 |
" ^\n" + |
839 |
" ^\n" + |
485 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
840 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
486 |
"----------\n" |
841 |
"----------\n"); |
487 |
); |
|
|
488 |
} |
842 |
} |
489 |
//TODO (maxime) - add case with non constant condition in conditional expression cond() ? ... : ... |
843 |
} |
490 |
|
844 |
|
491 |
// null analysis -- autoboxing |
845 |
// null analysis -- autoboxing |
492 |
// TODO (maxime) fix |
846 |
// origin: AssignmentTest#test020 |
493 |
public void _test0030_autoboxing_compound_assignment() { |
847 |
public void test0044_autoboxing() { |
494 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
848 |
this.runConformTest( |
495 |
this.runNegativeTest( |
849 |
new String[] { |
496 |
new String[] { |
850 |
"X.java", |
497 |
"X.java", |
851 |
"public class X {\n" + |
498 |
"public class X {\n" + |
852 |
" void foo() {\n" + |
499 |
" void foo() {\n" + |
853 |
" int i = 0;\n" + |
500 |
" Integer i = null;\n" + |
854 |
" boolean b = i < 10;\n" + |
501 |
" i += 1;\n" + |
855 |
" }\n" + |
502 |
" }\n" + |
856 |
"}\n"}, |
503 |
"}\n"}, |
|
|
504 |
"----------\n" + |
505 |
"1. WARNING in X.java (at line 4)\n" + |
506 |
" i += 1;\n" + |
507 |
" ^\n" + |
508 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
509 |
"----------\n" |
510 |
); |
511 |
} |
512 |
} |
513 |
|
514 |
// null analysis -- autoboxing |
515 |
// TODO (maxime) fix |
516 |
public void _test0031_autoboxing_increment_operator() { |
517 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
518 |
this.runNegativeTest( |
519 |
new String[] { |
520 |
"X.java", |
521 |
"public class X {\n" + |
522 |
" void foo() {\n" + |
523 |
" Integer i = null;\n" + |
524 |
" i++;\n" + // complain: this is null |
525 |
" ++i;\n" + // quiet (because previous step guards it) |
526 |
" }\n" + |
527 |
"}\n"}, |
528 |
"----------\n" + |
529 |
"1. WARNING in X.java (at line 4)\n" + |
530 |
" i++;\n" + |
531 |
" ^\n" + |
532 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
533 |
"----------\n" |
534 |
); |
535 |
} |
536 |
} |
537 |
|
538 |
// null analysis -- autoboxing |
539 |
public void test0032_autoboxing_literal() { |
540 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
541 |
this.runNegativeTest( |
542 |
new String[] { |
543 |
"X.java", |
544 |
"public class X {\n" + |
545 |
" void foo() {\n" + |
546 |
" Integer i = 0;\n" + |
547 |
" if (i == null) {};\n" + // complain: this is non null |
548 |
" }\n" + |
549 |
"}\n"}, |
550 |
"----------\n" + |
551 |
"1. WARNING in X.java (at line 4)\n" + |
552 |
" if (i == null) {};\n" + |
553 |
" ^\n" + |
554 |
"The variable i cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
555 |
"----------\n" |
556 |
); |
557 |
} |
558 |
} |
559 |
|
560 |
// null analysis -- autoboxing |
561 |
// TODO (maxime) fix |
562 |
public void _test0033_autoboxing_literal() { |
563 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
564 |
this.runNegativeTest( |
565 |
new String[] { |
566 |
"X.java", |
567 |
"public class X {\n" + |
568 |
" void foo() {\n" + |
569 |
" Integer i = null;\n" + |
570 |
" System.out.println(i + 4);\n" + // complain: this is null |
571 |
" }\n" + |
572 |
"}\n"}, |
573 |
"----------\n" + |
574 |
"1. WARNING in X.java (at line 4)\n" + |
575 |
" System.out.println(i + 4);\n" + |
576 |
" ^\n" + |
577 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
578 |
"----------\n" |
579 |
); |
580 |
} |
581 |
} |
582 |
|
583 |
// null analysis -- autoboxing |
584 |
// origin: AssignmentTest#test020 |
585 |
public void test034_autoboxing() { |
586 |
this.runNegativeTest( |
587 |
new String[] { |
588 |
"X.java", |
589 |
"public class X {\n" + |
590 |
" void foo() {\n" + |
591 |
" int i = 0;\n" + |
592 |
" boolean b = i < 10;\n" + |
593 |
" }\n" + |
594 |
"}\n", |
595 |
}, |
596 |
""); |
857 |
""); |
|
|
858 |
} |
859 |
|
860 |
// null analysis -- strings concatenation |
861 |
// JLS 15.18.1: if one of the operands is null, it is replaced by "null" |
862 |
// Note: having the diagnostic could come handing when the initialization path |
863 |
// is non trivial; to get the diagnostic, simply put in place an |
864 |
// extraneous call to toString() -- and remove it before releasing. |
865 |
public void test0045_strings_concatenation() { |
866 |
this.runConformTest( |
867 |
new String[] { |
868 |
"X.java", |
869 |
"public class X {\n" + |
870 |
" String foo(String s1, String s2) {\n" + |
871 |
" if (s1 == null) { /* */ };\n" + |
872 |
" return s1 + s2;\n" + |
873 |
" }\n" + |
874 |
"}\n"}, |
875 |
""); |
876 |
} |
877 |
|
878 |
// null analysis -- strings concatenation |
879 |
public void test0046_strings_concatenation() { |
880 |
this.runConformTest( |
881 |
new String[] { |
882 |
"X.java", |
883 |
"public class X {\n" + |
884 |
" String foo(String s1, String s2) {\n" + |
885 |
" if (s1 == null) { /* */ };\n" + |
886 |
" s1 += s2;\n" + |
887 |
" return s1;\n" + |
888 |
" }\n" + |
889 |
"}\n"}, |
890 |
""); |
891 |
} |
892 |
|
893 |
// null analysis -- strings concatenation |
894 |
public void test0047_strings_concatenation() { |
895 |
this.runNegativeTest( |
896 |
new String[] { |
897 |
"X.java", |
898 |
"public class X {\n" + |
899 |
" String foo(String s1) {\n" + |
900 |
" if (s1 == null) { /* */ };\n" + |
901 |
" return s1.toString();\n" + |
902 |
" }\n" + |
903 |
"}\n"}, |
904 |
"----------\n" + |
905 |
"1. ERROR in X.java (at line 4)\n" + |
906 |
" return s1.toString();\n" + |
907 |
" ^^\n" + |
908 |
"The variable s1 may be null\n" + |
909 |
"----------\n"); |
910 |
} |
911 |
|
912 |
// null analysis -- array |
913 |
public void test0050_array() { |
914 |
this.runConformTest( |
915 |
new String[] { |
916 |
"X.java", |
917 |
"public class X {\n" + |
918 |
" public static void main(String args[]) {\n" + |
919 |
" args = new String[] {\"zero\"};\n" + |
920 |
" args[0] = null;\n" + |
921 |
" if (args[0] == null) {};\n" + |
922 |
// quiet: we don't keep track of all array elements |
923 |
" }\n" + |
924 |
"}\n"}, |
925 |
""); |
926 |
} |
927 |
|
928 |
// null analysis -- array |
929 |
public void test0051_array() { |
930 |
this.runNegativeTest( |
931 |
new String[] { |
932 |
"X.java", |
933 |
"public class X {\n" + |
934 |
" public static void main(String args[]) {\n" + |
935 |
" args = null;\n" + |
936 |
" args[0].toString();\n" + // complain: args is null |
937 |
" }\n" + |
938 |
"}\n"}, |
939 |
"----------\n" + |
940 |
"1. ERROR in X.java (at line 4)\n" + |
941 |
" args[0].toString();\n" + |
942 |
" ^^^^\n" + |
943 |
"The variable args can only be null; it was either set to null or checked for null when last used\n" + |
944 |
"----------\n"); |
945 |
} |
946 |
|
947 |
// null analysis -- array |
948 |
public void test0052_array() { |
949 |
this.runConformTest( |
950 |
new String[] { |
951 |
"X.java", |
952 |
"public class X {\n" + |
953 |
" public void foo(String args[]) {\n" + |
954 |
" String s = args[0];\n" + |
955 |
" if (s == null) {};\n" + |
956 |
// quiet: we don't keep track of all array elements |
957 |
" }\n" + |
958 |
"}\n"}, |
959 |
""); |
960 |
} |
961 |
|
962 |
// null analysis -- array |
963 |
public void test0053_array() { |
964 |
this.runConformTest( |
965 |
new String[] { |
966 |
"X.java", |
967 |
"public class X {\n" + |
968 |
" public void foo(String args[]) {\n" + |
969 |
" for (int i = 0; i < args.length; i++) { /* */}\n" + |
970 |
" }\n" + |
971 |
"}\n"}, |
972 |
""); |
973 |
} |
974 |
|
975 |
// null analysis -- method call |
976 |
public void test0061_method_call_guard() { |
977 |
this.runNegativeTest( |
978 |
new String[] { |
979 |
"X.java", |
980 |
"public class X {\n" + |
981 |
" void foo(Object o) {\n" + |
982 |
" o.toString();\n" + // guards o from being null |
983 |
" if (o == null) {};\n" + // complain |
984 |
" }\n" + |
985 |
"}\n"}, |
986 |
"----------\n" + |
987 |
"1. ERROR in X.java (at line 4)\n" + |
988 |
" if (o == null) {};\n" + |
989 |
" ^\n" + |
990 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
991 |
"----------\n"); |
992 |
} |
993 |
|
994 |
// null analysis - method call |
995 |
public void test0062_method_call_isolation() { |
996 |
this.runNegativeTest( |
997 |
new String[] { |
998 |
"X.java", |
999 |
"public class X {\n" + |
1000 |
" void foo(Object o) {\n" + |
1001 |
" if (bar(o = null)) {\n" + |
1002 |
" if (o == null) {/* empty */}\n" + // complain |
1003 |
" }\n" + |
1004 |
" }\n" + |
1005 |
" boolean bar(Object o) {\n" + |
1006 |
" return true;\n" + |
1007 |
" }\n" + |
1008 |
"}\n"}, |
1009 |
"----------\n" + |
1010 |
"1. ERROR in X.java (at line 4)\n" + |
1011 |
" if (o == null) {/* empty */}\n" + |
1012 |
" ^\n" + |
1013 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1014 |
"----------\n"); |
1015 |
} |
1016 |
|
1017 |
// null analysis - method call |
1018 |
public void test0063_method_call_isolation() { |
1019 |
this.runConformTest( |
1020 |
new String[] { |
1021 |
"X.java", |
1022 |
"public class X {\n" + |
1023 |
" void foo(Object o) {\n" + |
1024 |
" if (bar(o == null ? new Object() : o)) {\n" + |
1025 |
" if (o == null) {/* empty */}\n" + // quiet |
1026 |
" }\n" + |
1027 |
" }\n" + |
1028 |
" boolean bar(Object o) {\n" + |
1029 |
" return true;\n" + |
1030 |
" }\n" + |
1031 |
"}\n"}, |
1032 |
""); |
1033 |
} |
1034 |
|
1035 |
// null analysis - method call |
1036 |
public void test0064_method_call_isolation() { |
1037 |
this.runNegativeTest( |
1038 |
new String[] { |
1039 |
"X.java", |
1040 |
"public class X {\n" + |
1041 |
" void foo(Object o) {\n" + |
1042 |
" if (bar(o = new Object())) {\n" + |
1043 |
" if (o == null) {/* empty */}\n" + // complain |
1044 |
" }\n" + |
1045 |
" }\n" + |
1046 |
" boolean bar(Object o) {\n" + |
1047 |
" return true;\n" + |
1048 |
" }\n" + |
1049 |
"}\n"}, |
1050 |
"----------\n" + |
1051 |
"1. ERROR in X.java (at line 4)\n" + |
1052 |
" if (o == null) {/* empty */}\n" + |
1053 |
" ^\n" + |
1054 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1055 |
"----------\n"); |
1056 |
} |
1057 |
|
1058 |
// null analysis - method call |
1059 |
public void test0065_method_call_invocation_target() { |
1060 |
this.runConformTest( |
1061 |
new String[] { |
1062 |
"X.java", |
1063 |
"public class X {\n" + |
1064 |
" void foo() {\n" + |
1065 |
" Object o = null;\n" + |
1066 |
" (o = new Object()).toString();\n" + // quiet |
1067 |
" }\n" + |
1068 |
"}\n"}, |
1069 |
""); |
1070 |
} |
1071 |
|
1072 |
// null analysis - method call |
1073 |
public void test0066_method_call_invocation_target() { |
1074 |
this.runNegativeTest( |
1075 |
new String[] { |
1076 |
"X.java", |
1077 |
"public class X {\n" + |
1078 |
" void foo() {\n" + |
1079 |
" Object o = new Object();\n" + |
1080 |
" (o = null).toString();\n" + // complain |
1081 |
" }\n" + |
1082 |
"}\n"}, |
1083 |
"----------\n" + |
1084 |
"1. ERROR in X.java (at line 4)\n" + |
1085 |
" (o = null).toString();\n" + |
1086 |
" ^^^^^^^^^^\n" + |
1087 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1088 |
"----------\n"); |
1089 |
} |
1090 |
|
1091 |
// null analysis - method call |
1092 |
public void test0067_method_call_invocation_target() { |
1093 |
this.runNegativeTest( |
1094 |
new String[] { |
1095 |
"X.java", |
1096 |
"public class X {\n" + |
1097 |
" void foo(Object o) {\n" + |
1098 |
" (o = new Object()).toString();\n" + // quiet |
1099 |
" if (o == null) { /* */ }\n" + // complain |
1100 |
" }\n" + |
1101 |
"}\n"}, |
1102 |
"----------\n" + |
1103 |
"1. ERROR in X.java (at line 4)\n" + |
1104 |
" if (o == null) { /* */ }\n" + |
1105 |
" ^\n" + |
1106 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1107 |
"----------\n"); |
1108 |
} |
1109 |
|
1110 |
// null analysis - method call |
1111 |
public void test0068_method_call_assignment() { |
1112 |
this.runConformTest( |
1113 |
new String[] { |
1114 |
"X.java", |
1115 |
"public class X {\n" + |
1116 |
" X bar() {\n" + |
1117 |
" return null;\n" + |
1118 |
" }\n" + |
1119 |
" void foo(X x) {\n" + |
1120 |
" x = x.bar();\n" + |
1121 |
" if (x == null) { /* */ }\n" + // quiet |
1122 |
" }\n" + |
1123 |
"}\n"}, |
1124 |
""); |
1125 |
} |
1126 |
|
1127 |
// null analysis -- type reference |
1128 |
public void test0070_type_reference() { |
1129 |
this.runNegativeTest( |
1130 |
new String[] { |
1131 |
"X.java", |
1132 |
"public class X {\n" + |
1133 |
" public static void main(String args[]) {\n" + |
1134 |
" Class c = java.lang.Object.class;\n" + |
1135 |
" if (c == null) {};\n" + |
1136 |
" }\n" + |
1137 |
"}\n"}, |
1138 |
"----------\n" + |
1139 |
"1. ERROR in X.java (at line 4)\n" + |
1140 |
" if (c == null) {};\n" + |
1141 |
" ^\n" + |
1142 |
"The variable c cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1143 |
"----------\n"); |
1144 |
} |
1145 |
|
1146 |
public void test0080_shortcut_boolean_expressions() { |
1147 |
this.runNegativeTest( |
1148 |
new String[] { |
1149 |
"X.java", |
1150 |
"public class X {\n" + |
1151 |
" void foo(Object o1, Object o2) {\n" + |
1152 |
" if (o1 != null && (o2 = o1) != null) { /* */ }\n" + |
1153 |
" }\n" + |
1154 |
"}\n"}, |
1155 |
"----------\n" + |
1156 |
"1. ERROR in X.java (at line 3)\n" + |
1157 |
" if (o1 != null && (o2 = o1) != null) { /* */ }\n" + |
1158 |
" ^^^^^^^^^\n" + |
1159 |
"The variable o2 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1160 |
"----------\n" |
1161 |
); |
1162 |
} |
1163 |
|
1164 |
public void test0081_shortcut_boolean_expressions() { |
1165 |
this.runNegativeTest( |
1166 |
new String[] { |
1167 |
"X.java", |
1168 |
"public class X {\n" + |
1169 |
" void foo(Object o1, Object o2) {\n" + |
1170 |
" while (o1 != null && (o2 = o1) != null) { /* */ }\n" + |
1171 |
" }\n" + |
1172 |
"}\n"}, |
1173 |
"----------\n" + |
1174 |
"1. ERROR in X.java (at line 3)\n" + |
1175 |
" while (o1 != null && (o2 = o1) != null) { /* */ }\n" + |
1176 |
" ^^^^^^^^^\n" + |
1177 |
"The variable o2 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1178 |
"----------\n" |
1179 |
); |
1180 |
} |
1181 |
|
1182 |
// null analysis - shortcut boolean expression |
1183 |
public void test0082_shortcut_boolean_expression() { |
1184 |
this.runNegativeTest( |
1185 |
new String[] { |
1186 |
"X.java", |
1187 |
"public class X {\n" + |
1188 |
" void foo(Object o) {\n" + |
1189 |
" if (o == null || o == null) {\n" + |
1190 |
" o = new Object();\n" + |
1191 |
" }\n" + |
1192 |
" if (o == null) { /* */ }\n" + |
1193 |
" }\n" + |
1194 |
"}"}, |
1195 |
"----------\n" + |
1196 |
"1. ERROR in X.java (at line 3)\n" + |
1197 |
" if (o == null || o == null) {\n" + |
1198 |
" ^\n" + |
1199 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1200 |
"----------\n" + |
1201 |
"2. ERROR in X.java (at line 6)\n" + |
1202 |
" if (o == null) { /* */ }\n" + |
1203 |
" ^\n" + |
1204 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1205 |
"----------\n"); |
1206 |
} |
1207 |
|
1208 |
// null analysis - shortcut boolean expression |
1209 |
public void test0083_shortcut_boolean_expression() { |
1210 |
this.runNegativeTest( |
1211 |
new String[] { |
1212 |
"X.java", |
1213 |
"public class X {\n" + |
1214 |
" void foo(Object o) {\n" + |
1215 |
" if (o == null && o == null) {\n" + |
1216 |
" o = new Object();\n" + |
1217 |
" }\n" + |
1218 |
" if (o == null) { /* */ }\n" + |
1219 |
" }\n" + |
1220 |
"}"}, |
1221 |
"----------\n" + |
1222 |
"1. ERROR in X.java (at line 3)\n" + |
1223 |
" if (o == null && o == null) {\n" + |
1224 |
" ^\n" + |
1225 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1226 |
"----------\n" + |
1227 |
"2. ERROR in X.java (at line 6)\n" + |
1228 |
" if (o == null) { /* */ }\n" + |
1229 |
" ^\n" + |
1230 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1231 |
"----------\n"); |
1232 |
} |
1233 |
|
1234 |
// null analysis -- instanceof |
1235 |
// JLS: instanceof returns false if o turns out to be null |
1236 |
public void test0090_instanceof() { |
1237 |
this.runConformTest( |
1238 |
new String[] { |
1239 |
"X.java", |
1240 |
"class X {\n" + |
1241 |
" boolean dummy;\n" + |
1242 |
" void foo (Object o) {\n" + |
1243 |
" if (dummy) {\n" + |
1244 |
" o = null;\n" + |
1245 |
" }\n" + |
1246 |
" if (o instanceof X) { /* */ }\n" + |
1247 |
" }\n" + |
1248 |
"}"}, |
1249 |
""); |
1250 |
} |
1251 |
|
1252 |
// null analysis -- instanceof |
1253 |
public void test0091_instanceof() { |
1254 |
this.runConformTest( |
1255 |
new String[] { |
1256 |
"X.java", |
1257 |
"class X {\n" + |
1258 |
" boolean dummy;\n" + |
1259 |
" void foo (Object o) {\n" + |
1260 |
" if (dummy) {\n" + |
1261 |
" o = null;\n" + |
1262 |
" }\n" + |
1263 |
" if (o instanceof X) { /* */ }\n" + |
1264 |
" if (o == null) { /* */ }\n" + |
1265 |
" }\n" + |
1266 |
"}"}, |
1267 |
""); |
1268 |
} |
1269 |
|
1270 |
// null analysis -- instanceof |
1271 |
// can only be null always yields false |
1272 |
public void test0092_instanceof() { |
1273 |
this.runNegativeTest( |
1274 |
new String[] { |
1275 |
"X.java", |
1276 |
"class X {\n" + |
1277 |
" boolean dummy;\n" + |
1278 |
" void foo () {\n" + |
1279 |
" Object o = null;\n" + |
1280 |
" if (o instanceof X) { /* */ }\n" + |
1281 |
" }\n" + |
1282 |
"}"}, |
1283 |
"----------\n" + |
1284 |
"1. ERROR in X.java (at line 5)\n" + |
1285 |
" if (o instanceof X) { /* */ }\n" + |
1286 |
" ^\n" + |
1287 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1288 |
"----------\n"); |
1289 |
} |
1290 |
|
1291 |
// null analysis -- instanceof |
1292 |
public void test0093_instanceof() { |
1293 |
this.runNegativeTest( |
1294 |
new String[] { |
1295 |
"X.java", |
1296 |
"class X {\n" + |
1297 |
" void foo(Object x) {\n" + |
1298 |
" if (x instanceof X) {\n" + |
1299 |
" if (x == null) { /* */ }\n" + // cannot happen |
1300 |
" }\n" + |
1301 |
" }\n" + |
1302 |
"}"}, |
1303 |
"----------\n" + |
1304 |
"1. ERROR in X.java (at line 4)\n" + |
1305 |
" if (x == null) { /* */ }\n" + |
1306 |
" ^\n" + |
1307 |
"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1308 |
"----------\n"); |
1309 |
} |
1310 |
|
1311 |
// null analysis -- instanceof |
1312 |
public void test0094_instanceof() { |
1313 |
this.runConformTest( |
1314 |
new String[] { |
1315 |
"X.java", |
1316 |
"class X {\n" + |
1317 |
" void foo(Object x) {\n" + |
1318 |
" if (x instanceof X) {\n" + |
1319 |
" return;\n" + |
1320 |
" }\n" + |
1321 |
" if (x != null) { /* */ }\n" + |
1322 |
// cannot decide: could be null of new Object() for example |
1323 |
" }\n" + |
1324 |
"}"}, |
1325 |
""); |
1326 |
} |
1327 |
|
1328 |
// null analysis -- if/else |
1329 |
// check that obviously unreachable code does not modify the null |
1330 |
// status of a local |
1331 |
// the said code is not marked as unreachable per JLS 14.21 (the rationale |
1332 |
// being the accommodation for the if (constant_flag_evaluating_to_false) |
1333 |
// {code...} volontary code exclusion pattern) |
1334 |
public void test0300_if_else() { |
1335 |
this.runNegativeTest( |
1336 |
new String[] { |
1337 |
"X.java", |
1338 |
"public class X {\n" + |
1339 |
" public void foo() {\n" + |
1340 |
" Object o = null;\n" + |
1341 |
" if (false) {\n" + |
1342 |
" o = new Object();\n" + // skipped |
1343 |
" }\n" + |
1344 |
" if (true) {\n" + |
1345 |
" //\n" + |
1346 |
" }\n" + |
1347 |
" else {\n" + |
1348 |
" o = new Object();\n" + // skipped |
1349 |
" }\n" + |
1350 |
" o.toString();\n" + |
1351 |
" }\n" + |
1352 |
"}\n"}, |
1353 |
"----------\n" + |
1354 |
"1. ERROR in X.java (at line 13)\n" + |
1355 |
" o.toString();\n" + |
1356 |
" ^\n" + |
1357 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1358 |
"----------\n"); |
1359 |
} |
1360 |
|
1361 |
// null analysis - if/else |
1362 |
public void test0301_if_else() { |
1363 |
this.runNegativeTest( |
1364 |
new String[] { |
1365 |
"X.java", |
1366 |
"public class X {\n" + |
1367 |
" void foo() {\n" + |
1368 |
" Object o = new Object();\n" + |
1369 |
" if (o != null) {\n" + |
1370 |
" }\n" + |
1371 |
" }\n" + |
1372 |
"}\n"}, |
1373 |
"----------\n" + |
1374 |
"1. ERROR in X.java (at line 4)\n" + |
1375 |
" if (o != null) {\n" + |
1376 |
" ^\n" + |
1377 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1378 |
"----------\n"); |
1379 |
} |
1380 |
|
1381 |
// null analysis - if/else |
1382 |
public void test0302_if_else() { |
1383 |
this.runNegativeTest( |
1384 |
new String[] { |
1385 |
"X.java", |
1386 |
"public class X {\n" + |
1387 |
" void foo(Object o) throws Exception {\n" + |
1388 |
" if (o == null) {\n" + |
1389 |
" throw new Exception();\n" + |
1390 |
" }\n" + |
1391 |
" if (o != null) {\n" + // only get there if o non null |
1392 |
" }\n" + |
1393 |
" }\n" + |
1394 |
"}\n"}, |
1395 |
"----------\n" + |
1396 |
"1. ERROR in X.java (at line 6)\n" + |
1397 |
" if (o != null) {\n" + |
1398 |
" ^\n" + |
1399 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1400 |
"----------\n"); |
1401 |
} |
1402 |
|
1403 |
// null analysis - if/else |
1404 |
public void test0303_if_else() { |
1405 |
this.runNegativeTest( |
1406 |
new String[] { |
1407 |
"X.java", |
1408 |
"public class X {\n" + |
1409 |
" void foo(Object o) {\n" + |
1410 |
" if (o == null) {\n" + |
1411 |
" return;\n" + |
1412 |
" }\n" + |
1413 |
" if (o != null) {\n" + |
1414 |
" }\n" + |
1415 |
" }\n" + |
1416 |
"}\n"}, |
1417 |
"----------\n" + |
1418 |
"1. ERROR in X.java (at line 6)\n" + |
1419 |
" if (o != null) {\n" + |
1420 |
" ^\n" + |
1421 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1422 |
"----------\n"); |
1423 |
} |
1424 |
|
1425 |
// null analysis - if/else |
1426 |
public void test0304_if_else() { |
1427 |
this.runNegativeTest( |
1428 |
new String[] { |
1429 |
"X.java", |
1430 |
"public class X {\n" + |
1431 |
" void foo(Object o) {\n" + |
1432 |
" if (o == null) {\n" + |
1433 |
" o.toString();\n" + |
1434 |
" }\n" + |
1435 |
" }\n" + |
1436 |
"}\n"}, |
1437 |
"----------\n" + |
1438 |
"1. ERROR in X.java (at line 4)\n" + |
1439 |
" o.toString();\n" + |
1440 |
" ^\n" + |
1441 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1442 |
"----------\n"); |
1443 |
} |
1444 |
|
1445 |
// null analysis - if/else |
1446 |
public void test0305_if_else() { |
1447 |
this.runNegativeTest( |
1448 |
new String[] { |
1449 |
"X.java", |
1450 |
"public class X {\n" + |
1451 |
" void foo(Object o) {\n" + |
1452 |
" if (o == null) {\n" + |
1453 |
" // do nothing\n" + |
1454 |
" }\n" + |
1455 |
" o.toString();\n" + |
1456 |
" }\n" + |
1457 |
"}\n"}, |
1458 |
"----------\n" + |
1459 |
"1. ERROR in X.java (at line 6)\n" + |
1460 |
" o.toString();\n" + |
1461 |
" ^\n" + |
1462 |
"The variable o may be null\n" + |
1463 |
"----------\n"); |
1464 |
} |
1465 |
|
1466 |
// null analysis - if/else |
1467 |
public void test0306_if_else() { |
1468 |
this.runNegativeTest( |
1469 |
new String[] { |
1470 |
"X.java", |
1471 |
"public class X {\n" + |
1472 |
" void foo(Object o) {\n" + |
1473 |
" if (o.toString().equals(\"\")) {\n" + |
1474 |
" if (o == null) {\n" + // complain: could not get here |
1475 |
" // do nothing\n" + |
1476 |
" }\n" + |
1477 |
" }\n" + |
1478 |
" }\n" + |
1479 |
"}\n"}, |
1480 |
"----------\n" + |
1481 |
"1. ERROR in X.java (at line 4)\n" + |
1482 |
" if (o == null) {\n" + |
1483 |
" ^\n" + |
1484 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1485 |
"----------\n"); |
1486 |
} |
1487 |
|
1488 |
// null analysis - if/else |
1489 |
public void test0307_if_else() { |
1490 |
this.runConformTest( |
1491 |
new String[] { |
1492 |
"X.java", |
1493 |
"public class X {\n" + |
1494 |
" void foo(Object o) {\n" + |
1495 |
" if (o == null) {\n" + |
1496 |
" System.exit(0);\n" + |
1497 |
" }\n" + |
1498 |
" if (o == null) {\n" + |
1499 |
// quiet |
1500 |
// a direct call to System.exit() can be recognized as such; yet, |
1501 |
// a lot of other methods may have the same property (aka calling |
1502 |
// System.exit() themselves.) |
1503 |
" // do nothing\n" + |
1504 |
" }\n" + |
1505 |
" }\n" + |
1506 |
"}\n"}, |
1507 |
""); |
1508 |
} |
1509 |
|
1510 |
// null analysis - if/else |
1511 |
public void test0308_if_else() { |
1512 |
this.runNegativeTest( |
1513 |
new String[] { |
1514 |
"X.java", |
1515 |
"public class X {\n" + |
1516 |
" boolean b;\n" + |
1517 |
" void foo(Object o) {\n" + |
1518 |
" if (b) {\n" + |
1519 |
" o = null;\n" + |
1520 |
" }\n" + |
1521 |
" o.toString();\n" + // complain |
1522 |
" }\n" + |
1523 |
"}\n"}, |
1524 |
"----------\n" + |
1525 |
"1. ERROR in X.java (at line 7)\n" + |
1526 |
" o.toString();\n" + |
1527 |
" ^\n" + |
1528 |
"The variable o may be null\n" + |
1529 |
"----------\n"); |
1530 |
} |
1531 |
|
1532 |
// null analysis - if/else |
1533 |
public void test0309_if_else() { |
1534 |
this.runNegativeTest( |
1535 |
new String[] { |
1536 |
"X.java", |
1537 |
"public class X {\n" + |
1538 |
" boolean b1, b2;\n" + |
1539 |
" void foo(Object o) {\n" + |
1540 |
" if (b1) {\n" + |
1541 |
" o = null;\n" + |
1542 |
" }\n" + |
1543 |
" if (b2) {\n" + |
1544 |
" o = new Object();\n" + |
1545 |
" }\n" + |
1546 |
" o.toString();\n" + // complain |
1547 |
" }\n" + |
1548 |
"}\n"}, |
1549 |
"----------\n" + |
1550 |
"1. ERROR in X.java (at line 10)\n" + |
1551 |
" o.toString();\n" + |
1552 |
" ^\n" + |
1553 |
"The variable o may be null\n" + |
1554 |
"----------\n"); |
1555 |
} |
1556 |
|
1557 |
// null analysis - if/else |
1558 |
public void test0310_if_else() { |
1559 |
this.runNegativeTest( |
1560 |
new String[] { |
1561 |
"X.java", |
1562 |
"public class X {\n" + |
1563 |
" boolean b1, b2;\n" + |
1564 |
" void foo(Object o) {\n" + |
1565 |
" if (b1) {\n" + |
1566 |
" o = null;\n" + |
1567 |
" }\n" + |
1568 |
" if (b2) {\n" + |
1569 |
" o.toString();\n" + // complain |
1570 |
" o.toString();\n" + // silent |
1571 |
" }\n" + |
1572 |
" o.toString();\n" + // complain |
1573 |
" }\n" + |
1574 |
"}\n"}, |
1575 |
"----------\n" + |
1576 |
"1. ERROR in X.java (at line 8)\n" + |
1577 |
" o.toString();\n" + |
1578 |
" ^\n" + |
1579 |
"The variable o may be null\n" + |
1580 |
"----------\n" + |
1581 |
"2. ERROR in X.java (at line 11)\n" + |
1582 |
" o.toString();\n" + |
1583 |
" ^\n" + |
1584 |
"The variable o may be null\n" + |
1585 |
"----------\n"); |
1586 |
} |
1587 |
|
1588 |
// null analysis - if/else |
1589 |
public void test0311_if_else() { |
1590 |
this.runConformTest( |
1591 |
new String[] { |
1592 |
"X.java", |
1593 |
"public class X {\n" + |
1594 |
" void foo(Object o) {\n" + |
1595 |
" if (o == null)\n" + |
1596 |
" o = new Object();\n" + |
1597 |
" o.toString();\n" + // quiet |
1598 |
" }\n" + |
1599 |
"}" }, |
1600 |
""); |
1601 |
} |
1602 |
|
1603 |
// null analysis - if/else |
1604 |
// PMT: exactly the case we talked about; what happens is that the first |
1605 |
// if shade doubts upon o; what we could do is to avoid marking in case |
1606 |
// of error? not sure this is appropriate though, because of inner code |
1607 |
// into the if itself; I believe I somewhat did that on purpose: the latest |
1608 |
// wins; completed with o.toString()... |
1609 |
// basically, the choice is about what we should do in case of error: |
1610 |
// neglect the effect of the error, or propagate this effect; the second |
1611 |
// tends to produce less repeated errors (I believe) than the first... |
1612 |
// PREMATURE could refine adding a null-dependent reachable mark... not urgent |
1613 |
public void test0312_if_else() { |
1614 |
this.runNegativeTest( |
1615 |
new String[] { |
1616 |
"X.java", |
1617 |
"public class X {\n" + |
1618 |
"\n" + |
1619 |
" void foo() {\n" + |
1620 |
" Object o = new Object();\n" + |
1621 |
" if (o == null) { /* */ }\n" + // complain |
1622 |
" if (o != null) { /* */ }\n" + // quiet |
1623 |
" o.toString();\n" + // complain |
1624 |
" }\n" + |
1625 |
"}\n"}, |
1626 |
"----------\n" + |
1627 |
"1. ERROR in X.java (at line 5)\n" + |
1628 |
" if (o == null) { /* */ }\n" + |
1629 |
" ^\n" + |
1630 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1631 |
"----------\n" + |
1632 |
"2. ERROR in X.java (at line 7)\n" + |
1633 |
" o.toString();\n" + |
1634 |
" ^\n" + |
1635 |
"The variable o may be null\n" + |
1636 |
"----------\n"); |
1637 |
} |
1638 |
|
1639 |
// null analysis - if/else |
1640 |
public void test0313_if_else() { |
1641 |
this.runNegativeTest( |
1642 |
new String[] { |
1643 |
"X.java", |
1644 |
"public class X {\n" + |
1645 |
" void foo(Object o) {\n" + |
1646 |
" if (o == null) {\n" + // quiet |
1647 |
" o = new Object();\n" + |
1648 |
" }\n" + |
1649 |
" if (o == null) { /* */ }\n" + |
1650 |
// complain: o set to non null iff it was null |
1651 |
" }\n" + |
1652 |
"}"}, |
1653 |
"----------\n" + |
1654 |
"1. ERROR in X.java (at line 6)\n" + |
1655 |
" if (o == null) { /* */ }\n" + |
1656 |
" ^\n" + |
1657 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1658 |
"----------\n"); |
1659 |
} |
1660 |
|
1661 |
// null analysis - if/else |
1662 |
public void test0314_if_else() { |
1663 |
this.runNegativeTest( |
1664 |
new String[] { |
1665 |
"X.java", |
1666 |
"public class X {\n" + |
1667 |
" void foo(Object o) {\n" + |
1668 |
" if (o != null) {\n" + // quiet |
1669 |
" o = null;\n" + |
1670 |
" }\n" + |
1671 |
" if (o == null) { /* */ }\n" + // complain |
1672 |
" }\n" + |
1673 |
"}"}, |
1674 |
"----------\n" + |
1675 |
"1. ERROR in X.java (at line 6)\n" + |
1676 |
" if (o == null) { /* */ }\n" + |
1677 |
" ^\n" + |
1678 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1679 |
"----------\n"); |
1680 |
} |
1681 |
|
1682 |
// null analysis - if/else |
1683 |
public void test0315_if_else() { |
1684 |
this.runNegativeTest( |
1685 |
new String[] { |
1686 |
"X.java", |
1687 |
"public class X {\n" + |
1688 |
" void foo(Object o) {\n" + |
1689 |
" if (o != null) {\n" + // quiet |
1690 |
" o = null;\n" + |
1691 |
" }\n" + |
1692 |
" o.toString();\n" + // complain |
1693 |
" }\n" + |
1694 |
"}"}, |
1695 |
"----------\n" + |
1696 |
"1. ERROR in X.java (at line 6)\n" + |
1697 |
" o.toString();\n" + |
1698 |
" ^\n" + |
1699 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1700 |
"----------\n"); |
1701 |
} |
1702 |
|
1703 |
// null analysis - if/else |
1704 |
public void test0316_if_else() { |
1705 |
this.runNegativeTest( |
1706 |
new String[] { |
1707 |
"X.java", |
1708 |
"public class X {\n" + |
1709 |
" void foo(Object o, boolean b) {\n" + |
1710 |
" if (o == null || b) { /* */ }\n" + // quiet |
1711 |
" else { /* */ }\n" + |
1712 |
" o.toString();\n" + // complain |
1713 |
" }\n" + |
1714 |
"}"}, |
1715 |
"----------\n" + |
1716 |
"1. ERROR in X.java (at line 5)\n" + |
1717 |
" o.toString();\n" + |
1718 |
" ^\n" + |
1719 |
"The variable o may be null\n" + |
1720 |
"----------\n"); |
1721 |
} |
1722 |
|
1723 |
// null analysis - if/else |
1724 |
public void test0317_if_else_nested() { |
1725 |
this.runConformTest( |
1726 |
new String[] { |
1727 |
"X.java", |
1728 |
"public class X {\n" + |
1729 |
" void foo(Object o, boolean b) {\n" + |
1730 |
" if (o != null) {\n" + // quiet |
1731 |
" if (b) {\n" + // quiet |
1732 |
" o = null;\n" + |
1733 |
" }\n" + |
1734 |
" }\n" + |
1735 |
" if (o == null) { /* */ }\n" + // quiet |
1736 |
" }\n" + |
1737 |
"}"}, |
1738 |
""); |
1739 |
} |
1740 |
|
1741 |
// null analysis - if/else |
1742 |
public void test0318_if_else_nested() { |
1743 |
this.runConformTest( |
1744 |
new String[] { |
1745 |
"X.java", |
1746 |
"public class X {\n" + |
1747 |
" void foo(Object o, boolean b) {\n" + |
1748 |
" if (o != null) {\n" + // quiet |
1749 |
" if (b) {\n" + // quiet |
1750 |
" o = null;\n" + |
1751 |
" }\n" + |
1752 |
" if (o == null) { /* */ }\n" + // quiet |
1753 |
" }\n" + |
1754 |
" }\n" + |
1755 |
"}"}, |
1756 |
""); |
1757 |
} |
1758 |
|
1759 |
// null analysis - if/else |
1760 |
// REVIEW we do nothing at this point to diagnose the contents of fake reachable code |
1761 |
public void test0319_if_else_dead_branch() { |
1762 |
this.runConformTest( |
1763 |
new String[] { |
1764 |
"X.java", |
1765 |
"public class X {\n" + |
1766 |
" void foo(Object o, boolean b) {\n" + |
1767 |
" if (false) {\n" + |
1768 |
" o = null;\n" + |
1769 |
" if (o == null) { /* */ }\n" + |
1770 |
" }\n" + |
1771 |
" }\n" + |
1772 |
"}"}, |
1773 |
""); |
1774 |
} |
1775 |
|
1776 |
// null analysis - if/else |
1777 |
public void test0320_if_else() { |
1778 |
this.runNegativeTest( |
1779 |
new String[] { |
1780 |
"X.java", |
1781 |
"public class X {\n" + |
1782 |
" void foo(Object o) {\n" + |
1783 |
" o.toString();\n" + |
1784 |
" if (o == null) { /* */ }\n" + // complain |
1785 |
" }\n" + |
1786 |
"}"}, |
1787 |
"----------\n" + |
1788 |
"1. ERROR in X.java (at line 4)\n" + |
1789 |
" if (o == null) { /* */ }\n" + |
1790 |
" ^\n" + |
1791 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1792 |
"----------\n"); |
1793 |
} |
1794 |
|
1795 |
// null analysis - if/else |
1796 |
public void test0321_if_else() { |
1797 |
this.runConformTest( |
1798 |
new String[] { |
1799 |
"X.java", |
1800 |
"public class X {\n" + |
1801 |
" void foo(Object o, boolean b) {\n" + |
1802 |
" Object other = new Object();\n" + |
1803 |
" if (b) {\n" + |
1804 |
" other = o;\n" + |
1805 |
" }\n" + |
1806 |
" if (o != null) { /* */ }\n" + // quiet |
1807 |
" }\n" + |
1808 |
"}"}, |
1809 |
""); |
1810 |
} |
1811 |
|
1812 |
// null analysis - if/else |
1813 |
public void test0322_if_else() { |
1814 |
this.runNegativeTest( |
1815 |
new String[] { |
1816 |
"X.java", |
1817 |
"public class X {\n" + |
1818 |
" void foo(Object o, boolean b) {\n" + |
1819 |
" o.toString();\n" + |
1820 |
" if (b) { /* */ }\n" + |
1821 |
" if (o == null) { /* */ }\n" + // complain |
1822 |
" }\n" + |
1823 |
"}"}, |
1824 |
"----------\n" + |
1825 |
"1. ERROR in X.java (at line 5)\n" + |
1826 |
" if (o == null) { /* */ }\n" + |
1827 |
" ^\n" + |
1828 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
1829 |
"----------\n"); |
1830 |
} |
1831 |
|
1832 |
// null analysis - if/else |
1833 |
public void test0323_if_else() { |
1834 |
this.runConformTest( |
1835 |
new String[] { |
1836 |
"X.java", |
1837 |
"public class X {\n" + |
1838 |
" void foo(Object o, boolean b) {\n" + |
1839 |
" if (o == null && b) {\n" + |
1840 |
" o = new Object();\n" + |
1841 |
" }\n" + |
1842 |
" if (o == null) { /* */ }\n" + // quiet |
1843 |
" }\n" + |
1844 |
"}"}, |
1845 |
""); |
1846 |
} |
1847 |
|
1848 |
// null analysis - if/else |
1849 |
public void test0324_if_else_nested() { |
1850 |
this.runConformTest( |
1851 |
new String[] { |
1852 |
"X.java", |
1853 |
"class X {\n" + |
1854 |
" void foo (boolean b) {\n" + |
1855 |
" String s = null;\n" + |
1856 |
" if (b) {\n" + |
1857 |
" if (b) {\n" + |
1858 |
" s = \"1\";\n" + |
1859 |
" } \n" + |
1860 |
" else {\n" + |
1861 |
" s = \"2\";\n" + |
1862 |
" }\n" + |
1863 |
" } \n" + |
1864 |
" else if (b) {\n" + |
1865 |
" s = \"3\"; \n" + |
1866 |
" } \n" + |
1867 |
" else {\n" + |
1868 |
" s = \"4\";\n" + |
1869 |
" }\n" + |
1870 |
" s.toString();\n" + |
1871 |
" }\n" + |
1872 |
"}"}, |
1873 |
""); |
1874 |
} |
1875 |
|
1876 |
// null analysis - if/else |
1877 |
public void test0325_if_else_nested() { |
1878 |
this.runNegativeTest( |
1879 |
new String[] { |
1880 |
"X.java", |
1881 |
"class X {\n" + |
1882 |
" void foo (boolean b) {\n" + |
1883 |
" String s = null;\n" + |
1884 |
" if (b) {\n" + |
1885 |
" if (b) {\n" + |
1886 |
" s = \"1\";\n" + |
1887 |
" } \n" + |
1888 |
" else {\n" + |
1889 |
" s = \"2\";\n" + |
1890 |
" }\n" + |
1891 |
" } \n" + |
1892 |
" else if (b) {\n" + |
1893 |
" if (b) {\n" + |
1894 |
" s = \"3\"; \n" + |
1895 |
" }\n" + |
1896 |
" } \n" + |
1897 |
" else {\n" + |
1898 |
" s = \"4\";\n" + |
1899 |
" }\n" + |
1900 |
" s.toString();\n" + |
1901 |
" }\n" + |
1902 |
"}"}, |
1903 |
"----------\n" + |
1904 |
"1. ERROR in X.java (at line 20)\n" + |
1905 |
" s.toString();\n" + |
1906 |
" ^\n" + |
1907 |
"The variable s may be null\n" + |
1908 |
"----------\n"); |
1909 |
} |
1910 |
|
1911 |
// null analysis - if/else |
1912 |
// REVIEW limit: we cannot sync on external factors, even if this is a pattern |
1913 |
// REVIEW that is quite used |
1914 |
public void test0326_if_else() { |
1915 |
this.runNegativeTest( |
1916 |
new String[] { |
1917 |
"X.java", |
1918 |
"class X {\n" + |
1919 |
" void foo (boolean b) {\n" + |
1920 |
" String s1 = null;\n" + |
1921 |
" if (b) {\n" + |
1922 |
" s1 = \"1\";\n" + |
1923 |
" }\n" + |
1924 |
" s1.toString();\n" + // complain: can't guess if b means anything for s1 init |
1925 |
" }\n" + |
1926 |
"}"}, |
1927 |
"----------\n" + |
1928 |
"1. ERROR in X.java (at line 7)\n" + |
1929 |
" s1.toString();\n" + |
1930 |
" ^^\n" + |
1931 |
"The variable s1 may be null\n" + |
1932 |
"----------\n"); |
1933 |
} |
1934 |
|
1935 |
// null analysis - if/else |
1936 |
// REVIEW limit: we cannot sync on external factors, even if this is a pattern |
1937 |
// REVIEW that is quite used |
1938 |
public void test0327_if_else() { |
1939 |
this.runNegativeTest( |
1940 |
new String[] { |
1941 |
"X.java", |
1942 |
"class X {\n" + |
1943 |
" void foo (String s1) {\n" + |
1944 |
" String s2 = null;\n" + |
1945 |
" if (s1 == null) {\n" + |
1946 |
" s1 = \"1\";\n" + |
1947 |
" s2 = \"2\";\n" + |
1948 |
" }\n" + |
1949 |
" s1.toString();\n" + // quiet |
1950 |
" s2.toString();\n" + // complain: can't guess whether s2 depends on s1 for init |
1951 |
" }\n" + |
1952 |
"}"}, |
1953 |
"----------\n" + |
1954 |
"1. ERROR in X.java (at line 9)\n" + |
1955 |
" s2.toString();\n" + |
1956 |
" ^^\n" + |
1957 |
"The variable s2 may be null\n" + |
1958 |
"----------\n"); |
1959 |
} |
1960 |
|
1961 |
// null analysis - if/else |
1962 |
public void test0328_if_else() { |
1963 |
this.runNegativeTest( |
1964 |
new String[] { |
1965 |
"X.java", |
1966 |
"public class X {\n" + |
1967 |
" void foo(Object o, boolean b) {\n" + |
1968 |
" if (o != null || b) {\n" + |
1969 |
" if (b) {\n" + |
1970 |
" o = new Object();\n" + |
1971 |
" }\n" + |
1972 |
" }\n" + // quiet |
1973 |
" else { /* */ }\n" + |
1974 |
" o.toString();\n" + // complain |
1975 |
" }\n" + |
1976 |
"}"}, |
1977 |
"----------\n" + |
1978 |
"1. ERROR in X.java (at line 9)\n" + |
1979 |
" o.toString();\n" + |
1980 |
" ^\n" + |
1981 |
"The variable o may be null\n" + |
1982 |
"----------\n"); |
1983 |
} |
1984 |
|
1985 |
// null analysis - if/else |
1986 |
// REVIEW may be surprising within more elaborate code |
1987 |
public void test0329_if_else_nested() { |
1988 |
this.runNegativeTest( |
1989 |
new String[] { |
1990 |
"X.java", |
1991 |
"public class X {\n" + |
1992 |
" void foo(Object o, boolean b) {\n" + |
1993 |
" if (b) {\n" + |
1994 |
" if (o != null) { /* */ }\n" + // shade doubts on o |
1995 |
" }\n" + |
1996 |
" o.toString();\n" + // complain |
1997 |
" }\n" + |
1998 |
"}"}, |
1999 |
"----------\n" + |
2000 |
"1. ERROR in X.java (at line 6)\n" + |
2001 |
" o.toString();\n" + |
2002 |
" ^\n" + |
2003 |
"The variable o may be null\n" + |
2004 |
"----------\n"); |
2005 |
} |
2006 |
|
2007 |
// null analysis - if/else |
2008 |
public void test0330_if_else_nested() { |
2009 |
this.runConformTest( |
2010 |
new String[] { |
2011 |
"X.java", |
2012 |
"public class X {\n" + |
2013 |
" void foo(Object o, boolean b) {\n" + |
2014 |
" if (b) {\n" + |
2015 |
" if (o == null) {\n" + |
2016 |
" o = new Object();\n" + |
2017 |
" }\n" + |
2018 |
" }\n" + |
2019 |
" o.toString();\n" + // quiet |
2020 |
" }\n" + |
2021 |
"}"}, |
2022 |
""); |
2023 |
} |
2024 |
|
2025 |
// null analysis - if/else |
2026 |
public void test0331_if_else_nested() { |
2027 |
this.runConformTest( |
2028 |
new String[] { |
2029 |
"X.java", |
2030 |
"public class X {\n" + |
2031 |
" void foo(Object o1, Object o2) {\n" + |
2032 |
" Object o3 = o2;\n" + |
2033 |
" if (o1 != null) {\n" + |
2034 |
" o3.toString(); // guards o3\n" + |
2035 |
" }\n" + |
2036 |
" o1 = o3;\n" + |
2037 |
" if (o1 != null) { /* */ }\n" + |
2038 |
" }\n" + |
2039 |
"}"}, |
2040 |
""); |
2041 |
} |
2042 |
|
2043 |
// null analysis - if/else |
2044 |
public void test0332_if_else() { |
2045 |
this.runNegativeTest( |
2046 |
new String[] { |
2047 |
"X.java", |
2048 |
"public class X {\n" + |
2049 |
" void foo(Object o, boolean b) {\n" + |
2050 |
" o = new Object();\n" + |
2051 |
" if (b) {\n" + |
2052 |
" o = new Object();\n" + |
2053 |
" }\n" + |
2054 |
" if (o != null) { /* */ }\n" + // complain |
2055 |
" }\n" + |
2056 |
"}"}, |
2057 |
"----------\n" + |
2058 |
"1. ERROR in X.java (at line 7)\n" + |
2059 |
" if (o != null) { /* */ }\n" + |
2060 |
" ^\n" + |
2061 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
2062 |
"----------\n"); |
2063 |
} |
2064 |
|
2065 |
// null analysis -- while |
2066 |
public void test0401_while() { |
2067 |
this.runNegativeTest( |
2068 |
new String[] { |
2069 |
"X.java", |
2070 |
"public class X {\n" + |
2071 |
" void foo() {\n" + |
2072 |
" Object o = null;\n" + |
2073 |
" while (o.toString() != null) {/* */}\n" + |
2074 |
// complain: NPE |
2075 |
" }\n" + |
2076 |
"}\n"}, |
2077 |
"----------\n" + |
2078 |
"1. ERROR in X.java (at line 4)\n" + |
2079 |
" while (o.toString() != null) {/* */}\n" + |
2080 |
" ^\n" + |
2081 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2082 |
"----------\n"); |
2083 |
} |
2084 |
|
2085 |
// null analysis -- while |
2086 |
public void test0402_while() { |
2087 |
this.runNegativeTest( |
2088 |
new String[] { |
2089 |
"X.java", |
2090 |
"public class X {\n" + |
2091 |
" void foo() {\n" + |
2092 |
" Object o = null;\n" + |
2093 |
" while (o != null) {/* */}\n" + |
2094 |
// complain: get o null first time and forever |
2095 |
" }\n" + |
2096 |
"}\n"}, |
2097 |
"----------\n" + |
2098 |
"1. ERROR in X.java (at line 4)\n" + |
2099 |
" while (o != null) {/* */}\n" + |
2100 |
" ^\n" + |
2101 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2102 |
"----------\n"); |
2103 |
} |
2104 |
|
2105 |
// null analysis -- while |
2106 |
public void test0403_while() { |
2107 |
this.runConformTest( |
2108 |
new String[] { |
2109 |
"X.java", |
2110 |
"public class X {\n" + |
2111 |
" void foo() {\n" + |
2112 |
" Object o = null;\n" + |
2113 |
" while (o == null) {\n" + |
2114 |
// quiet: first iteration is sure to find o null, |
2115 |
// but other iterations may change it |
2116 |
" o = new Object();\n" + |
2117 |
" }\n" + |
2118 |
" }\n" + |
2119 |
"}\n"}, |
2120 |
""); |
2121 |
} |
2122 |
|
2123 |
// null analysis -- while |
2124 |
public void test0404_while() { |
2125 |
this.runConformTest( |
2126 |
new String[] { |
2127 |
"X.java", |
2128 |
"public class X {\n" + |
2129 |
" void foo() {\n" + |
2130 |
" Object o = null;\n" + |
2131 |
" while (o == null) {\n" + |
2132 |
// quiet: first iteration is sure to find o null, |
2133 |
// but other iterations may change it |
2134 |
" if (System.currentTimeMillis() > 10L) {\n" + |
2135 |
" o = new Object();\n" + |
2136 |
" }\n" + |
2137 |
" }\n" + |
2138 |
" }\n" + |
2139 |
"}\n"}, |
2140 |
""); |
2141 |
} |
2142 |
|
2143 |
// null analysis -- while |
2144 |
public void test0405_while() { |
2145 |
this.runNegativeTest( |
2146 |
new String[] { |
2147 |
"X.java", |
2148 |
"public class X {\n" + |
2149 |
" boolean bar() {\n" + |
2150 |
" return true;\n" + |
2151 |
" }\n" + |
2152 |
" void foo(Object o) {\n" + |
2153 |
" while (bar() && o == null) {\n" + |
2154 |
" o.toString();\n" + // complain: NPE |
2155 |
" o = new Object();\n" + |
2156 |
" }\n" + |
2157 |
" }\n" + |
2158 |
"}\n"}, |
2159 |
"----------\n" + |
2160 |
"1. ERROR in X.java (at line 7)\n" + |
2161 |
" o.toString();\n" + |
2162 |
" ^\n" + |
2163 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2164 |
"----------\n"); |
2165 |
} |
2166 |
|
2167 |
// null analysis -- while |
2168 |
public void test0406_while() { |
2169 |
this.runNegativeTest( |
2170 |
new String[] { |
2171 |
"X.java", |
2172 |
"public class X {\n" + |
2173 |
" boolean dummy;\n" + |
2174 |
" void foo(Object o) {\n" + |
2175 |
" o = null;\n" + |
2176 |
" while (dummy || o != null) { /* */ }\n" + // o can only be null |
2177 |
" }\n" + |
2178 |
"}\n"}, |
2179 |
"----------\n" + |
2180 |
"1. ERROR in X.java (at line 5)\n" + |
2181 |
" while (dummy || o != null) { /* */ }\n" + |
2182 |
" ^\n" + |
2183 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2184 |
"----------\n"); |
2185 |
} |
2186 |
|
2187 |
// null analysis -- while |
2188 |
public void test0407_while() { |
2189 |
this.runNegativeTest( |
2190 |
new String[] { |
2191 |
"X.java", |
2192 |
"public class X {\n" + |
2193 |
" boolean dummy;\n" + |
2194 |
" void foo() {\n" + |
2195 |
" Object o = null;\n" + |
2196 |
" while (dummy) {\n" + |
2197 |
" o.toString();\n" + // complain: NPE on first iteration |
2198 |
" o = new Object();\n" + |
2199 |
" }\n" + |
2200 |
" }\n" + |
2201 |
"}\n"}, |
2202 |
"----------\n" + |
2203 |
"1. ERROR in X.java (at line 6)\n" + |
2204 |
" o.toString();\n" + |
2205 |
" ^\n" + |
2206 |
"The variable o may be null\n" + |
2207 |
"----------\n"); |
2208 |
} |
2209 |
|
2210 |
// null analysis -- while |
2211 |
// this test shows that, as long as we do not explore all possible |
2212 |
// paths, we have to take potential initializations into account |
2213 |
// even in branches that could be pruned in the first passes |
2214 |
// first approximation is to stop pruning code conditioned by |
2215 |
// variables |
2216 |
// second approximation could still rely upon variables that are |
2217 |
// never affected by the looping code (unassigned variables) |
2218 |
// complete solution would call for multiple iterations in the |
2219 |
// null analysis |
2220 |
public void test0408_while() { |
2221 |
this.runConformTest( |
2222 |
new String[] { |
2223 |
"X.java", |
2224 |
"public class X {\n" + |
2225 |
" void foo() {\n" + |
2226 |
" Object o = null,\n" + |
2227 |
" u = new Object(),\n" + |
2228 |
" v = new Object();\n" + |
2229 |
" while (o == null) {\n" + |
2230 |
" if (v == null) {\n" + |
2231 |
" o = new Object();\n" + |
2232 |
" };\n" + |
2233 |
" if (u == null) {\n" + |
2234 |
" v = null;\n" + |
2235 |
" };\n" + |
2236 |
" u = null;\n" + |
2237 |
" }\n" + |
2238 |
" }\n" + |
2239 |
"}\n"}, |
2240 |
""); |
2241 |
} |
2242 |
|
2243 |
// null analysis -- while |
2244 |
public void test0409_while() { |
2245 |
this.runNegativeTest( |
2246 |
new String[] { |
2247 |
"X.java", |
2248 |
"public class X {\n" + |
2249 |
" boolean dummy;\n" + |
2250 |
" void foo() {\n" + |
2251 |
" Object o = null;\n" + |
2252 |
" while (dummy || (o = new Object()).equals(o)) {\n" + |
2253 |
" o.toString();\n" + |
2254 |
" }\n" + |
2255 |
" }\n" + |
2256 |
"}\n"}, |
2257 |
"----------\n" + |
2258 |
"1. ERROR in X.java (at line 6)\n" + |
2259 |
" o.toString();\n" + |
2260 |
" ^\n" + |
2261 |
"The variable o may be null\n" + |
2262 |
"----------\n"); |
2263 |
} |
2264 |
|
2265 |
// null analysis -- while |
2266 |
public void test0410_while_nested() { |
2267 |
this.runConformTest( |
2268 |
new String[] { |
2269 |
"X.java", |
2270 |
"public class X {\n" + |
2271 |
" boolean dummy;\n" + |
2272 |
" void foo() {\n" + |
2273 |
" Object o = null;\n" + |
2274 |
" while (dummy) {\n" + |
2275 |
" while (o != null) {\n" + |
2276 |
" o.toString();\n" + |
2277 |
" }\n" + |
2278 |
" if (System.currentTimeMillis() > 10L) {\n" + |
2279 |
" o = new Object();\n" + |
2280 |
" }\n" + |
2281 |
" }\n" + |
2282 |
" }\n" + |
2283 |
"}\n"}, |
2284 |
""); |
2285 |
} |
2286 |
|
2287 |
// null analysis -- while |
2288 |
public void test0411_while_nested() { |
2289 |
this.runConformTest( |
2290 |
new String[] { |
2291 |
"X.java", |
2292 |
"public class X {\n" + |
2293 |
" void foo() {\n" + |
2294 |
" Object o = null,\n" + |
2295 |
" u = new Object(),\n" + |
2296 |
" v = new Object();\n" + |
2297 |
" while (o == null) {\n" + |
2298 |
" if (v == null) {\n" + |
2299 |
" o = new Object();\n" + |
2300 |
" };\n" + |
2301 |
" while (o == null) {\n" + |
2302 |
" if (u == null) {\n" + |
2303 |
" v = null;\n" + |
2304 |
" };\n" + |
2305 |
" u = null;\n" + |
2306 |
" }\n" + |
2307 |
" }\n" + |
2308 |
" }\n" + |
2309 |
"}\n"}, |
2310 |
""); |
2311 |
} |
2312 |
|
2313 |
// null analysis -- while |
2314 |
public void test0412_while_if_nested() { |
2315 |
this.runNegativeTest( |
2316 |
new String[] { |
2317 |
"X.java", |
2318 |
"public class X {\n" + |
2319 |
" boolean dummy, other;\n" + |
2320 |
" void foo() {\n" + |
2321 |
" Object o = null;\n" + |
2322 |
" while (dummy) {\n" + |
2323 |
" if (other) {\n" + |
2324 |
" o.toString();\n" + |
2325 |
" }\n" + |
2326 |
" o = new Object();\n" + |
2327 |
" }\n" + |
2328 |
" }\n" + |
2329 |
"}\n"}, |
2330 |
"----------\n" + |
2331 |
"1. ERROR in X.java (at line 7)\n" + |
2332 |
" o.toString();\n" + |
2333 |
" ^\n" + |
2334 |
"The variable o may be null\n" + |
2335 |
"----------\n"); |
2336 |
} |
2337 |
|
2338 |
// null analysis -- while |
2339 |
public void test0413_while_unknown_field() { |
2340 |
this.runConformTest( |
2341 |
new String[] { |
2342 |
"X.java", |
2343 |
"public class X {\n" + |
2344 |
" Object o;\n" + |
2345 |
" void foo(boolean dummy) {\n" + |
2346 |
" while (dummy) {\n" + |
2347 |
" o = null;\n" + |
2348 |
" }\n" + |
2349 |
" o.toString();\n" + |
2350 |
" }\n" + |
2351 |
"}\n"}, |
2352 |
""); |
2353 |
} |
2354 |
|
2355 |
// null analysis -- while |
2356 |
public void test0414_while_unknown_parameter() { |
2357 |
this.runNegativeTest( |
2358 |
new String[] { |
2359 |
"X.java", |
2360 |
"public class X {\n" + |
2361 |
" boolean dummy;\n" + |
2362 |
" void foo(Object o) {\n" + |
2363 |
" while (dummy) {\n" + |
2364 |
" o = null;\n" + // quiet: first iteration doesn't know |
2365 |
" }\n" + |
2366 |
" o.toString();\n" + // complain: only get out of the loop with null |
2367 |
" }\n" + |
2368 |
"}\n"}, |
2369 |
"----------\n" + |
2370 |
"1. ERROR in X.java (at line 7)\n" + |
2371 |
" o.toString();\n" + |
2372 |
" ^\n" + |
2373 |
"The variable o may be null\n" + |
2374 |
"----------\n"); |
2375 |
} |
2376 |
|
2377 |
// null analysis -- while |
2378 |
public void test0415_while_unknown_if_else() { |
2379 |
this.runConformTest( |
2380 |
new String[] { |
2381 |
"X.java", |
2382 |
"public class X {\n" + |
2383 |
" boolean dummy;\n" + |
2384 |
" void foo() {\n" + |
2385 |
" Object o = null;\n" + |
2386 |
" if (dummy) {\n" + |
2387 |
" o = new Object();\n" + |
2388 |
" }\n" + |
2389 |
" while (dummy) {\n" + |
2390 |
// limit of the analysis: we do not correlate if and while conditions |
2391 |
" if (o == null) {/* */}\n" + |
2392 |
" }\n" + |
2393 |
" }\n" + |
2394 |
"}\n"}, |
2395 |
""); |
2396 |
} |
2397 |
|
2398 |
// null analysis -- while |
2399 |
public void test0416_while() { |
2400 |
this.runNegativeTest( |
2401 |
new String[] { |
2402 |
"X.java", |
2403 |
"public class X {\n" + |
2404 |
" boolean dummy;\n" + |
2405 |
" void foo() {\n" + |
2406 |
" Object o = null;\n" + |
2407 |
" while (dummy) {\n" + |
2408 |
" o = new Object();\n" + |
2409 |
" }\n" + |
2410 |
" o.toString();\n" + |
2411 |
" }\n" + |
2412 |
"}\n"}, |
2413 |
"----------\n" + |
2414 |
"1. ERROR in X.java (at line 8)\n" + |
2415 |
" o.toString();\n" + |
2416 |
" ^\n" + |
2417 |
"The variable o may be null\n" + |
2418 |
"----------\n"); |
2419 |
} |
2420 |
|
2421 |
// null analysis -- while |
2422 |
public void test0417_while() { |
2423 |
this.runNegativeTest( |
2424 |
new String[] { |
2425 |
"X.java", |
2426 |
"public class X {\n" + |
2427 |
" boolean dummy;\n" + |
2428 |
" void foo() {\n" + |
2429 |
" Object o = null;\n" + |
2430 |
" while (dummy) { /* */ }\n" + // doesn't affect o |
2431 |
" o.toString();\n" + |
2432 |
" }\n" + |
2433 |
"}\n"}, |
2434 |
"----------\n" + |
2435 |
"1. ERROR in X.java (at line 6)\n" + |
2436 |
" o.toString();\n" + |
2437 |
" ^\n" + |
2438 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2439 |
"----------\n"); |
2440 |
} |
2441 |
|
2442 |
// null analysis -- while |
2443 |
// origin AssignmentTest.testO22 |
2444 |
public void test0418_while_try() { |
2445 |
this.runConformTest( |
2446 |
new String[] { |
2447 |
"X.java", |
2448 |
"public class X {\n" + |
2449 |
" boolean bool() { return true; }\n" + |
2450 |
" void foo() {\n" + |
2451 |
" Object o = null;\n" + |
2452 |
" while (bool()) {\n" + |
2453 |
" try {\n" + |
2454 |
" if (o == null) {\n" + |
2455 |
" o = new Object();\n" + |
2456 |
" }\n" + |
2457 |
" } finally { /* */ }\n" + |
2458 |
" }\n" + |
2459 |
" }\n" + |
2460 |
"}"}, |
2461 |
""); |
2462 |
} |
2463 |
|
2464 |
// null analysis -- while |
2465 |
public void test0419_while() { |
2466 |
this.runNegativeTest( |
2467 |
new String[] { |
2468 |
"X.java", |
2469 |
"public class X {\n" + |
2470 |
" boolean bool;\n" + |
2471 |
" void foo(Object o) {\n" + |
2472 |
" while (bool) {\n" + |
2473 |
" o.toString();" + // complain NPE because of second iteration |
2474 |
" o = null;\n" + |
2475 |
" }\n" + |
2476 |
" }\n" + |
2477 |
"}"}, |
2478 |
"----------\n" + |
2479 |
"1. ERROR in X.java (at line 5)\n" + |
2480 |
" o.toString(); o = null;\n" + |
2481 |
" ^\n" + |
2482 |
"The variable o may be null\n" + |
2483 |
"----------\n"); |
2484 |
} |
2485 |
|
2486 |
// null analysis -- while |
2487 |
public void test0420_while() { |
2488 |
this.runNegativeTest( |
2489 |
new String[] { |
2490 |
"X.java", |
2491 |
"public class X {\n" + |
2492 |
" boolean bool;\n" + |
2493 |
" void foo(Object compare) {\n" + |
2494 |
" Object o = new Object();\n" + |
2495 |
" while ((o = null) == compare) {\n" + |
2496 |
" if (true) {\n" + |
2497 |
" break;\n" + |
2498 |
" }\n" + |
2499 |
" }\n" + |
2500 |
" if (o == null) { /* */ }\n" + // complain can only be null |
2501 |
" }\n" + |
2502 |
"}"}, |
2503 |
"----------\n" + |
2504 |
"1. ERROR in X.java (at line 10)\n" + |
2505 |
" if (o == null) { /* */ }\n" + |
2506 |
" ^\n" + |
2507 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2508 |
"----------\n"); |
2509 |
} |
2510 |
|
2511 |
// null analysis -- while |
2512 |
public void test0421_while() { |
2513 |
this.runConformTest( |
2514 |
new String[] { |
2515 |
"X.java", |
2516 |
"public class X {\n" + |
2517 |
" boolean bool;\n" + |
2518 |
" void foo(Object compare) {\n" + |
2519 |
" Object o = null;\n" + |
2520 |
" while (bool) {\n" + |
2521 |
" o = new Object();\n" + |
2522 |
" o.toString();\n" + |
2523 |
" }\n" + |
2524 |
" }\n" + |
2525 |
"}"}, |
2526 |
""); |
2527 |
} |
2528 |
|
2529 |
// null analysis -- while |
2530 |
public void test0422_while() { |
2531 |
this.runNegativeTest( |
2532 |
new String[] { |
2533 |
"X.java", |
2534 |
"public class X {\n" + |
2535 |
" boolean bool;\n" + |
2536 |
" void foo() {\n" + |
2537 |
" Object o;\n" + |
2538 |
" while (bool) {\n" + |
2539 |
" o = new Object();\n" + |
2540 |
" if (o == null) { /* */ }\n" + |
2541 |
" o = null;\n" + |
2542 |
" }\n" + |
2543 |
" }\n" + |
2544 |
"}"}, |
2545 |
"----------\n" + |
2546 |
"1. ERROR in X.java (at line 7)\n" + |
2547 |
" if (o == null) { /* */ }\n" + |
2548 |
" ^\n" + |
2549 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
2550 |
"----------\n"); |
2551 |
} |
2552 |
|
2553 |
// null analysis -- while |
2554 |
// REVIEW we get one extraneous message that looks a bit strange |
2555 |
public void test0423_while() { |
2556 |
this.runNegativeTest( |
2557 |
new String[] { |
2558 |
"X.java", |
2559 |
"public class X {\n" + |
2560 |
" boolean bool;\n" + |
2561 |
" void foo() {\n" + |
2562 |
" Object o = null;\n" + |
2563 |
" while (bool) {\n" + |
2564 |
" o = new Object();\n" + |
2565 |
" if (o == null) { /* */ }\n" + |
2566 |
" o = null;\n" + |
2567 |
" }\n" + |
2568 |
" }\n" + |
2569 |
"}"}, |
2570 |
"----------\n" + |
2571 |
"1. ERROR in X.java (at line 7)\n" + |
2572 |
" if (o == null) { /* */ }\n" + |
2573 |
" ^\n" + |
2574 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
2575 |
"----------\n" + |
2576 |
"2. ERROR in X.java (at line 8)\n" + |
2577 |
" o = null;\n" + |
2578 |
" ^\n" + |
2579 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2580 |
"----------\n"); |
2581 |
} |
2582 |
|
2583 |
// null analysis -- while |
2584 |
public void test0424_while_try() { |
2585 |
this.runConformTest( |
2586 |
new String[] { |
2587 |
"X.java", |
2588 |
"public class X {\n" + |
2589 |
" void foo(boolean b) {\n" + |
2590 |
" Object o = null;\n" + |
2591 |
" while (o == null) {\n" + |
2592 |
// quiet: first iteration is sure to find o null, |
2593 |
// but other iterations may change it |
2594 |
" try { /* */ }\n" + |
2595 |
" finally {\n" + |
2596 |
" if (b) {\n" + |
2597 |
" o = new Object();\n" + |
2598 |
" }\n" + |
2599 |
" }\n" + |
2600 |
" }\n" + |
2601 |
" }\n" + |
2602 |
"}\n"}, |
2603 |
""); |
2604 |
} |
2605 |
|
2606 |
// null analysis -- while |
2607 |
public void test0425_while() { |
2608 |
this.runNegativeTest( |
2609 |
new String[] { |
2610 |
"X.java", |
2611 |
"public class X {\n" + |
2612 |
" boolean dummy;\n" + |
2613 |
" void foo(Object u) {\n" + |
2614 |
" Object o = null;\n" + |
2615 |
" while (dummy) {\n" + |
2616 |
" o = u;\n" + |
2617 |
" }\n" + |
2618 |
" o.toString();\n" + |
2619 |
" }\n" + |
2620 |
"}\n"}, |
2621 |
"----------\n" + |
2622 |
"1. ERROR in X.java (at line 8)\n" + |
2623 |
" o.toString();\n" + |
2624 |
" ^\n" + |
2625 |
"The variable o may be null\n" + |
2626 |
"----------\n"); |
2627 |
} |
2628 |
|
2629 |
// null analysis -- while |
2630 |
public void test0426_while() { |
2631 |
this.runNegativeTest( |
2632 |
new String[] { |
2633 |
"X.java", |
2634 |
"public class X {\n" + |
2635 |
" boolean dummy;\n" + |
2636 |
" void foo(Object o) {\n" + |
2637 |
" o.toString();\n" + |
2638 |
" while (dummy) { /* */ }\n" + |
2639 |
" if (o == null) { /* */ }\n" + // complain |
2640 |
" }\n" + |
2641 |
"}\n"}, |
2642 |
"----------\n" + |
2643 |
"1. ERROR in X.java (at line 6)\n" + |
2644 |
" if (o == null) { /* */ }\n" + |
2645 |
" ^\n" + |
2646 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
2647 |
"----------\n"); |
2648 |
} |
2649 |
|
2650 |
// null analysis -- while |
2651 |
public void test0427_while_return() { |
2652 |
this.runNegativeTest( |
2653 |
new String[] { |
2654 |
"X.java", |
2655 |
"public class X {\n" + |
2656 |
" boolean dummy;\n" + |
2657 |
" void foo() {\n" + |
2658 |
" Object o = null;\n" + |
2659 |
" while (dummy) {\n" + |
2660 |
" if (o == null) {\n" + |
2661 |
" return;\n" + |
2662 |
" }\n" + |
2663 |
" }\n" + |
2664 |
" }\n" + |
2665 |
"}\n"}, |
2666 |
"----------\n" + |
2667 |
"1. ERROR in X.java (at line 6)\n" + |
2668 |
" if (o == null) {\n" + |
2669 |
" ^\n" + |
2670 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2671 |
"----------\n"); |
2672 |
} |
2673 |
|
2674 |
// null analysis - while |
2675 |
public void test0428_while() { |
2676 |
this.runConformTest( |
2677 |
new String[] { |
2678 |
"X.java", |
2679 |
"public class X {\n" + |
2680 |
" X bar() {\n" + |
2681 |
" return null;\n" + |
2682 |
" }\n" + |
2683 |
" void foo(X x) {\n" + |
2684 |
" x.bar();\n" + |
2685 |
" while (x != null) {\n" + |
2686 |
" x = x.bar();\n" + |
2687 |
" }\n" + |
2688 |
" }\n" + |
2689 |
"}\n"}, |
2690 |
""); |
2691 |
} |
2692 |
|
2693 |
// null analysis - while |
2694 |
public void test0429_while_nested() { |
2695 |
this.runConformTest( |
2696 |
new String[] { |
2697 |
"X.java", |
2698 |
"class X {\n" + |
2699 |
" boolean dummy;\n" + |
2700 |
" void foo (X[] xa) {\n" + |
2701 |
" while (dummy) {\n" + |
2702 |
" xa = null;\n" + |
2703 |
" if (dummy) {\n" + |
2704 |
" xa = new X[5];\n" + |
2705 |
" }\n" + |
2706 |
" if (xa != null) {\n" + |
2707 |
" int i = 0;\n" + |
2708 |
" while (dummy) {\n" + |
2709 |
" X x = xa[i++];\n" + |
2710 |
" x.toString();\n" + |
2711 |
" }\n" + |
2712 |
" }\n" + |
2713 |
" }\n" + |
2714 |
" }\n" + |
2715 |
"}"}, |
2716 |
""); |
2717 |
} |
2718 |
|
2719 |
// null analysis - while |
2720 |
public void test0430_while_for_nested() { |
2721 |
this.runConformTest( |
2722 |
new String[] { |
2723 |
"X.java", |
2724 |
"class X {\n" + |
2725 |
" boolean dummy;\n" + |
2726 |
" void foo (X[] xa) {\n" + |
2727 |
" while (dummy) {\n" + |
2728 |
" xa = null;\n" + |
2729 |
" if (dummy) {\n" + |
2730 |
" xa = new X[5];\n" + |
2731 |
" }\n" + |
2732 |
" if (xa != null) {\n" + |
2733 |
" for (int i = 0; i < xa.length; i++) {\n" + |
2734 |
" X x = xa[i];\n" + |
2735 |
" x.toString();\n" + |
2736 |
" }\n" + |
2737 |
" }\n" + |
2738 |
" }\n" + |
2739 |
" }\n" + |
2740 |
"}"}, |
2741 |
""); |
2742 |
} |
2743 |
|
2744 |
// null analysis - while |
2745 |
public void test0431_while() { |
2746 |
this.runConformTest( |
2747 |
new String[] { |
2748 |
"X.java", |
2749 |
"class X {\n" + |
2750 |
" boolean dummy;\n" + |
2751 |
" void foo (X x) {\n" + |
2752 |
" x = null;\n" + |
2753 |
" while (dummy) {\n" + |
2754 |
" x = bar();\n" + |
2755 |
" x.toString();\n" + |
2756 |
" }\n" + |
2757 |
" }\n" + |
2758 |
" X bar() {\n" + |
2759 |
" return null;\n" + |
2760 |
" }\n" + |
2761 |
"}"}, |
2762 |
""); |
2763 |
} |
2764 |
|
2765 |
// null analysis - while |
2766 |
public void test0432_while() { |
2767 |
this.runConformTest( |
2768 |
new String[] { |
2769 |
"X.java", |
2770 |
"class X {\n" + |
2771 |
" boolean dummy;\n" + |
2772 |
" void foo (X x) {\n" + |
2773 |
" while (dummy) {\n" + |
2774 |
" x = bar();\n" + |
2775 |
" x.toString();\n" + |
2776 |
" }\n" + |
2777 |
" }\n" + |
2778 |
" X bar() {\n" + |
2779 |
" return null;\n" + |
2780 |
" }\n" + |
2781 |
"}"}, |
2782 |
""); |
2783 |
} |
2784 |
|
2785 |
// null analysis - while |
2786 |
public void test0433_while() { |
2787 |
this.runNegativeTest( |
2788 |
new String[] { |
2789 |
"X.java", |
2790 |
"class X {\n" + |
2791 |
" boolean dummy;\n" + |
2792 |
" void foo (X x) {\n" + |
2793 |
" x = null;\n" + |
2794 |
" while (dummy) {\n" + |
2795 |
" x.toString();\n" + // complain and protect |
2796 |
" x.toString();\n" + // quiet |
2797 |
" }\n" + |
2798 |
" }\n" + |
2799 |
"}"}, |
2800 |
"----------\n" + |
2801 |
"1. ERROR in X.java (at line 6)\n" + |
2802 |
" x.toString();\n" + |
2803 |
" ^\n" + |
2804 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
2805 |
"----------\n"); |
2806 |
} |
2807 |
|
2808 |
// null analysis - while |
2809 |
// this one shows that we cannot project definitely unknown onto potentially unknown too soon |
2810 |
public void test0434_while_switch_nested() { |
2811 |
this.runConformTest( |
2812 |
new String[] { |
2813 |
"X.java", |
2814 |
"class X {\n" + |
2815 |
" Object bar() {\n" + |
2816 |
" return new Object();\n" + |
2817 |
" }\n" + |
2818 |
" void foo(boolean b, int selector) {\n" + |
2819 |
" Object o = null;\n" + |
2820 |
" while (b) {\n" + |
2821 |
" switch (selector) {\n" + |
2822 |
" case 0:\n" + |
2823 |
" o = bar();\n" + |
2824 |
" if (o != null) { \n" + |
2825 |
" return;\n" + |
2826 |
" }\n" + |
2827 |
" }\n" + |
2828 |
" }\n" + |
2829 |
" }\n" + |
2830 |
"}"}, |
2831 |
""); |
2832 |
} |
2833 |
|
2834 |
// null analysis - while |
2835 |
public void test0435_while_init() { |
2836 |
this.runConformTest( |
2837 |
new String[] { |
2838 |
"X.java", |
2839 |
"class X {\n" + |
2840 |
" int f1;\n" + |
2841 |
" X f2;\n" + |
2842 |
" void foo(X x1, boolean b) {\n" + |
2843 |
" X x2;\n" + |
2844 |
" x2 = x1;\n" + |
2845 |
" while (b) {\n" + |
2846 |
// " if (x2.f1 > 0) { /* */ }\n" + |
2847 |
" if (x2.toString().equals(\"\")) { /* */ }\n" + |
2848 |
" x2 = x2.f2;\n" + |
2849 |
" }\n" + |
2850 |
" }\n" + |
2851 |
"}"}, |
2852 |
""); |
2853 |
} |
2854 |
|
2855 |
// null analysis - while |
2856 |
public void test0436_while_init() { |
2857 |
this.runConformTest( |
2858 |
new String[] { |
2859 |
"X.java", |
2860 |
"class X {\n" + |
2861 |
" int f1;\n" + |
2862 |
" X f2;\n" + |
2863 |
" void foo(X x1, boolean b) {\n" + |
2864 |
" X x2 = x1;\n" + |
2865 |
" while (b) {\n" + |
2866 |
" if (x2.f1 > 0) { /* */ }\n" + |
2867 |
" x2 = x2.f2;\n" + |
2868 |
" }\n" + |
2869 |
" }\n" + |
2870 |
"}"}, |
2871 |
""); |
2872 |
} |
2873 |
|
2874 |
// null analysis - while |
2875 |
public void test0437_while_exit() { |
2876 |
this.runConformTest( |
2877 |
new String[] { |
2878 |
"X.java", |
2879 |
"class X {\n" + |
2880 |
" void foo(boolean b) {\n" + |
2881 |
" Object o = null;\n" + |
2882 |
" while (b) {\n" + |
2883 |
" if (b) {\n" + |
2884 |
" o = new Object();\n" + |
2885 |
" }\n" + |
2886 |
" if (o != null) {\n" + |
2887 |
" throw new RuntimeException(); \n" + |
2888 |
" }\n" + |
2889 |
" }\n" + |
2890 |
" }\n" + |
2891 |
"}"}, |
2892 |
""); |
2893 |
} |
2894 |
|
2895 |
|
2896 |
// null analysis - while |
2897 |
public void test0438_while() { |
2898 |
this.runNegativeTest( |
2899 |
new String[] { |
2900 |
"X.java", |
2901 |
"class X {\n" + |
2902 |
" void foo(Object o) {\n" + |
2903 |
" while (o == null) { /* */ }\n" + |
2904 |
" o.toString();\n" + // quiet |
2905 |
" if (o != null) { /* */ }\n" + // complain |
2906 |
" }\n" + |
2907 |
"}"}, |
2908 |
"----------\n" + |
2909 |
"1. ERROR in X.java (at line 5)\n" + |
2910 |
" if (o != null) { /* */ }\n" + |
2911 |
" ^\n" + |
2912 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
2913 |
"----------\n"); |
2914 |
} |
2915 |
|
2916 |
// null analysis - while |
2917 |
public void test0439_while() { |
2918 |
this.runNegativeTest( |
2919 |
new String[] { |
2920 |
"X.java", |
2921 |
"class X {\n" + |
2922 |
" void foo(Object o) {\n" + |
2923 |
" while (o == null) {\n" + |
2924 |
" o = new Object();\n" + |
2925 |
" }\n" + |
2926 |
" o.toString();\n" + // quiet |
2927 |
" }\n" + |
2928 |
"}"}, |
2929 |
""); |
2930 |
} |
2931 |
|
2932 |
// null analysis - while |
2933 |
public void test0440_while() { |
2934 |
this.runNegativeTest( |
2935 |
new String[] { |
2936 |
"X.java", |
2937 |
"class X {\n" + |
2938 |
" void foo(Object o) {\n" + |
2939 |
" while (o == null) {\n" + |
2940 |
" o = new Object();\n" + |
2941 |
" }\n" + |
2942 |
" if (o != null) { /* */ }\n" + // complain |
2943 |
" }\n" + |
2944 |
"}"}, |
2945 |
"----------\n" + |
2946 |
"1. ERROR in X.java (at line 6)\n" + |
2947 |
" if (o != null) { /* */ }\n" + |
2948 |
" ^\n" + |
2949 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
2950 |
"----------\n"); |
2951 |
} |
2952 |
|
2953 |
// null analysis - while |
2954 |
public void test0441_while() { |
2955 |
this.runNegativeTest( |
2956 |
new String[] { |
2957 |
"X.java", |
2958 |
"class X {\n" + |
2959 |
" X bar() {\n" + |
2960 |
" return new X();\n" + |
2961 |
" }\n" + |
2962 |
" void foo(Object o) {\n" + |
2963 |
" while (o == null) {\n" + |
2964 |
" o = bar();\n" + |
2965 |
" }\n" + |
2966 |
" if (o != null) { /* */ }\n" + // complain |
2967 |
" }\n" + |
2968 |
"}"}, |
2969 |
"----------\n" + |
2970 |
"1. ERROR in X.java (at line 9)\n" + |
2971 |
" if (o != null) { /* */ }\n" + |
2972 |
" ^\n" + |
2973 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
2974 |
"----------\n"); |
2975 |
} |
2976 |
|
2977 |
// null analysis - while |
2978 |
public void test0442_while() { |
2979 |
this.runNegativeTest( |
2980 |
new String[] { |
2981 |
"X.java", |
2982 |
"class X {\n" + |
2983 |
" boolean bar() {\n" + |
2984 |
" return true;\n" + |
2985 |
" }\n" + |
2986 |
" void foo(Object o) {\n" + |
2987 |
" while (o == null && bar()) { /* */ }\n" + |
2988 |
" o.toString();\n" + // complain |
2989 |
" }\n" + |
2990 |
"}"}, |
2991 |
"----------\n" + |
2992 |
"1. ERROR in X.java (at line 7)\n" + |
2993 |
" o.toString();\n" + |
2994 |
" ^\n" + |
2995 |
"The variable o may be null\n" + |
2996 |
"----------\n"); |
2997 |
} |
2998 |
|
2999 |
// null analysis - while |
3000 |
public void test0443_while_nested() { |
3001 |
this.runConformTest( |
3002 |
new String[] { |
3003 |
"X.java", |
3004 |
"class X {\n" + |
3005 |
" void foo() {\n" + |
3006 |
" Object o = null;\n" + |
3007 |
" ext: for (int i = 0; i < 5 ; i++) {\n" + |
3008 |
" if (o != null) {\n" + |
3009 |
" break;\n" + |
3010 |
" }\n" + |
3011 |
" o = new Object();\n" + |
3012 |
" int j = 0;\n" + |
3013 |
" while (j++ < 2) {\n" + |
3014 |
" continue ext;\n" + |
3015 |
" }\n" + |
3016 |
" return;\n" + |
3017 |
" }\n" + |
3018 |
" }\n" + |
3019 |
"}"}, |
3020 |
""); |
3021 |
} |
3022 |
|
3023 |
// null analysis - while |
3024 |
public void test0444_while_deeply_nested() { |
3025 |
this.runConformTest( |
3026 |
new String[] { |
3027 |
"X.java", |
3028 |
"class X {\n" + |
3029 |
" void foo(boolean b) {\n" + |
3030 |
" Object o = null;\n" + |
3031 |
" ext: for (int i = 0; i < 5 ; i++) {\n" + |
3032 |
" if (o != null) {\n" + |
3033 |
" break;\n" + |
3034 |
" }\n" + |
3035 |
" do {\n" + |
3036 |
" o = new Object();\n" + |
3037 |
" int j = 0;\n" + |
3038 |
" while (j++ < 2) {\n" + |
3039 |
" continue ext;\n" + |
3040 |
" }\n" + |
3041 |
" } while (b);\n" + |
3042 |
" return;\n" + |
3043 |
" }\n" + |
3044 |
" }\n" + |
3045 |
"}"}, |
3046 |
""); |
3047 |
} |
3048 |
|
3049 |
// null analysis - while |
3050 |
public void test0445_while_deeply_nested() { |
3051 |
this.runNegativeTest( |
3052 |
new String[] { |
3053 |
"X.java", |
3054 |
"class X {\n" + |
3055 |
" void foo(boolean b) {\n" + |
3056 |
" Object o = null;\n" + |
3057 |
" ext: for (int i = 0; i < 5 ; i++) {\n" + |
3058 |
" if (o != null) {\n" + |
3059 |
" break;\n" + |
3060 |
" }\n" + |
3061 |
" do {\n" + |
3062 |
" // o = new Object();\n" + |
3063 |
" int j = 0;\n" + |
3064 |
" while (j++ < 2) {\n" + |
3065 |
" continue ext;\n" + |
3066 |
" }\n" + |
3067 |
" } while (b);\n" + |
3068 |
" return;\n" + |
3069 |
" }\n" + |
3070 |
" }\n" + |
3071 |
"}"}, |
3072 |
"----------\n" + |
3073 |
"1. ERROR in X.java (at line 5)\n" + |
3074 |
" if (o != null) {\n" + |
3075 |
" ^\n" + |
3076 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3077 |
"----------\n"); |
3078 |
} |
3079 |
|
3080 |
// null analysis - while |
3081 |
public void test0446_while() { |
3082 |
this.runNegativeTest( |
3083 |
new String[] { |
3084 |
"X.java", |
3085 |
"class X {\n" + |
3086 |
" void foo(Object o, boolean b) {\n" + |
3087 |
" while (o == null || b) {\n" + |
3088 |
" o = new Object();\n" + |
3089 |
" }\n" + |
3090 |
" if (o != null) { /* */ }\n" + // complain |
3091 |
" }\n" + |
3092 |
"}"}, |
3093 |
"----------\n" + |
3094 |
"1. ERROR in X.java (at line 6)\n" + |
3095 |
" if (o != null) { /* */ }\n" + |
3096 |
" ^\n" + |
3097 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
3098 |
"----------\n"); |
3099 |
} |
3100 |
|
3101 |
// null analysis - while |
3102 |
public void test0447_while() { |
3103 |
this.runConformTest( |
3104 |
new String[] { |
3105 |
"X.java", |
3106 |
"class X {\n" + |
3107 |
" void foo(Object o, boolean b) {\n" + |
3108 |
" while (o == null & b) {\n" + |
3109 |
" o = new Object();\n" + |
3110 |
" }\n" + |
3111 |
" if (o != null) { /* */ }\n" + |
3112 |
" }\n" + |
3113 |
"}"}, |
3114 |
""); |
3115 |
} |
3116 |
|
3117 |
// null analysis - while |
3118 |
public void test0448_while() { |
3119 |
this.runNegativeTest( |
3120 |
new String[] { |
3121 |
"X.java", |
3122 |
"class X {\n" + |
3123 |
" void foo(boolean b[]) {\n" + |
3124 |
" Object o = null;\n" + |
3125 |
" ext: for (int i = 0; i < 5 ; i++) {\n" + |
3126 |
" if (o != null) {\n" + |
3127 |
" break;\n" + |
3128 |
" }\n" + |
3129 |
" while (b[1]) {\n" + |
3130 |
" continue ext;\n" + |
3131 |
" }\n" + |
3132 |
" while (b[2]) {\n" + |
3133 |
" continue ext;\n" + |
3134 |
" }\n" + |
3135 |
" while (b[3]) {\n" + |
3136 |
" continue ext;\n" + |
3137 |
" }\n" + |
3138 |
" while (b[4]) {\n" + |
3139 |
" continue ext;\n" + |
3140 |
" }\n" + |
3141 |
" while (b[5]) {\n" + |
3142 |
" continue ext;\n" + |
3143 |
" }\n" + |
3144 |
" while (b[6]) {\n" + |
3145 |
" continue ext;\n" + |
3146 |
" }\n" + |
3147 |
" return;\n" + |
3148 |
" }\n" + |
3149 |
" }\n" + |
3150 |
"}"}, |
3151 |
"----------\n" + |
3152 |
"1. ERROR in X.java (at line 5)\n" + |
3153 |
" if (o != null) {\n" + |
3154 |
" ^\n" + |
3155 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3156 |
"----------\n"); |
3157 |
} |
3158 |
|
3159 |
// null analysis - while |
3160 |
// REVIEW this series (up to 451) shows that the merge of the states |
3161 |
// REVIEW potential non null and potential unknown yields damages in |
3162 |
// REVIEW case of nested loops (unested loops still OK because we can |
3163 |
// REVIEW carry the definite non null property) |
3164 |
public void test0449_while_nested() { |
3165 |
this.runConformTest( |
3166 |
new String[] { |
3167 |
"X.java", |
3168 |
"class X {\n" + |
3169 |
" void foo(Object p, boolean b) {\n" + |
3170 |
" Object o = new Object();\n" + |
3171 |
" while (b) {\n" + |
3172 |
" while (b) {\n" + |
3173 |
" o = p;\n" + // now o is unknown |
3174 |
" }\n" + |
3175 |
" }\n" + |
3176 |
" if (o != null) { /* */ }\n" + |
3177 |
" }\n" + |
3178 |
"}"}, |
3179 |
""); |
3180 |
} |
3181 |
|
3182 |
// null analysis - while |
3183 |
public void test0450_while() { |
3184 |
this.runNegativeTest( |
3185 |
new String[] { |
3186 |
"X.java", |
3187 |
"class X {\n" + |
3188 |
" void foo(boolean b) {\n" + |
3189 |
" Object o = new Object();\n" + |
3190 |
" while (b) {\n" + |
3191 |
" o = new Object();\n" + // o still non null |
3192 |
" }\n" + |
3193 |
" if (o != null) { /* */ }\n" + |
3194 |
" }\n" + |
3195 |
"}"}, |
3196 |
"----------\n" + |
3197 |
"1. ERROR in X.java (at line 7)\n" + |
3198 |
" if (o != null) { /* */ }\n" + |
3199 |
" ^\n" + |
3200 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
3201 |
"----------\n"); |
3202 |
} |
3203 |
|
3204 |
// null analysis - while |
3205 |
public void _test0451_while_nested() { |
3206 |
this.runNegativeTest( |
3207 |
new String[] { |
3208 |
"X.java", |
3209 |
"class X {\n" + |
3210 |
" void foo(boolean b) {\n" + |
3211 |
" Object o = new Object();\n" + |
3212 |
" while (b) {\n" + |
3213 |
" while (b) {\n" + |
3214 |
" o = new Object();\n" + // o still non null |
3215 |
" }\n" + |
3216 |
" }\n" + |
3217 |
" if (o != null) { /* */ }\n" + |
3218 |
" }\n" + |
3219 |
"}"}, |
3220 |
"ERR"); |
3221 |
} |
3222 |
|
3223 |
// null analysis -- try/finally |
3224 |
public void test0500_try_finally() { |
3225 |
this.runConformTest( |
3226 |
new String[] { |
3227 |
"X.java", |
3228 |
"public class X {\n" + |
3229 |
" Object m;\n" + |
3230 |
" void foo() {\n" + |
3231 |
" Object o = null;\n" + |
3232 |
" try { /* */ }\n" + |
3233 |
" finally {\n" + |
3234 |
" o = m;\n" + |
3235 |
" }\n" + |
3236 |
" o.toString();\n" + |
3237 |
" }\n" + |
3238 |
"}\n"}, |
3239 |
"" // because finally assigns to unknown value |
3240 |
); |
3241 |
} |
3242 |
|
3243 |
// null analysis -- try/finally |
3244 |
public void test0501_try_finally() { |
3245 |
this.runNegativeTest( |
3246 |
new String[] { |
3247 |
"X.java", |
3248 |
"public class X {\n" + |
3249 |
" void foo() {\n" + |
3250 |
" Object o = new Object();\n" + |
3251 |
" try { /* */ }\n" + |
3252 |
" finally {\n" + |
3253 |
" o = null;\n" + |
3254 |
" }\n" + |
3255 |
" o.toString();\n" + |
3256 |
" }\n" + |
3257 |
"}\n"}, |
3258 |
"----------\n" + |
3259 |
"1. ERROR in X.java (at line 8)\n" + |
3260 |
" o.toString();\n" + |
3261 |
" ^\n" + |
3262 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3263 |
"----------\n" // because finally assigns to null |
3264 |
); |
3265 |
} |
3266 |
|
3267 |
// null analysis -- try/finally |
3268 |
public void test0502_try_finally() { |
3269 |
this.runConformTest( |
3270 |
new String[] { |
3271 |
"X.java", |
3272 |
"public class X {\n" + |
3273 |
" void foo() {\n" + |
3274 |
" Object o = null;\n" + |
3275 |
" try {\n" + |
3276 |
" System.out.println();\n" + // might throw a runtime exception |
3277 |
" o = new Object();\n" + |
3278 |
" }\n" + |
3279 |
" finally { /* */ }\n" + |
3280 |
" o.toString();\n" + |
3281 |
// still OK because in case of exception this code is |
3282 |
// not reached |
3283 |
" }\n" + |
3284 |
"}\n"}, |
3285 |
""); |
3286 |
} |
3287 |
|
3288 |
// null analysis -- try/finally |
3289 |
public void test0503_try_finally() { |
3290 |
this.runNegativeTest( |
3291 |
new String[] { |
3292 |
"X.java", |
3293 |
"public class X {\n" + |
3294 |
" void foo(X x) {\n" + |
3295 |
" x = null;\n" + |
3296 |
" try {\n" + |
3297 |
" x = null;\n" + // complain, already null |
3298 |
" } finally { /* */ }\n" + |
3299 |
" }\n" + |
3300 |
"}\n"}, |
3301 |
"----------\n" + |
3302 |
"1. ERROR in X.java (at line 5)\n" + |
3303 |
" x = null;\n" + |
3304 |
" ^\n" + |
3305 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
3306 |
"----------\n"); |
3307 |
} |
3308 |
|
3309 |
// null analysis -- try/finally |
3310 |
public void test0504_try_finally() { |
3311 |
this.runNegativeTest( |
3312 |
new String[] { |
3313 |
"X.java", |
3314 |
"public class X {\n" + |
3315 |
" void foo(X x) {\n" + |
3316 |
" x = null;\n" + |
3317 |
" try {\n" + |
3318 |
" } finally {\n" + |
3319 |
" if (x != null) { /* */ }\n" + // complain null |
3320 |
" }\n" + |
3321 |
" }\n" + |
3322 |
"}\n"}, |
3323 |
"----------\n" + |
3324 |
"1. ERROR in X.java (at line 6)\n" + |
3325 |
" if (x != null) { /* */ }\n" + |
3326 |
" ^\n" + |
3327 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
3328 |
"----------\n"); |
3329 |
} |
3330 |
|
3331 |
// null analysis -- try/finally |
3332 |
// origin: AssignmentTest#test017 |
3333 |
// The whole issue here is whether or not to detect premature exits. We |
3334 |
// follow JLS's conservative approach, which considers that the try |
3335 |
// block may exit before the assignment is completed. |
3336 |
// Note: conversely, without line 1, we would complain about x not being |
3337 |
// initialized (for sure) on line 2. |
3338 |
public void test0505_try_finally() { |
3339 |
this.runConformTest( |
3340 |
new String[] { |
3341 |
"X.java", |
3342 |
"public class X {\n" + |
3343 |
" void foo(X x) {\n" + |
3344 |
" x = this;\n" + // 1 |
3345 |
" try {\n" + |
3346 |
" x = null;\n" + |
3347 |
" } finally {\n" + |
3348 |
" if (x == null) {/* */}\n" + // 2 |
3349 |
" }\n" + |
3350 |
" }\n" + |
3351 |
"}\n"}, |
3352 |
""); |
3353 |
} |
3354 |
|
3355 |
// null analysis -- try finally |
3356 |
public void test0506_try_finally() { |
3357 |
this.runNegativeTest( |
3358 |
new String[] { |
3359 |
"X.java", |
3360 |
"public class X {\n" + |
3361 |
" void foo(Object o) {\n" + |
3362 |
" try { /* */ }\n" + |
3363 |
" finally {\n" + |
3364 |
" o = new Object();\n" + |
3365 |
" }\n" + |
3366 |
" if (o == null) { /* */ }\n" + |
3367 |
" }\n" + |
3368 |
"}\n"}, |
3369 |
"----------\n" + |
3370 |
"1. ERROR in X.java (at line 7)\n" + |
3371 |
" if (o == null) { /* */ }\n" + |
3372 |
" ^\n" + |
3373 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
3374 |
"----------\n"); |
3375 |
} |
3376 |
|
3377 |
// null analysis -- try finally |
3378 |
public void test0507_try_finally() { |
3379 |
this.runNegativeTest( |
3380 |
new String[] { |
3381 |
"X.java", |
3382 |
"public class X {\n" + |
3383 |
" void foo(Object o, boolean b) {\n" + |
3384 |
" try { /* */ }\n" + |
3385 |
" finally {\n" + |
3386 |
" o.toString();\n" + // protect |
3387 |
" }\n" + |
3388 |
" if (o == null) {\n" + // complain |
3389 |
" o = new Object();\n" + |
3390 |
" }\n" + |
3391 |
" }\n" + |
3392 |
"}\n"}, |
3393 |
"----------\n" + |
3394 |
"1. ERROR in X.java (at line 7)\n" + |
3395 |
" if (o == null) {\n" + |
3396 |
" ^\n" + |
3397 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
3398 |
"----------\n"); |
3399 |
} |
3400 |
|
3401 |
// null analysis -- try finally |
3402 |
public void test0508_try_finally() { |
3403 |
this.runNegativeTest( |
3404 |
new String[] { |
3405 |
"X.java", |
3406 |
"public class X {\n" + |
3407 |
" void foo(Object o) {\n" + |
3408 |
" o = null;" + |
3409 |
" try { /* */ }\n" + |
3410 |
" finally {\n" + |
3411 |
" o.toString();\n" + // complain and protect |
3412 |
" o.toString();\n" + // quiet |
3413 |
" }\n" + |
3414 |
" o.toString();\n" + // quiet |
3415 |
" }\n" + |
3416 |
"}\n"}, |
3417 |
"----------\n" + |
3418 |
"1. ERROR in X.java (at line 5)\n" + |
3419 |
" o.toString();\n" + |
3420 |
" ^\n" + |
3421 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3422 |
"----------\n"); |
3423 |
} |
3424 |
|
3425 |
// null analysis -- try finally |
3426 |
public void test0509_try_finally_embedded() { |
3427 |
this.runNegativeTest( |
3428 |
new String[] { |
3429 |
"X.java", |
3430 |
"public class X {\n" + |
3431 |
" void foo(Object o1) {\n" + |
3432 |
" Object o2 = null;" + |
3433 |
" while (true) {\n" + |
3434 |
" // o2 = o1;\n" + |
3435 |
" try { /* */ }\n" + |
3436 |
" finally {\n" + |
3437 |
" o2.toString();\n" + // complain and protect |
3438 |
" o2.toString();\n" + // quiet |
3439 |
" }\n" + |
3440 |
" o2.toString();\n" + // quiet |
3441 |
" }\n" + |
3442 |
" }\n" + |
3443 |
"}\n"}, |
3444 |
"----------\n" + |
3445 |
"1. ERROR in X.java (at line 7)\n" + |
3446 |
" o2.toString();\n" + |
3447 |
" ^^\n" + |
3448 |
"The variable o2 can only be null; it was either set to null or checked for null when last used\n" + |
3449 |
"----------\n"); |
3450 |
} |
3451 |
|
3452 |
// null analysis -- try finally |
3453 |
public void test0510_try_finally() { |
3454 |
this.runConformTest( |
3455 |
new String[] { |
3456 |
"X.java", |
3457 |
"public class X {\n" + |
3458 |
" void bar() throws Exception {\n" + |
3459 |
" // empty\n" + |
3460 |
" }\n" + |
3461 |
" void foo(Object o, boolean b) throws Exception {\n" + |
3462 |
" try {\n" + |
3463 |
" bar();\n" + |
3464 |
" if (b) {\n" + |
3465 |
" o.toString();\n" + |
3466 |
" }\n" + |
3467 |
" }\n" + |
3468 |
" finally {\n" + |
3469 |
" if (o != null) {\n" + |
3470 |
" o.toString();\n" + |
3471 |
" }\n" + |
3472 |
" }\n" + |
3473 |
" }\n" + |
3474 |
"}\n"}, |
3475 |
""); |
3476 |
} |
3477 |
|
3478 |
// null analysis -- try finally |
3479 |
public void test0511_try_finally() { |
3480 |
this.runConformTest( |
3481 |
new String[] { |
3482 |
"X.java", |
3483 |
"public class X {\n" + |
3484 |
" void foo(Object o1, boolean b) {\n" + |
3485 |
" Object o2 = null;\n" + |
3486 |
" if (b) {\n" + |
3487 |
" o2 = new Object();\n" + |
3488 |
" }\n" + // 0011 |
3489 |
" try { /* */ }\n" + |
3490 |
" finally {\n" + |
3491 |
" o2 = o1;\n" + // 1011 |
3492 |
" }\n" + |
3493 |
" o2.toString();\n" + // 1011 -- quiet |
3494 |
" }\n" + |
3495 |
"}\n"}, |
3496 |
""); |
3497 |
} |
3498 |
|
3499 |
// null analysis -- try/finally |
3500 |
public void test0512_try_finally() { |
3501 |
this.runNegativeTest( |
3502 |
new String[] { |
3503 |
"X.java", |
3504 |
"public class X {\n" + |
3505 |
" void foo(X x) {\n" + |
3506 |
" x = null;\n" + |
3507 |
" try {\n" + |
3508 |
" x = new X();\n" + |
3509 |
" } finally {\n" + |
3510 |
" x.toString();\n" + |
3511 |
" }\n" + |
3512 |
" }\n" + |
3513 |
"}\n"}, |
3514 |
"----------\n" + |
3515 |
"1. ERROR in X.java (at line 7)\n" + |
3516 |
" x.toString();\n" + |
3517 |
" ^\n" + |
3518 |
"The variable x may be null\n" + |
3519 |
"----------\n"); |
3520 |
} |
3521 |
|
3522 |
// null analysis -- try/catch |
3523 |
public void test0550_try_catch() { |
3524 |
this.runConformTest( |
3525 |
new String[] { |
3526 |
"X.java", |
3527 |
"public class X {\n" + |
3528 |
" void foo() {\n" + |
3529 |
" Object o = null;\n" + |
3530 |
" try {\n" + |
3531 |
" System.out.println();\n" + // might throw a runtime exception |
3532 |
" o = new Object();\n" + |
3533 |
" }\n" + |
3534 |
" catch (Throwable t) {\n" + // catches everything |
3535 |
" return;\n" + // gets out |
3536 |
" }\n" + |
3537 |
" o.toString();\n" + // non null |
3538 |
" }\n" + |
3539 |
"}\n"}, |
3540 |
""); |
3541 |
} |
3542 |
|
3543 |
// null analysis - try/catch |
3544 |
public void test0551_try_catch() { |
3545 |
this.runNegativeTest( |
3546 |
new String[] { |
3547 |
"X.java", |
3548 |
"public class X {\n" + |
3549 |
" boolean dummy;\n" + |
3550 |
" void foo() {\n" + |
3551 |
" Object o = new Object();\n" + |
3552 |
" try {\n" + |
3553 |
" System.out.println();\n" + |
3554 |
" if (dummy) {\n" + |
3555 |
" o = null;\n" + |
3556 |
" throw new Exception();\n" + |
3557 |
" }\n" + |
3558 |
" }\n" + |
3559 |
" catch (Exception e) {\n" + |
3560 |
" o.toString();\n" + // complain |
3561 |
" }\n" + |
3562 |
" }\n" + |
3563 |
"}\n"}, |
3564 |
"----------\n" + |
3565 |
"1. ERROR in X.java (at line 13)\n" + |
3566 |
" o.toString();\n" + |
3567 |
" ^\n" + |
3568 |
"The variable o may be null\n" + |
3569 |
"----------\n"); |
3570 |
} |
3571 |
|
3572 |
// null analysis - try/catch |
3573 |
public void test0552_try_catch() { |
3574 |
this.runConformTest( |
3575 |
new String[] { |
3576 |
"X.java", |
3577 |
"public class X {\n" + |
3578 |
" boolean dummy;\n" + |
3579 |
" void foo() throws Exception {\n" + |
3580 |
" Object o = new Object();\n" + |
3581 |
" try {\n" + |
3582 |
" if (dummy) {\n" + |
3583 |
" o = null;\n" + |
3584 |
" throw new Exception();\n" + |
3585 |
" }\n" + |
3586 |
" }\n" + |
3587 |
" catch (Exception e) {\n" + |
3588 |
" }\n" + |
3589 |
" if (o != null) {\n" + |
3590 |
// quiet: get out of try either through normal flow, leaves a new |
3591 |
// object, or through Exception, leaves a null |
3592 |
" }\n" + |
3593 |
" }\n" + |
3594 |
"}\n"}, |
3595 |
""); |
3596 |
} |
3597 |
|
3598 |
// null analysis - try/catch |
3599 |
public void test0553_try_catch() { |
3600 |
this.runNegativeTest( |
3601 |
new String[] { |
3602 |
"X.java", |
3603 |
"public class X {\n" + |
3604 |
" boolean dummy, other;\n" + |
3605 |
" void foo() {\n" + |
3606 |
" Object o = new Object();\n" + |
3607 |
" try {\n" + |
3608 |
" if (dummy) {\n" + |
3609 |
" if (other) {\n" + |
3610 |
" throw new LocalException();\n" + // may launch new exception |
3611 |
" }\n" + |
3612 |
" o = null;\n" + |
3613 |
" throw new LocalException();\n" + // must launch new exception |
3614 |
" }\n" + |
3615 |
" }\n" + |
3616 |
" catch (LocalException e) {\n" + |
3617 |
" o.toString();\n" + // complain |
3618 |
" }\n" + |
3619 |
" }\n" + |
3620 |
" class LocalException extends Exception {\n" + |
3621 |
" private static final long serialVersionUID = 1L;\n" + |
3622 |
" }\n" + |
3623 |
"}\n"}, |
3624 |
"----------\n" + |
3625 |
"1. ERROR in X.java (at line 15)\n" + |
3626 |
" o.toString();\n" + |
3627 |
" ^\n" + |
3628 |
"The variable o may be null\n" + |
3629 |
"----------\n"); |
3630 |
} |
3631 |
|
3632 |
// null analysis - try/catch |
3633 |
public void test0554_try_catch() { |
3634 |
this.runConformTest( |
3635 |
new String[] { |
3636 |
"X.java", |
3637 |
"public class X {\n" + |
3638 |
" void foo(Object o) throws Exception {\n" + |
3639 |
" try {\n" + |
3640 |
" o = null;\n" + |
3641 |
" throwLocalException();\n" + |
3642 |
" throw new Exception();\n" + |
3643 |
" }\n" + |
3644 |
" catch (LocalException e) {\n" + |
3645 |
" }\n" + |
3646 |
" if (o != null) {\n" + |
3647 |
// complain: only way to get out of try and get there is to go |
3648 |
// through throwLocalException, after the assignment |
3649 |
" }\n" + |
3650 |
" }\n" + |
3651 |
" class LocalException extends Exception {\n" + |
3652 |
" private static final long serialVersionUID = 1L;\n" + |
3653 |
" }\n" + |
3654 |
" void throwLocalException() throws LocalException {\n" + |
3655 |
" throw new LocalException();\n" + |
3656 |
" }\n" + |
3657 |
"}\n"}, |
3658 |
"" |
3659 |
// conservative flow analysis suppresses the warning |
3660 |
// "----------\n" + |
3661 |
// "1. ERROR in X.java (at line 10)\n" + |
3662 |
// " if (o != null) {\n" + |
3663 |
// " ^\n" + |
3664 |
// "The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3665 |
// "----------\n" |
3666 |
); |
3667 |
} |
3668 |
|
3669 |
// null analysis - try/catch |
3670 |
public void test0555_try_catch() { |
3671 |
this.runNegativeTest( |
3672 |
new String[] { |
3673 |
"X.java", |
3674 |
"public class X {\n" + |
3675 |
" void foo() {\n" + |
3676 |
" Object o = new Object();\n" + |
3677 |
" try {\n" + |
3678 |
" o = null;\n" + |
3679 |
" throwException();\n" + |
3680 |
" }\n" + |
3681 |
" catch (Exception e) {\n" + |
3682 |
" o.toString();\n" + // complain NPE |
3683 |
" }\n" + |
3684 |
" }\n" + |
3685 |
" void throwException() throws Exception {\n" + |
3686 |
" throw new Exception();\n" + |
3687 |
" }\n" + |
3688 |
"}\n"}, |
3689 |
"----------\n" + |
3690 |
"1. ERROR in X.java (at line 9)\n" + |
3691 |
" o.toString();\n" + |
3692 |
" ^\n" + |
3693 |
"The variable o may be null\n" + |
3694 |
"----------\n"); |
3695 |
} |
3696 |
|
3697 |
// null analysis - try/catch |
3698 |
public void test0556_try_catch() { |
3699 |
this.runNegativeTest( |
3700 |
new String[] { |
3701 |
"X.java", |
3702 |
"public class X {\n" + |
3703 |
" void foo() {\n" + |
3704 |
" Object o = new Object();\n" + |
3705 |
" try {\n" + |
3706 |
" o = null;\n" + |
3707 |
" throwException();\n" + |
3708 |
" }\n" + |
3709 |
" catch (Throwable t) {\n" + |
3710 |
" o.toString();\n" + // complain NPE |
3711 |
" }\n" + |
3712 |
" }\n" + |
3713 |
" void throwException() throws Exception {\n" + |
3714 |
" throw new Exception();\n" + |
3715 |
" }\n" + |
3716 |
"}\n"}, |
3717 |
"----------\n" + |
3718 |
"1. ERROR in X.java (at line 9)\n" + |
3719 |
" o.toString();\n" + |
3720 |
" ^\n" + |
3721 |
"The variable o may be null\n" + |
3722 |
"----------\n"); |
3723 |
} |
3724 |
|
3725 |
// null analysis - try/catch |
3726 |
public void test0557_try_catch() { |
3727 |
this.runNegativeTest( |
3728 |
new String[] { |
3729 |
"X.java", |
3730 |
"public class X {\n" + |
3731 |
" boolean dummy;\n" + |
3732 |
" void foo() {\n" + |
3733 |
" Object o = new Object();\n" + |
3734 |
" try {\n" + |
3735 |
" if (dummy) {\n" + |
3736 |
" o = null;\n" + |
3737 |
" throw new Exception();\n" + |
3738 |
" }\n" + |
3739 |
" }\n" + |
3740 |
" catch (Exception e) {\n" + |
3741 |
" o.toString();\n" + // complain NPE |
3742 |
" }\n" + |
3743 |
" }\n" + |
3744 |
"}\n"}, |
3745 |
"----------\n" + |
3746 |
"1. ERROR in X.java (at line 12)\n" + |
3747 |
" o.toString();\n" + |
3748 |
" ^\n" + |
3749 |
"The variable o may be null\n" + |
3750 |
"----------\n"); |
3751 |
} |
3752 |
|
3753 |
// null analysis - try/catch |
3754 |
public void test0558_try_catch() { |
3755 |
this.runNegativeTest( |
3756 |
new String[] { |
3757 |
"X.java", |
3758 |
"public class X {\n" + |
3759 |
" boolean dummy;\n" + |
3760 |
" void foo() {\n" + |
3761 |
" Object o = new Object();\n" + |
3762 |
" try {\n" + |
3763 |
" if (dummy) {\n" + |
3764 |
" System.out.print(0);\n" + // may thow RuntimeException |
3765 |
" o = null;\n" + |
3766 |
" throw new LocalException();\n" + |
3767 |
" }\n" + |
3768 |
" }\n" + |
3769 |
" catch (LocalException e) {\n" + // doesn't catch RuntimeException |
3770 |
" o.toString();\n" + // complain NPE |
3771 |
" }\n" + |
3772 |
" }\n" + |
3773 |
" class LocalException extends Exception {\n" + |
3774 |
" private static final long serialVersionUID = 1L;\n" + |
3775 |
" }\n" + |
3776 |
"}\n"}, |
3777 |
"----------\n" + |
3778 |
"1. ERROR in X.java (at line 13)\n" + |
3779 |
" o.toString();\n" + |
3780 |
" ^\n" + |
3781 |
// "The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3782 |
"The variable o may be null\n" + |
3783 |
// conservative flow analysis softens the error |
3784 |
"----------\n"); |
3785 |
} |
3786 |
|
3787 |
// null analysis - try/catch |
3788 |
public void test0559_try_catch() { |
3789 |
this.runNegativeTest( |
3790 |
new String[] { |
3791 |
"X.java", |
3792 |
"public class X {\n" + |
3793 |
" boolean dummy;\n" + |
3794 |
" void foo() {\n" + |
3795 |
" Object o = new Object();\n" + |
3796 |
" try {\n" + |
3797 |
" if (dummy) {\n" + |
3798 |
" o = null;\n" + |
3799 |
" throw new SubException();\n" + |
3800 |
" }\n" + |
3801 |
" }\n" + |
3802 |
" catch (LocalException e) {\n" + // must catch SubException |
3803 |
" o.toString();\n" + // complain NPE |
3804 |
" }\n" + |
3805 |
" }\n" + |
3806 |
" class LocalException extends Exception {\n" + |
3807 |
" private static final long serialVersionUID = 1L;\n" + |
3808 |
" }\n" + |
3809 |
" class SubException extends LocalException {\n" + |
3810 |
" private static final long serialVersionUID = 1L;\n" + |
3811 |
" }\n" + |
3812 |
"}\n"}, |
3813 |
"----------\n" + |
3814 |
"1. ERROR in X.java (at line 12)\n" + |
3815 |
" o.toString();\n" + |
3816 |
" ^\n" + |
3817 |
// "The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3818 |
"The variable o may be null\n" + |
3819 |
// conservative flow analysis softens the error |
3820 |
"----------\n"); |
3821 |
} |
3822 |
|
3823 |
// null analysis - try/catch |
3824 |
public void test0560_try_catch() { |
3825 |
this.runNegativeTest( |
3826 |
new String[] { |
3827 |
"X.java", |
3828 |
"public class X {\n" + |
3829 |
" Class bar(boolean b) throws ClassNotFoundException {\n" + |
3830 |
" if (b) {\n" + |
3831 |
" throw new ClassNotFoundException();\n" + |
3832 |
" }\n" + |
3833 |
" return null;\n" + |
3834 |
" }\n" + |
3835 |
" public Class foo(Class c, boolean b) {\n" + |
3836 |
" if (c != null)\n" + |
3837 |
" return c;\n" + |
3838 |
" if (b) {\n" + |
3839 |
" try {\n" + |
3840 |
" c = bar(b);\n" + |
3841 |
" return c;\n" + |
3842 |
" } catch (ClassNotFoundException e) {\n" + |
3843 |
" // empty\n" + |
3844 |
" }\n" + |
3845 |
" }\n" + |
3846 |
" if (c == null) { // should complain: c can only be null\n" + |
3847 |
" }\n" + |
3848 |
" return c;\n" + |
3849 |
" }\n" + |
3850 |
"}\n"}, |
3851 |
"----------\n" + |
3852 |
"1. ERROR in X.java (at line 19)\n" + |
3853 |
" if (c == null) { // should complain: c can only be null\n" + |
3854 |
" ^\n" + |
3855 |
"The variable c can only be null; it was either set to null or checked for null when last used\n" + |
3856 |
"----------\n"); |
3857 |
} |
3858 |
|
3859 |
// null analysis -- do while |
3860 |
public void test0601_do_while() { |
3861 |
this.runNegativeTest( |
3862 |
new String[] { |
3863 |
"X.java", |
3864 |
"public class X {\n" + |
3865 |
" void foo() {\n" + |
3866 |
" Object o = null;\n" + |
3867 |
" do {/* */}\n" + |
3868 |
" while (o.toString() != null);\n" + |
3869 |
// complain: NPE |
3870 |
" }\n" + |
3871 |
"}\n"}, |
3872 |
"----------\n" + |
3873 |
"1. ERROR in X.java (at line 5)\n" + |
3874 |
" while (o.toString() != null);\n" + |
3875 |
" ^\n" + |
3876 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3877 |
"----------\n"); |
3878 |
} |
3879 |
|
3880 |
// null analysis -- do while |
3881 |
public void test0602_do_while() { |
3882 |
this.runNegativeTest( |
3883 |
new String[] { |
3884 |
"X.java", |
3885 |
"public class X {\n" + |
3886 |
" void foo() {\n" + |
3887 |
" Object o = null;\n" + |
3888 |
" do {/* */}\n" + |
3889 |
" while (o != null);\n" + |
3890 |
// complain: get o null first time and forever |
3891 |
" }\n" + |
3892 |
"}\n"}, |
3893 |
"----------\n" + |
3894 |
"1. ERROR in X.java (at line 5)\n" + |
3895 |
" while (o != null);\n" + |
3896 |
" ^\n" + |
3897 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3898 |
"----------\n"); |
3899 |
} |
3900 |
|
3901 |
// null analysis -- do while |
3902 |
public void test0603_do_while() { |
3903 |
this.runNegativeTest( |
3904 |
new String[] { |
3905 |
"X.java", |
3906 |
"public class X {\n" + |
3907 |
" void foo() {\n" + |
3908 |
" Object o = null;\n" + |
3909 |
" do {\n" + |
3910 |
" o = new Object();\n" + |
3911 |
" }\n" + |
3912 |
" while (o == null);\n" + |
3913 |
// complain: set it to non null before test, for each iteration |
3914 |
" }\n" + |
3915 |
"}\n"}, |
3916 |
"----------\n" + |
3917 |
"1. ERROR in X.java (at line 7)\n" + |
3918 |
" while (o == null);\n" + |
3919 |
" ^\n" + |
3920 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
3921 |
"----------\n"); |
3922 |
} |
3923 |
|
3924 |
// null analysis -- do while |
3925 |
public void test0604_do_while() { |
3926 |
this.runConformTest( |
3927 |
new String[] { |
3928 |
"X.java", |
3929 |
"public class X {\n" + |
3930 |
" void foo() {\n" + |
3931 |
" Object o = null;\n" + |
3932 |
" do {\n" + |
3933 |
" if (System.currentTimeMillis() > 10L) {\n" + |
3934 |
" o = new Object();\n" + |
3935 |
" }\n" + |
3936 |
" }\n" + |
3937 |
" while (o == null);\n" + |
3938 |
" }\n" + |
3939 |
"}\n"}, |
3940 |
""); |
3941 |
} |
3942 |
|
3943 |
// null analysis -- do while |
3944 |
public void test0605_do_while() { |
3945 |
this.runNegativeTest( |
3946 |
new String[] { |
3947 |
"X.java", |
3948 |
"public class X {\n" + |
3949 |
" boolean dummy;\n" + |
3950 |
" void foo(Object o) {\n" + |
3951 |
" o = null;\n" + |
3952 |
" do {\n" + |
3953 |
" // do nothing\n" + |
3954 |
" }\n" + |
3955 |
" while (dummy || o != null);\n" + |
3956 |
" }\n" + |
3957 |
"}\n"}, |
3958 |
"----------\n" + |
3959 |
"1. ERROR in X.java (at line 8)\n" + |
3960 |
" while (dummy || o != null);\n" + |
3961 |
" ^\n" + |
3962 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
3963 |
"----------\n"); |
3964 |
} |
3965 |
|
3966 |
// null analysis -- do while |
3967 |
public void test0606_do_while() { |
3968 |
this.runConformTest( |
3969 |
new String[] { |
3970 |
"X.java", |
3971 |
"public class X {\n" + |
3972 |
" void foo() {\n" + |
3973 |
" Object o = null,\n" + |
3974 |
" u = new Object(),\n" + |
3975 |
" v = new Object();\n" + |
3976 |
" do {\n" + |
3977 |
" if (v == null) {\n" + |
3978 |
" o = new Object();\n" + |
3979 |
" };\n" + |
3980 |
" if (u == null) {\n" + |
3981 |
" v = null;\n" + |
3982 |
" };\n" + |
3983 |
" u = null;\n" + |
3984 |
" }\n" + |
3985 |
" while (o == null);\n" + |
3986 |
" }\n" + |
3987 |
"}\n"}, |
3988 |
""); |
3989 |
} |
3990 |
|
3991 |
// null analysis -- do while |
3992 |
public void test0607_do_while() { |
3993 |
this.runNegativeTest( |
3994 |
new String[] { |
3995 |
"X.java", |
3996 |
"public class X {\n" + |
3997 |
" boolean dummy;\n" + |
3998 |
" void foo() {\n" + |
3999 |
" Object o = null;\n" + |
4000 |
" do {\n" + |
4001 |
" o.toString();\n" + |
4002 |
// complain: NPE |
4003 |
" o = new Object();\n" + |
4004 |
" }\n" + |
4005 |
" while (dummy);\n" + |
4006 |
" }\n" + |
4007 |
"}\n"}, |
4008 |
"----------\n" + |
4009 |
"1. ERROR in X.java (at line 6)\n" + |
4010 |
" o.toString();\n" + |
4011 |
" ^\n" + |
4012 |
"The variable o may be null\n" + |
4013 |
"----------\n"); |
4014 |
} |
4015 |
|
4016 |
// null analysis -- do while |
4017 |
public void test0608_do_while() { |
4018 |
this.runConformTest( |
4019 |
new String[] { |
4020 |
"X.java", |
4021 |
"public class X {\n" + |
4022 |
" boolean dummy;\n" + |
4023 |
" void foo() {\n" + |
4024 |
" Object o = null;\n" + |
4025 |
" do {\n" + |
4026 |
" o = new Object();\n" + |
4027 |
" }\n" + |
4028 |
" while (dummy);\n" + |
4029 |
" o.toString();\n" + |
4030 |
" }\n" + |
4031 |
"}\n"}, |
4032 |
""); |
4033 |
} |
4034 |
|
4035 |
// null analysis -- do while |
4036 |
public void test0609_do_while() { |
4037 |
this.runNegativeTest( |
4038 |
new String[] { |
4039 |
"X.java", |
4040 |
"public class X {\n" + |
4041 |
" boolean dummy;\n" + |
4042 |
" void foo() {\n" + |
4043 |
" Object o = null;\n" + |
4044 |
" do { /* */ }\n" + |
4045 |
" while (dummy);\n" + |
4046 |
" o.toString();\n" + |
4047 |
" }\n" + |
4048 |
"}\n"}, |
4049 |
"----------\n" + |
4050 |
"1. ERROR in X.java (at line 7)\n" + |
4051 |
" o.toString();\n" + |
4052 |
" ^\n" + |
4053 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4054 |
"----------\n"); |
4055 |
} |
4056 |
|
4057 |
// null analysis - do while |
4058 |
public void test0610_do_while() { |
4059 |
this.runConformTest( |
4060 |
new String[] { |
4061 |
"X.java", |
4062 |
"public class X {\n" + |
4063 |
" X bar() {\n" + |
4064 |
" return null;\n" + |
4065 |
" }\n" + |
4066 |
" void foo(X x) {\n" + |
4067 |
" x.bar();\n" + |
4068 |
" do {\n" + |
4069 |
" x = x.bar();\n" + |
4070 |
" } while (x != null);\n" + // quiet |
4071 |
" }\n" + |
4072 |
"}\n"}, |
4073 |
""); |
4074 |
} |
4075 |
|
4076 |
// null analysis - do while |
4077 |
public void test0611_do_while() { |
4078 |
this.runNegativeTest( |
4079 |
new String[] { |
4080 |
"X.java", |
4081 |
"class X {\n" + |
4082 |
" X bar() {\n" + |
4083 |
" return new X();\n" + |
4084 |
" }\n" + |
4085 |
" void foo(Object o) {\n" + |
4086 |
" do {\n" + |
4087 |
" o = bar();\n" + |
4088 |
" } while (o == null);\n" + |
4089 |
" if (o != null) { /* */ }\n" + // complain |
4090 |
" }\n" + |
4091 |
"}"}, |
4092 |
"----------\n" + |
4093 |
"1. ERROR in X.java (at line 9)\n" + |
4094 |
" if (o != null) { /* */ }\n" + |
4095 |
" ^\n" + |
4096 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
4097 |
"----------\n"); |
4098 |
} |
4099 |
|
4100 |
// the problem here is that a single pass cannot know for the return |
4101 |
// embedded into the if; prior approach did use the upstream flow |
4102 |
// info to catch this, but this is inappropriate in many cases (eg |
4103 |
// test0606); may be able to do better if keeping all deep returns |
4104 |
// as we do for labeled continue |
4105 |
// TODO (maxime) https://bugs.eclipse.org/bugs/show_bug.cgi?id=123399 |
4106 |
public void _test0612_do_while() { |
4107 |
this.runNegativeTest( |
4108 |
new String[] { |
4109 |
"X.java", |
4110 |
"public class X {\n" + |
4111 |
" void foo(Object doubt) {\n" + |
4112 |
" Object o = null;\n" + |
4113 |
" do {\n" + |
4114 |
" if (o == null) {\n" + |
4115 |
" return;\n" + |
4116 |
" }\n" + |
4117 |
" o = doubt;\n" + |
4118 |
" } while (true);\n" + |
4119 |
" }\n" + |
4120 |
"}"}, |
4121 |
"----------\n" + |
4122 |
"1. ERROR in X.java (at line 6)\n" + |
4123 |
" if (o == null) {\n" + |
4124 |
" ^\n" + |
4125 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4126 |
"----------\n" |
4127 |
); |
4128 |
} |
4129 |
|
4130 |
// null analysis -- for |
4131 |
public void test0701_for() { |
4132 |
this.runNegativeTest( |
4133 |
new String[] { |
4134 |
"X.java", |
4135 |
"public class X {\n" + |
4136 |
" void foo() {\n" + |
4137 |
" Object o = null;\n" + |
4138 |
" for (;o.toString() != null;) {/* */}\n" + |
4139 |
// complain: NPE |
4140 |
" }\n" + |
4141 |
"}\n"}, |
4142 |
"----------\n" + |
4143 |
"1. ERROR in X.java (at line 4)\n" + |
4144 |
" for (;o.toString() != null;) {/* */}\n" + |
4145 |
" ^\n" + |
4146 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4147 |
"----------\n"); |
4148 |
} |
4149 |
|
4150 |
// null analysis -- for |
4151 |
public void test0702_for() { |
4152 |
this.runNegativeTest( |
4153 |
new String[] { |
4154 |
"X.java", |
4155 |
"public class X {\n" + |
4156 |
" void foo() {\n" + |
4157 |
" Object o = null;\n" + |
4158 |
" for (;o != null;) {/* */}\n" + |
4159 |
// complain: get o null first time and forever |
4160 |
" }\n" + |
4161 |
"}\n"}, |
4162 |
"----------\n" + |
4163 |
"1. ERROR in X.java (at line 4)\n" + |
4164 |
" for (;o != null;) {/* */}\n" + |
4165 |
" ^\n" + |
4166 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4167 |
"----------\n"); |
4168 |
} |
4169 |
|
4170 |
// null analysis -- for |
4171 |
public void test0703_for() { |
4172 |
this.runConformTest( |
4173 |
new String[] { |
4174 |
"X.java", |
4175 |
"public class X {\n" + |
4176 |
" void foo() {\n" + |
4177 |
" Object o = null;\n" + |
4178 |
" for (;o == null;) {\n" + |
4179 |
// quiet: first iteration is sure to find it null, |
4180 |
// but other iterations may change it |
4181 |
" o = new Object();\n" + |
4182 |
" }\n" + |
4183 |
" }\n" + |
4184 |
"}\n"}, |
4185 |
""); |
4186 |
} |
4187 |
|
4188 |
// null analysis -- for |
4189 |
public void test0704_for() { |
4190 |
this.runConformTest( |
4191 |
new String[] { |
4192 |
"X.java", |
4193 |
"public class X {\n" + |
4194 |
" void foo() {\n" + |
4195 |
" Object o = null;\n" + |
4196 |
" for (;o == null;) {\n" + |
4197 |
// quiet: first iteration is sure to find it null, |
4198 |
// but other iterations may change it |
4199 |
" if (System.currentTimeMillis() > 10L) {\n" + |
4200 |
" o = new Object();\n" + |
4201 |
" }\n" + |
4202 |
" }\n" + |
4203 |
" }\n" + |
4204 |
"}\n"}, |
4205 |
""); |
4206 |
} |
4207 |
|
4208 |
// null analysis -- for |
4209 |
public void test0705_for() { |
4210 |
this.runNegativeTest( |
4211 |
new String[] { |
4212 |
"X.java", |
4213 |
"public class X {\n" + |
4214 |
" boolean bar() {\n" + |
4215 |
" return true;\n" + |
4216 |
" }\n" + |
4217 |
" void foo(Object o) {\n" + |
4218 |
" for (;bar() && o == null;) {\n" + |
4219 |
" o.toString();\n" + // complain: NPE because of condition |
4220 |
" o = new Object();\n" + |
4221 |
" }\n" + |
4222 |
" }\n" + |
4223 |
"}\n"}, |
4224 |
"----------\n" + |
4225 |
"1. ERROR in X.java (at line 7)\n" + |
4226 |
" o.toString();\n" + |
4227 |
" ^\n" + |
4228 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4229 |
"----------\n"); |
4230 |
} |
4231 |
|
4232 |
// null analysis -- for |
4233 |
public void test0707_for() { |
4234 |
this.runConformTest( |
4235 |
new String[] { |
4236 |
"X.java", |
4237 |
"public class X {\n" + |
4238 |
" void foo(Object o) {\n" + |
4239 |
" for (;o == null; o.toString()) {\n" + |
4240 |
" o = new Object();\n" + |
4241 |
" }\n" + |
4242 |
" }\n" + |
4243 |
"}\n"}, |
4244 |
""); |
4245 |
} |
4246 |
|
4247 |
// null analysis -- for |
4248 |
public void test0708_for() { |
4249 |
this.runNegativeTest( |
4250 |
new String[] { |
4251 |
"X.java", |
4252 |
"public class X {\n" + |
4253 |
" void foo(Object o) {\n" + |
4254 |
" for (;o == null; o.toString()) {\n" + |
4255 |
" }\n" + |
4256 |
" }\n" + |
4257 |
"}\n"}, |
4258 |
"----------\n" + |
4259 |
"1. ERROR in X.java (at line 3)\n" + |
4260 |
" for (;o == null; o.toString()) {\n" + |
4261 |
" ^\n" + |
4262 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4263 |
"----------\n"); |
4264 |
} |
4265 |
|
4266 |
// null analysis -- for |
4267 |
public void test0709_for() { |
4268 |
this.runNegativeTest( |
4269 |
new String[] { |
4270 |
"X.java", |
4271 |
"public class X {\n" + |
4272 |
" void foo(Object o) {\n" + |
4273 |
" for (o.toString(); o == null;) { /* */ }\n" + // complain: protected then unchanged |
4274 |
" }\n" + |
4275 |
"}\n"}, |
4276 |
"----------\n" + |
4277 |
"1. ERROR in X.java (at line 3)\n" + |
4278 |
" for (o.toString(); o == null;) { /* */ }\n" + |
4279 |
" ^\n" + |
4280 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
4281 |
"----------\n"); |
4282 |
} |
4283 |
|
4284 |
// null analysis -- for |
4285 |
public void test0710_for() { |
4286 |
this.runNegativeTest( |
4287 |
new String[] { |
4288 |
"X.java", |
4289 |
"public class X {\n" + |
4290 |
" boolean bar() {\n" + |
4291 |
" return true;\n" + |
4292 |
" }\n" + |
4293 |
" void foo(Object o) {\n" + |
4294 |
" o = null;\n" + |
4295 |
" for (o.toString(); bar();) {\n" + |
4296 |
" }\n" + |
4297 |
" }\n" + |
4298 |
"}\n"}, |
4299 |
"----------\n" + |
4300 |
"1. ERROR in X.java (at line 7)\n" + |
4301 |
" for (o.toString(); bar();) {\n" + |
4302 |
" ^\n" + |
4303 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4304 |
"----------\n"); |
4305 |
} |
4306 |
|
4307 |
// null analysis -- for |
4308 |
public void test0711_for() { |
4309 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
4310 |
this.runNegativeTest( |
4311 |
new String[] { |
4312 |
"X.java", |
4313 |
"public class X {\n" + |
4314 |
" void foo() {\n" + |
4315 |
" Object t[] = null;\n" + |
4316 |
" for (Object o : t) {/* */}\n" + |
4317 |
// complain: NPE |
4318 |
" }\n" + |
4319 |
"}\n"}, |
4320 |
"----------\n" + |
4321 |
"1. ERROR in X.java (at line 4)\n" + |
4322 |
" for (Object o : t) {/* */}\n" + |
4323 |
" ^\n" + |
4324 |
"The variable t can only be null; it was either set to null or checked for null when last used\n" + |
4325 |
"----------\n"); |
4326 |
} |
4327 |
} |
4328 |
|
4329 |
// null analysis -- for |
4330 |
public void test0712_for() { |
4331 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
4332 |
this.runNegativeTest( |
4333 |
new String[] { |
4334 |
"X.java", |
4335 |
"public class X {\n" + |
4336 |
" void foo() {\n" + |
4337 |
" Iterable i = null;\n" + |
4338 |
" for (Object o : i) {/* */}\n" + |
4339 |
// complain: NPE |
4340 |
" }\n" + |
4341 |
"}\n"}, |
4342 |
"----------\n" + |
4343 |
"1. ERROR in X.java (at line 4)\n" + |
4344 |
" for (Object o : i) {/* */}\n" + |
4345 |
" ^\n" + |
4346 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
4347 |
"----------\n"); |
4348 |
} |
4349 |
} |
4350 |
|
4351 |
// null analysis -- for |
4352 |
public void test0713_for() { |
4353 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
4354 |
this.runConformTest( |
4355 |
new String[] { |
4356 |
"X.java", |
4357 |
"public class X {\n" + |
4358 |
" void foo() {\n" + |
4359 |
" Object t[] = new Object[1];\n" + |
4360 |
" for (Object o : t) {/* */}\n" + |
4361 |
" }\n" + |
4362 |
"}\n"}, |
4363 |
""); |
4364 |
} |
4365 |
} |
4366 |
|
4367 |
// null analysis -- for |
4368 |
public void test0714_for() { |
4369 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
4370 |
this.runConformTest( |
4371 |
new String[] { |
4372 |
"X.java", |
4373 |
"public class X {\n" + |
4374 |
" void foo() {\n" + |
4375 |
" Iterable i = new java.util.Vector<Object>();\n" + |
4376 |
" for (Object o : i) {/* */}\n" + |
4377 |
" }\n" + |
4378 |
"}\n"}, |
4379 |
""); |
4380 |
} |
4381 |
} |
4382 |
|
4383 |
// null analysis -- for |
4384 |
public void test0715_for() { |
4385 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
4386 |
this.runNegativeTest( |
4387 |
new String[] { |
4388 |
"X.java", |
4389 |
"public class X {\n" + |
4390 |
" void foo() {\n" + |
4391 |
" Iterable i = new java.util.Vector<Object>();\n" + |
4392 |
" Object flag = null;\n" + |
4393 |
" for (Object o : i) {\n" + |
4394 |
" flag = new Object();\n" + |
4395 |
" }\n" + |
4396 |
" flag.toString();\n" + |
4397 |
// complain: cannot know if at least one iteration got executed |
4398 |
" }\n" + |
4399 |
"}\n"}, |
4400 |
"----------\n" + |
4401 |
"1. ERROR in X.java (at line 8)\n" + |
4402 |
" flag.toString();\n" + |
4403 |
" ^^^^\n" + |
4404 |
"The variable flag may be null\n" + |
4405 |
"----------\n"); |
4406 |
} |
4407 |
} |
4408 |
|
4409 |
// null analysis -- for |
4410 |
public void test0716_for() { |
4411 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
4412 |
this.runNegativeTest( |
4413 |
new String[] { |
4414 |
"X.java", |
4415 |
"public class X {\n" + |
4416 |
" void foo() {\n" + |
4417 |
" Iterable i = new java.util.Vector<Object>();\n" + |
4418 |
" Object flag = null;\n" + |
4419 |
" for (Object o : i) { /* */ }\n" + |
4420 |
" flag.toString();\n" + |
4421 |
" }\n" + |
4422 |
"}\n"}, |
4423 |
"----------\n" + |
4424 |
"1. ERROR in X.java (at line 6)\n" + |
4425 |
" flag.toString();\n" + |
4426 |
" ^^^^\n" + |
4427 |
"The variable flag can only be null; it was either set to null or checked for null when last used\n" + |
4428 |
"----------\n"); |
4429 |
} |
4430 |
} |
4431 |
|
4432 |
// null analysis -- for |
4433 |
public void test0717_for() { |
4434 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
4435 |
this.runNegativeTest( |
4436 |
new String[] { |
4437 |
"X.java", |
4438 |
"public class X {\n" + |
4439 |
" void foo(boolean dummy) {\n" + |
4440 |
" Object flag = null;\n" + |
4441 |
" for (;dummy;) {\n" + |
4442 |
" flag = new Object();\n" + |
4443 |
" }\n" + |
4444 |
" flag.toString();\n" + |
4445 |
" }\n" + |
4446 |
"}\n"}, |
4447 |
"----------\n" + |
4448 |
"1. ERROR in X.java (at line 7)\n" + |
4449 |
" flag.toString();\n" + |
4450 |
" ^^^^\n" + |
4451 |
"The variable flag may be null\n" + |
4452 |
"----------\n"); |
597 |
} |
4453 |
} |
|
|
4454 |
} |
4455 |
|
4456 |
// null analysis -- for |
4457 |
public void test0718_for() { |
4458 |
this.runNegativeTest( |
4459 |
new String[] { |
4460 |
"X.java", |
4461 |
"public class X {\n" + |
4462 |
" void foo(boolean dummy) {\n" + |
4463 |
" Object flag = null;\n" + |
4464 |
" for (;dummy;) { /* */ }\n" + |
4465 |
" flag.toString();\n" + |
4466 |
" }\n" + |
4467 |
"}\n"}, |
4468 |
"----------\n" + |
4469 |
"1. ERROR in X.java (at line 5)\n" + |
4470 |
" flag.toString();\n" + |
4471 |
" ^^^^\n" + |
4472 |
"The variable flag can only be null; it was either set to null or checked for null when last used\n" + |
4473 |
"----------\n"); |
4474 |
} |
4475 |
|
4476 |
// null analysis -- for |
4477 |
// origin: AssignmentTest#test019 |
4478 |
public void test0719_for() { |
4479 |
this.runConformTest( |
4480 |
new String[] { |
4481 |
"X.java", |
4482 |
"public class X {\n" + |
4483 |
" public static final char[] foo(char[] a, char c1, char c2) {\n" + |
4484 |
" char[] r = null;\n" + |
4485 |
" for (int i = 0, length = a.length; i < length; i++) {\n" + |
4486 |
" char c = a[i];\n" + |
4487 |
" if (c == c1) {\n" + |
4488 |
" if (r == null) {\n" + |
4489 |
" r = new char[length];\n" + |
4490 |
" }\n" + |
4491 |
" r[i] = c2;\n" + |
4492 |
" } else if (r != null) {\n" + |
4493 |
" r[i] = c;\n" + |
4494 |
" }\n" + |
4495 |
" }\n" + |
4496 |
" if (r == null) return a;\n" + |
4497 |
" return r;\n" + |
4498 |
" }\n" + |
4499 |
"}\n"}, |
4500 |
""); |
4501 |
} |
4502 |
|
4503 |
// null analysis -- for |
4504 |
public void test0720_for_continue_break() { |
4505 |
this.runNegativeTest( |
4506 |
new String[] { |
4507 |
"X.java", |
4508 |
"public class X {\n" + |
4509 |
" void foo() {\n" + |
4510 |
" Object o = new Object();\n" + |
4511 |
" for (int i = 0; i < 10; i++) {\n" + |
4512 |
" if (o == null) {\n" + // complain: o cannot be null |
4513 |
" continue;\n" + |
4514 |
" }\n" + |
4515 |
" o = null;\n" + |
4516 |
" break;\n" + |
4517 |
" }\n" + |
4518 |
" }\n" + |
4519 |
"}\n"}, |
4520 |
"----------\n" + |
4521 |
"1. ERROR in X.java (at line 5)\n" + |
4522 |
" if (o == null) {\n" + |
4523 |
" ^\n" + |
4524 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
4525 |
"----------\n"); |
4526 |
} |
4527 |
|
4528 |
// null analysis -- for |
4529 |
public void test0721_for() { |
4530 |
this.runConformTest( |
4531 |
new String[] { |
4532 |
"X.java", |
4533 |
"public class X {\n" + |
4534 |
" void foo(boolean b) {\n" + |
4535 |
" Object o = null;\n" + |
4536 |
" for (; b ? (o = new Object()).equals(o) : false ;) {\n" + |
4537 |
// contrast this with test0238; here the condition shades doubts |
4538 |
// upon o being null |
4539 |
" /* */\n" + |
4540 |
" }\n" + |
4541 |
" if (o == null) { /* */ }\n" + |
4542 |
" }\n" + |
4543 |
"}\n"}, |
4544 |
""); |
4545 |
} |
4546 |
|
4547 |
// null analysis -- for |
4548 |
public void test0722_for_return() { |
4549 |
this.runNegativeTest( |
4550 |
new String[] { |
4551 |
"X.java", |
4552 |
"public class X {\n" + |
4553 |
" void foo (boolean b) {\n" + |
4554 |
" Object o = null;\n" + |
4555 |
" for (int i = 0; i < 25; i++) {\n" + |
4556 |
" if (b) {\n" + |
4557 |
" if (o == null) {\n" + |
4558 |
" o = new Object();\n" + // cleared by return downstream |
4559 |
" }\n" + |
4560 |
" return;\n" + |
4561 |
" }\n" + |
4562 |
" }\n" + |
4563 |
" }\n" + |
4564 |
"}\n"}, |
4565 |
"----------\n" + |
4566 |
"1. ERROR in X.java (at line 6)\n" + |
4567 |
" if (o == null) {\n" + |
4568 |
" ^\n" + |
4569 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4570 |
"----------\n"); |
4571 |
} |
4572 |
|
4573 |
// null analysis -- for |
4574 |
public void test0723_for() { |
4575 |
this.runConformTest( |
4576 |
new String[] { |
4577 |
"X.java", |
4578 |
"public class X {\n" + |
4579 |
" void foo () {\n" + |
4580 |
" Object o[] = new Object[1];\n" + |
4581 |
" for (int i = 0; i < 1; i++) {\n" + |
4582 |
" if (i < 1) {\n" + |
4583 |
" o[i].toString();\n" + |
4584 |
" }\n" + |
4585 |
" }\n" + |
4586 |
" }\n" + |
4587 |
"}\n"}, |
4588 |
""); |
4589 |
} |
4590 |
|
4591 |
// null analysis -- for |
4592 |
public void test0724_for_with_initialization() { |
4593 |
this.runConformTest( |
4594 |
new String[] { |
4595 |
"X.java", |
4596 |
"public class X {\n" + |
4597 |
" X field;\n" + |
4598 |
" void foo(X x1) {\n" + |
4599 |
" // X x2;\n" + |
4600 |
" outer: for (int i = 0; i < 30; i++) {\n" + |
4601 |
" X x2 = x1;\n" + |
4602 |
" do {\n" + |
4603 |
" if (x2.equals(x1)) {\n" + |
4604 |
" continue outer;\n" + |
4605 |
" }\n" + |
4606 |
" x2 = x2.field;\n" + |
4607 |
" } while (x2 != null);\n" + |
4608 |
" }\n" + |
4609 |
" }\n" + |
4610 |
"}\n"}, |
4611 |
""); |
4612 |
} |
4613 |
|
4614 |
// null analysis -- for |
4615 |
public void test0725_for_with_assignment() { |
4616 |
this.runConformTest( |
4617 |
new String[] { |
4618 |
"X.java", |
4619 |
"public class X {\n" + |
4620 |
" X field;\n" + |
4621 |
" void foo(X x1) {\n" + |
4622 |
" X x2;\n" + |
4623 |
" outer: for (int i = 0; i < 30; i++) {\n" + |
4624 |
" x2 = x1;\n" + |
4625 |
" do {\n" + |
4626 |
" if (x2.equals(x1)) {\n" + |
4627 |
" continue outer;\n" + |
4628 |
" }\n" + |
4629 |
" x2 = x2.field;\n" + |
4630 |
" } while (x2 != null);\n" + |
4631 |
" }\n" + |
4632 |
" }\n" + |
4633 |
"}\n"}, |
4634 |
""); |
4635 |
} |
4636 |
|
4637 |
// null analysis -- for |
4638 |
// contrast this with #311 |
4639 |
public void test0726_for() { |
4640 |
this.runNegativeTest( |
4641 |
new String[] { |
4642 |
"X.java", |
4643 |
"public class X {\n" + |
4644 |
" void foo(X x1) {\n" + |
4645 |
" X x2 = null;\n" + |
4646 |
" for (int i = 0; i < 5; i++) {\n" + |
4647 |
" if (x2 == null) {\n" + |
4648 |
" x2 = x1;\n" + |
4649 |
" }\n" + |
4650 |
" x2.toString();\n" + |
4651 |
" }\n" + |
4652 |
" }\n" + |
4653 |
"}\n"}, |
4654 |
"----------\n" + |
4655 |
"1. ERROR in X.java (at line 8)\n" + |
4656 |
" x2.toString();\n" + |
4657 |
" ^^\n" + |
4658 |
"The variable x2 may be null\n" + |
4659 |
"----------\n"); |
4660 |
} |
4661 |
|
4662 |
// null analysis -- for |
4663 |
public void test0727_for() { |
4664 |
this.runConformTest( |
4665 |
new String[] { |
4666 |
"X.java", |
4667 |
"public class X {\n" + |
4668 |
" void foo() {\n" + |
4669 |
" for (; true;) { /* */ }\n" + |
4670 |
" }\n" + |
4671 |
"}\n"}, |
4672 |
""); |
4673 |
} |
4674 |
|
4675 |
// null analysis -- for |
4676 |
public void test0728_for() { |
4677 |
this.runNegativeTest( |
4678 |
new String[] { |
4679 |
"X.java", |
4680 |
"public class X {\n" + |
4681 |
" void foo(X x) {\n" + |
4682 |
" for (; true; x.toString()) { /* */ }\n" + |
4683 |
" if (x == null) { /* */ }\n" + // complain |
4684 |
" }\n" + |
4685 |
"}\n"}, |
4686 |
"----------\n" + |
4687 |
"1. ERROR in X.java (at line 4)\n" + |
4688 |
" if (x == null) { /* */ }\n" + |
4689 |
" ^^^^^^^^^^^^^^^^^^^^^^^^\n" + |
4690 |
"Unreachable code\n" + |
4691 |
"----------\n"); |
4692 |
} |
4693 |
|
4694 |
// null analysis -- for |
4695 |
public void test0729_for_try_catch_finally() { |
4696 |
this.runConformTest( |
4697 |
new String[] { |
4698 |
"X.java", |
4699 |
"import java.io.IOException;\n" + |
4700 |
"class X {\n" + |
4701 |
" X f;\n" + |
4702 |
" void bar() throws IOException {\n" + |
4703 |
" throw new IOException();\n" + |
4704 |
" }\n" + |
4705 |
" void foo(boolean b) {\n" + |
4706 |
" for (int i = 0 ; i < 5 ; i++) {\n" + |
4707 |
" X x = this.f;\n" + |
4708 |
" if (x == null) { \n" + |
4709 |
" continue;\n" + |
4710 |
" }\n" + |
4711 |
" if (b) {\n" + |
4712 |
" try {\n" + |
4713 |
" bar();\n" + |
4714 |
" } \n" + |
4715 |
" catch(IOException e) { /* */ }\n" + |
4716 |
" finally {\n" + |
4717 |
" x.toString();\n" + |
4718 |
" }\n" + |
4719 |
" }\n" + |
4720 |
" }\n" + |
4721 |
" }\n" + |
4722 |
"}"}, |
4723 |
""); |
4724 |
} |
4725 |
|
4726 |
// null analysis - for |
4727 |
public void test0730_for() { |
4728 |
this.runNegativeTest( |
4729 |
new String[] { |
4730 |
"X.java", |
4731 |
"class X {\n" + |
4732 |
" void foo(Object o) {\n" + |
4733 |
" for ( ; o == null ; ) {\n" + |
4734 |
" o = new Object();\n" + |
4735 |
" }\n" + |
4736 |
" if (o != null) { /* */ }\n" + // complain |
4737 |
" }\n" + |
4738 |
"}"}, |
4739 |
"----------\n" + |
4740 |
"1. ERROR in X.java (at line 6)\n" + |
4741 |
" if (o != null) { /* */ }\n" + |
4742 |
" ^\n" + |
4743 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
4744 |
"----------\n"); |
4745 |
} |
4746 |
|
4747 |
// null analysis - for |
4748 |
public void test0731_for() { |
4749 |
this.runNegativeTest( |
4750 |
new String[] { |
4751 |
"X.java", |
4752 |
"class X {\n" + |
4753 |
" X bar() {\n" + |
4754 |
" return new X();\n" + |
4755 |
" }\n" + |
4756 |
" void foo(Object o) {\n" + |
4757 |
" for ( ; o == null ; ) {\n" + |
4758 |
" o = bar();\n" + |
4759 |
" }\n" + |
4760 |
" if (o != null) { /* */ }\n" + // complain |
4761 |
" }\n" + |
4762 |
"}"}, |
4763 |
"----------\n" + |
4764 |
"1. ERROR in X.java (at line 9)\n" + |
4765 |
" if (o != null) { /* */ }\n" + |
4766 |
" ^\n" + |
4767 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
4768 |
"----------\n"); |
4769 |
} |
4770 |
|
4771 |
// null analysis -- switch |
4772 |
public void test0800_switch() { |
4773 |
this.runConformTest( |
4774 |
new String[] { |
4775 |
"X.java", |
4776 |
"public class X {\n" + |
4777 |
" int k;\n" + |
4778 |
" void foo() {\n" + |
4779 |
" Object o = null;\n" + |
4780 |
" switch (k) {\n" + |
4781 |
" case 0 :\n" + |
4782 |
" o = new Object();\n" + |
4783 |
" break;\n" + |
4784 |
" case 2 :\n" + |
4785 |
" return;\n" + |
4786 |
" }\n" + |
4787 |
" if(o == null) { /* */ }\n" + // quiet: don't know whether came from 0 or default |
4788 |
" }\n" + |
4789 |
"}\n"}, |
4790 |
""); |
4791 |
} |
4792 |
|
4793 |
// null analysis -- switch |
4794 |
public void test0801_switch() { |
4795 |
this.runNegativeTest( |
4796 |
new String[] { |
4797 |
"X.java", |
4798 |
"public class X {\n" + |
4799 |
" int k;\n" + |
4800 |
" void foo() {\n" + |
4801 |
" Object o = null;\n" + |
4802 |
" switch (k) {\n" + |
4803 |
" case 0 :\n" + |
4804 |
" o = new Object();\n" + |
4805 |
" break;\n" + |
4806 |
" default :\n" + |
4807 |
" return;\n" + |
4808 |
" }\n" + |
4809 |
" if(o == null) { /* */ }\n" + // complain: only get there through 0, o non null |
4810 |
" }\n" + |
4811 |
"}\n"}, |
4812 |
"----------\n" + |
4813 |
"1. ERROR in X.java (at line 12)\n" + |
4814 |
" if(o == null) { /* */ }\n" + |
4815 |
" ^\n" + |
4816 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
4817 |
"----------\n"); |
4818 |
} |
4819 |
|
4820 |
// null analysis -- switch |
4821 |
public void test0802_switch() { |
4822 |
this.runNegativeTest( |
4823 |
new String[] { |
4824 |
"X.java", |
4825 |
"public class X {\n" + |
4826 |
" int k;\n" + |
4827 |
" void foo() {\n" + |
4828 |
" Object o = null;\n" + |
4829 |
" switch (k) {\n" + |
4830 |
" case 0 :\n" + |
4831 |
" o.toString();\n" + // complain: o can only be null |
4832 |
" break;\n" + |
4833 |
" }\n" + |
4834 |
" }\n" + |
4835 |
"}\n"}, |
4836 |
"----------\n" + |
4837 |
"1. ERROR in X.java (at line 7)\n" + |
4838 |
" o.toString();\n" + |
4839 |
" ^\n" + |
4840 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
4841 |
"----------\n"); |
4842 |
} |
4843 |
|
4844 |
// null analysis -- switch |
4845 |
public void test0803_switch() { |
4846 |
this.runNegativeTest( |
4847 |
new String[] { |
4848 |
"X.java", |
4849 |
"public class X {\n" + |
4850 |
" int k;\n" + |
4851 |
" void foo() {\n" + |
4852 |
" Object o = null;\n" + |
4853 |
" switch (k) {\n" + |
4854 |
" case 0 :\n" + |
4855 |
" o = new Object();\n" + |
4856 |
" case 1 :\n" + |
4857 |
" o.toString();\n" + // complain: may come through 0 or 1 |
4858 |
" break;\n" + |
4859 |
" }\n" + |
4860 |
" }\n" + |
4861 |
"}\n"}, |
4862 |
"----------\n" + |
4863 |
"1. ERROR in X.java (at line 9)\n" + |
4864 |
" o.toString();\n" + |
4865 |
" ^\n" + |
4866 |
"The variable o may be null\n" + |
4867 |
"----------\n"); |
4868 |
} |
4869 |
|
4870 |
// null analysis -- switch |
4871 |
public void test0804_switch() { |
4872 |
this.runNegativeTest( |
4873 |
new String[] { |
4874 |
"X.java", |
4875 |
"public class X {\n" + |
4876 |
" void foo (Object o, int info) {\n" + |
4877 |
" o = null;\n" + |
4878 |
" switch (info) {\n" + |
4879 |
" case 0 :\n" + |
4880 |
" o = new Object();\n" + |
4881 |
" break;\n" + |
4882 |
" case 1 :\n" + |
4883 |
" o = new String();\n" + |
4884 |
" break;\n" + |
4885 |
" default :\n" + |
4886 |
" o = new X();\n" + |
4887 |
" break;\n" + |
4888 |
" }\n" + |
4889 |
" if(o != null) { /* */ }\n" + // complain: all branches allocate a new o |
4890 |
" }\n" + |
4891 |
"}\n"}, |
4892 |
"----------\n" + |
4893 |
"1. ERROR in X.java (at line 15)\n" + |
4894 |
" if(o != null) { /* */ }\n" + |
4895 |
" ^\n" + |
4896 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
4897 |
"----------\n"); |
4898 |
} |
4899 |
|
4900 |
// null analysis -- switch |
4901 |
public void test0805_switch() { |
4902 |
this.runConformTest( |
4903 |
new String[] { |
4904 |
"X.java", |
4905 |
"public class X {\n" + |
4906 |
" void foo(X p) {\n" + |
4907 |
" X x = this;\n" + |
4908 |
" for (int i = 0; i < 5; i++) {\n" + |
4909 |
" switch (i) {\n" + |
4910 |
" case 1:\n" + |
4911 |
" x = p;\n" + |
4912 |
" }\n" + |
4913 |
" }\n" + |
4914 |
" if (x != null) { /* */ }\n" + |
4915 |
" }\n" + |
4916 |
"}\n"}, |
4917 |
""); |
4918 |
} |
4919 |
|
4920 |
// null analysis -- non null protection tag |
4921 |
public void test0900_non_null_protection_tag() { |
4922 |
this.runConformTest( |
4923 |
new String[] { |
4924 |
"X.java", |
4925 |
"public class X {\n" + |
4926 |
" void foo(Object o) {\n" + |
4927 |
" boolean b = o != null;\n" + // shades doubts upon o |
4928 |
" o/*NN*/.toString();\n" + // protection => do not complain |
4929 |
" o.toString();\n" + // protected by previous line |
4930 |
" }\n" + |
4931 |
"}\n"}, |
4932 |
""); |
4933 |
} |
4934 |
|
4935 |
// null analysis -- non null protection tag |
4936 |
public void test0901_non_null_protection_tag() { |
4937 |
this.runConformTest( |
4938 |
new String[] { |
4939 |
"X.java", |
4940 |
"public class X {\n" + |
4941 |
" void foo(Object o, boolean b) {\n" + |
4942 |
" if (b) {\n" + |
4943 |
" o = null;\n" + |
4944 |
" }\n" + |
4945 |
" o/*NN*/.toString();\n" + |
4946 |
" if (b) {\n" + |
4947 |
" o = null;\n" + |
4948 |
" }\n" + |
4949 |
" o/*\n" + |
4950 |
" NN comment */.toString();\n" + |
4951 |
" if (b) {\n" + |
4952 |
" o = null;\n" + |
4953 |
" }\n" + |
4954 |
" o/* NN\n" + |
4955 |
" */.toString();\n" + |
4956 |
" if (b) {\n" + |
4957 |
" o = null;\n" + |
4958 |
" }\n" + |
4959 |
" o // NN \n" + |
4960 |
" .toString();\n" + |
4961 |
" }\n" + |
4962 |
"}\n"}, |
4963 |
""); |
4964 |
} |
4965 |
|
4966 |
// null analysis -- non null protection tag |
4967 |
public void test0902_non_null_protection_tag() { |
4968 |
this.runConformTest( |
4969 |
new String[] { |
4970 |
"X.java", |
4971 |
"public class X {\n" + |
4972 |
" void foo(Object o, boolean b) {\n" + |
4973 |
" if (b) {\n" + |
4974 |
" o = null;\n" + |
4975 |
" }\n" + |
4976 |
" o/*NON-NULL*/.toString();\n" + |
4977 |
" if (b) {\n" + |
4978 |
" o = null;\n" + |
4979 |
" }\n" + |
4980 |
" o/* NON-NULL comment */.toString();\n" + |
4981 |
" if (b) {\n" + |
4982 |
" o = null;\n" + |
4983 |
" }\n" + |
4984 |
" o/* NON-NULL \n" + |
4985 |
" */.toString();\n" + |
4986 |
" if (b) {\n" + |
4987 |
" o = null;\n" + |
4988 |
" }\n" + |
4989 |
" o // NON-NULL \n" + |
4990 |
" .toString();\n" + |
4991 |
" }\n" + |
4992 |
"}\n"}, |
4993 |
""); |
4994 |
} |
4995 |
|
4996 |
// null analysis -- non null protection tag |
4997 |
public void test0903_non_null_protection_tag() { |
4998 |
this.runNegativeTest( |
4999 |
new String[] { |
5000 |
"X.java", |
5001 |
"public class X {\n" + |
5002 |
" void foo(Object o, boolean b) {\n" + |
5003 |
" if (b) {\n" + |
5004 |
" o = null;\n" + |
5005 |
" }\n" + |
5006 |
" o/*N N*/.toString();\n" + |
5007 |
" if (b) {\n" + |
5008 |
" o = null;\n" + |
5009 |
" }\n" + |
5010 |
" o/*NNa*/.toString();\n" + |
5011 |
" if (b) {\n" + |
5012 |
" o = null;\n" + |
5013 |
" }\n" + |
5014 |
" o/*aNN */.toString();\n" + |
5015 |
" if (b) {\n" + |
5016 |
" o = null;\n" + |
5017 |
" }\n" + |
5018 |
" o/*NON NULL*/.toString();\n" + |
5019 |
" if (b) {\n" + |
5020 |
" o = null;\n" + |
5021 |
" }\n" + |
5022 |
" o/*Non-Null*/.toString();\n" + |
5023 |
" if (b) {\n" + |
5024 |
" o = null;\n" + |
5025 |
" }\n" + |
5026 |
" o/*aNON-NULL */.toString();\n" + |
5027 |
" }\n" + |
5028 |
"}\n"}, |
5029 |
"----------\n" + |
5030 |
"1. ERROR in X.java (at line 6)\n" + |
5031 |
" o/*N N*/.toString();\n" + |
5032 |
" ^\n" + |
5033 |
"The variable o may be null\n" + |
5034 |
"----------\n" + |
5035 |
"2. ERROR in X.java (at line 10)\n" + |
5036 |
" o/*NNa*/.toString();\n" + |
5037 |
" ^\n" + |
5038 |
"The variable o may be null\n" + |
5039 |
"----------\n" + |
5040 |
"3. ERROR in X.java (at line 14)\n" + |
5041 |
" o/*aNN */.toString();\n" + |
5042 |
" ^\n" + |
5043 |
"The variable o may be null\n" + |
5044 |
"----------\n" + |
5045 |
"4. ERROR in X.java (at line 18)\n" + |
5046 |
" o/*NON NULL*/.toString();\n" + |
5047 |
" ^\n" + |
5048 |
"The variable o may be null\n" + |
5049 |
"----------\n" + |
5050 |
"5. ERROR in X.java (at line 22)\n" + |
5051 |
" o/*Non-Null*/.toString();\n" + |
5052 |
" ^\n" + |
5053 |
"The variable o may be null\n" + |
5054 |
"----------\n" + |
5055 |
"6. ERROR in X.java (at line 26)\n" + |
5056 |
" o/*aNON-NULL */.toString();\n" + |
5057 |
" ^\n" + |
5058 |
"The variable o may be null\n" + |
5059 |
"----------\n"); |
5060 |
} |
5061 |
|
5062 |
|
5063 |
// null analysis -- non null protection tag |
5064 |
public void test0905_non_null_protection_tag() { |
5065 |
this.runNegativeTest( |
5066 |
new String[] { |
5067 |
"X.java", |
5068 |
"public class X {\n" + |
5069 |
" void foo(Object o) {\n" + |
5070 |
" boolean b = o != null;\n" + // shades doubts upon o |
5071 |
" o.toString();/*NN*/\n" + // too late to protect => complain |
5072 |
" }\n" + |
5073 |
"}\n"}, |
5074 |
"----------\n" + |
5075 |
"1. ERROR in X.java (at line 4)\n" + |
5076 |
" o.toString();/*NN*/\n" + |
5077 |
" ^\n" + |
5078 |
"The variable o may be null\n" + |
5079 |
"----------\n"); |
5080 |
} |
5081 |
|
5082 |
// null analysis -- non null protection tag |
5083 |
public void test0906_non_null_protection_tag() { |
5084 |
this.runNegativeTest( |
5085 |
new String[] { |
5086 |
"X.java", |
5087 |
"public class X {\n" + |
5088 |
" void foo(Object o) {\n" + |
5089 |
" boolean b = o != null;\n" + // shades doubts upon o |
5090 |
" /*NN*/o.toString();\n" + // too soon to protect => complain |
5091 |
" }\n" + |
5092 |
"}\n"}, |
5093 |
"----------\n" + |
5094 |
"1. ERROR in X.java (at line 4)\n" + |
5095 |
" /*NN*/o.toString();\n" + |
5096 |
" ^\n" + |
5097 |
"The variable o may be null\n" + |
5098 |
"----------\n"); |
5099 |
} |
5100 |
|
5101 |
// null analysis -- notNull protection tag |
5102 |
public void _test0900_notNull_protection_tag() { |
5103 |
this.runNegativeTest( |
5104 |
new String[] { |
5105 |
"X.java", |
5106 |
"public class X {\n" + |
5107 |
" void foo(/** @notNull */ Object o) {\n" + |
5108 |
" boolean b = o != null;\n" + |
5109 |
" }\n" + |
5110 |
"}\n"}, |
5111 |
"ERR cannot be null"); |
5112 |
} |
5113 |
|
5114 |
// null analysis -- notNull protection tag |
5115 |
public void _test0901_notNull_protection_tag() { |
5116 |
this.runNegativeTest( |
5117 |
new String[] { |
5118 |
"X.java", |
5119 |
"public class X {\n" + |
5120 |
" void foo(Object o) {\n" + |
5121 |
" /** @notNull */ Object l = o;\n" + |
5122 |
" }\n" + |
5123 |
"}\n"}, |
5124 |
"ERR cannot be null... ou pas ?"); |
5125 |
} |
5126 |
|
5127 |
// null analysis -- notNull protection tag |
5128 |
public void _test0902_notNull_protection_tag() { |
5129 |
this.runNegativeTest( |
5130 |
new String[] { |
5131 |
"X.java", |
5132 |
"public class X {\n" + |
5133 |
" void foo(/** @nullable */ Object o) {\n" + |
5134 |
" /** @notNull */ Object l = o;\n" + |
5135 |
" }\n" + |
5136 |
"}\n"}, |
5137 |
"ERR cannot be null"); |
5138 |
} |
5139 |
|
5140 |
// null analysis -- notNull protection tag |
5141 |
public void _test0903_notNull_protection_tag() { |
5142 |
this.runConformTest( |
5143 |
new String[] { |
5144 |
"X.java", |
5145 |
"public class X {\n" + |
5146 |
" Object bar() {\n" + |
5147 |
" return null;\n" + |
5148 |
" }\n" + |
5149 |
" void foo() {\n" + |
5150 |
" /** @notNull */ Object l = bar();\n" + |
5151 |
" }\n" + |
5152 |
"}\n"}, |
5153 |
""); |
5154 |
} |
5155 |
|
5156 |
// null analysis -- notNull protection tag |
5157 |
public void _test0904_notNull_protection_tag() { |
5158 |
this.runNegativeTest( |
5159 |
new String[] { |
5160 |
"X.java", |
5161 |
"public class X {\n" + |
5162 |
" /** @notNull */\n" + |
5163 |
" Object bar() {\n" + |
5164 |
" return new Object();\n" + |
5165 |
" }\n" + |
5166 |
" void foo() {\n" + |
5167 |
" Object l = bar();\n" + |
5168 |
" if (l == null) { /* empty */ }\n" + |
5169 |
" }\n" + |
5170 |
"}\n"}, |
5171 |
"ERR cannot be null"); |
5172 |
} |
5173 |
|
5174 |
// null analysis -- notNull protection tag |
5175 |
public void _test0905_notNull_protection_tag() { |
5176 |
this.runNegativeTest( |
5177 |
new String[] { |
5178 |
"X.java", |
5179 |
"public class X {\n" + |
5180 |
" /** @notNull */\n" + |
5181 |
" Object bar() {\n" + |
5182 |
" return null;\n" + |
5183 |
" }\n" + |
5184 |
"}\n"}, |
5185 |
"ERR cannot be null"); |
5186 |
} |
5187 |
|
5188 |
// null analysis -- nullable tag |
5189 |
public void _test0950_nullable_tag() { |
5190 |
this.runConformTest( |
5191 |
new String[] { |
5192 |
"X.java", |
5193 |
"public class X {\n" + |
5194 |
" void foo(/** @nullable */ Object o) {\n" + |
5195 |
" o.toString();\n" + |
5196 |
" }\n" + |
5197 |
"}\n"}, |
5198 |
"ERR may be null"); |
5199 |
} |
5200 |
|
5201 |
// null analysis -- nullable tag |
5202 |
public void _test0951_nullable_tag() { |
5203 |
this.runConformTest( |
5204 |
new String[] { |
5205 |
"X.java", |
5206 |
"public class X {\n" + |
5207 |
" void foo(/** @nullable */ Object o) {\n" + |
5208 |
" Object l = o;\n" + |
5209 |
" l.toString();\n" + |
5210 |
" }\n" + |
5211 |
"}\n"}, |
5212 |
"ERR may be null"); |
5213 |
} |
5214 |
|
5215 |
// null analysis -- nullable tag |
5216 |
public void _test0952_nullable_tag() { |
5217 |
this.runConformTest( |
5218 |
new String[] { |
5219 |
"X.java", |
5220 |
"public class X {\n" + |
5221 |
" void foo(boolean b) {\n" + |
5222 |
" /** @nullable */ Object o;\n" + |
5223 |
" if (b) {\n" + |
5224 |
" o = new Object();\n" + |
5225 |
" }\n" + |
5226 |
" o.toString();\n" + |
5227 |
" }\n" + |
5228 |
"}\n"}, |
5229 |
"ERR may be null"); |
5230 |
} |
5231 |
|
5232 |
// moved from AssignmentTest |
5233 |
public void test1004() { |
5234 |
this.runNegativeTest( |
5235 |
new String[] { |
5236 |
"X.java", |
5237 |
"public class X {\n" + |
5238 |
" X foo(X x) {\n" + |
5239 |
" x.foo(null); // 0\n" + |
5240 |
" if (x != null) { // 1\n" + |
5241 |
" if (x == null) { // 2\n" + |
5242 |
" x.foo(null); // 3\n" + |
5243 |
" } else if (x instanceof X) { // 4\n" + |
5244 |
" x.foo(null); // 5 \n" + |
5245 |
" } else if (x != null) { // 6\n" + |
5246 |
" x.foo(null); // 7\n" + |
5247 |
" }\n" + |
5248 |
" x.foo(null); // 8\n" + |
5249 |
" }\n" + |
5250 |
" return this;\n" + |
5251 |
" }\n" + |
5252 |
"}\n"}, |
5253 |
"----------\n" + |
5254 |
"1. ERROR in X.java (at line 4)\n" + |
5255 |
" if (x != null) { // 1\n" + |
5256 |
" ^\n" + |
5257 |
"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5258 |
"----------\n" + |
5259 |
"2. ERROR in X.java (at line 5)\n" + |
5260 |
" if (x == null) { // 2\n" + |
5261 |
" ^\n" + |
5262 |
"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5263 |
"----------\n" + |
5264 |
"3. ERROR in X.java (at line 6)\n" + |
5265 |
" x.foo(null); // 3\n" + |
5266 |
" ^\n" + |
5267 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
5268 |
"----------\n" + |
5269 |
"4. ERROR in X.java (at line 9)\n" + |
5270 |
" } else if (x != null) { // 6\n" + |
5271 |
" ^\n" + |
5272 |
"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5273 |
"----------\n" + |
5274 |
"5. ERROR in X.java (at line 12)\n" + |
5275 |
" x.foo(null); // 8\n" + |
5276 |
" ^\n" + |
5277 |
"The variable x may be null\n" + |
5278 |
"----------\n"); |
5279 |
} |
5280 |
|
5281 |
public void test1005() { |
5282 |
this.runConformTest( |
5283 |
new String[] { |
5284 |
"X.java", |
5285 |
"public class X {\n" + |
5286 |
" void foo(Class c) {\n" + |
5287 |
" if (c.isArray() ) {\n" + |
5288 |
" } else if (c == java.lang.String.class ) {\n" + |
5289 |
" }\n" + |
5290 |
" }\n" + |
5291 |
"}\n"}, |
5292 |
""); |
5293 |
} |
5294 |
|
5295 |
public void test1006() { |
5296 |
this.runConformTest( |
5297 |
new String[] { |
5298 |
"X.java", |
5299 |
"public class X {\n" + |
5300 |
" void foo(X x) {\n" + |
5301 |
" if (x == this)\n" + |
5302 |
" return;\n" + |
5303 |
" x.foo(this);\n" + |
5304 |
" }\n" + |
5305 |
"}\n"}, |
5306 |
""); |
5307 |
} |
5308 |
|
5309 |
public void test1007() { |
5310 |
this.runConformTest( |
5311 |
new String[] { |
5312 |
"X.java", |
5313 |
"public class X {\n" + |
5314 |
" void foo(X x, X x2) {\n" + |
5315 |
" if (x != null)\n" + |
5316 |
" return;\n" + |
5317 |
" x = x2;\n" + |
5318 |
" if (x == null) {\n" + |
5319 |
" }\n" + |
5320 |
" }\n" + |
5321 |
"}\n"}, |
5322 |
""); |
5323 |
} |
5324 |
|
5325 |
public void test1008() { |
5326 |
this.runConformTest( |
5327 |
new String[] { |
5328 |
"X.java", |
5329 |
"public class X {\n" + |
5330 |
" void foo(X x, X x2) {\n" + |
5331 |
" if (x != null)\n" + |
5332 |
" return;\n" + |
5333 |
" try {\n" + |
5334 |
" x = x2;\n" + |
5335 |
" } catch(Exception e) {}\n" + |
5336 |
" if (x == null) {\n" + |
5337 |
" }\n" + |
5338 |
" }\n" + |
5339 |
"}\n"}, |
5340 |
""); |
5341 |
} |
5342 |
|
5343 |
// TODO (philippe) reenable once fixed |
5344 |
public void _test1009() { |
5345 |
this.runNegativeTest( |
5346 |
new String[] { |
5347 |
"X.java", |
5348 |
"import java.io.File;\n" + |
5349 |
"\n" + |
5350 |
"public class X {\n" + |
5351 |
" boolean check(String name) { return true; }\n" + |
5352 |
" Class bar(String name) throws ClassNotFoundException { return null; }\n" + |
5353 |
" File baz(String name) { return null; }\n" + |
5354 |
" \n" + |
5355 |
" public Class foo(String name, boolean resolve) throws ClassNotFoundException {\n" + |
5356 |
" \n" + |
5357 |
" Class c = bar(name);\n" + |
5358 |
" if (c != null)\n" + |
5359 |
" return c;\n" + |
5360 |
" if (check(name)) {\n" + |
5361 |
" try {\n" + |
5362 |
" c= bar(name);\n" + |
5363 |
" return c;\n" + |
5364 |
" } catch (ClassNotFoundException e) {\n" + |
5365 |
" // keep searching\n" + |
5366 |
" // only path to here left c unassigned from try block, means it was assumed to be null\n" + |
5367 |
" }\n" + |
5368 |
" }\n" + |
5369 |
" if (c == null) {// should complain: c can only be null\n" + |
5370 |
" File file= baz(name);\n" + |
5371 |
" if (file == null)\n" + |
5372 |
" throw new ClassNotFoundException();\n" + |
5373 |
" }\n" + |
5374 |
" return c;\n" + |
5375 |
" }\n" + |
5376 |
"\n" + |
5377 |
"}\n"}, |
5378 |
"----------\n" + |
5379 |
"1. ERROR in X.java (at line 22)\n" + |
5380 |
" if (c == null) {// should complain: c can only be null\n" + |
5381 |
" ^\n" + |
5382 |
"The variable c can only be null; it was either set to null or checked for null when last used\n" + |
5383 |
"----------\n"); |
5384 |
} |
5385 |
|
5386 |
// REVIEW maybe leave this one in AssignmentTest? |
5387 |
public void test1010() { |
5388 |
this.runConformTest( |
5389 |
new String[] { |
5390 |
"X.java", |
5391 |
"public class X {\n" + |
5392 |
"\n" + |
5393 |
" X itself() { return this; }\n" + |
5394 |
"\n" + |
5395 |
" void bar() {\n" + |
5396 |
" X itself = this.itself();\n" + |
5397 |
" if (this == itself) {\n" + |
5398 |
" System.out.println(itself.toString()); //1\n" + |
5399 |
" } else {\n" + |
5400 |
" System.out.println(itself.toString()); //2\n" + |
5401 |
" }\n" + |
5402 |
" }\n" + |
5403 |
"}\n"}, |
5404 |
""); |
5405 |
} |
5406 |
|
5407 |
public void test1011() { |
5408 |
this.runNegativeTest( |
5409 |
new String[] { |
5410 |
"X.java", |
5411 |
"public class X {\n" + |
5412 |
"\n" + |
5413 |
" X itself() { return this; }\n" + |
5414 |
"\n" + |
5415 |
" void bar() {\n" + |
5416 |
" X itself = this.itself();\n" + |
5417 |
" if (this == itself) {\n" + |
5418 |
" X other = (X)itself;\n" + |
5419 |
" if (other != null) {\n" + |
5420 |
" }\n" + |
5421 |
" if (other == null) {\n" + |
5422 |
" }\n" + |
5423 |
" }\n" + |
5424 |
" }\n" + |
5425 |
"}\n"}, |
5426 |
"----------\n" + |
5427 |
"1. ERROR in X.java (at line 9)\n" + |
5428 |
" if (other != null) {\n" + |
5429 |
" ^^^^^\n" + |
5430 |
"The variable other cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5431 |
"----------\n"); |
5432 |
} |
5433 |
|
5434 |
public void test1012() { |
5435 |
this.runNegativeTest( |
5436 |
new String[] { |
5437 |
"X.java", |
5438 |
"public class X {\n" + |
5439 |
" \n" + |
5440 |
" void foo() {\n" + |
5441 |
" Object o = null;\n" + |
5442 |
" do {\n" + |
5443 |
" if (o == null) {\n" + |
5444 |
" return;\n" + |
5445 |
" }\n" + |
5446 |
" // o = bar();\n" + |
5447 |
" } while (true);\n" + |
5448 |
" }\n" + |
5449 |
" X bar() { \n" + |
5450 |
" return null; \n" + |
5451 |
" }\n" + |
5452 |
"}"}, |
5453 |
"----------\n" + |
5454 |
"1. ERROR in X.java (at line 6)\n" + |
5455 |
" if (o == null) {\n" + |
5456 |
" ^\n" + |
5457 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
5458 |
"----------\n" |
5459 |
); |
5460 |
} |
5461 |
|
5462 |
// REVIEW here we do not catch the dead branch: x cannot equal this then null with no assignment in between |
5463 |
public void test1013() { |
5464 |
this.runNegativeTest( |
5465 |
new String[] { |
5466 |
"X.java", |
5467 |
"public class X {\n" + |
5468 |
" void foo(X x) {\n" + |
5469 |
" if (x == this) {\n" + |
5470 |
" if (x == null) {\n" + |
5471 |
" x.foo(this);\n" + |
5472 |
" }\n" + |
5473 |
" }\n" + |
5474 |
" }\n" + |
5475 |
"}\n"}, |
5476 |
"----------\n" + |
5477 |
"1. ERROR in X.java (at line 4)\n" + |
5478 |
" if (x == null) {\n" + |
5479 |
" ^\n" + |
5480 |
"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5481 |
"----------\n" + |
5482 |
"2. ERROR in X.java (at line 5)\n" + |
5483 |
" x.foo(this);\n" + |
5484 |
" ^\n" + |
5485 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
5486 |
"----------\n"); |
5487 |
} |
5488 |
|
5489 |
public void test1014() { |
5490 |
this.runNegativeTest( |
5491 |
new String[] { |
5492 |
"X.java", |
5493 |
"public class X {\n" + |
5494 |
" void foo(X x) {\n" + |
5495 |
" x = null;\n" + |
5496 |
" try {\n" + |
5497 |
" x = this;\n" + |
5498 |
" } finally {\n" + |
5499 |
" x.foo(null);\n" + |
5500 |
" }\n" + |
5501 |
" }\n" + |
5502 |
"}\n"}, |
5503 |
"----------\n" + |
5504 |
"1. ERROR in X.java (at line 7)\n" + |
5505 |
" x.foo(null);\n" + |
5506 |
" ^\n" + |
5507 |
"The variable x may be null\n" + |
5508 |
"----------\n"); |
5509 |
} |
5510 |
|
5511 |
public void test1015() { |
5512 |
this.runConformTest( |
5513 |
new String[] { |
5514 |
"X.java", |
5515 |
"public class X {\n" + |
5516 |
" void foo() {\n" + |
5517 |
" Object o = null;\n" + |
5518 |
" int i = 1;\n" + |
5519 |
" switch (i) {\n" + |
5520 |
" case 1:\n" + |
5521 |
" o = new Object();\n" + |
5522 |
" break;\n" + |
5523 |
" }\n" + |
5524 |
" if (o != null)\n" + |
5525 |
" o.toString();\n" + |
5526 |
" }\n" + |
5527 |
"}\n"}, |
5528 |
""); |
5529 |
} |
5530 |
|
5531 |
public void test1016() { |
5532 |
this.runNegativeTest( |
5533 |
new String[] { |
5534 |
"X.java", |
5535 |
"public class X {\n" + |
5536 |
" void foo(X x) {\n" + |
5537 |
" x = null;\n" + |
5538 |
" try {\n" + |
5539 |
" x = null;\n" + |
5540 |
" } finally {\n" + |
5541 |
" if (x != null) {\n" + |
5542 |
" x.foo(null);\n" + |
5543 |
" }\n" + |
5544 |
" }\n" + |
5545 |
" }\n" + |
5546 |
"}\n"}, |
5547 |
"----------\n" + |
5548 |
"1. ERROR in X.java (at line 5)\n" + |
5549 |
" x = null;\n" + |
5550 |
" ^\n" + |
5551 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
5552 |
"----------\n" + |
5553 |
"2. ERROR in X.java (at line 7)\n" + |
5554 |
" if (x != null) {\n" + |
5555 |
" ^\n" + |
5556 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
5557 |
"----------\n"); |
5558 |
} |
598 |
|
5559 |
|
599 |
// null analysis -- array |
5560 |
public void test1017() { |
600 |
public void test0041_array() { |
5561 |
this.runNegativeTest( |
601 |
this.runNegativeTest( |
5562 |
new String[] { |
602 |
new String[] { |
5563 |
"X.java", |
603 |
"X.java", |
5564 |
"public class X {\n" + |
604 |
"public class X {\n" + |
5565 |
" void foo(X x) {\n" + |
605 |
" public static void main(String args[]) {\n" + |
5566 |
" x = this;\n" + |
606 |
" args[0] = null;\n" + |
5567 |
" try {\n" + |
607 |
" if (args[0] == null) {};\n" + |
5568 |
" x = null;\n" + |
608 |
// quiet: we don't keep track of all array elements |
5569 |
" } finally {\n" + |
609 |
" }\n" + |
5570 |
" if (x == null) {\n" + |
610 |
"}\n"}, |
5571 |
" x.foo(null);\n" + |
611 |
"" |
5572 |
" }\n" + |
612 |
); |
5573 |
" }\n" + |
613 |
} |
5574 |
" }\n" + |
|
|
5575 |
"}\n"}, |
5576 |
"----------\n" + |
5577 |
"1. ERROR in X.java (at line 8)\n" + |
5578 |
" x.foo(null);\n" + |
5579 |
" ^\n" + |
5580 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
5581 |
"----------\n"); |
5582 |
} |
614 |
|
5583 |
|
615 |
// null analysis -- array |
5584 |
public void test1018() { |
616 |
public void test0042_array() { |
5585 |
this.runNegativeTest( |
617 |
this.runNegativeTest( |
5586 |
new String[] { |
618 |
new String[] { |
5587 |
"X.java", |
619 |
"X.java", |
5588 |
"public class X {\n" + |
620 |
"public class X {\n" + |
5589 |
" \n" + |
621 |
" public static void main(String args[]) {\n" + |
5590 |
" void foo() {\n" + |
622 |
" args = null;\n" + |
5591 |
" Object o = null;\n" + |
623 |
" args[0].toString();\n" + // complain: args is null |
5592 |
" do {\n" + |
624 |
" }\n" + |
5593 |
" if (o != null) return;\n" + |
625 |
"}\n"}, |
5594 |
" o = null;\n" + |
626 |
"----------\n" + |
5595 |
" } while (true);\n" + |
627 |
"1. WARNING in X.java (at line 4)\n" + |
5596 |
" }\n" + |
628 |
" args[0].toString();\n" + |
5597 |
" X bar() { \n" + |
629 |
" ^^^^\n" + |
5598 |
" return null; \n" + |
630 |
"The variable args can only be null; it was either set to null or checked for null when last used\n" + |
5599 |
" }\n" + |
631 |
"----------\n" |
5600 |
"}"}, |
632 |
); |
5601 |
"----------\n" + |
633 |
} |
5602 |
"1. ERROR in X.java (at line 6)\r\n" + |
|
|
5603 |
" if (o != null) return;\r\n" + |
5604 |
" ^\n" + |
5605 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
5606 |
"----------\n" + |
5607 |
"2. ERROR in X.java (at line 7)\r\n" + |
5608 |
" o = null;\r\n" + |
5609 |
" ^\n" + |
5610 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
5611 |
"----------\n"); |
5612 |
} |
634 |
|
5613 |
|
635 |
// null analysis -- type reference |
5614 |
public void test1019() { |
636 |
public void test0051_type_reference() { |
5615 |
this.runConformTest( |
637 |
this.runNegativeTest( |
5616 |
new String[] { |
638 |
new String[] { |
5617 |
"X.java", |
639 |
"X.java", |
5618 |
"public class X {\n" + |
640 |
"public class X {\n" + |
5619 |
" public static final char[] replaceOnCopy(\n" + |
641 |
" public static void main(String args[]) {\n" + |
5620 |
" char[] array,\n" + |
642 |
" Class c = java.lang.Object.class;\n" + |
5621 |
" char toBeReplaced,\n" + |
643 |
" if (c == null) {};\n" + |
5622 |
" char replacementChar) {\n" + |
644 |
" }\n" + |
5623 |
" \n" + |
645 |
"}\n"}, |
5624 |
" char[] result = null;\n" + |
646 |
"----------\n" + |
5625 |
" for (int i = 0, length = array.length; i < length; i++) {\n" + |
647 |
"1. WARNING in X.java (at line 4)\n" + |
5626 |
" char c = array[i];\n" + |
648 |
" if (c == null) {};\n" + |
5627 |
" if (c == toBeReplaced) {\n" + |
649 |
" ^\n" + |
5628 |
" if (result == null) {\n" + |
650 |
"The variable c cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5629 |
" result = new char[length];\n" + |
651 |
"----------\n" |
5630 |
" System.arraycopy(array, 0, result, 0, i);\n" + |
652 |
); |
5631 |
" }\n" + |
653 |
} |
5632 |
" result[i] = replacementChar;\n" + |
|
|
5633 |
" } else if (result != null) {\n" + |
5634 |
" result[i] = c;\n" + |
5635 |
" }\n" + |
5636 |
" }\n" + |
5637 |
" if (result == null) return array;\n" + |
5638 |
" return result;\n" + |
5639 |
" }\n" + |
5640 |
"}\n"}, |
5641 |
""); |
5642 |
} |
654 |
|
5643 |
|
655 |
// null analysis -- method call |
5644 |
public void test1021() { |
656 |
public void test0061_method_call_guard() { |
5645 |
this.runConformTest( |
657 |
this.runNegativeTest( |
5646 |
new String[] { |
658 |
new String[] { |
5647 |
"X.java", |
659 |
"X.java", |
5648 |
"public class X {\n" + |
660 |
"public class X {\n" + |
5649 |
" int kind;\n" + |
661 |
" void foo(Object o) {\n" + |
5650 |
" X parent;\n" + |
662 |
" if (o == null) {};\n" + // quiet: we don't know anything |
5651 |
" Object[] foo() { return null; }\n" + |
663 |
" o.toString();\n" + // guards o from being null |
5652 |
" void findTypeParameters(X scope) {\n" + |
664 |
" if (o == null) {};\n" + // complain |
5653 |
" Object[] typeParameters = null;\n" + |
665 |
" }\n" + |
5654 |
" while (scope != null) {\n" + |
666 |
"}\n"}, |
5655 |
" typeParameters = null;\n" + |
667 |
"----------\n" + |
5656 |
" switch (scope.kind) {\n" + |
668 |
"1. WARNING in X.java (at line 5)\n" + |
5657 |
" case 0 :\n" + |
669 |
" if (o == null) {};\n" + |
5658 |
" typeParameters = foo();\n" + |
670 |
" ^\n" + |
5659 |
" break;\n" + |
671 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5660 |
" case 1 :\n" + |
672 |
"----------\n" |
5661 |
" typeParameters = foo();\n" + |
673 |
); |
5662 |
" break;\n" + |
674 |
} |
5663 |
" case 2 :\n" + |
675 |
|
5664 |
" return;\n" + |
676 |
// null analysis - method call |
5665 |
" }\n" + |
677 |
public void test0062_method_call_isolation() { |
5666 |
" if(typeParameters != null) {\n" + |
678 |
this.runNegativeTest( |
5667 |
" foo();\n" + |
679 |
new String[] { |
5668 |
" }\n" + |
680 |
"X.java", |
5669 |
" scope = scope.parent;\n" + |
681 |
"public class X {\n" + |
5670 |
" }\n" + |
682 |
" void foo(Object o) {\n" + |
5671 |
" }\n" + |
683 |
" if (bar(o = null)) {\n" + |
5672 |
"}\n"}, |
684 |
" if (o == null) {/* empty */}\n" + // complain |
5673 |
""); |
685 |
" }\n" + |
5674 |
} |
686 |
" }\n" + |
|
|
687 |
" boolean bar(Object o) {\n" + |
688 |
" return true;\n" + |
689 |
" }\n" + |
690 |
"}\n"}, |
691 |
"----------\n" + |
692 |
"1. WARNING in X.java (at line 4)\n" + |
693 |
" if (o == null) {/* empty */}\n" + |
694 |
" ^\n" + |
695 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
696 |
"----------\n" |
697 |
); |
698 |
} |
699 |
|
700 |
// null analysis - method call |
701 |
public void test0063_method_call_isolation() { |
702 |
this.runNegativeTest( |
703 |
new String[] { |
704 |
"X.java", |
705 |
"public class X {\n" + |
706 |
" void foo(Object o) {\n" + |
707 |
" if (bar(o == null ? new Object() : o)) {\n" + |
708 |
" if (o == null) {/* empty */}\n" + // quiet |
709 |
" }\n" + |
710 |
" }\n" + |
711 |
" boolean bar(Object o) {\n" + |
712 |
" return true;\n" + |
713 |
" }\n" + |
714 |
"}\n"}, |
715 |
"" |
716 |
); |
717 |
} |
718 |
|
719 |
// null analysis - method call |
720 |
public void test0064_method_call_isolation() { |
721 |
this.runNegativeTest( |
722 |
new String[] { |
723 |
"X.java", |
724 |
"public class X {\n" + |
725 |
" void foo(Object o) {\n" + |
726 |
" if (bar(o = new Object())) {\n" + |
727 |
" if (o == null) {/* empty */}\n" + // complain |
728 |
" }\n" + |
729 |
" }\n" + |
730 |
" boolean bar(Object o) {\n" + |
731 |
" return true;\n" + |
732 |
" }\n" + |
733 |
"}\n"}, |
734 |
"----------\n" + |
735 |
"1. WARNING in X.java (at line 4)\n" + |
736 |
" if (o == null) {/* empty */}\n" + |
737 |
" ^\n" + |
738 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
739 |
"----------\n" |
740 |
); |
741 |
} |
742 |
|
5675 |
|
743 |
// null analysis - method call |
5676 |
public void test1022() { |
744 |
public void test0065_method_call_invocation_target() { |
5677 |
this.runConformTest( |
745 |
this.runNegativeTest( |
5678 |
new String[] { |
746 |
new String[] { |
5679 |
"X.java", |
747 |
"X.java", |
5680 |
"public class X {\n" + |
748 |
"public class X {\n" + |
5681 |
" boolean bool() { return true; }\n" + |
749 |
" void foo() {\n" + |
5682 |
" void doSomething() {}\n" + |
750 |
" Object o = null;\n" + |
5683 |
" \n" + |
751 |
" (o = new Object()).toString();\n" + // quiet |
5684 |
" void foo() {\n" + |
752 |
" }\n" + |
5685 |
" Object progressJob = null;\n" + |
753 |
"}\n"}, |
5686 |
" while (bool()) {\n" + |
754 |
"" |
5687 |
" if (bool()) {\n" + |
755 |
); |
5688 |
" if (progressJob != null)\n" + |
756 |
} |
5689 |
" progressJob = null;\n" + |
757 |
|
5690 |
" doSomething();\n" + |
758 |
// null analysis - method call |
5691 |
" }\n" + |
759 |
// TODO (maxime) fix |
5692 |
" try {\n" + |
760 |
public void _test0066_method_call_invocation_target() { |
5693 |
" if (progressJob == null) {\n" + |
761 |
this.runNegativeTest( |
5694 |
" progressJob = new Object();\n" + |
762 |
new String[] { |
5695 |
" }\n" + |
763 |
"X.java", |
5696 |
" } finally {\n" + |
764 |
"public class X {\n" + |
5697 |
" doSomething();\n" + |
765 |
" void foo() {\n" + |
5698 |
" }\n" + |
766 |
" Object o = new Object();\n" + |
5699 |
" }\n" + |
767 |
" (o = null).toString();\n" + // complain |
5700 |
" }\n" + |
768 |
" }\n" + |
5701 |
"}"}, |
769 |
"}\n"}, |
5702 |
""); |
770 |
"----------\n" + |
5703 |
} |
771 |
"1. WARNING in X.java (at line 4)\n" + |
|
|
772 |
" (o = null).toString();\n" + |
773 |
" ^^^^^^^^^^\n" + |
774 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
775 |
"----------\n" |
776 |
); |
777 |
} |
778 |
|
779 |
// null analysis -- if/else |
780 |
// check that obviously unreachable code does not modify the null |
781 |
// status of a local |
782 |
// the said code is not marked as unreachable per JLS 14.21 (the rationale |
783 |
// being the accommodation for the if (constant_flag_evaluating_to_false) |
784 |
// {code...} volontary code exclusion pattern) |
785 |
// TODO (maxime) fix |
786 |
public void _test0100_if_else() { |
787 |
this.runNegativeTest( |
788 |
new String[] { |
789 |
"X.java", |
790 |
"public class X {\n" + |
791 |
" public void foo() {\n" + |
792 |
" Object o = null;\n" + |
793 |
" if (false) {\n" + |
794 |
" o = new Object();\n" + // skipped |
795 |
" }\n" + |
796 |
" if (true) {\n" + |
797 |
" //\n" + |
798 |
" }\n" + |
799 |
" else {\n" + |
800 |
" o = new Object();\n" + // skipped |
801 |
" }\n" + |
802 |
" o.toString();\n" + |
803 |
" }\n" + |
804 |
"}\n"}, |
805 |
"----------\n" + |
806 |
"1. WARNING in X.java (at line 13)\n" + |
807 |
" o.toString();\n" + |
808 |
" ^\n" + |
809 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
810 |
"----------\n" |
811 |
); |
812 |
} |
813 |
|
814 |
// TODO (maxime) - what about further diagnostics inside fake reachable code ? if (false) { o = null; o.toString(); } |
815 |
|
816 |
// null analysis - if/else |
817 |
public void test0101_if_else() { |
818 |
this.runNegativeTest( |
819 |
new String[] { |
820 |
"X.java", |
821 |
"public class X {\n" + |
822 |
" void foo() {\n" + |
823 |
" Object o = new Object();\n" + |
824 |
" if (o != null) {\n" + |
825 |
" }\n" + |
826 |
" }\n" + |
827 |
"}\n"}, |
828 |
"----------\n" + |
829 |
"1. WARNING in X.java (at line 4)\n" + |
830 |
" if (o != null) {\n" + |
831 |
" ^\n" + |
832 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
833 |
"----------\n" |
834 |
); |
835 |
} |
836 |
|
5704 |
|
837 |
// null analysis - if/else |
5705 |
public void test1023() { |
838 |
public void test0102_if_else() { |
5706 |
this.runNegativeTest( |
839 |
this.runNegativeTest( |
5707 |
new String[] { |
840 |
new String[] { |
5708 |
"X.java", |
841 |
"X.java", |
5709 |
"public class X {\n" + |
842 |
"public class X {\n" + |
5710 |
"\n" + |
843 |
" void foo(Object o) throws Exception {\n" + |
5711 |
" void foo() {\n" + |
844 |
" if (o == null) {\n" + |
5712 |
" Object o = new Object();\n" + |
845 |
" throw new Exception();\n" + |
5713 |
" while (this != null) {\n" + |
846 |
" }\n" + |
5714 |
" try {\n" + |
847 |
" if (o != null) {\n" + // only get there if o non null |
5715 |
" o = null;\n" + |
848 |
" }\n" + |
5716 |
" break;\n" + |
849 |
" }\n" + |
5717 |
" } finally {\n" + |
850 |
"}\n"}, |
5718 |
" o = new Object();\n" + |
851 |
"----------\n" + |
5719 |
" }\n" + |
852 |
"1. WARNING in X.java (at line 6)\n" + |
5720 |
" }\n" + |
853 |
" if (o != null) {\n" + |
5721 |
" if (o == null) return;\n" + |
854 |
" ^\n" + |
5722 |
" }\n" + |
855 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5723 |
"}\n"}, |
856 |
"----------\n" |
5724 |
"----------\n" + |
857 |
); |
5725 |
"1. ERROR in X.java (at line 13)\n" + |
858 |
} |
5726 |
" if (o == null) return;\n" + |
|
|
5727 |
" ^\n" + |
5728 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5729 |
"----------\n"); |
5730 |
} |
859 |
|
5731 |
|
860 |
// null analysis - if/else |
5732 |
public void test1024() { |
861 |
public void test0103_if_else() { |
5733 |
this.runNegativeTest( |
862 |
this.runNegativeTest( |
5734 |
new String[] { |
863 |
new String[] { |
5735 |
"X.java", |
864 |
"X.java", |
5736 |
"public class X {\n" + |
865 |
"public class X {\n" + |
5737 |
" \n" + |
866 |
" void foo(Object o) {\n" + |
5738 |
" boolean bool() { return true; }\n" + |
867 |
" if (o == null) {\n" + |
5739 |
" void doSomething() {}\n" + |
868 |
" return;\n" + |
5740 |
" \n" + |
869 |
" }\n" + |
5741 |
" void foo() {\n" + |
870 |
" if (o != null) {\n" + |
5742 |
" Object progressJob = null;\n" + |
871 |
" }\n" + |
5743 |
" while (bool()) {\n" + |
872 |
" }\n" + |
5744 |
" if (progressJob != null)\n" + |
873 |
"}\n"}, |
5745 |
" progressJob = null;\n" + |
874 |
"----------\n" + |
5746 |
" doSomething();\n" + |
875 |
"1. WARNING in X.java (at line 6)\n" + |
5747 |
" try {\n" + |
876 |
" if (o != null) {\n" + |
5748 |
" if (progressJob == null) {\n" + |
877 |
" ^\n" + |
5749 |
" progressJob = new Object();\n" + |
878 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5750 |
" }\n" + |
879 |
"----------\n" |
5751 |
" } finally {\n" + |
880 |
); |
5752 |
" doSomething();\n" + |
881 |
} |
5753 |
" }\n" + |
|
|
5754 |
" }\n" + |
5755 |
" }\n" + |
5756 |
"}"}, |
5757 |
"----------\n" + |
5758 |
"1. ERROR in X.java (at line 13)\n" + |
5759 |
" if (progressJob == null) {\n" + |
5760 |
" ^^^^^^^^^^^\n" + |
5761 |
"The variable progressJob can only be null; it was either set to null or checked for null when last used\n" + |
5762 |
"----------\n"); |
5763 |
} |
882 |
|
5764 |
|
883 |
// null analysis - if/else |
5765 |
public void test1025() { |
884 |
public void test0104_if_else() { |
5766 |
this.runNegativeTest( |
885 |
this.runNegativeTest( |
5767 |
new String[] { |
886 |
new String[] { |
5768 |
"X.java", |
887 |
"X.java", |
5769 |
"public class X {\n" + |
888 |
"public class X {\n" + |
5770 |
" \n" + |
889 |
" void foo(Object o) {\n" + |
5771 |
" void foo() {\n" + |
890 |
" if (o == null) {\n" + |
5772 |
" Object o;\n" + |
891 |
" o.toString();\n" + |
5773 |
" try {\n" + |
892 |
" }\n" + |
5774 |
" o = null;\n" + |
893 |
" }\n" + |
5775 |
" } finally {\n" + |
894 |
"}\n"}, |
5776 |
" o = new Object();\n" + |
895 |
"----------\n" + |
5777 |
" }\n" + |
896 |
"1. WARNING in X.java (at line 4)\n" + |
5778 |
" if (o == null) return;\n" + |
897 |
" o.toString();\n" + |
5779 |
" }\n" + |
898 |
" ^\n" + |
5780 |
"}\n"}, |
899 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
5781 |
"----------\n" + |
900 |
"----------\n" |
5782 |
"1. ERROR in X.java (at line 10)\n" + |
901 |
); |
5783 |
" if (o == null) return;\n" + |
902 |
} |
5784 |
" ^\n" + |
|
|
5785 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5786 |
"----------\n"); |
5787 |
} |
903 |
|
5788 |
|
904 |
// null analysis - if/else |
5789 |
// TODO (philippe) reenable once fixed |
905 |
public void test0105_if_else() { |
5790 |
public void _test1026() { |
906 |
this.runNegativeTest( |
5791 |
this.runConformTest( |
907 |
new String[] { |
5792 |
new String[] { |
908 |
"X.java", |
5793 |
"X.java", |
909 |
"public class X {\n" + |
5794 |
"public class X {\n" + |
910 |
" void foo(Object o) {\n" + |
5795 |
" \n" + |
911 |
" if (o == null) {\n" + |
5796 |
" public static void main(String[] args) {\n" + |
912 |
" // do nothing\n" + |
5797 |
" Object o;\n" + |
913 |
" }\n" + |
5798 |
" try {\n" + |
914 |
" o.toString();\n" + |
5799 |
" o = null;\n" + |
915 |
" }\n" + |
5800 |
" } finally {\n" + |
916 |
"}\n"}, |
5801 |
" if (args == null) o = new Object();\n" + |
917 |
"" |
5802 |
" }\n" + |
918 |
); |
5803 |
" if (o == null) System.out.println(\"SUCCESS\");\n" + |
919 |
} |
5804 |
" }\n" + |
|
|
5805 |
"}\n"}, |
5806 |
"SUCCESS"); |
5807 |
} |
920 |
|
5808 |
|
921 |
// null analysis - if/else |
5809 |
// TODO (philippe) reenable once fixed |
922 |
public void test0106_if_else() { |
5810 |
public void _test1027() { |
923 |
this.runNegativeTest( |
5811 |
this.runConformTest( |
924 |
new String[] { |
5812 |
new String[] { |
925 |
"X.java", |
5813 |
"X.java", |
926 |
"public class X {\n" + |
5814 |
"public class X {\n" + |
927 |
" void foo(Object o) {\n" + |
5815 |
" boolean b;\n" + |
928 |
" if (o.toString().equals(\"\")) {\n" + |
5816 |
" void foo() {\n" + |
929 |
" if (o == null) {\n" + // complain: could not get here |
5817 |
" Object o = null;\n" + |
930 |
" // do nothing\n" + |
5818 |
" while (b) {\n" + |
931 |
" }\n" + |
5819 |
" try {\n" + |
932 |
" }\n" + |
5820 |
" o = null;\n" + |
933 |
" }\n" + |
5821 |
" } finally {\n" + |
934 |
"}\n"}, |
5822 |
" if (o == null) \n" + |
935 |
"----------\n" + |
5823 |
" o = new Object();\n" + |
936 |
"1. WARNING in X.java (at line 4)\n" + |
5824 |
" }\n" + |
937 |
" if (o == null) {\n" + |
5825 |
" }\n" + |
938 |
" ^\n" + |
5826 |
" if (o == null) return;\n" + |
939 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5827 |
" }\n" + |
940 |
"----------\n" |
5828 |
"}\n"}, |
941 |
); |
5829 |
""); |
942 |
} |
5830 |
} |
|
|
5831 |
|
5832 |
// TODO (philippe) reenable once fixed |
5833 |
public void _test1028() { |
5834 |
this.runConformTest( |
5835 |
new String[] { |
5836 |
"X.java", |
5837 |
"public class X {\n" + |
5838 |
" boolean b;\n" + |
5839 |
" void foo() {\n" + |
5840 |
" Object o = null;\n" + |
5841 |
" while (b) {\n" + |
5842 |
" try {\n" + |
5843 |
" o = null;\n" + |
5844 |
" break;\n" + |
5845 |
" } finally {\n" + |
5846 |
" if (o == null) \n" + |
5847 |
" o = new Object();\n" + |
5848 |
" }\n" + |
5849 |
" }\n" + |
5850 |
" if (o == null) return;\n" + |
5851 |
" }\n" + |
5852 |
"}\n"}, |
5853 |
""); |
5854 |
} |
5855 |
|
5856 |
public void test1029() { |
5857 |
this.runConformTest( |
5858 |
new String[] { |
5859 |
"X.java", |
5860 |
"public class X {\n" + |
5861 |
" public static void main(String[] args) {\n" + |
5862 |
" Object o = null;\n" + |
5863 |
" int i = 0;\n" + |
5864 |
" while (i++ < 2) {\n" + |
5865 |
" try {\n" + |
5866 |
" if (i == 2) return;\n" + |
5867 |
" o = null;\n" + |
5868 |
" } finally {\n" + |
5869 |
" if (i == 2) System.out.println(o);\n" + |
5870 |
" o = \"SUCCESS\";\n" + |
5871 |
" }\n" + |
5872 |
" }\n" + |
5873 |
" if (o == null) return;\n" + |
5874 |
" }\n" + |
5875 |
"}\n"}, |
5876 |
"SUCCESS"); |
5877 |
} |
5878 |
|
5879 |
public void test1030() { |
5880 |
this.runNegativeTest( |
5881 |
new String[] { |
5882 |
"X.java", |
5883 |
"public class X {\n" + |
5884 |
" \n" + |
5885 |
" void foo() {\n" + |
5886 |
" Object a = null;\n" + |
5887 |
" while (true) {\n" + |
5888 |
" a = null;\n" + |
5889 |
" if (a == null) {\n" + |
5890 |
" System.out.println();\n" + |
5891 |
" }\n" + |
5892 |
" a = new Object();\n" + |
5893 |
" break;\n" + |
5894 |
" }\n" + |
5895 |
" }\n" + |
5896 |
"}\n"}, |
5897 |
"----------\n" + |
5898 |
"1. ERROR in X.java (at line 7)\n" + |
5899 |
" if (a == null) {\n" + |
5900 |
" ^\n" + |
5901 |
"The variable a can only be null; it was either set to null or checked for null when last used\n" + |
5902 |
"----------\n"); |
5903 |
} |
5904 |
|
5905 |
// TODO (philippe) reenable once fixed |
5906 |
public void _test1031() { |
5907 |
this.runNegativeTest( |
5908 |
new String[] { |
5909 |
"X.java", |
5910 |
"public class X {\n" + |
5911 |
" \n" + |
5912 |
" void foo() {\n" + |
5913 |
" Object a = null;\n" + |
5914 |
" while (true) {\n" + |
5915 |
" a = null;\n" + |
5916 |
" if (a == null) {\n" + |
5917 |
" System.out.println();\n" + |
5918 |
" }\n" + |
5919 |
" a = new Object();\n" + |
5920 |
" break;\n" + |
5921 |
" }\n" + |
5922 |
" if (a == null) {\n" + |
5923 |
" System.out.println();\n" + |
5924 |
" }\n" + |
5925 |
" }\n" + |
5926 |
"}\n"}, |
5927 |
"----------\n" + |
5928 |
"1. ERROR in X.java (at line 7)\n" + |
5929 |
" if (a == null) {\n" + |
5930 |
" ^\n" + |
5931 |
"The variable a can only be null; it was either set to null or checked for null when last used\n" + |
5932 |
"----------\n" + |
5933 |
"2. ERROR in X.java (at line 13)\n" + |
5934 |
" if (a == null) {\n" + |
5935 |
" ^\n" + |
5936 |
"The variable a cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5937 |
"----------\n"); |
5938 |
} |
5939 |
|
5940 |
public void test1032() { |
5941 |
this.runNegativeTest( |
5942 |
new String[] { |
5943 |
"X.java", |
5944 |
"public class X {\n" + |
5945 |
" void foo() {\n" + |
5946 |
" Object o1 = this;\n" + |
5947 |
" Object o3;\n" + |
5948 |
" while (o1 != null && (o3 = o1) != null) {\n" + |
5949 |
" o1 = o3;\n" + |
5950 |
" }\n" + |
5951 |
" }\n" + |
5952 |
"}\n"}, |
5953 |
"----------\n" + |
5954 |
"1. ERROR in X.java (at line 5)\n" + |
5955 |
" while (o1 != null && (o3 = o1) != null) {\n" + |
5956 |
" ^^\n" + |
5957 |
"The variable o1 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5958 |
"----------\n" + |
5959 |
"2. ERROR in X.java (at line 5)\n" + |
5960 |
" while (o1 != null && (o3 = o1) != null) {\n" + |
5961 |
" ^^^^^^^^^\n" + |
5962 |
"The variable o3 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5963 |
"----------\n"); |
5964 |
} |
5965 |
|
5966 |
// (simplified to focus on nulls) |
5967 |
public void test1033() { |
5968 |
this.runNegativeTest( |
5969 |
new String[] { |
5970 |
"X.java", |
5971 |
"public class X {\n" + |
5972 |
" \n" + |
5973 |
" void foo() {\n" + |
5974 |
" String a,b;\n" + |
5975 |
" do{\n" + |
5976 |
" a=\"Hello \";\n" + |
5977 |
" }while(a!=null);\n" + |
5978 |
" if(a!=null)\n" + |
5979 |
" { /* */ }\n" + |
5980 |
" }\n" + |
5981 |
"}\n"}, |
5982 |
"----------\n" + |
5983 |
"1. ERROR in X.java (at line 7)\n" + |
5984 |
" }while(a!=null);\n" + |
5985 |
" ^\n" + |
5986 |
"The variable a cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
5987 |
"----------\n" + |
5988 |
"2. ERROR in X.java (at line 8)\n" + |
5989 |
" if(a!=null)\n" + |
5990 |
" ^\n" + |
5991 |
"The variable a can only be null; it was either set to null or checked for null when last used\n" + |
5992 |
"----------\n"); |
5993 |
} |
5994 |
|
5995 |
// from AssignmentTest#test034, simplified |
5996 |
public void test1034() { |
5997 |
this.runConformTest( |
5998 |
new String[] { |
5999 |
"X.java", |
6000 |
"public final class X \n" + |
6001 |
"{\n" + |
6002 |
" void foo()\n" + |
6003 |
" {\n" + |
6004 |
" String rs = null;\n" + |
6005 |
" try\n" + |
6006 |
" {\n" + |
6007 |
" rs = \"\";\n" + |
6008 |
" return;\n" + |
6009 |
" }\n" + |
6010 |
" catch (Exception e)\n" + |
6011 |
" {\n" + |
6012 |
" }\n" + |
6013 |
" finally\n" + |
6014 |
" {\n" + |
6015 |
" if (rs != null)\n" + |
6016 |
" {\n" + |
6017 |
" try\n" + |
6018 |
" {\n" + |
6019 |
" rs.toString();\n" + |
6020 |
" }\n" + |
6021 |
" catch (Exception e)\n" + |
6022 |
" {\n" + |
6023 |
" }\n" + |
6024 |
" }\n" + |
6025 |
" }\n" + |
6026 |
" return;\n" + |
6027 |
" }\n" + |
6028 |
"}\n", |
6029 |
}, |
6030 |
""); |
6031 |
} |
6032 |
|
6033 |
public void test1036() { |
6034 |
this.runNegativeTest( |
6035 |
new String[] { |
6036 |
"X.java", |
6037 |
"public class X {\n" + |
6038 |
"\n" + |
6039 |
" void foo() {\n" + |
6040 |
" Object o = new Object();\n" + |
6041 |
" do {\n" + |
6042 |
" o = null;\n" + |
6043 |
" } while (o != null);\n" + |
6044 |
" if (o == null) {\n" + |
6045 |
" // throw new Exception();\n" + |
6046 |
" }\n" + |
6047 |
" }\n" + |
6048 |
"}\n"}, |
6049 |
"----------\n" + |
6050 |
"1. ERROR in X.java (at line 7)\n" + |
6051 |
" } while (o != null);\n" + |
6052 |
" ^\n" + |
6053 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
6054 |
"----------\n" + |
6055 |
"2. ERROR in X.java (at line 8)\n" + |
6056 |
" if (o == null) {\n" + |
6057 |
" ^\n" + |
6058 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
6059 |
"----------\n"); |
6060 |
} |
6061 |
|
6062 |
// flow info low-level validation |
6063 |
public void test2000_flow_info() { |
6064 |
this.runNegativeTest( |
6065 |
new String[] { |
6066 |
"X.java", |
6067 |
"public class X {\n" + |
6068 |
"\n" + |
6069 |
" void foo() {\n" + |
6070 |
" Object o0 = new Object(), o1 = o0, o2 = o0, o3 = o0, o4 = o0,\n" + |
6071 |
" o5 = o0, o6 = o0, o7 = o0, o8 = o0, o9 = o0,\n" + |
6072 |
" o10 = o0, o11 = o0, o12 = o0, o13 = o0, o14 = o0,\n" + |
6073 |
" o15 = o0, o16 = o0, o17 = o0, o18 = o0, o19 = o0,\n" + |
6074 |
" o20 = o0, o21 = o0, o22 = o0, o23 = o0, o24 = o0,\n" + |
6075 |
" o25 = o0, o26 = o0, o27 = o0, o28 = o0, o29 = o0,\n" + |
6076 |
" o30 = o0, o31 = o0, o32 = o0, o33 = o0, o34 = o0,\n" + |
6077 |
" o35 = o0, o36 = o0, o37 = o0, o38 = o0, o39 = o0,\n" + |
6078 |
" o40 = o0, o41 = o0, o42 = o0, o43 = o0, o44 = o0,\n" + |
6079 |
" o45 = o0, o46 = o0, o47 = o0, o48 = o0, o49 = o0,\n" + |
6080 |
" o50 = o0, o51 = o0, o52 = o0, o53 = o0, o54 = o0,\n" + |
6081 |
" o55 = o0, o56 = o0, o57 = o0, o58 = o0, o59 = o0,\n" + |
6082 |
" o60 = o0, o61 = o0, o62 = o0, o63 = o0, o64 = o0,\n" + |
6083 |
" o65 = o0, o66 = o0, o67 = o0, o68 = o0, o69 = o0;\n" + |
6084 |
" if (o65 == null) { /* */ }\n" + // complain |
6085 |
" if (o65 != null) { /* */ }\n" + // quiet (already reported) |
6086 |
" }\n" + |
6087 |
"}\n"}, |
6088 |
"----------\n" + |
6089 |
"1. ERROR in X.java (at line 18)\n" + |
6090 |
" if (o65 == null) { /* */ }\n" + |
6091 |
" ^^^\n" + |
6092 |
"The variable o65 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
6093 |
"----------\n"); |
6094 |
} |
6095 |
|
6096 |
public void test2001_flow_info() { |
6097 |
this.runConformTest( |
6098 |
new String[] { |
6099 |
"X.java", |
6100 |
"public class X {\n" + |
6101 |
"\n" + |
6102 |
" void foo(\n" + |
6103 |
" Object o0, Object o1, Object o2, Object o3, Object o4,\n" + |
6104 |
" Object o5, Object o6, Object o7, Object o8, Object o9,\n" + |
6105 |
" Object o10, Object o11, Object o12, Object o13, Object o14,\n" + |
6106 |
" Object o15, Object o16, Object o17, Object o18, Object o19,\n" + |
6107 |
" Object o20, Object o21, Object o22, Object o23, Object o24,\n" + |
6108 |
" Object o25, Object o26, Object o27, Object o28, Object o29,\n" + |
6109 |
" Object o30, Object o31, Object o32, Object o33, Object o34,\n" + |
6110 |
" Object o35, Object o36, Object o37, Object o38, Object o39,\n" + |
6111 |
" Object o40, Object o41, Object o42, Object o43, Object o44,\n" + |
6112 |
" Object o45, Object o46, Object o47, Object o48, Object o49,\n" + |
6113 |
" Object o50, Object o51, Object o52, Object o53, Object o54,\n" + |
6114 |
" Object o55, Object o56, Object o57, Object o58, Object o59,\n" + |
6115 |
" Object o60, Object o61, Object o62, Object o63, Object o64,\n" + |
6116 |
" Object o65, Object o66, Object o67, Object o68, Object o69) {\n" + |
6117 |
" if (o65 == null) { /* */ }\n" + |
6118 |
" if (o65 != null) { /* */ }\n" + |
6119 |
" }\n" + |
6120 |
"}\n"}, |
6121 |
""); |
6122 |
} |
6123 |
|
6124 |
public void test2002_flow_info() { |
6125 |
this.runConformTest( |
6126 |
new String[] { |
6127 |
"X.java", |
6128 |
"public class X {\n" + |
6129 |
" Object m0, m1, m2, m3, m4,\n" + |
6130 |
" m5, m6, m7, m8, m9,\n" + |
6131 |
" m10, m11, m12, m13, m14,\n" + |
6132 |
" m15, m16, m17, m18, m19,\n" + |
6133 |
" m20, m21, m22, m23, m24,\n" + |
6134 |
" m25, m26, m27, m28, m29,\n" + |
6135 |
" m30, m31, m32, m33, m34,\n" + |
6136 |
" m35, m36, m37, m38, m39,\n" + |
6137 |
" m40, m41, m42, m43, m44,\n" + |
6138 |
" m45, m46, m47, m48, m49,\n" + |
6139 |
" m50, m51, m52, m53, m54,\n" + |
6140 |
" m55, m56, m57, m58, m59,\n" + |
6141 |
" m60, m61, m62, m63;\n" + |
6142 |
" void foo(Object o) {\n" + |
6143 |
" if (o == null) { /* */ }\n" + |
6144 |
" if (o != null) { /* */ }\n" + |
6145 |
" }\n" + |
6146 |
"}\n"}, |
6147 |
""); |
6148 |
} |
6149 |
|
6150 |
public void test2003_flow_info() { |
6151 |
this.runConformTest( |
6152 |
new String[] { |
6153 |
"X.java", |
6154 |
"public class X {\n" + |
6155 |
" Object m0, m1, m2, m3, m4,\n" + |
6156 |
" m5, m6, m7, m8, m9,\n" + |
6157 |
" m10, m11, m12, m13, m14,\n" + |
6158 |
" m15, m16, m17, m18, m19,\n" + |
6159 |
" m20, m21, m22, m23, m24,\n" + |
6160 |
" m25, m26, m27, m28, m29,\n" + |
6161 |
" m30, m31, m32, m33, m34,\n" + |
6162 |
" m35, m36, m37, m38, m39,\n" + |
6163 |
" m40, m41, m42, m43, m44,\n" + |
6164 |
" m45, m46, m47, m48, m49,\n" + |
6165 |
" m50, m51, m52, m53, m54,\n" + |
6166 |
" m55, m56, m57, m58, m59,\n" + |
6167 |
" m60, m61, m62, m63;\n" + |
6168 |
" void foo(Object o) {\n" + |
6169 |
" o.toString();\n" + |
6170 |
" }\n" + |
6171 |
"}\n"}, |
6172 |
""); |
6173 |
} |
6174 |
|
6175 |
public void test2004_flow_info() { |
6176 |
this.runNegativeTest( |
6177 |
new String[] { |
6178 |
"X.java", |
6179 |
"public class X {\n" + |
6180 |
" Object m0, m1, m2, m3, m4,\n" + |
6181 |
" m5, m6, m7, m8, m9,\n" + |
6182 |
" m10, m11, m12, m13, m14,\n" + |
6183 |
" m15, m16, m17, m18, m19,\n" + |
6184 |
" m20, m21, m22, m23, m24,\n" + |
6185 |
" m25, m26, m27, m28, m29,\n" + |
6186 |
" m30, m31, m32, m33, m34,\n" + |
6187 |
" m35, m36, m37, m38, m39,\n" + |
6188 |
" m40, m41, m42, m43, m44,\n" + |
6189 |
" m45, m46, m47, m48, m49,\n" + |
6190 |
" m50, m51, m52, m53, m54,\n" + |
6191 |
" m55, m56, m57, m58, m59,\n" + |
6192 |
" m60, m61, m62, m63;\n" + |
6193 |
" void foo() {\n" + |
6194 |
" Object o;\n" + |
6195 |
" if (o == null) { /* */ }\n" + |
6196 |
" }\n" + |
6197 |
"}\n"}, |
6198 |
"----------\n" + |
6199 |
"1. ERROR in X.java (at line 17)\n" + |
6200 |
" if (o == null) { /* */ }\n" + |
6201 |
" ^\n" + |
6202 |
"The local variable o may not have been initialized\n" + |
6203 |
"----------\n"); |
6204 |
} |
6205 |
|
6206 |
public void test2005_flow_info() { |
6207 |
this.runConformTest( |
6208 |
new String[] { |
6209 |
"X.java", |
6210 |
"public class X {\n" + |
6211 |
" Object m0, m1, m2, m3, m4,\n" + |
6212 |
" m5, m6, m7, m8, m9,\n" + |
6213 |
" m10, m11, m12, m13, m14,\n" + |
6214 |
" m15, m16, m17, m18, m19,\n" + |
6215 |
" m20, m21, m22, m23, m24,\n" + |
6216 |
" m25, m26, m27, m28, m29,\n" + |
6217 |
" m30, m31, m32, m33, m34,\n" + |
6218 |
" m35, m36, m37, m38, m39,\n" + |
6219 |
" m40, m41, m42, m43, m44,\n" + |
6220 |
" m45, m46, m47, m48, m49,\n" + |
6221 |
" m50, m51, m52, m53, m54,\n" + |
6222 |
" m55, m56, m57, m58, m59,\n" + |
6223 |
" m60, m61, m62, m63;\n" + |
6224 |
" void foo(Object o) {\n" + |
6225 |
" o = null;\n" + |
6226 |
" }\n" + |
6227 |
"}\n"}, |
6228 |
""); |
6229 |
} |
6230 |
|
6231 |
public void test2006_flow_info() { |
6232 |
this.runConformTest( |
6233 |
new String[] { |
6234 |
"X.java", |
6235 |
"public class X {\n" + |
6236 |
" Object m0, m1, m2, m3, m4,\n" + |
6237 |
" m5, m6, m7, m8, m9,\n" + |
6238 |
" m10, m11, m12, m13, m14,\n" + |
6239 |
" m15, m16, m17, m18, m19,\n" + |
6240 |
" m20, m21, m22, m23, m24,\n" + |
6241 |
" m25, m26, m27, m28, m29,\n" + |
6242 |
" m30, m31, m32, m33, m34,\n" + |
6243 |
" m35, m36, m37, m38, m39,\n" + |
6244 |
" m40, m41, m42, m43, m44,\n" + |
6245 |
" m45, m46, m47, m48, m49,\n" + |
6246 |
" m50, m51, m52, m53, m54,\n" + |
6247 |
" m55, m56, m57, m58, m59,\n" + |
6248 |
" m60, m61, m62, m63;\n" + |
6249 |
" void foo() {\n" + |
6250 |
" Object o = null;\n" + |
6251 |
" }\n" + |
6252 |
"}\n"}, |
6253 |
""); |
6254 |
} |
6255 |
|
6256 |
public void test2007_flow_info() { |
6257 |
this.runConformTest( |
6258 |
new String[] { |
6259 |
"X.java", |
6260 |
"public class X {\n" + |
6261 |
" Object m0, m1, m2, m3, m4,\n" + |
6262 |
" m5, m6, m7, m8, m9,\n" + |
6263 |
" m10, m11, m12, m13, m14,\n" + |
6264 |
" m15, m16, m17, m18, m19,\n" + |
6265 |
" m20, m21, m22, m23, m24,\n" + |
6266 |
" m25, m26, m27, m28, m29,\n" + |
6267 |
" m30, m31, m32, m33, m34,\n" + |
6268 |
" m35, m36, m37, m38, m39,\n" + |
6269 |
" m40, m41, m42, m43, m44,\n" + |
6270 |
" m45, m46, m47, m48, m49,\n" + |
6271 |
" m50, m51, m52, m53, m54,\n" + |
6272 |
" m55, m56, m57, m58, m59,\n" + |
6273 |
" m60, m61, m62, m63;\n" + |
6274 |
" void foo() {\n" + |
6275 |
" Object o[] = null;\n" + |
6276 |
" }\n" + |
6277 |
"}\n"}, |
6278 |
""); |
6279 |
} |
6280 |
|
6281 |
// null analysis -- flow info |
6282 |
public void test2008_flow_info() { |
6283 |
this.runConformTest( |
6284 |
new String[] { |
6285 |
"X.java", |
6286 |
"public class X {\n" + |
6287 |
" Object m0, m1, m2, m3, m4,\n" + |
6288 |
" m5, m6, m7, m8, m9,\n" + |
6289 |
" m10, m11, m12, m13, m14,\n" + |
6290 |
" m15, m16, m17, m18, m19,\n" + |
6291 |
" m20, m21, m22, m23, m24,\n" + |
6292 |
" m25, m26, m27, m28, m29,\n" + |
6293 |
" m30, m31, m32, m33, m34,\n" + |
6294 |
" m35, m36, m37, m38, m39,\n" + |
6295 |
" m40, m41, m42, m43, m44,\n" + |
6296 |
" m45, m46, m47, m48, m49,\n" + |
6297 |
" m50, m51, m52, m53, m54,\n" + |
6298 |
" m55, m56, m57, m58, m59,\n" + |
6299 |
" m60, m61, m62, m63;\n" + |
6300 |
" void foo(boolean b) {\n" + |
6301 |
" Object o = null;\n" + |
6302 |
" while (o == null) {\n" + |
6303 |
// quiet: first iteration is sure to find o null, |
6304 |
// but other iterations may change it |
6305 |
" try { /* */ }\n" + |
6306 |
" finally {\n" + |
6307 |
" if (b) {\n" + |
6308 |
" o = new Object();\n" + |
6309 |
" }\n" + |
6310 |
" }\n" + |
6311 |
" }\n" + |
6312 |
" }\n" + |
6313 |
"}\n"}, |
6314 |
""); |
6315 |
} |
6316 |
|
6317 |
// null analysis -- flow info |
6318 |
public void test2009_flow_info() { |
6319 |
this.runNegativeTest( |
6320 |
new String[] { |
6321 |
"X.java", |
6322 |
"public class X {\n" + |
6323 |
" Object m0, m1, m2, m3, m4,\n" + |
6324 |
" m5, m6, m7, m8, m9,\n" + |
6325 |
" m10, m11, m12, m13, m14,\n" + |
6326 |
" m15, m16, m17, m18, m19,\n" + |
6327 |
" m20, m21, m22, m23, m24,\n" + |
6328 |
" m25, m26, m27, m28, m29,\n" + |
6329 |
" m30, m31, m32, m33, m34,\n" + |
6330 |
" m35, m36, m37, m38, m39,\n" + |
6331 |
" m40, m41, m42, m43, m44,\n" + |
6332 |
" m45, m46, m47, m48, m49,\n" + |
6333 |
" m50, m51, m52, m53, m54,\n" + |
6334 |
" m55, m56, m57, m58, m59,\n" + |
6335 |
" m60, m61, m62, m63;\n" + |
6336 |
" void foo(Object o) {\n" + |
6337 |
" try { /* */ }\n" + |
6338 |
" finally {\n" + |
6339 |
" o = new Object();\n" + |
6340 |
" }\n" + |
6341 |
" if (o == null) { /* */ }\n" + |
6342 |
" }\n" + |
6343 |
"}\n"}, |
6344 |
"----------\n" + |
6345 |
"1. ERROR in X.java (at line 20)\n" + |
6346 |
" if (o == null) { /* */ }\n" + |
6347 |
" ^\n" + |
6348 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
6349 |
"----------\n"); |
6350 |
} |
6351 |
|
6352 |
// null analysis -- flow info |
6353 |
public void test2010_flow_info() { |
6354 |
this.runNegativeTest( |
6355 |
new String[] { |
6356 |
"X.java", |
6357 |
"public class X {\n" + |
6358 |
" Object m00, m01, m02, m03, m04,\n" + |
6359 |
" m05, m06, m07, m08, m09,\n" + |
6360 |
" m10, m11, m12, m13, m14,\n" + |
6361 |
" m15, m16, m17, m18, m19,\n" + |
6362 |
" m20, m21, m22, m23, m24,\n" + |
6363 |
" m25, m26, m27, m28, m29,\n" + |
6364 |
" m30, m31, m32, m33, m34,\n" + |
6365 |
" m35, m36, m37, m38, m39,\n" + |
6366 |
" m40, m41, m42, m43, m44,\n" + |
6367 |
" m45, m46, m47, m48, m49,\n" + |
6368 |
" m50, m51, m52, m53, m54,\n" + |
6369 |
" m55, m56, m57, m58, m59,\n" + |
6370 |
" m60, m61, m62, m63;\n" + |
6371 |
" void foo() {\n" + |
6372 |
" Object o;\n" + |
6373 |
" try { /* */ }\n" + |
6374 |
" finally {\n" + |
6375 |
" o = new Object();\n" + |
6376 |
" }\n" + |
6377 |
" if (o == null) { /* */ }\n" + |
6378 |
" }\n" + |
6379 |
"}\n"}, |
6380 |
"----------\n" + |
6381 |
"1. ERROR in X.java (at line 21)\n" + |
6382 |
" if (o == null) { /* */ }\n" + |
6383 |
" ^\n" + |
6384 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
6385 |
"----------\n"); |
6386 |
} |
6387 |
|
6388 |
// null analysis -- flow info |
6389 |
public void test2011_flow_info() { |
6390 |
this.runNegativeTest( |
6391 |
new String[] { |
6392 |
"X.java", |
6393 |
"public class X {\n" + |
6394 |
" Object m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
6395 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
6396 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
6397 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
6398 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
6399 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
6400 |
" m060, m061, m062, m063;\n" + |
6401 |
" void foo() {\n" + |
6402 |
" Object o000, o001, o002, o003, o004, o005, o006, o007, o008, o009,\n" + |
6403 |
" o010, o011, o012, o013, o014, o015, o016, o017, o018, o019,\n" + |
6404 |
" o020, o021, o022, o023, o024, o025, o026, o027, o028, o029,\n" + |
6405 |
" o030, o031, o032, o033, o034, o035, o036, o037, o038, o039,\n" + |
6406 |
" o040, o041, o042, o043, o044, o045, o046, o047, o048, o049,\n" + |
6407 |
" o050, o051, o052, o053, o054, o055, o056, o057, o058, o059,\n" + |
6408 |
" o060, o061, o062, o063;\n" + |
6409 |
" Object o;\n" + |
6410 |
" try {\n" + |
6411 |
" o000 = new Object();\n" + |
6412 |
" }\n" + |
6413 |
" finally {\n" + |
6414 |
" o = new Object();\n" + |
6415 |
" }\n" + |
6416 |
" if (o == null) { /* */ }\n" + |
6417 |
" }\n" + |
6418 |
"}\n"}, |
6419 |
"----------\n" + |
6420 |
"1. ERROR in X.java (at line 24)\n" + |
6421 |
" if (o == null) { /* */ }\n" + |
6422 |
" ^\n" + |
6423 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
6424 |
"----------\n"); |
6425 |
} |
6426 |
|
6427 |
// null analysis -- flow info |
6428 |
public void test2012_flow_info() { |
6429 |
this.runNegativeTest( |
6430 |
new String[] { |
6431 |
"X.java", |
6432 |
"public class X {\n" + |
6433 |
" Object m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
6434 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
6435 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
6436 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
6437 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
6438 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
6439 |
" m060, m061, m062, m063;\n" + |
6440 |
" void foo() {\n" + |
6441 |
" Object o000, o001, o002, o003, o004, o005, o006, o007, o008, o009,\n" + |
6442 |
" o010, o011, o012, o013, o014, o015, o016, o017, o018, o019,\n" + |
6443 |
" o020, o021, o022, o023, o024, o025, o026, o027, o028, o029,\n" + |
6444 |
" o030, o031, o032, o033, o034, o035, o036, o037, o038, o039,\n" + |
6445 |
" o040, o041, o042, o043, o044, o045, o046, o047, o048, o049,\n" + |
6446 |
" o050, o051, o052, o053, o054, o055, o056, o057, o058, o059,\n" + |
6447 |
" o060, o061, o062, o063;\n" + |
6448 |
" Object o;\n" + |
6449 |
" try {\n" + |
6450 |
" o = new Object();\n" + |
6451 |
" }\n" + |
6452 |
" finally {\n" + |
6453 |
" o000 = new Object();\n" + |
6454 |
" }\n" + |
6455 |
" if (o == null) { /* */ }\n" + |
6456 |
" }\n" + |
6457 |
"}\n"}, |
6458 |
"----------\n" + |
6459 |
"1. ERROR in X.java (at line 24)\n" + |
6460 |
" if (o == null) { /* */ }\n" + |
6461 |
" ^\n" + |
6462 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
6463 |
"----------\n"); |
6464 |
} |
6465 |
|
6466 |
// null analysis -- flow info |
6467 |
public void test2013_flow_info() { |
6468 |
this.runNegativeTest( |
6469 |
new String[] { |
6470 |
"X.java", |
6471 |
"public class X {\n" + |
6472 |
" boolean dummy;\n" + |
6473 |
" Object m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
6474 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
6475 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
6476 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
6477 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
6478 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
6479 |
" m060, m061, m062, m063;\n" + |
6480 |
" void foo(Object u) {\n" + |
6481 |
" Object o = null;\n" + |
6482 |
" while (dummy) {\n" + |
6483 |
" o = u;\n" + |
6484 |
" }\n" + |
6485 |
" o.toString();\n" + |
6486 |
" }\n" + |
6487 |
"}\n"}, |
6488 |
"----------\n" + |
6489 |
"1. ERROR in X.java (at line 15)\n" + |
6490 |
" o.toString();\n" + |
6491 |
" ^\n" + |
6492 |
"The variable o may be null\n" + |
6493 |
"----------\n"); |
6494 |
} |
6495 |
|
6496 |
// null analysis -- flow info |
6497 |
public void test2014_flow_info() { |
6498 |
this.runNegativeTest( |
6499 |
new String[] { |
6500 |
"X.java", |
6501 |
"class X {\n" + |
6502 |
" int m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
6503 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
6504 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
6505 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
6506 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
6507 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
6508 |
" m060, m061, m062, m063;\n" + |
6509 |
" final int m064;\n" + |
6510 |
" X() {\n" + |
6511 |
" m064 = 10;\n" + |
6512 |
" class Inner extends X {\n" + |
6513 |
" int m100, m101, m102, m103, m104, m105, m106, m107, m108, m109,\n" + |
6514 |
" m110, m111, m112, m113, m114, m115, m116, m117, m118, m119,\n" + |
6515 |
" m120, m121, m122, m123, m124, m125, m126, m127, m128, m129,\n" + |
6516 |
" m130, m131, m132, m133, m134, m135, m136, m137, m138, m139,\n" + |
6517 |
" m140, m141, m142, m143, m144, m145, m146, m147, m148, m149,\n" + |
6518 |
" m150, m151, m152, m153, m154, m155, m156, m157, m158, m159,\n" + |
6519 |
" m160, m161, m162, m163;\n" + |
6520 |
" final int m164;\n" + |
6521 |
" int bar() {\n" + |
6522 |
" return m100 + m101 + m102 + m103 + m104 +\n" + |
6523 |
" m105 + m106 + m107 + m108 + m109 +\n" + |
6524 |
" m110 + m111 + m112 + m113 + m114 +\n" + |
6525 |
" m115 + m116 + m117 + m118 + m119 +\n" + |
6526 |
" m120 + m121 + m122 + m123 + m124 +\n" + |
6527 |
" m125 + m126 + m127 + m128 + m129 +\n" + |
6528 |
" m130 + m131 + m132 + m133 + m134 +\n" + |
6529 |
" m135 + m136 + m137 + m138 + m139 +\n" + |
6530 |
" m140 + m141 + m142 + m143 + m144 +\n" + |
6531 |
" m145 + m146 + m147 + m148 + m149 +\n" + |
6532 |
" m150 + m151 + m152 + m153 + m154 +\n" + |
6533 |
" m155 + m156 + m157 + m158 + m159 +\n" + |
6534 |
" m160 + m161 + m162 + m163 + m164;\n" + |
6535 |
" }\n" + |
6536 |
" };\n" + |
6537 |
" System.out.println((new Inner()).bar());\n" + |
6538 |
" }\n" + |
6539 |
"}\n"}, |
6540 |
"----------\n" + |
6541 |
"1. ERROR in X.java (at line 12)\n" + |
6542 |
" class Inner extends X {\n" + |
6543 |
" ^^^^^\n" + |
6544 |
"The blank final field m164 may not have been initialized\n" + |
6545 |
"----------\n"); |
6546 |
} |
6547 |
|
6548 |
// null analysis -- flow info |
6549 |
public void test2015_flow_info() { |
6550 |
this.runNegativeTest( |
6551 |
new String[] { |
6552 |
"X.java", |
6553 |
"class X {\n" + |
6554 |
" int m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
6555 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
6556 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
6557 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
6558 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
6559 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
6560 |
" m060, m061, m062, m063;\n" + |
6561 |
" final int m200;\n" + |
6562 |
" int m201, m202, m203, m204, m205, m206, m207, m208, m209,\n" + |
6563 |
" m210, m211, m212, m213, m214, m215, m216, m217, m218, m219,\n" + |
6564 |
" m220, m221, m222, m223, m224, m225, m226, m227, m228, m229,\n" + |
6565 |
" m230, m231, m232, m233, m234, m235, m236, m237, m238, m239,\n" + |
6566 |
" m240, m241, m242, m243, m244, m245, m246, m247, m248, m249,\n" + |
6567 |
" m250, m251, m252, m253, m254, m255, m256, m257, m258, m259,\n" + |
6568 |
" m260, m261, m262, m263;\n" + |
6569 |
" int m301, m302, m303, m304, m305, m306, m307, m308, m309,\n" + |
6570 |
" m310, m311, m312, m313, m314, m315, m316, m317, m318, m319,\n" + |
6571 |
" m320, m321, m322, m323, m324, m325, m326, m327, m328, m329,\n" + |
6572 |
" m330, m331, m332, m333, m334, m335, m336, m337, m338, m339,\n" + |
6573 |
" m340, m341, m342, m343, m344, m345, m346, m347, m348, m349,\n" + |
6574 |
" m350, m351, m352, m353, m354, m355, m356, m357, m358, m359,\n" + |
6575 |
" m360, m361, m362, m363;\n" + |
6576 |
" X() {\n" + |
6577 |
" m200 = 10;\n" + |
6578 |
" class Inner extends X {\n" + |
6579 |
" int m100, m101, m102, m103, m104, m105, m106, m107, m108, m109,\n" + |
6580 |
" m110, m111, m112, m113, m114, m115, m116, m117, m118, m119,\n" + |
6581 |
" m120, m121, m122, m123, m124, m125, m126, m127, m128, m129,\n" + |
6582 |
" m130, m131, m132, m133, m134, m135, m136, m137, m138, m139,\n" + |
6583 |
" m140, m141, m142, m143, m144, m145, m146, m147, m148, m149,\n" + |
6584 |
" m150, m151, m152, m153, m154, m155, m156, m157, m158, m159,\n" + |
6585 |
" m160, m161, m162, m163;\n" + |
6586 |
" final int m164;\n" + |
6587 |
" int bar() {\n" + |
6588 |
" return m100 + m101 + m102 + m103 + m104 +\n" + |
6589 |
" m105 + m106 + m107 + m108 + m109 +\n" + |
6590 |
" m110 + m111 + m112 + m113 + m114 +\n" + |
6591 |
" m115 + m116 + m117 + m118 + m119 +\n" + |
6592 |
" m120 + m121 + m122 + m123 + m124 +\n" + |
6593 |
" m125 + m126 + m127 + m128 + m129 +\n" + |
6594 |
" m130 + m131 + m132 + m133 + m134 +\n" + |
6595 |
" m135 + m136 + m137 + m138 + m139 +\n" + |
6596 |
" m140 + m141 + m142 + m143 + m144 +\n" + |
6597 |
" m145 + m146 + m147 + m148 + m149 +\n" + |
6598 |
" m150 + m151 + m152 + m153 + m154 +\n" + |
6599 |
" m155 + m156 + m157 + m158 + m159 +\n" + |
6600 |
" m160 + m161 + m162 + m163 + m164;\n" + |
6601 |
" }\n" + |
6602 |
" };\n" + |
6603 |
" System.out.println((new Inner()).bar());\n" + |
6604 |
" }\n" + |
6605 |
"}\n"}, |
6606 |
"----------\n" + |
6607 |
"1. ERROR in X.java (at line 26)\n" + |
6608 |
" class Inner extends X {\n" + |
6609 |
" ^^^^^\n" + |
6610 |
"The blank final field m164 may not have been initialized\n" + |
6611 |
"----------\n"); |
6612 |
} |
6613 |
|
6614 |
// null analysis -- flow info |
6615 |
public void test2016_flow_info() { |
6616 |
this.runNegativeTest( |
6617 |
new String[] { |
6618 |
"X.java", |
6619 |
"class X {\n" + |
6620 |
" int m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
6621 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
6622 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
6623 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
6624 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
6625 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
6626 |
" m060, m061;\n" + |
6627 |
" final int m062;\n" + |
6628 |
" {\n" + |
6629 |
" int l063, m201 = 0, m202, m203, m204, m205, m206, m207, m208, m209,\n" + |
6630 |
" m210, m211, m212, m213, m214, m215, m216, m217, m218, m219,\n" + |
6631 |
" m220, m221, m222, m223, m224, m225, m226, m227, m228, m229,\n" + |
6632 |
" m230, m231, m232, m233, m234, m235, m236, m237, m238, m239,\n" + |
6633 |
" m240, m241, m242, m243, m244, m245, m246, m247, m248, m249,\n" + |
6634 |
" m250, m251, m252, m253, m254, m255, m256, m257, m258, m259,\n" + |
6635 |
" m260, m261, m262, m263;\n" + |
6636 |
" int m301, m302, m303, m304, m305, m306, m307, m308, m309,\n" + |
6637 |
" m310, m311, m312, m313, m314, m315, m316, m317, m318, m319,\n" + |
6638 |
" m320, m321, m322, m323, m324, m325, m326, m327, m328, m329,\n" + |
6639 |
" m330, m331, m332, m333, m334, m335, m336, m337, m338, m339,\n" + |
6640 |
" m340, m341, m342, m343, m344, m345, m346, m347, m348, m349,\n" + |
6641 |
" m350, m351, m352, m353, m354, m355, m356, m357, m358, m359,\n" + |
6642 |
" m360 = 0, m361 = 0, m362 = 0, m363 = 0;\n" + |
6643 |
" m062 = m360;\n" + |
6644 |
" }\n" + |
6645 |
" X() {\n" + |
6646 |
" int l0, l1;\n" + |
6647 |
" m000 = l1;\n" + |
6648 |
" class Inner extends X {\n" + |
6649 |
" int bar() {\n" + |
6650 |
" return 0;\n" + |
6651 |
" }\n" + |
6652 |
" };\n" + |
6653 |
" System.out.println((new Inner()).bar());\n" + |
6654 |
" }\n" + |
6655 |
"}\n"}, |
6656 |
"----------\n" + |
6657 |
"1. ERROR in X.java (at line 29)\n" + |
6658 |
" m000 = l1;\n" + |
6659 |
" ^^\n" + |
6660 |
"The local variable l1 may not have been initialized\n" + |
6661 |
"----------\n"); |
6662 |
} |
943 |
|
6663 |
|
944 |
// null analysis - if/else |
6664 |
public void test2017_flow_info() { |
945 |
public void test0107_if_else() { |
6665 |
this.runConformTest( |
946 |
this.runNegativeTest( |
6666 |
new String[] { |
947 |
new String[] { |
6667 |
"X.java", |
948 |
"X.java", |
6668 |
"public class X {\n" + |
949 |
"public class X {\n" + |
6669 |
" boolean dummy;\n" + |
950 |
" void foo(Object o) {\n" + |
6670 |
" Object m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
951 |
" if (o == null) {\n" + |
6671 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
952 |
" System.exit(0);\n" + |
6672 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
953 |
" }\n" + |
6673 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
954 |
" if (o == null) {\n" + |
6674 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
955 |
// quiet |
6675 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
956 |
// a direct call to System.exit() can be recognized as such; yet, |
6676 |
" m060, m061, m062, m063;\n" + |
957 |
// a lot of other methods may have the same property (aka calling |
6677 |
" void foo(Object u) {\n" + |
958 |
// System.exit() themselves.) |
6678 |
" Object o = null;\n" + |
959 |
" // do nothing\n" + |
6679 |
" while (dummy) {\n" + |
960 |
" }\n" + |
6680 |
" if (dummy) {\n" + // uncorrelated |
961 |
" }\n" + |
6681 |
" o = u;\n" + |
962 |
"}\n"}, |
6682 |
" continue;\n" + |
963 |
"" |
6683 |
" }\n" + |
964 |
); |
6684 |
" }\n" + |
965 |
} |
6685 |
" if (o != null) { /* */ }\n" + |
966 |
|
6686 |
" }\n" + |
967 |
// null analysis -- while |
6687 |
"}\n"}, |
968 |
// TODO (maxime) fix |
6688 |
""); |
969 |
public void _test0111_while() { |
6689 |
} |
970 |
this.runNegativeTest( |
|
|
971 |
new String[] { |
972 |
"X.java", |
973 |
"public class X {\n" + |
974 |
" void foo() {\n" + |
975 |
" Object o = null;\n" + |
976 |
" while (o.toString() != null) {/* */}\n" + |
977 |
// complain: NPE |
978 |
" }\n" + |
979 |
"}\n"}, |
980 |
"----------\n" + |
981 |
"1. WARNING in X.java (at line 4)\n" + |
982 |
" while (o.toString() != null) {/* */}\n" + |
983 |
" ^\n" + |
984 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
985 |
"----------\n" |
986 |
); |
987 |
} |
988 |
/* TODO (maxime) |
989 |
Object o = new Object(); |
990 |
while (b) { |
991 |
o.toString(); // should signal NPE risk |
992 |
if (b2) o = null; |
993 |
} |
994 |
*/ |
995 |
|
996 |
/* TODO (maxime) |
997 |
Object o = new Object(); |
998 |
if (b2) o = null; |
999 |
o.toString(); // should barf |
1000 |
*/ |
1001 |
// null analysis -- while |
1002 |
// TODO (maxime) fix |
1003 |
public void _test0112_while() { |
1004 |
this.runNegativeTest( |
1005 |
new String[] { |
1006 |
"X.java", |
1007 |
"public class X {\n" + |
1008 |
" void foo() {\n" + |
1009 |
" Object o = null;\n" + |
1010 |
" while (o != null) {/* */}\n" + |
1011 |
// complain: get o null first time and forever |
1012 |
" }\n" + |
1013 |
"}\n"}, |
1014 |
"----------\n" + |
1015 |
"1. WARNING in X.java (at line 4)\n" + |
1016 |
" while (o != null) {/* */}\n" + |
1017 |
" ^\n" + |
1018 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1019 |
"----------\n" |
1020 |
); |
1021 |
} |
1022 |
|
6690 |
|
1023 |
// null analysis -- while |
6691 |
public void test2018_flow_info() { |
1024 |
public void test0113_while() { |
6692 |
this.runNegativeTest( |
1025 |
this.runNegativeTest( |
6693 |
new String[] { |
1026 |
new String[] { |
6694 |
"X.java", |
1027 |
"X.java", |
6695 |
"public class X {\n" + |
1028 |
"public class X {\n" + |
6696 |
" boolean dummy;\n" + |
1029 |
" void foo() {\n" + |
6697 |
" Object m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
1030 |
" Object o = null;\n" + |
6698 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
1031 |
" while (o == null) {\n" + |
6699 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
1032 |
// quiet: first iteration is sure to find o null, |
6700 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
1033 |
// but other iterations may change it |
6701 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
1034 |
" o = new Object();\n" + |
6702 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
1035 |
" }\n" + |
6703 |
" m060, m061, m062, m063;\n" + |
1036 |
" }\n" + |
6704 |
" void foo() {\n" + |
1037 |
"}\n"}, |
6705 |
" Object o;\n" + |
1038 |
"" |
6706 |
" while (dummy) {\n" + |
1039 |
); |
6707 |
" if (dummy) {\n" + // uncorrelated |
1040 |
} |
6708 |
" o = null;\n" + |
|
|
6709 |
" continue;\n" + |
6710 |
" }\n" + |
6711 |
" }\n" + |
6712 |
" o.toString();\n" + |
6713 |
" }\n" + |
6714 |
"}\n"}, |
6715 |
"----------\n" + |
6716 |
"1. ERROR in X.java (at line 18)\n" + |
6717 |
" o.toString();\n" + |
6718 |
" ^\n" + |
6719 |
"The local variable o may not have been initialized\n" + |
6720 |
"----------\n" + |
6721 |
"2. ERROR in X.java (at line 18)\n" + |
6722 |
" o.toString();\n" + |
6723 |
" ^\n" + |
6724 |
"The variable o may be null\n" + |
6725 |
"----------\n"); |
6726 |
} |
1041 |
|
6727 |
|
1042 |
// null analysis -- while |
6728 |
public void test2019_flow_info() { |
1043 |
public void test0114_while() { |
6729 |
this.runNegativeTest( |
1044 |
this.runNegativeTest( |
6730 |
new String[] { |
1045 |
new String[] { |
6731 |
"X.java", |
1046 |
"X.java", |
6732 |
"public class X {\n" + |
1047 |
"public class X {\n" + |
6733 |
" boolean dummy;\n" + |
1048 |
" void foo() {\n" + |
6734 |
" Object m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
1049 |
" Object o = null;\n" + |
6735 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
1050 |
" while (o == null) {\n" + |
6736 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
1051 |
// quiet: first iteration is sure to find o null, |
6737 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
1052 |
// but other iterations may change it |
6738 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
1053 |
" if (System.currentTimeMillis() > 10L) {\n" + |
6739 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
1054 |
" o = new Object();\n" + |
6740 |
" m060, m061, m062, m063;\n" + |
1055 |
" }\n" + |
6741 |
" void foo() {\n" + |
1056 |
" }\n" + |
6742 |
" Object o;\n" + |
1057 |
" }\n" + |
6743 |
" while (dummy) {\n" + |
1058 |
"}\n"}, |
6744 |
" if (dummy) {\n" + // uncorrelated |
1059 |
"" |
6745 |
" continue;\n" + |
1060 |
); |
6746 |
" }\n" + |
1061 |
} |
6747 |
" o = null;\n" + |
|
|
6748 |
" }\n" + |
6749 |
" o.toString();\n" + |
6750 |
" }\n" + |
6751 |
"}\n"}, |
6752 |
"----------\n" + |
6753 |
"1. ERROR in X.java (at line 18)\n" + |
6754 |
" o.toString();\n" + |
6755 |
" ^\n" + |
6756 |
"The local variable o may not have been initialized\n" + |
6757 |
"----------\n" + |
6758 |
"2. ERROR in X.java (at line 18)\n" + |
6759 |
" o.toString();\n" + |
6760 |
" ^\n" + |
6761 |
"The variable o may be null\n" + |
6762 |
"----------\n"); |
6763 |
} |
1062 |
|
6764 |
|
1063 |
// null analysis -- while |
6765 |
public void test2020_flow_info() { |
1064 |
// TODO (maxime) fix |
6766 |
this.runNegativeTest( |
1065 |
public void _test0115_while() { |
6767 |
new String[] { |
1066 |
this.runNegativeTest( |
6768 |
"X.java", |
1067 |
new String[] { |
6769 |
"public class X {\n" + |
1068 |
"X.java", |
6770 |
" boolean dummy;\n" + |
1069 |
"public class X {\n" + |
6771 |
" Object m000, m001, m002, m003, m004, m005, m006, m007, m008, m009,\n" + |
1070 |
" boolean bar() {\n" + |
6772 |
" m010, m011, m012, m013, m014, m015, m016, m017, m018, m019,\n" + |
1071 |
" return true;\n" + |
6773 |
" m020, m021, m022, m023, m024, m025, m026, m027, m028, m029,\n" + |
1072 |
" }\n" + |
6774 |
" m030, m031, m032, m033, m034, m035, m036, m037, m038, m039,\n" + |
1073 |
" void foo(Object o) {\n" + |
6775 |
" m040, m041, m042, m043, m044, m045, m046, m047, m048, m049,\n" + |
1074 |
" while (bar() && o == null) {\n" + |
6776 |
" m050, m051, m052, m053, m054, m055, m056, m057, m058, m059,\n" + |
1075 |
" o.toString();\n" + // complain: NPE |
6777 |
" m060, m061, m062, m063;\n" + |
1076 |
" o = new Object();\n" + |
6778 |
" int m200, m201, m202, m203, m204, m205, m206, m207, m208, m209,\n" + |
1077 |
" }\n" + |
6779 |
" m210, m211, m212, m213, m214, m215, m216, m217, m218, m219,\n" + |
1078 |
" }\n" + |
6780 |
" m220, m221, m222, m223, m224, m225, m226, m227, m228, m229,\n" + |
1079 |
"}\n"}, |
6781 |
" m230, m231, m232, m233, m234, m235, m236, m237, m238, m239,\n" + |
1080 |
"----------\n" + |
6782 |
" m240, m241, m242, m243, m244, m245, m246, m247, m248, m249,\n" + |
1081 |
"1. WARNING in X.java (at line 7)\n" + |
6783 |
" m250, m251, m252, m253, m254, m255, m256, m257, m258, m259,\n" + |
1082 |
" o.toString();\n" + |
6784 |
" m260, m261;\n" + |
1083 |
" ^\n" + |
6785 |
" void foo() {\n" + |
1084 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
6786 |
" Object o0, o1;\n" + |
1085 |
"----------\n" |
6787 |
" while (dummy) {\n" + |
1086 |
); |
6788 |
" o0 = new Object();\n" + |
1087 |
} |
6789 |
" if (dummy) {\n" + // uncorrelated |
|
|
6790 |
" o1 = null;\n" + |
6791 |
" continue;\n" + |
6792 |
" }\n" + |
6793 |
" }\n" + |
6794 |
" o1.toString();\n" + |
6795 |
" }\n" + |
6796 |
"}\n"}, |
6797 |
"----------\n" + |
6798 |
"1. ERROR in X.java (at line 26)\n" + |
6799 |
" o1.toString();\n" + |
6800 |
" ^^\n" + |
6801 |
"The local variable o1 may not have been initialized\n" + |
6802 |
"----------\n" + |
6803 |
"2. ERROR in X.java (at line 26)\n" + |
6804 |
" o1.toString();\n" + |
6805 |
" ^^\n" + |
6806 |
"The variable o1 may be null\n" + |
6807 |
"----------\n"); |
6808 |
} |
1088 |
|
6809 |
|
1089 |
// null analysis -- while |
6810 |
// Technical tests -- only available with patched sources |
1090 |
// TODO (maxime) fix |
6811 |
static final boolean |
1091 |
public void _test0116_while() { |
6812 |
printTablesAsNames = false, |
1092 |
this.runNegativeTest( |
6813 |
printTablesAsCodes = false, |
1093 |
new String[] { |
6814 |
printTruthMaps = false; |
1094 |
"X.java", |
6815 |
static final int |
1095 |
"public class X {\n" + |
6816 |
combinationTestsloopsNb = 1; // define to 10000s to measure performances |
1096 |
" boolean dummy;\n" + |
6817 |
|
1097 |
" void foo(Object o) {\n" + |
6818 |
|
1098 |
" o = null;\n" + |
6819 |
public void test2050_markAsComparedEqualToNonNull() { |
1099 |
" while (dummy || o != null) { /* */ }\n" + // o can only be null |
6820 |
long [][][] testData = { |
1100 |
" }\n" + |
6821 |
{{0,0,0,0},{1,1,0,0}}, |
1101 |
"}\n"}, |
6822 |
{{0,0,0,1},{1,1,0,1}}, |
1102 |
"----------\n" + |
6823 |
{{0,0,1,0},{1,1,0,0}}, |
1103 |
"1. WARNING in X.java (at line 5)\n" + |
6824 |
{{0,0,1,1},{1,1,0,1}}, |
1104 |
" while (dummy || o != null) {\n" + |
6825 |
{{0,1,0,0},{1,1,0,0}}, |
1105 |
" ^\n" + |
6826 |
{{0,1,0,1},{1,1,0,1}}, |
1106 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
6827 |
{{0,1,1,0},{1,1,0,0}}, |
1107 |
"----------\n" |
6828 |
{{0,1,1,1},{1,1,0,1}}, |
1108 |
); |
6829 |
{{1,0,0,0},{1,1,0,0}}, |
|
|
6830 |
{{1,0,0,1},{1,0,0,1}}, |
6831 |
{{1,0,1,0},{1,1,0,0}}, |
6832 |
{{1,0,1,1},{1,1,0,1}}, |
6833 |
{{1,1,0,0},{1,1,0,0}}, |
6834 |
{{1,1,0,1},{1,1,0,1}}, |
6835 |
{{1,1,1,0},{1,1,0,0}}, |
6836 |
{{1,1,1,1},{1,1,0,1}}, |
6837 |
}; |
6838 |
int failures = 0; |
6839 |
LocalVariableBinding local = new TestLocalVariableBinding(0); |
6840 |
for (int i = 0; i < testData.length; i++) { |
6841 |
UnconditionalFlowInfoTestHarness |
6842 |
result = UnconditionalFlowInfoTestHarness. |
6843 |
testUnconditionalFlowInfo(testData[i][0]); |
6844 |
result.markAsComparedEqualToNonNull(local); |
6845 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
6846 |
testUnconditionalFlowInfo(testData[i][1])))) { |
6847 |
if (failures == 0) { |
6848 |
System.out.println("markAsComparedEqualToNonNull failures: "); |
6849 |
} |
6850 |
failures++; |
6851 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
6852 |
',' + result.testString() + |
6853 |
"}, // instead of: " + testStringValueOf(testData[i][1])); |
6854 |
} |
1109 |
} |
6855 |
} |
1110 |
|
6856 |
local = new TestLocalVariableBinding(64); |
1111 |
// null analysis -- while |
6857 |
for (int i = 0; i < testData.length; i++) { |
1112 |
// TODO (maxime) fix |
6858 |
UnconditionalFlowInfoTestHarness |
1113 |
public void _test0117_while() { |
6859 |
result = UnconditionalFlowInfoTestHarness. |
1114 |
this.runNegativeTest( |
6860 |
testUnconditionalFlowInfo(testData[i][0], 64), |
1115 |
new String[] { |
6861 |
expected = UnconditionalFlowInfoTestHarness. |
1116 |
"X.java", |
6862 |
testUnconditionalFlowInfo(testData[i][1], 64); |
1117 |
"public class X {\n" + |
6863 |
result.markAsComparedEqualToNonNull(local); |
1118 |
" boolean dummy;\n" + |
6864 |
if (!(result.testEquals(expected))) { |
1119 |
" void foo() {\n" + |
6865 |
if (failures == 0) { |
1120 |
" Object o = null;\n" + |
6866 |
System.out.println("markAsComparedEqualToNonNull failures: "); |
1121 |
" while (dummy) {\n" + |
6867 |
} |
1122 |
" o.toString();\n" + // complain: NPE on first iteration |
6868 |
failures++; |
1123 |
" o = new Object();\n" + |
6869 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
1124 |
" }\n" + |
6870 |
',' + result.testString() + |
1125 |
" }\n" + |
6871 |
"}, // (64) instead of: " + testStringValueOf(testData[i][1])); |
1126 |
"}\n"}, |
6872 |
} |
1127 |
"----------\n" + |
6873 |
if (testData[i][0][0] == 0 && |
1128 |
"1. WARNING in X.java (at line 6)\n" + |
6874 |
testData[i][0][1] == 0 && |
1129 |
" o.toString();\n" + |
6875 |
testData[i][0][2] == 0 && |
1130 |
" ^\n" + |
6876 |
testData[i][0][3] == 0) { |
1131 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
6877 |
result = UnconditionalFlowInfoTestHarness. |
1132 |
"----------\n" |
6878 |
testUnconditionalFlowInfo(testData[i][1]); |
1133 |
); |
6879 |
result.markAsComparedEqualToNonNull(local); |
|
|
6880 |
if (!result.testEquals(expected, 64)) { |
6881 |
if (failures == 0) { |
6882 |
System.out.println("markAsComparedEqualToNonNull failures: "); |
6883 |
} |
6884 |
failures++; |
6885 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
6886 |
',' + result.testString() + |
6887 |
"}, // (zero 64) instead of: " + testStringValueOf(testData[i][1])); |
6888 |
} |
6889 |
} |
1134 |
} |
6890 |
} |
1135 |
|
6891 |
local = new TestLocalVariableBinding(128); |
1136 |
// TODO (maxime) should nuance error message: The variable o may be null... |
6892 |
for (int i = 0; i < testData.length; i++) { |
1137 |
|
6893 |
if (testData[i][0][0] == 0 && |
1138 |
// null analysis -- while |
6894 |
testData[i][0][1] == 0 && |
1139 |
// this test shows that, as long as we do not explore all possible |
6895 |
testData[i][0][2] == 0 && |
1140 |
// paths, we have to take potential initializations into account |
6896 |
testData[i][0][3] == 0) { |
1141 |
// even in branches that could be pruned in the first passes |
6897 |
UnconditionalFlowInfoTestHarness |
1142 |
// first approximation is to stop pruning code conditioned by |
6898 |
result = UnconditionalFlowInfoTestHarness. |
1143 |
// variables |
6899 |
testUnconditionalFlowInfo(testData[i][1], 64), |
1144 |
// second approximation could still rely upon variables that are |
6900 |
expected = UnconditionalFlowInfoTestHarness. |
1145 |
// never affected by the looping code (unassigned variables) |
6901 |
testUnconditionalFlowInfo(testData[i][1], 128); |
1146 |
// complete solution would call for multiple iterations in the |
6902 |
result.markAsComparedEqualToNonNull(local); |
1147 |
// null analysis |
6903 |
if (!result.testEquals(expected, 128)) { |
1148 |
// TODO (maxime) fix |
6904 |
if (failures == 0) { |
1149 |
public void _test0118_while() { |
6905 |
System.out.println("markAsComparedEqualToNonNull failures: "); |
1150 |
this.runNegativeTest( |
6906 |
} |
1151 |
new String[] { |
6907 |
failures++; |
1152 |
"X.java", |
6908 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
1153 |
"public class X {\n" + |
6909 |
',' + result.testString() + |
1154 |
" void foo() {\n" + |
6910 |
"}, // (zero 128) instead of: " + testStringValueOf(testData[i][1])); |
1155 |
" Object o = null,\n" + |
6911 |
} |
1156 |
" u = new Object(),\n" + |
6912 |
} |
1157 |
" v = new Object();\n" + |
|
|
1158 |
" while (o == null) {\n" + |
1159 |
" if (v == null) {\n" + |
1160 |
" o = new Object();\n" + |
1161 |
" };\n" + |
1162 |
" if (u == null) {\n" + |
1163 |
" v = null;\n" + |
1164 |
" };\n" + |
1165 |
" u = null;\n" + |
1166 |
" }\n" + |
1167 |
" }\n" + |
1168 |
"}\n"}, |
1169 |
"" |
1170 |
); |
1171 |
} |
6913 |
} |
1172 |
|
6914 |
if (printTablesAsNames) { |
1173 |
// null analysis -- while |
6915 |
System.out.println("RECAP TABLE FOR MARK COMPARED NON NULL"); |
1174 |
public void test0119_while() { |
6916 |
for (int i = 0; i < testData.length; i++) { |
1175 |
this.runNegativeTest( |
6917 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + |
1176 |
new String[] { |
6918 |
testSymbolicValueOf(testData[i][1])); |
1177 |
"X.java", |
6919 |
} |
1178 |
"public class X {\n" + |
6920 |
} |
1179 |
" boolean dummy;\n" + |
6921 |
if (printTablesAsCodes) { |
1180 |
" void foo() {\n" + |
6922 |
System.out.println("RECAP TABLE FOR MARK COMPARED NON NULL"); |
1181 |
" Object o = null;\n" + |
6923 |
for (int i = 0; i < testData.length; i++) { |
1182 |
" while (dummy || (o = new Object()).equals(o)) {\n" + |
6924 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
1183 |
" o.toString();\n" + |
6925 |
testCodedValueOf(testData[i][1])); |
1184 |
" }\n" + |
6926 |
} |
1185 |
" }\n" + |
|
|
1186 |
"}\n"}, |
1187 |
"" |
1188 |
); |
1189 |
} |
6927 |
} |
|
|
6928 |
assertTrue("nb of failures: " + failures, failures == 0); |
6929 |
} |
1190 |
|
6930 |
|
1191 |
// null analysis -- while |
6931 |
public void test2051_markAsComparedEqualToNull() { |
1192 |
public void test0120_while_nested() { |
6932 |
long [][][] testData = { |
1193 |
this.runNegativeTest( |
6933 |
{{0,0,0,0},{0,1,0,0}}, |
1194 |
new String[] { |
6934 |
{{0,0,0,1},{0,1,0,0}}, |
1195 |
"X.java", |
6935 |
{{0,0,1,0},{0,1,1,0}}, |
1196 |
"public class X {\n" + |
6936 |
{{0,0,1,1},{0,1,1,0}}, |
1197 |
" boolean dummy;\n" + |
6937 |
{{0,1,0,0},{0,1,0,0}}, |
1198 |
" void foo() {\n" + |
6938 |
{{0,1,0,1},{0,1,0,0}}, |
1199 |
" Object o = null;\n" + |
6939 |
{{0,1,1,0},{0,1,1,0}}, |
1200 |
" while (dummy) {\n" + |
6940 |
{{0,1,1,1},{0,1,1,0}}, |
1201 |
" while (o != null) {\n" + |
6941 |
{{1,0,0,0},{0,1,0,0}}, |
1202 |
" o.toString();\n" + |
6942 |
{{1,0,0,1},{0,1,0,0}}, |
1203 |
" }\n" + |
6943 |
{{1,0,1,0},{1,0,1,0}}, |
1204 |
" if (System.currentTimeMillis() > 10L) {\n" + |
6944 |
{{1,0,1,1},{0,1,0,0}}, |
1205 |
" o = new Object();\n" + |
6945 |
{{1,1,0,0},{0,1,0,0}}, |
1206 |
" }\n" + |
6946 |
{{1,1,0,1},{0,1,0,0}}, |
1207 |
" }\n" + |
6947 |
{{1,1,1,0},{0,1,1,0}}, |
1208 |
" }\n" + |
6948 |
{{1,1,1,1},{0,1,1,0}}, |
1209 |
"}\n"}, |
6949 |
}; |
1210 |
"" |
6950 |
int failures = 0; |
1211 |
); |
6951 |
LocalVariableBinding local = new TestLocalVariableBinding(0); |
|
|
6952 |
for (int i = 0; i < testData.length; i++) { |
6953 |
UnconditionalFlowInfoTestHarness |
6954 |
result = UnconditionalFlowInfoTestHarness. |
6955 |
testUnconditionalFlowInfo(testData[i][0]); |
6956 |
result.markAsComparedEqualToNull(local); |
6957 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
6958 |
testUnconditionalFlowInfo(testData[i][1])))) { |
6959 |
if (failures == 0) { |
6960 |
System.out.println("markAsComparedEqualToNull failures: "); |
6961 |
} |
6962 |
failures++; |
6963 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
6964 |
',' + result.testString() + |
6965 |
"}, // instead of: " + testStringValueOf(testData[i][1])); |
6966 |
} |
1212 |
} |
6967 |
} |
1213 |
|
6968 |
local = new TestLocalVariableBinding(64); |
1214 |
// null analysis -- while |
6969 |
for (int i = 0; i < testData.length; i++) { |
1215 |
// TODO (maxime) fix |
6970 |
UnconditionalFlowInfoTestHarness |
1216 |
public void _test0121_while_nested() { |
6971 |
result = UnconditionalFlowInfoTestHarness. |
1217 |
this.runNegativeTest( |
6972 |
testUnconditionalFlowInfo(testData[i][0], 64), |
1218 |
new String[] { |
6973 |
expected = UnconditionalFlowInfoTestHarness. |
1219 |
"X.java", |
6974 |
testUnconditionalFlowInfo(testData[i][1], 64); |
1220 |
"public class X {\n" + |
6975 |
result.markAsComparedEqualToNull(local); |
1221 |
" void foo() {\n" + |
6976 |
if (!(result.testEquals(expected))) { |
1222 |
" Object o = null,\n" + |
6977 |
if (failures == 0) { |
1223 |
" u = new Object(),\n" + |
6978 |
System.out.println("markAsComparedEqualToNull failures: "); |
1224 |
" v = new Object();\n" + |
6979 |
} |
1225 |
" while (o == null) {\n" + |
6980 |
failures++; |
1226 |
" if (v == null) {\n" + |
6981 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
1227 |
" o = new Object();\n" + |
6982 |
',' + result.testString() + |
1228 |
" };\n" + |
6983 |
"}, // (64) instead of: " + testStringValueOf(testData[i][1])); |
1229 |
" while (o == null) {\n" + |
6984 |
} |
1230 |
" if (u == null) {\n" + |
6985 |
if (testData[i][0][0] == 0 && |
1231 |
" v = null;\n" + |
6986 |
testData[i][0][1] == 0 && |
1232 |
" };\n" + |
6987 |
testData[i][0][2] == 0 && |
1233 |
" u = null;\n" + |
6988 |
testData[i][0][3] == 0) { |
1234 |
" }\n" + |
6989 |
result = UnconditionalFlowInfoTestHarness. |
1235 |
" }\n" + |
6990 |
testUnconditionalFlowInfo(testData[i][1]); |
1236 |
" }\n" + |
6991 |
result.markAsComparedEqualToNull(local); |
1237 |
"}\n"}, |
6992 |
if (!result.testEquals(expected, 64)) { |
1238 |
"" |
6993 |
if (failures == 0) { |
1239 |
); |
6994 |
System.out.println("markAsComparedEqualToNull failures: "); |
|
|
6995 |
} |
6996 |
failures++; |
6997 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
6998 |
',' + result.testString() + |
6999 |
"}, // (zero 64) instead of: " + testStringValueOf(testData[i][1])); |
7000 |
} |
7001 |
} |
7002 |
} |
7003 |
local = new TestLocalVariableBinding(128); |
7004 |
for (int i = 0; i < testData.length; i++) { |
7005 |
if (testData[i][0][0] == 0 && |
7006 |
testData[i][0][1] == 0 && |
7007 |
testData[i][0][2] == 0 && |
7008 |
testData[i][0][3] == 0) { |
7009 |
UnconditionalFlowInfoTestHarness |
7010 |
result = UnconditionalFlowInfoTestHarness. |
7011 |
testUnconditionalFlowInfo(testData[i][1], 64), |
7012 |
expected = UnconditionalFlowInfoTestHarness. |
7013 |
testUnconditionalFlowInfo(testData[i][1], 128); |
7014 |
result.markAsComparedEqualToNull(local); |
7015 |
if (!result.testEquals(expected, 128)) { |
7016 |
if (failures == 0) { |
7017 |
System.out.println("markAsComparedEqualToNull failures: "); |
7018 |
} |
7019 |
failures++; |
7020 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7021 |
',' + result.testString() + |
7022 |
"}, // (zero 128) instead of: " + testStringValueOf(testData[i][1])); |
7023 |
} |
7024 |
} |
7025 |
} |
7026 |
if (printTablesAsNames) { |
7027 |
System.out.println("RECAP TABLE FOR MARK COMPARED NULL"); |
7028 |
for (int i = 0; i < testData.length; i++) { |
7029 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + |
7030 |
testSymbolicValueOf(testData[i][1])); |
7031 |
} |
7032 |
} |
7033 |
if (printTablesAsCodes) { |
7034 |
System.out.println("RECAP TABLE FOR MARK COMPARED NULL"); |
7035 |
for (int i = 0; i < testData.length; i++) { |
7036 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
7037 |
testCodedValueOf(testData[i][1])); |
7038 |
} |
1240 |
} |
7039 |
} |
|
|
7040 |
assertTrue("nb of failures: " + failures, failures == 0); |
7041 |
} |
1241 |
|
7042 |
|
1242 |
// null analysis -- while |
7043 |
public void test2052_markAsDefinitelyNonNull() { |
1243 |
public void test0122_while_if_nested() { |
7044 |
long [][][] testData = { |
1244 |
this.runNegativeTest( |
7045 |
{{0,0,0,0},{1,0,0,1}}, |
1245 |
new String[] { |
7046 |
{{0,0,0,1},{1,0,0,1}}, |
1246 |
"X.java", |
7047 |
{{0,0,1,0},{1,0,0,1}}, |
1247 |
"public class X {\n" + |
7048 |
{{0,0,1,1},{1,0,0,1}}, |
1248 |
" boolean dummy, other;\n" + |
7049 |
{{0,1,0,0},{1,0,0,1}}, |
1249 |
" void foo() {\n" + |
7050 |
{{0,1,0,1},{1,0,0,1}}, |
1250 |
" Object o = null;\n" + |
7051 |
{{0,1,1,0},{1,0,0,1}}, |
1251 |
" while (dummy) {\n" + |
7052 |
{{0,1,1,1},{1,0,0,1}}, |
1252 |
" if (other) {\n" + |
7053 |
{{1,0,0,0},{1,0,0,1}}, |
1253 |
" o.toString();\n" + |
7054 |
{{1,0,0,1},{1,0,0,1}}, |
1254 |
" }\n" + |
7055 |
{{1,0,1,0},{1,0,0,1}}, |
1255 |
" o = new Object();\n" + |
7056 |
{{1,0,1,1},{1,0,0,1}}, |
1256 |
" }\n" + |
7057 |
{{1,1,0,0},{1,0,0,1}}, |
1257 |
" }\n" + |
7058 |
{{1,1,0,1},{1,0,0,1}}, |
1258 |
"}\n"}, |
7059 |
{{1,1,1,0},{1,0,0,1}}, |
1259 |
"" |
7060 |
{{1,1,1,1},{1,0,0,1}}, |
1260 |
); |
7061 |
}; |
|
|
7062 |
int failures = 0; |
7063 |
LocalVariableBinding local = new TestLocalVariableBinding(0); |
7064 |
for (int i = 0; i < testData.length; i++) { |
7065 |
UnconditionalFlowInfoTestHarness |
7066 |
result = UnconditionalFlowInfoTestHarness. |
7067 |
testUnconditionalFlowInfo(testData[i][0]); |
7068 |
result.markAsDefinitelyNonNull(local); |
7069 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
7070 |
testUnconditionalFlowInfo(testData[i][1])))) { |
7071 |
if (failures == 0) { |
7072 |
System.out.println("markAsDefinitelyNonNull failures: "); |
7073 |
} |
7074 |
failures++; |
7075 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7076 |
',' + result.testString() + |
7077 |
"}, // instead of: " + testStringValueOf(testData[i][1])); |
7078 |
} |
1261 |
} |
7079 |
} |
1262 |
|
7080 |
local = new TestLocalVariableBinding(64); |
1263 |
// null analysis -- while |
7081 |
for (int i = 0; i < testData.length; i++) { |
1264 |
public void test0123_while_unknown_field() { |
7082 |
UnconditionalFlowInfoTestHarness |
1265 |
this.runNegativeTest( |
7083 |
result = UnconditionalFlowInfoTestHarness. |
1266 |
new String[] { |
7084 |
testUnconditionalFlowInfo(testData[i][0], 64); |
1267 |
"X.java", |
7085 |
result.markAsDefinitelyNonNull(local); |
1268 |
"public class X {\n" + |
7086 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
1269 |
" Object o;\n" + |
7087 |
testUnconditionalFlowInfo(testData[i][1], 64)))) { |
1270 |
" void foo(boolean dummy) {\n" + |
7088 |
if (failures == 0) { |
1271 |
" while (dummy) {\n" + |
7089 |
System.out.println("markAsDefinitelyNonNull failures: "); |
1272 |
" o = null;\n" + |
7090 |
} |
1273 |
" }\n" + |
7091 |
failures++; |
1274 |
" o.toString();\n" + |
7092 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
1275 |
" }\n" + |
7093 |
',' + result.testString() + |
1276 |
"}\n"}, |
7094 |
"}, // (64) instead of: " + testStringValueOf(testData[i][1])); |
1277 |
"" |
7095 |
} |
1278 |
); |
|
|
1279 |
} |
7096 |
} |
1280 |
|
7097 |
if (printTablesAsNames) { |
1281 |
// null analysis -- while |
7098 |
System.out.println("RECAP TABLE FOR MARK DEFINITELY NON NULL"); |
1282 |
public void test0124_while_unknown_parameter() { |
7099 |
for (int i = 0; i < testData.length; i++) { |
1283 |
this.runNegativeTest( |
7100 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + |
1284 |
new String[] { |
7101 |
testSymbolicValueOf(testData[i][1])); |
1285 |
"X.java", |
7102 |
} |
1286 |
"public class X {\n" + |
7103 |
} |
1287 |
" boolean dummy;\n" + |
7104 |
if (printTablesAsCodes) { |
1288 |
" void foo(Object o) {\n" + |
7105 |
System.out.println("RECAP TABLE FOR MARK DEFINITELY NON NULL"); |
1289 |
" while (dummy) {\n" + |
7106 |
for (int i = 0; i < testData.length; i++) { |
1290 |
" o = null;\n" + |
7107 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
1291 |
" }\n" + |
7108 |
testCodedValueOf(testData[i][1])); |
1292 |
" o.toString();\n" + |
7109 |
} |
1293 |
" }\n" + |
|
|
1294 |
"}\n"}, |
1295 |
"" |
1296 |
); |
1297 |
} |
7110 |
} |
|
|
7111 |
assertTrue("nb of failures: " + failures, failures == 0); |
7112 |
} |
1298 |
|
7113 |
|
1299 |
// null analysis -- while |
7114 |
public void test2053_markAsDefinitelyNull() { |
1300 |
public void test0125_while_unknown_if_else() { |
7115 |
long [][][] testData = { |
1301 |
this.runNegativeTest( |
7116 |
{{0,0,0,0},{1,0,1,0}}, |
1302 |
new String[] { |
7117 |
{{0,0,0,1},{1,0,1,0}}, |
1303 |
"X.java", |
7118 |
{{0,0,1,0},{1,0,1,0}}, |
1304 |
"public class X {\n" + |
7119 |
{{0,0,1,1},{1,0,1,0}}, |
1305 |
" boolean dummy;\n" + |
7120 |
{{0,1,0,0},{1,0,1,0}}, |
1306 |
" void foo() {\n" + |
7121 |
{{0,1,0,1},{1,0,1,0}}, |
1307 |
" Object o = null;\n" + |
7122 |
{{0,1,1,0},{1,0,1,0}}, |
1308 |
" if (dummy) {\n" + |
7123 |
{{0,1,1,1},{1,0,1,0}}, |
1309 |
" o = new Object();\n" + |
7124 |
{{1,0,0,0},{1,0,1,0}}, |
1310 |
" }\n" + |
7125 |
{{1,0,0,1},{1,0,1,0}}, |
1311 |
" while (dummy) {\n" + |
7126 |
{{1,0,1,0},{1,0,1,0}}, |
1312 |
// limit of the analysis: we do not correlate if and while conditions |
7127 |
{{1,0,1,1},{1,0,1,0}}, |
1313 |
" if (o == null) {/* */}\n" + |
7128 |
{{1,1,0,0},{1,0,1,0}}, |
1314 |
" }\n" + |
7129 |
{{1,1,0,1},{1,0,1,0}}, |
1315 |
" }\n" + |
7130 |
{{1,1,1,0},{1,0,1,0}}, |
1316 |
"}\n"}, |
7131 |
{{1,1,1,1},{1,0,1,0}}, |
1317 |
"" |
7132 |
}; |
1318 |
); |
7133 |
int failures = 0; |
|
|
7134 |
LocalVariableBinding local = new TestLocalVariableBinding(0); |
7135 |
for (int i = 0; i < testData.length; i++) { |
7136 |
UnconditionalFlowInfoTestHarness |
7137 |
result = UnconditionalFlowInfoTestHarness. |
7138 |
testUnconditionalFlowInfo(testData[i][0]); |
7139 |
result.markAsDefinitelyNull(local); |
7140 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
7141 |
testUnconditionalFlowInfo(testData[i][1])))) { |
7142 |
if (failures == 0) { |
7143 |
System.out.println("markAsDefinitelyNull failures: "); |
7144 |
} |
7145 |
failures++; |
7146 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7147 |
',' + result.testString() + |
7148 |
"}, // instead of: " + testStringValueOf(testData[i][1])); |
7149 |
} |
7150 |
} |
7151 |
local = new TestLocalVariableBinding(64); |
7152 |
for (int i = 0; i < testData.length; i++) { |
7153 |
UnconditionalFlowInfoTestHarness |
7154 |
result = UnconditionalFlowInfoTestHarness. |
7155 |
testUnconditionalFlowInfo(testData[i][0], 64); |
7156 |
result.markAsDefinitelyNull(local); |
7157 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
7158 |
testUnconditionalFlowInfo(testData[i][1], 64)))) { |
7159 |
if (failures == 0) { |
7160 |
System.out.println("markAsDefinitelyNull failures: "); |
7161 |
} |
7162 |
failures++; |
7163 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7164 |
',' + result.testString() + |
7165 |
"}, // (64) instead of: " + testStringValueOf(testData[i][1])); |
7166 |
} |
7167 |
} |
7168 |
if (printTablesAsNames) { |
7169 |
System.out.println("RECAP TABLE FOR MARK DEFINITELY NULL"); |
7170 |
for (int i = 0; i < testData.length; i++) { |
7171 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + |
7172 |
testSymbolicValueOf(testData[i][1])); |
7173 |
} |
7174 |
} |
7175 |
if (printTablesAsCodes) { |
7176 |
System.out.println("RECAP TABLE FOR MARK DEFINITELY NULL"); |
7177 |
for (int i = 0; i < testData.length; i++) { |
7178 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
7179 |
testCodedValueOf(testData[i][1])); |
7180 |
} |
1319 |
} |
7181 |
} |
|
|
7182 |
assertTrue("nb of failures: " + failures, failures == 0); |
7183 |
} |
1320 |
|
7184 |
|
1321 |
// null analysis -- while |
7185 |
public void test2054_markAsDefinitelyUnknown() { |
1322 |
public void test0126_while() { |
7186 |
long [][][] testData = { |
1323 |
this.runNegativeTest( |
7187 |
{{0,0,0,0},{1,0,1,1}}, |
1324 |
new String[] { |
7188 |
{{0,0,0,1},{1,0,1,1}}, |
1325 |
"X.java", |
7189 |
{{0,0,1,0},{1,0,1,1}}, |
1326 |
"public class X {\n" + |
7190 |
{{0,0,1,1},{1,0,1,1}}, |
1327 |
" boolean dummy;\n" + |
7191 |
{{0,1,0,0},{1,0,1,1}}, |
1328 |
" void foo() {\n" + |
7192 |
{{0,1,0,1},{1,0,1,1}}, |
1329 |
" Object o = null;\n" + |
7193 |
{{0,1,1,0},{1,0,1,1}}, |
1330 |
" while (dummy) {\n" + |
7194 |
{{0,1,1,1},{1,0,1,1}}, |
1331 |
" o = new Object();\n" + |
7195 |
{{1,0,0,0},{1,0,1,1}}, |
1332 |
" }\n" + |
7196 |
{{1,0,0,1},{1,0,1,1}}, |
1333 |
" o.toString();\n" + |
7197 |
{{1,0,1,0},{1,0,1,1}}, |
1334 |
" }\n" + |
7198 |
{{1,0,1,1},{1,0,1,1}}, |
1335 |
"}\n"}, |
7199 |
{{1,1,0,0},{1,0,1,1}}, |
1336 |
"" |
7200 |
{{1,1,0,1},{1,0,1,1}}, |
1337 |
); |
7201 |
{{1,1,1,0},{1,0,1,1}}, |
|
|
7202 |
{{1,1,1,1},{1,0,1,1}}, |
7203 |
}; |
7204 |
int failures = 0; |
7205 |
LocalVariableBinding local = new TestLocalVariableBinding(0); |
7206 |
for (int i = 0; i < testData.length; i++) { |
7207 |
UnconditionalFlowInfoTestHarness |
7208 |
result = UnconditionalFlowInfoTestHarness. |
7209 |
testUnconditionalFlowInfo(testData[i][0]); |
7210 |
result.markAsDefinitelyUnknown(local); |
7211 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
7212 |
testUnconditionalFlowInfo(testData[i][1])))) { |
7213 |
if (failures == 0) { |
7214 |
System.out.println("markAsDefinitelyUnknown failures: "); |
7215 |
} |
7216 |
failures++; |
7217 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7218 |
',' + result.testString() + |
7219 |
"}, // instead of: " + testStringValueOf(testData[i][1])); |
7220 |
} |
1338 |
} |
7221 |
} |
1339 |
|
7222 |
local = new TestLocalVariableBinding(64); |
1340 |
// null analysis -- while |
7223 |
for (int i = 0; i < testData.length; i++) { |
1341 |
// TODO (maxime) fix |
7224 |
UnconditionalFlowInfoTestHarness |
1342 |
public void _test0127_while() { |
7225 |
result = UnconditionalFlowInfoTestHarness. |
1343 |
this.runNegativeTest( |
7226 |
testUnconditionalFlowInfo(testData[i][0], 64); |
1344 |
new String[] { |
7227 |
result.markAsDefinitelyUnknown(local); |
1345 |
"X.java", |
7228 |
if (!(result.testEquals(UnconditionalFlowInfoTestHarness. |
1346 |
"public class X {\n" + |
7229 |
testUnconditionalFlowInfo(testData[i][1], 64)))) { |
1347 |
" boolean dummy;\n" + |
7230 |
if (failures == 0) { |
1348 |
" void foo() {\n" + |
7231 |
System.out.println("markAsDefinitelyUnknown failures: "); |
1349 |
" Object o = null;\n" + |
7232 |
} |
1350 |
" while (dummy) { /* */ }\n" + // doesn't affect o |
7233 |
failures++; |
1351 |
" o.toString();\n" + |
7234 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
1352 |
" }\n" + |
7235 |
',' + result.testString() + |
1353 |
"}\n"}, |
7236 |
"}, // (64) instead of: " + testStringValueOf(testData[i][1])); |
1354 |
"----------\n" + |
7237 |
} |
1355 |
"1. WARNING in X.java (at line 6)\n" + |
|
|
1356 |
" o.toString();\n" + |
1357 |
" ^\n" + |
1358 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1359 |
"----------\n" |
1360 |
); |
1361 |
} |
7238 |
} |
1362 |
|
7239 |
if (printTablesAsNames) { |
1363 |
// null analysis -- while |
7240 |
System.out.println("RECAP TABLE FOR MARK DEFINITELY UNKNOWN"); |
1364 |
// origin AssignmentTest.testO22 |
7241 |
for (int i = 0; i < testData.length; i++) { |
1365 |
public void test0128_while_try() { |
7242 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " -> " + |
1366 |
this.runNegativeTest( |
7243 |
testSymbolicValueOf(testData[i][1])); |
1367 |
new String[] { |
7244 |
} |
1368 |
"X.java", |
7245 |
} |
1369 |
"public class X {\n" + |
7246 |
if (printTablesAsCodes) { |
1370 |
" boolean bool() { return true; }\n" + |
7247 |
System.out.println("RECAP TABLE FOR MARK DEFINITELY UNKNOWN"); |
1371 |
" void foo() {\n" + |
7248 |
for (int i = 0; i < testData.length; i++) { |
1372 |
" Object o = null;\n" + |
7249 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
1373 |
" while (bool()) {\n" + |
7250 |
testCodedValueOf(testData[i][1])); |
1374 |
" try {\n" + |
7251 |
} |
1375 |
" if (o == null) {\n" + |
|
|
1376 |
" o = new Object();\n" + |
1377 |
" }\n" + |
1378 |
" } finally { /* */ }\n" + |
1379 |
" }\n" + |
1380 |
" }\n" + |
1381 |
"}", |
1382 |
}, |
1383 |
""); |
1384 |
} |
7252 |
} |
|
|
7253 |
assertTrue("nb of failures: " + failures, failures == 0); |
7254 |
} |
1385 |
|
7255 |
|
1386 |
// null analysis -- try/finally |
7256 |
public void test2055_addInitializationsFrom() { |
1387 |
// TODO (maxime) fix |
7257 |
long [][][] testData = { |
1388 |
public void _test0150_try_finally() { |
7258 |
{{0,0,0,0},{0,0,0,0},{0,0,0,0}}, |
1389 |
this.runNegativeTest( |
7259 |
{{0,0,0,0},{0,0,0,1},{0,0,0,1}}, |
1390 |
new String[] { |
7260 |
{{0,0,0,0},{0,0,1,0},{0,0,1,0}}, |
1391 |
"X.java", |
7261 |
{{0,0,0,0},{0,0,1,1},{0,0,1,1}}, |
1392 |
"public class X {\n" + |
7262 |
{{0,0,0,0},{0,1,0,0},{0,1,0,0}}, |
1393 |
" Object m;\n" + |
7263 |
{{0,0,0,0},{0,1,1,0},{0,1,1,0}}, |
1394 |
" void foo() {\n" + |
7264 |
{{0,0,0,0},{1,0,0,1},{1,0,0,1}}, |
1395 |
" Object o = null;\n" + |
7265 |
{{0,0,0,0},{1,0,1,0},{1,0,1,0}}, |
1396 |
" try { /* */ }\n" + |
7266 |
{{0,0,0,0},{1,0,1,1},{1,0,1,1}}, |
1397 |
" finally {\n" + |
7267 |
{{0,0,0,0},{1,1,0,0},{1,1,0,0}}, |
1398 |
" o = m;\n" + |
7268 |
{{0,0,0,0},{1,1,0,1},{1,1,0,1}}, |
1399 |
" }\n" + |
7269 |
{{0,0,0,1},{0,0,0,0},{0,0,0,1}}, |
1400 |
" o.toString();\n" + |
7270 |
{{0,0,0,1},{0,0,0,1},{0,0,0,1}}, |
1401 |
" }\n" + |
7271 |
{{0,0,0,1},{0,0,1,0},{0,0,1,1}}, |
1402 |
"}\n"}, |
7272 |
{{0,0,0,1},{0,0,1,1},{0,0,1,1}}, |
1403 |
"" // because finally assigns to unknown value |
7273 |
{{0,0,0,1},{0,1,0,0},{0,1,0,0}}, |
1404 |
); |
7274 |
{{0,0,0,1},{0,1,1,0},{0,1,0,0}}, |
|
|
7275 |
{{0,0,0,1},{1,0,0,1},{1,0,0,1}}, |
7276 |
{{0,0,0,1},{1,0,1,0},{1,0,1,0}}, |
7277 |
{{0,0,0,1},{1,0,1,1},{1,0,1,1}}, |
7278 |
{{0,0,0,1},{1,1,0,0},{1,1,0,1}}, |
7279 |
{{0,0,0,1},{1,1,0,1},{1,1,0,1}}, |
7280 |
{{0,0,1,0},{0,0,0,0},{0,0,1,0}}, |
7281 |
{{0,0,1,0},{0,0,0,1},{0,0,1,1}}, |
7282 |
{{0,0,1,0},{0,0,1,0},{0,0,1,0}}, |
7283 |
{{0,0,1,0},{0,0,1,1},{0,0,1,1}}, |
7284 |
{{0,0,1,0},{0,1,0,0},{0,1,1,0}}, |
7285 |
{{0,0,1,0},{0,1,1,0},{0,1,1,0}}, |
7286 |
{{0,0,1,0},{1,0,0,1},{1,0,0,1}}, |
7287 |
{{0,0,1,0},{1,0,1,0},{1,0,1,0}}, |
7288 |
{{0,0,1,0},{1,0,1,1},{1,0,1,1}}, |
7289 |
{{0,0,1,0},{1,1,0,0},{1,1,0,0}}, |
7290 |
{{0,0,1,0},{1,1,0,1},{1,1,0,1}}, |
7291 |
{{0,0,1,1},{0,0,0,0},{0,0,1,1}}, |
7292 |
{{0,0,1,1},{0,0,0,1},{0,0,1,1}}, |
7293 |
{{0,0,1,1},{0,0,1,0},{0,0,1,1}}, |
7294 |
{{0,0,1,1},{0,0,1,1},{0,0,1,1}}, |
7295 |
{{0,0,1,1},{0,1,0,0},{0,1,1,0}}, |
7296 |
{{0,0,1,1},{0,1,1,0},{0,1,1,0}}, |
7297 |
{{0,0,1,1},{1,0,0,1},{1,0,0,1}}, |
7298 |
{{0,0,1,1},{1,0,1,0},{1,0,1,0}}, |
7299 |
{{0,0,1,1},{1,0,1,1},{1,0,1,1}}, |
7300 |
{{0,0,1,1},{1,1,0,0},{1,1,0,1}}, |
7301 |
{{0,0,1,1},{1,1,0,1},{1,1,0,1}}, |
7302 |
{{0,1,0,0},{0,0,0,0},{0,1,0,0}}, |
7303 |
{{0,1,0,0},{0,0,0,1},{0,0,0,1}}, |
7304 |
{{0,1,0,0},{0,0,1,0},{0,1,1,0}}, |
7305 |
{{0,1,0,0},{0,0,1,1},{0,0,1,1}}, |
7306 |
{{0,1,0,0},{0,1,0,0},{0,1,0,0}}, |
7307 |
{{0,1,0,0},{0,1,1,0},{0,1,1,0}}, |
7308 |
{{0,1,0,0},{1,0,0,1},{1,0,0,1}}, |
7309 |
{{0,1,0,0},{1,0,1,0},{1,0,1,0}}, |
7310 |
{{0,1,0,0},{1,0,1,1},{1,0,1,1}}, |
7311 |
{{0,1,0,0},{1,1,0,0},{1,1,0,0}}, |
7312 |
{{0,1,0,0},{1,1,0,1},{1,1,0,1}}, |
7313 |
{{0,1,1,0},{0,0,0,0},{0,1,1,0}}, |
7314 |
{{0,1,1,0},{0,0,0,1},{0,0,1,1}}, |
7315 |
{{0,1,1,0},{0,0,1,0},{0,1,1,0}}, |
7316 |
{{0,1,1,0},{0,0,1,1},{0,0,1,1}}, |
7317 |
{{0,1,1,0},{0,1,0,0},{0,1,1,0}}, |
7318 |
{{0,1,1,0},{0,1,1,0},{0,1,1,0}}, |
7319 |
{{0,1,1,0},{1,0,0,1},{1,0,0,1}}, |
7320 |
{{0,1,1,0},{1,0,1,0},{1,0,1,0}}, |
7321 |
{{0,1,1,0},{1,0,1,1},{1,0,1,1}}, |
7322 |
{{0,1,1,0},{1,1,0,0},{1,1,0,0}}, |
7323 |
{{0,1,1,0},{1,1,0,1},{1,1,0,1}}, |
7324 |
{{1,0,0,1},{0,0,0,0},{1,0,0,1}}, |
7325 |
{{1,0,0,1},{0,0,0,1},{1,0,0,1}}, |
7326 |
{{1,0,0,1},{0,0,1,0},{0,0,1,1}}, |
7327 |
{{1,0,0,1},{0,0,1,1},{0,0,1,1}}, |
7328 |
{{1,0,0,1},{0,1,0,0},{0,1,0,0}}, |
7329 |
{{1,0,0,1},{0,1,1,0},{0,1,1,0}}, |
7330 |
{{1,0,0,1},{1,0,0,1},{1,0,0,1}}, |
7331 |
{{1,0,0,1},{1,0,1,0},{1,0,1,0}}, |
7332 |
{{1,0,0,1},{1,0,1,1},{1,0,1,1}}, |
7333 |
{{1,0,0,1},{1,1,0,0},{1,1,0,1}}, |
7334 |
{{1,0,0,1},{1,1,0,1},{1,1,0,1}}, |
7335 |
{{1,0,1,0},{0,0,0,0},{1,0,1,0}}, |
7336 |
{{1,0,1,0},{0,0,0,1},{0,0,1,1}}, |
7337 |
{{1,0,1,0},{0,0,1,0},{1,0,1,0}}, |
7338 |
{{1,0,1,0},{0,0,1,1},{0,0,1,1}}, |
7339 |
{{1,0,1,0},{0,1,0,0},{1,0,1,0}}, |
7340 |
{{1,0,1,0},{0,1,1,0},{1,0,1,0}}, |
7341 |
{{1,0,1,0},{1,0,0,1},{1,0,0,1}}, |
7342 |
{{1,0,1,0},{1,0,1,0},{1,0,1,0}}, |
7343 |
{{1,0,1,0},{1,0,1,1},{1,0,1,1}}, |
7344 |
{{1,0,1,0},{1,1,0,0},{1,1,0,0}}, |
7345 |
{{1,0,1,0},{1,1,0,1},{1,1,0,1}}, |
7346 |
{{1,0,1,1},{0,0,0,0},{1,0,1,1}}, |
7347 |
{{1,0,1,1},{0,0,0,1},{1,0,1,1}}, |
7348 |
{{1,0,1,1},{0,0,1,0},{0,0,1,1}}, |
7349 |
{{1,0,1,1},{0,0,1,1},{0,0,1,1}}, |
7350 |
{{1,0,1,1},{0,1,0,0},{0,1,0,0}}, |
7351 |
{{1,0,1,1},{0,1,1,0},{0,1,1,0}}, |
7352 |
{{1,0,1,1},{1,0,0,1},{1,0,0,1}}, |
7353 |
{{1,0,1,1},{1,0,1,0},{1,0,1,0}}, |
7354 |
{{1,0,1,1},{1,0,1,1},{1,0,1,1}}, |
7355 |
{{1,0,1,1},{1,1,0,0},{1,1,0,1}}, |
7356 |
{{1,0,1,1},{1,1,0,1},{1,1,0,1}}, |
7357 |
{{1,1,0,0},{0,0,0,0},{1,1,0,0}}, |
7358 |
{{1,1,0,0},{0,0,0,1},{1,1,0,1}}, |
7359 |
{{1,1,0,0},{0,0,1,0},{0,0,1,0}}, |
7360 |
{{1,1,0,0},{0,0,1,1},{0,0,1,1}}, |
7361 |
{{1,1,0,0},{0,1,0,0},{0,1,0,0}}, |
7362 |
{{1,1,0,0},{0,1,1,0},{0,1,1,0}}, |
7363 |
{{1,1,0,0},{1,0,0,1},{1,0,0,1}}, |
7364 |
{{1,1,0,0},{1,0,1,0},{1,0,1,0}}, |
7365 |
{{1,1,0,0},{1,0,1,1},{1,0,1,1}}, |
7366 |
{{1,1,0,0},{1,1,0,0},{1,1,0,0}}, |
7367 |
{{1,1,0,0},{1,1,0,1},{1,1,0,1}}, |
7368 |
{{1,1,0,1},{0,0,0,0},{1,1,0,1}}, |
7369 |
{{1,1,0,1},{0,0,0,1},{0,0,0,1}}, |
7370 |
{{1,1,0,1},{0,0,1,0},{0,0,1,1}}, |
7371 |
{{1,1,0,1},{0,0,1,1},{0,0,1,1}}, |
7372 |
{{1,1,0,1},{0,1,0,0},{0,1,0,0}}, |
7373 |
{{1,1,0,1},{0,1,1,0},{0,1,1,0}}, |
7374 |
{{1,1,0,1},{1,0,0,1},{1,0,0,1}}, |
7375 |
{{1,1,0,1},{1,0,1,0},{1,0,1,0}}, |
7376 |
{{1,1,0,1},{1,0,1,1},{1,0,1,1}}, |
7377 |
{{1,1,0,1},{1,1,0,0},{1,1,0,1}}, |
7378 |
{{1,1,0,1},{1,1,0,1},{1,1,0,1}}, |
7379 |
}; |
7380 |
int failures = 0; |
7381 |
long start; |
7382 |
if (combinationTestsloopsNb > 1) { |
7383 |
start = System.currentTimeMillis(); |
7384 |
} |
7385 |
String header = "addInitializationsFrom failures: "; //$NON-NLS-1$ |
7386 |
for (int l = 0; l < combinationTestsloopsNb ; l++) { |
7387 |
for (int i = 0; i < testData.length; i++) { |
7388 |
UnconditionalFlowInfoTestHarness result; |
7389 |
if (!(result = (UnconditionalFlowInfoTestHarness)( |
7390 |
UnconditionalFlowInfoTestHarness. |
7391 |
testUnconditionalFlowInfo(testData[i][0])). |
7392 |
addInitializationsFrom( |
7393 |
UnconditionalFlowInfoTestHarness. |
7394 |
testUnconditionalFlowInfo(testData[i][1]))). |
7395 |
testEquals(UnconditionalFlowInfoTestHarness. |
7396 |
testUnconditionalFlowInfo(testData[i][2]))) { |
7397 |
if (failures == 0) { |
7398 |
System.out.println(header); |
7399 |
} |
7400 |
failures++; |
7401 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7402 |
',' + testStringValueOf(testData[i][1]) + |
7403 |
',' + result.testString() + |
7404 |
"}, // instead of: " + testStringValueOf(testData[i][2])); |
7405 |
} |
7406 |
} |
1405 |
} |
7407 |
} |
1406 |
|
7408 |
if (combinationTestsloopsNb > 1) { |
1407 |
// null analysis -- try/finally |
7409 |
System.out.println("addInitial...\t\t" + combinationTestsloopsNb + "\t" + |
1408 |
public void test0151_try_finally() { |
7410 |
(System.currentTimeMillis() - start)); |
1409 |
this.runNegativeTest( |
7411 |
} |
1410 |
new String[] { |
7412 |
// PREMATURE optimize test (extraneous allocations and copies) |
1411 |
"X.java", |
7413 |
// PREMATURE optimize test (extraneous iterations - undup) |
1412 |
"public class X {\n" + |
7414 |
UnconditionalFlowInfoTestHarness |
1413 |
" void foo() {\n" + |
7415 |
zero = UnconditionalFlowInfoTestHarness. |
1414 |
" Object o = new Object();\n" + |
7416 |
testUnconditionalFlowInfo(new long[] {0,0,0,0}), |
1415 |
" try { /* */ }\n" + |
7417 |
left0, left1, right1, left2, right2, |
1416 |
" finally {\n" + |
7418 |
expected0, expected1, expected2, result; |
1417 |
" o = null;\n" + |
7419 |
for (int i = 0; i < testData.length; i++) { |
1418 |
" }\n" + |
7420 |
left0 = UnconditionalFlowInfoTestHarness. |
1419 |
" o.toString();\n" + |
7421 |
testUnconditionalFlowInfo(testData[i][0]); |
1420 |
" }\n" + |
7422 |
left1 = UnconditionalFlowInfoTestHarness. |
1421 |
"}\n"}, |
7423 |
testUnconditionalFlowInfo(testData[i][0], 64); |
1422 |
"----------\n" + |
7424 |
left2 = UnconditionalFlowInfoTestHarness. |
1423 |
"1. WARNING in X.java (at line 8)\n" + |
7425 |
testUnconditionalFlowInfo(testData[i][0], 128); |
1424 |
" o.toString();\n" + |
7426 |
right1 = UnconditionalFlowInfoTestHarness. |
1425 |
" ^\n" + |
7427 |
testUnconditionalFlowInfo(testData[i][1], 64); |
1426 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
7428 |
right2 = UnconditionalFlowInfoTestHarness. |
1427 |
"----------\n" // because finally assigns to null |
7429 |
testUnconditionalFlowInfo(testData[i][1], 128); |
1428 |
); |
7430 |
expected0 = UnconditionalFlowInfoTestHarness. |
|
|
7431 |
testUnconditionalFlowInfo(testData[i][2]); |
7432 |
expected1 = UnconditionalFlowInfoTestHarness. |
7433 |
testUnconditionalFlowInfo(testData[i][2], 64); |
7434 |
expected2 = UnconditionalFlowInfoTestHarness. |
7435 |
testUnconditionalFlowInfo(testData[i][2], 128); |
7436 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7437 |
left1.copy().addInitializationsFrom(right1)). |
7438 |
testEquals(expected1)) { |
7439 |
if (failures == 0) { |
7440 |
System.out.println(header); |
7441 |
} |
7442 |
failures++; |
7443 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7444 |
',' + testStringValueOf(testData[i][1]) + |
7445 |
',' + result.testString() + |
7446 |
"}, // (64, 64) - instead of: " + testStringValueOf(testData[i][2])); |
7447 |
} |
7448 |
if ((testData[i][0][0] | testData[i][0][1] | |
7449 |
testData[i][0][2] | testData[i][0][3]) == 0) { |
7450 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7451 |
zero.copy().addInitializationsFrom(right1)). |
7452 |
testEquals(expected1)) { |
7453 |
if (failures == 0) { |
7454 |
System.out.println(header); |
7455 |
} |
7456 |
failures++; |
7457 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7458 |
',' + testStringValueOf(testData[i][1]) + |
7459 |
',' + result.testString() + |
7460 |
"}, // (zero, 64) - instead of: " + testStringValueOf(testData[i][2])); |
7461 |
} |
7462 |
if (!(result = (UnconditionalFlowInfoTestHarness) right2.copy(). |
7463 |
addInitializationsFrom(right1)). |
7464 |
testEquals(expected1, 64)) { |
7465 |
if (failures == 0) { |
7466 |
System.out.println(header); |
7467 |
} |
7468 |
failures++; |
7469 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7470 |
',' + testStringValueOf(testData[i][1]) + |
7471 |
',' + result.testString() + |
7472 |
"}, // (zero 128, 64) - instead of: " + testStringValueOf(testData[i][2])); |
7473 |
} |
7474 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7475 |
zero.copy().addInitializationsFrom(right2)). |
7476 |
testEquals(expected2, 128)) { |
7477 |
if (failures == 0) { |
7478 |
System.out.println(header); |
7479 |
} |
7480 |
failures++; |
7481 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7482 |
',' + testStringValueOf(testData[i][1]) + |
7483 |
',' + result.testString(128) + |
7484 |
"}, // (zero, 128) - instead of: " + testStringValueOf(testData[i][2])); |
7485 |
} |
7486 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7487 |
right1.copy().addInitializationsFrom(right2)). |
7488 |
testEquals(expected2, 128)) { |
7489 |
if (failures == 0) { |
7490 |
System.out.println(header); |
7491 |
} |
7492 |
failures++; |
7493 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7494 |
',' + testStringValueOf(testData[i][1]) + |
7495 |
',' + result.testString(128) + |
7496 |
"}, // (zero 64, 128) - instead of: " + testStringValueOf(testData[i][2])); |
7497 |
} |
7498 |
} |
7499 |
if ((testData[i][1][0] | testData[i][1][1] | |
7500 |
testData[i][1][2] | testData[i][1][3]) == 0) { |
7501 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7502 |
left0.copy().addInitializationsFrom(left2)). |
7503 |
testEquals(expected0, 0)) { |
7504 |
if (failures == 0) { |
7505 |
System.out.println(header); |
7506 |
} |
7507 |
failures++; |
7508 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7509 |
',' + testStringValueOf(testData[i][1]) + |
7510 |
',' + result.testString() + |
7511 |
"}, // (1, zero 128) - instead of: " + testStringValueOf(testData[i][2])); |
7512 |
} |
7513 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7514 |
left1.copy().addInitializationsFrom(zero)). |
7515 |
testEquals(expected1)) { |
7516 |
if (failures == 0) { |
7517 |
System.out.println(header); |
7518 |
} |
7519 |
failures++; |
7520 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7521 |
',' + testStringValueOf(testData[i][1]) + |
7522 |
',' + result.testString() + |
7523 |
"}, // (64, zero) - instead of: " + testStringValueOf(testData[i][2])); |
7524 |
} |
7525 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7526 |
left1.copy().addInitializationsFrom(left2)). |
7527 |
testEquals(expected1, 64)) { |
7528 |
if (failures == 0) { |
7529 |
System.out.println(header); |
7530 |
} |
7531 |
failures++; |
7532 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7533 |
',' + testStringValueOf(testData[i][1]) + |
7534 |
',' + result.testString() + |
7535 |
"}, // (64, zero 128) - instead of: " + testStringValueOf(testData[i][2])); |
7536 |
} |
7537 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7538 |
left2.copy().addInitializationsFrom(zero)). |
7539 |
testEquals(expected2, 128)) { |
7540 |
if (failures == 0) { |
7541 |
System.out.println(header); |
7542 |
} |
7543 |
failures++; |
7544 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7545 |
',' + testStringValueOf(testData[i][1]) + |
7546 |
',' + result.testString() + |
7547 |
"}, // (128, zero) - instead of: " + testStringValueOf(testData[i][2])); |
7548 |
} |
7549 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7550 |
left2.addInitializationsFrom(left1)). |
7551 |
testEquals(expected2, 128)) { |
7552 |
if (failures == 0) { |
7553 |
System.out.println(header); |
7554 |
} |
7555 |
failures++; |
7556 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7557 |
',' + testStringValueOf(testData[i][1]) + |
7558 |
',' + result.testString() + |
7559 |
"}, // (128, zero 64) - instead of: " + testStringValueOf(testData[i][2])); |
7560 |
} |
7561 |
} |
1429 |
} |
7562 |
} |
1430 |
|
7563 |
if (printTablesAsNames) { |
1431 |
// null analysis -- try/finally |
7564 |
System.out.println("RECAP TABLE FOR ADD"); |
1432 |
public void test0152_try_finally() { |
7565 |
for (int i = 0; i < testData.length; i++) { |
1433 |
this.runNegativeTest( |
7566 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " + " + |
1434 |
new String[] { |
7567 |
testSymbolicValueOf(testData[i][1]) + " -> " + |
1435 |
"X.java", |
7568 |
testSymbolicValueOf(testData[i][2])); |
1436 |
"public class X {\n" + |
7569 |
} |
1437 |
" void foo() {\n" + |
7570 |
} |
1438 |
" Object o = null;\n" + |
7571 |
if (printTablesAsCodes) { |
1439 |
" try {\n" + |
7572 |
System.out.println("RECAP TABLE FOR ADD"); |
1440 |
" System.out.println();\n" + // might throw a runtime exception |
7573 |
for (int i = 0; i < testData.length; i++) { |
1441 |
" o = new Object();\n" + |
7574 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
1442 |
" }\n" + |
7575 |
testCodedValueOf(testData[i][1]) + " " + |
1443 |
" finally { /* */ }\n" + |
7576 |
testCodedValueOf(testData[i][2])); |
1444 |
" o.toString();\n" + |
7577 |
} |
1445 |
// still OK because in case of exception this code is |
|
|
1446 |
// not reached |
1447 |
" }\n" + |
1448 |
"}\n"}, |
1449 |
"" |
1450 |
); |
1451 |
} |
7578 |
} |
|
|
7579 |
if (printTruthMaps) { |
7580 |
for (int i = 0; i < 4; i++) { |
7581 |
System.out.println("======================================================"); |
7582 |
System.out.println("Truth map for addInitializationsFrom null bit " + (i + 1)); |
7583 |
System.out.println(); |
7584 |
printTruthMap(testData, i); |
7585 |
} |
7586 |
} |
7587 |
assertTrue("nb of failures: " + failures, failures == 0); |
7588 |
} |
1452 |
|
7589 |
|
1453 |
// null analysis -- try/finally |
7590 |
public void test2056_addPotentialInitializationsFrom() { |
1454 |
public void test0153_try_finally() { |
7591 |
long [][][] testData = { |
1455 |
this.runNegativeTest( |
7592 |
{{0,0,0,0},{0,0,0,0},{0,0,0,0}}, |
1456 |
new String[] { |
7593 |
{{0,0,0,0},{0,0,0,1},{0,0,0,1}}, |
1457 |
"X.java", |
7594 |
{{0,0,0,0},{0,0,1,0},{0,0,1,0}}, |
1458 |
"public class X {\n" + |
7595 |
{{0,0,0,0},{0,0,1,1},{0,0,1,1}}, |
1459 |
" void foo(X x) {\n" + |
7596 |
{{0,0,0,0},{0,1,0,0},{0,0,0,0}}, |
1460 |
" x = null;\n" + |
7597 |
{{0,0,0,0},{0,1,1,0},{0,0,1,0}}, |
1461 |
" try {\n" + |
7598 |
{{0,0,0,0},{1,0,0,1},{0,0,0,1}}, |
1462 |
" x = null;\n" + // complain, already null |
7599 |
{{0,0,0,0},{1,0,1,0},{0,0,1,0}}, |
1463 |
" } finally { /* */ }\n" + |
7600 |
{{0,0,0,0},{1,0,1,1},{0,0,0,1}}, |
1464 |
" }\n" + |
7601 |
{{0,0,0,0},{1,1,0,0},{0,0,0,0}}, |
1465 |
"}\n", |
7602 |
{{0,0,0,0},{1,1,0,1},{0,0,0,1}}, |
1466 |
}, |
7603 |
{{0,0,0,1},{0,0,0,0},{0,0,0,1}}, |
1467 |
"----------\n" + |
7604 |
{{0,0,0,1},{0,0,0,1},{0,0,0,1}}, |
1468 |
"1. WARNING in X.java (at line 5)\n" + |
7605 |
{{0,0,0,1},{0,0,1,0},{0,0,1,1}}, |
1469 |
" x = null;\n" + |
7606 |
{{0,0,0,1},{0,0,1,1},{0,0,1,1}}, |
1470 |
" ^\n" + |
7607 |
{{0,0,0,1},{0,1,0,0},{0,0,0,1}}, |
1471 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
7608 |
{{0,0,0,1},{0,1,1,0},{0,0,1,1}}, |
1472 |
"----------\n"); |
7609 |
{{0,0,0,1},{1,0,0,1},{0,0,0,1}}, |
|
|
7610 |
{{0,0,0,1},{1,0,1,0},{0,0,1,1}}, |
7611 |
{{0,0,0,1},{1,0,1,1},{0,0,0,1}}, |
7612 |
{{0,0,0,1},{1,1,0,0},{0,0,0,1}}, |
7613 |
{{0,0,0,1},{1,1,0,1},{0,0,0,1}}, |
7614 |
{{0,0,1,0},{0,0,0,0},{0,0,1,0}}, |
7615 |
{{0,0,1,0},{0,0,0,1},{0,0,1,1}}, |
7616 |
{{0,0,1,0},{0,0,1,0},{0,0,1,0}}, |
7617 |
{{0,0,1,0},{0,0,1,1},{0,0,1,1}}, |
7618 |
{{0,0,1,0},{0,1,0,0},{0,0,1,0}}, |
7619 |
{{0,0,1,0},{0,1,1,0},{0,0,1,0}}, |
7620 |
{{0,0,1,0},{1,0,0,1},{0,0,1,1}}, |
7621 |
{{0,0,1,0},{1,0,1,0},{0,0,1,0}}, |
7622 |
{{0,0,1,0},{1,0,1,1},{0,0,1,1}}, |
7623 |
{{0,0,1,0},{1,1,0,0},{0,0,1,0}}, |
7624 |
{{0,0,1,0},{1,1,0,1},{0,0,1,1}}, |
7625 |
{{0,0,1,1},{0,0,0,0},{0,0,1,1}}, |
7626 |
{{0,0,1,1},{0,0,0,1},{0,0,1,1}}, |
7627 |
{{0,0,1,1},{0,0,1,0},{0,0,1,1}}, |
7628 |
{{0,0,1,1},{0,0,1,1},{0,0,1,1}}, |
7629 |
{{0,0,1,1},{0,1,0,0},{0,0,1,1}}, |
7630 |
{{0,0,1,1},{0,1,1,0},{0,0,1,1}}, |
7631 |
{{0,0,1,1},{1,0,0,1},{0,0,1,1}}, |
7632 |
{{0,0,1,1},{1,0,1,0},{0,0,1,1}}, |
7633 |
{{0,0,1,1},{1,0,1,1},{0,0,1,1}}, |
7634 |
{{0,0,1,1},{1,1,0,0},{0,0,1,1}}, |
7635 |
{{0,0,1,1},{1,1,0,1},{0,0,1,1}}, |
7636 |
{{0,1,0,0},{0,0,0,0},{0,1,0,0}}, |
7637 |
{{0,1,0,0},{0,0,0,1},{0,0,0,1}}, |
7638 |
{{0,1,0,0},{0,0,1,0},{0,1,1,0}}, |
7639 |
{{0,1,0,0},{0,0,1,1},{0,0,1,1}}, |
7640 |
{{0,1,0,0},{0,1,0,0},{0,1,0,0}}, |
7641 |
{{0,1,0,0},{0,1,1,0},{0,1,1,0}}, |
7642 |
{{0,1,0,0},{1,0,0,1},{0,0,0,1}}, |
7643 |
{{0,1,0,0},{1,0,1,0},{0,1,1,0}}, |
7644 |
{{0,1,0,0},{1,0,1,1},{0,0,0,1}}, |
7645 |
{{0,1,0,0},{1,1,0,0},{0,1,0,0}}, |
7646 |
{{0,1,0,0},{1,1,0,1},{0,0,0,1}}, |
7647 |
{{0,1,1,0},{0,0,0,0},{0,1,1,0}}, |
7648 |
{{0,1,1,0},{0,0,0,1},{0,0,1,1}}, |
7649 |
{{0,1,1,0},{0,0,1,0},{0,1,1,0}}, |
7650 |
{{0,1,1,0},{0,0,1,1},{0,0,1,1}}, |
7651 |
{{0,1,1,0},{0,1,0,0},{0,1,1,0}}, |
7652 |
{{0,1,1,0},{0,1,1,0},{0,1,1,0}}, |
7653 |
{{0,1,1,0},{1,0,0,1},{0,0,1,1}}, |
7654 |
{{0,1,1,0},{1,0,1,0},{0,1,1,0}}, |
7655 |
{{0,1,1,0},{1,0,1,1},{0,0,1,1}}, |
7656 |
{{0,1,1,0},{1,1,0,0},{0,1,1,0}}, |
7657 |
{{0,1,1,0},{1,1,0,1},{0,0,1,1}}, |
7658 |
{{1,0,0,1},{0,0,0,0},{1,0,0,1}}, |
7659 |
{{1,0,0,1},{0,0,0,1},{1,0,1,1}}, |
7660 |
{{1,0,0,1},{0,0,1,0},{0,0,1,1}}, |
7661 |
{{1,0,0,1},{0,0,1,1},{0,0,1,1}}, |
7662 |
{{1,0,0,1},{0,1,0,0},{1,0,0,1}}, |
7663 |
{{1,0,0,1},{0,1,1,0},{0,0,1,1}}, |
7664 |
{{1,0,0,1},{1,0,0,1},{1,0,0,1}}, |
7665 |
{{1,0,0,1},{1,0,1,0},{0,0,1,1}}, |
7666 |
{{1,0,0,1},{1,0,1,1},{1,0,1,1}}, |
7667 |
{{1,0,0,1},{1,1,0,0},{1,0,0,1}}, |
7668 |
{{1,0,0,1},{1,1,0,1},{1,0,0,1}}, |
7669 |
{{1,0,1,0},{0,0,0,0},{1,0,1,0}}, |
7670 |
{{1,0,1,0},{0,0,0,1},{0,0,1,1}}, |
7671 |
{{1,0,1,0},{0,0,1,0},{1,0,1,0}}, |
7672 |
{{1,0,1,0},{0,0,1,1},{0,0,1,1}}, |
7673 |
{{1,0,1,0},{0,1,0,0},{1,0,1,0}}, |
7674 |
{{1,0,1,0},{0,1,1,0},{1,0,1,0}}, |
7675 |
{{1,0,1,0},{1,0,0,1},{0,0,1,1}}, |
7676 |
{{1,0,1,0},{1,0,1,0},{1,0,1,0}}, |
7677 |
{{1,0,1,0},{1,0,1,1},{0,0,1,1}}, |
7678 |
{{1,0,1,0},{1,1,0,0},{1,0,1,0}}, |
7679 |
{{1,0,1,0},{1,1,0,1},{0,0,1,1}}, |
7680 |
{{1,0,1,1},{0,0,0,0},{1,0,1,1}}, |
7681 |
{{1,0,1,1},{0,0,0,1},{1,0,1,1}}, |
7682 |
{{1,0,1,1},{0,0,1,0},{0,0,1,1}}, |
7683 |
{{1,0,1,1},{0,0,1,1},{0,0,1,1}}, |
7684 |
{{1,0,1,1},{0,1,0,0},{1,0,1,1}}, |
7685 |
{{1,0,1,1},{0,1,1,0},{0,0,1,1}}, |
7686 |
{{1,0,1,1},{1,0,0,1},{1,0,1,1}}, |
7687 |
{{1,0,1,1},{1,0,1,0},{0,0,1,1}}, |
7688 |
{{1,0,1,1},{1,0,1,1},{1,0,1,1}}, |
7689 |
{{1,0,1,1},{1,1,0,0},{1,0,1,1}}, |
7690 |
{{1,0,1,1},{1,1,0,1},{1,0,1,1}}, |
7691 |
{{1,1,0,0},{0,0,0,0},{1,1,0,0}}, |
7692 |
{{1,1,0,0},{0,0,0,1},{0,0,0,1}}, |
7693 |
{{1,1,0,0},{0,0,1,0},{0,0,1,0}}, |
7694 |
{{1,1,0,0},{0,0,1,1},{0,0,1,1}}, |
7695 |
{{1,1,0,0},{0,1,0,0},{1,1,0,0}}, |
7696 |
{{1,1,0,0},{0,1,1,0},{0,0,1,0}}, |
7697 |
{{1,1,0,0},{1,0,0,1},{0,0,0,1}}, |
7698 |
{{1,1,0,0},{1,0,1,0},{0,0,1,0}}, |
7699 |
{{1,1,0,0},{1,0,1,1},{0,0,0,1}}, |
7700 |
{{1,1,0,0},{1,1,0,0},{1,1,0,0}}, |
7701 |
{{1,1,0,0},{1,1,0,1},{1,1,0,1}}, |
7702 |
{{1,1,0,1},{0,0,0,0},{1,1,0,1}}, |
7703 |
{{1,1,0,1},{0,0,0,1},{0,0,0,1}}, |
7704 |
{{1,1,0,1},{0,0,1,0},{0,0,1,1}}, |
7705 |
{{1,1,0,1},{0,0,1,1},{0,0,1,1}}, |
7706 |
{{1,1,0,1},{0,1,0,0},{1,1,0,1}}, |
7707 |
{{1,1,0,1},{0,1,1,0},{0,0,1,1}}, |
7708 |
{{1,1,0,1},{1,0,0,1},{0,0,0,1}}, |
7709 |
{{1,1,0,1},{1,0,1,0},{0,0,1,1}}, |
7710 |
{{1,1,0,1},{1,0,1,1},{0,0,0,1}}, |
7711 |
{{1,1,0,1},{1,1,0,0},{1,1,0,1}}, |
7712 |
{{1,1,0,1},{1,1,0,1},{1,1,0,1}}, |
7713 |
}; |
7714 |
int failures = 0; |
7715 |
long start; |
7716 |
if (combinationTestsloopsNb > 1) { |
7717 |
start = System.currentTimeMillis(); |
7718 |
} |
7719 |
String header = "addPotentialInitializationsFrom failures: "; //$NON-NLS-1$ |
7720 |
for (int l = 0; l < combinationTestsloopsNb ; l++) { |
7721 |
for (int i = 0; i < testData.length; i++) { |
7722 |
UnconditionalFlowInfoTestHarness result; |
7723 |
if (!(result = (UnconditionalFlowInfoTestHarness)( |
7724 |
UnconditionalFlowInfoTestHarness. |
7725 |
testUnconditionalFlowInfo(testData[i][0])). |
7726 |
addPotentialInitializationsFrom( |
7727 |
UnconditionalFlowInfoTestHarness. |
7728 |
testUnconditionalFlowInfo(testData[i][1]))). |
7729 |
testEquals(UnconditionalFlowInfoTestHarness. |
7730 |
testUnconditionalFlowInfo(testData[i][2]))) { |
7731 |
if (failures == 0) { |
7732 |
System.out.println(header); |
7733 |
} |
7734 |
failures++; |
7735 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7736 |
',' + testStringValueOf(testData[i][1]) + |
7737 |
',' + result.testString() + |
7738 |
"}, // instead of: " + testStringValueOf(testData[i][2])); |
7739 |
} |
7740 |
if (combinationTestsloopsNb < 2 && |
7741 |
!(result = (UnconditionalFlowInfoTestHarness)( |
7742 |
UnconditionalFlowInfoTestHarness. |
7743 |
testUnconditionalFlowInfo(testData[i][0])). |
7744 |
addPotentialNullInfoFrom( |
7745 |
UnconditionalFlowInfoTestHarness. |
7746 |
testUnconditionalFlowInfo(testData[i][1], 128))). |
7747 |
testEquals(UnconditionalFlowInfoTestHarness. |
7748 |
testUnconditionalFlowInfo(testData[14][0], 65), 64)) { |
7749 |
if (failures == 0) { |
7750 |
System.out.println(header); |
7751 |
} |
7752 |
failures++; |
7753 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7754 |
',' + testStringValueOf(testData[i][1]) + |
7755 |
',' + result.testString(64) + |
7756 |
"}, // bit 64 only, instead of: {0,0,0,0}"); |
7757 |
} |
7758 |
} |
1473 |
} |
7759 |
} |
1474 |
|
7760 |
if (combinationTestsloopsNb > 1) { |
1475 |
// null analysis -- try/finally |
7761 |
System.out.println("addPotential...\t" + combinationTestsloopsNb + "\t" + |
1476 |
public void test0154_try_finally() { |
7762 |
(System.currentTimeMillis() - start)); |
1477 |
this.runNegativeTest( |
7763 |
} |
1478 |
new String[] { |
7764 |
UnconditionalFlowInfoTestHarness |
1479 |
"X.java", |
7765 |
zero = UnconditionalFlowInfoTestHarness. |
1480 |
"public class X {\n" + |
7766 |
testUnconditionalFlowInfo(new long[] {0,0,0,0}), |
1481 |
" void foo(X x) {\n" + |
7767 |
left0, left1, right1, left2, right2, |
1482 |
" x = null;\n" + |
7768 |
expected0, expected1, expected2, result; |
1483 |
" try {\n" + |
7769 |
for (int i = 0; i < testData.length; i++) { |
1484 |
" x = null;\n" + |
7770 |
left0 = UnconditionalFlowInfoTestHarness. |
1485 |
" } finally {\n" + |
7771 |
testUnconditionalFlowInfo(testData[i][0]); |
1486 |
" if (x != null) { /* */ }\n" + // complain, null in both paths |
7772 |
left1 = UnconditionalFlowInfoTestHarness. |
1487 |
" }\n" + |
7773 |
testUnconditionalFlowInfo(testData[i][0], 64); |
1488 |
" }\n" + |
7774 |
left2 = UnconditionalFlowInfoTestHarness. |
1489 |
"}\n", |
7775 |
testUnconditionalFlowInfo(testData[i][0], 128); |
1490 |
}, |
7776 |
right1 = UnconditionalFlowInfoTestHarness. |
1491 |
"----------\n" + |
7777 |
testUnconditionalFlowInfo(testData[i][1], 64); |
1492 |
"1. WARNING in X.java (at line 5)\n" + |
7778 |
right2 = UnconditionalFlowInfoTestHarness. |
1493 |
" x = null;\n" + |
7779 |
testUnconditionalFlowInfo(testData[i][1], 128); |
1494 |
" ^\n" + |
7780 |
expected0 = UnconditionalFlowInfoTestHarness. |
1495 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
7781 |
testUnconditionalFlowInfo(testData[i][2]); |
1496 |
"----------\n" + |
7782 |
expected1 = UnconditionalFlowInfoTestHarness. |
1497 |
"2. WARNING in X.java (at line 7)\n" + |
7783 |
testUnconditionalFlowInfo(testData[i][2], 64); |
1498 |
" if (x != null) { /* */ }\n" + |
7784 |
expected2 = UnconditionalFlowInfoTestHarness. |
1499 |
" ^\n" + |
7785 |
testUnconditionalFlowInfo(testData[i][2], 128); |
1500 |
"The variable x can only be null; it was either set to null or checked for null when last used\n" + |
7786 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
1501 |
"----------\n"); |
7787 |
left1.copy().addPotentialInitializationsFrom(right1)). |
|
|
7788 |
testEquals(expected1)) { |
7789 |
if (failures == 0) { |
7790 |
System.out.println(header); |
7791 |
} |
7792 |
failures++; |
7793 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7794 |
',' + testStringValueOf(testData[i][1]) + |
7795 |
',' + result.testString() + |
7796 |
"}, // (64, 64) - instead of: " + testStringValueOf(testData[i][2])); |
7797 |
} |
7798 |
if (testData[i][0][0] + testData[i][0][1] + |
7799 |
testData[i][0][2] + testData[i][0][3] == 0) { |
7800 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7801 |
zero.copy().addPotentialInitializationsFrom(right1)). |
7802 |
testEquals(expected1)) { |
7803 |
if (failures == 0) { |
7804 |
System.out.println(header); |
7805 |
} |
7806 |
failures++; |
7807 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7808 |
',' + testStringValueOf(testData[i][1]) + |
7809 |
',' + result.testString() + |
7810 |
"}, // (zero, 64) - instead of: " + testStringValueOf(testData[i][2])); |
7811 |
} |
7812 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7813 |
right2.copy().addPotentialInitializationsFrom(right1)). |
7814 |
testEquals(expected1, 64)) { |
7815 |
if (failures == 0) { |
7816 |
System.out.println(header); |
7817 |
} |
7818 |
failures++; |
7819 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7820 |
',' + testStringValueOf(testData[i][1]) + |
7821 |
',' + result.testString() + |
7822 |
"}, // (zero 128, 64) - instead of: " + testStringValueOf(testData[i][2])); |
7823 |
} |
7824 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7825 |
(UnconditionalFlowInfoTestHarness. |
7826 |
testUnconditionalFlowInfo(new long[] {0,0,0,0}, 64)). |
7827 |
// make just in time to get the needed structure |
7828 |
addPotentialNullInfoFrom(right2)). |
7829 |
testEquals(expected2, 128)) { |
7830 |
if (failures == 0) { |
7831 |
System.out.println(header); |
7832 |
} |
7833 |
failures++; |
7834 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7835 |
',' + testStringValueOf(testData[i][1]) + |
7836 |
',' + result.testString() + |
7837 |
"}, // (zero extra, 128) null only - instead of: " + testStringValueOf(testData[i][2])); |
7838 |
} |
7839 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7840 |
((UnconditionalFlowInfo)right2.copy()). |
7841 |
addPotentialNullInfoFrom(right1)). |
7842 |
testEquals(expected1, 64)) { |
7843 |
if (failures == 0) { |
7844 |
System.out.println(header); |
7845 |
} |
7846 |
failures++; |
7847 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7848 |
',' + testStringValueOf(testData[i][1]) + |
7849 |
',' + result.testString() + |
7850 |
"}, // (zero 128, 64) null only - instead of: " + testStringValueOf(testData[i][2])); |
7851 |
} |
7852 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7853 |
((UnconditionalFlowInfo)zero.copy()). |
7854 |
addPotentialNullInfoFrom(right2)). |
7855 |
testEquals(expected2, 128)) { |
7856 |
if (failures == 0) { |
7857 |
System.out.println(header); |
7858 |
} |
7859 |
failures++; |
7860 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7861 |
',' + testStringValueOf(testData[i][1]) + |
7862 |
',' + result.testString(128) + |
7863 |
"}, // (zero, 128) null only - instead of: " + testStringValueOf(testData[i][2])); |
7864 |
} |
7865 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7866 |
((UnconditionalFlowInfo)right1.copy()). |
7867 |
addPotentialNullInfoFrom(right2)). |
7868 |
testEquals(expected2, 128)) { |
7869 |
if (failures == 0) { |
7870 |
System.out.println(header); |
7871 |
} |
7872 |
failures++; |
7873 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7874 |
',' + testStringValueOf(testData[i][1]) + |
7875 |
',' + result.testString(128) + |
7876 |
"}, // (zero 64, 128) null only - instead of: " + testStringValueOf(testData[i][2])); |
7877 |
} } |
7878 |
if (testData[i][1][0] + testData[i][1][1] + |
7879 |
testData[i][1][2] + testData[i][1][3] == 0) { |
7880 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7881 |
((UnconditionalFlowInfoTestHarness)left0.copy()). |
7882 |
addPotentialNullInfoFrom(left2)). |
7883 |
testEquals(expected0, 1)) { |
7884 |
if (failures == 0) { |
7885 |
System.out.println(header); |
7886 |
} |
7887 |
failures++; |
7888 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7889 |
',' + testStringValueOf(testData[i][1]) + |
7890 |
',' + result.testString() + |
7891 |
"}, // (1, zero 128) null only - instead of: " + testStringValueOf(testData[i][2])); |
7892 |
} |
7893 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7894 |
left1.copy().addPotentialInitializationsFrom(zero)). |
7895 |
testEquals(expected1)) { |
7896 |
if (failures == 0) { |
7897 |
System.out.println(header); |
7898 |
} |
7899 |
failures++; |
7900 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7901 |
',' + testStringValueOf(testData[i][1]) + |
7902 |
',' + result.testString() + |
7903 |
"}, // (64, zero) - instead of: " + testStringValueOf(testData[i][2])); |
7904 |
} |
7905 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7906 |
left1.copy().addPotentialInitializationsFrom(left2)). |
7907 |
testEquals(expected1, 64)) { |
7908 |
if (failures == 0) { |
7909 |
System.out.println(header); |
7910 |
} |
7911 |
failures++; |
7912 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7913 |
',' + testStringValueOf(testData[i][1]) + |
7914 |
',' + result.testString() + |
7915 |
"}, // (64, zero 128) - instead of: " + testStringValueOf(testData[i][2])); |
7916 |
} |
7917 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7918 |
((UnconditionalFlowInfo)left1.copy()). |
7919 |
addPotentialNullInfoFrom(left2)). |
7920 |
testEquals(expected1, 64)) { |
7921 |
if (failures == 0) { |
7922 |
System.out.println(header); |
7923 |
} |
7924 |
failures++; |
7925 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7926 |
',' + testStringValueOf(testData[i][1]) + |
7927 |
',' + result.testString() + |
7928 |
"}, // (64, zero 128) null only - instead of: " + testStringValueOf(testData[i][2])); |
7929 |
} |
7930 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7931 |
((UnconditionalFlowInfo)left2.copy()). |
7932 |
addPotentialNullInfoFrom(zero)). |
7933 |
testEquals(expected2, 128)) { |
7934 |
if (failures == 0) { |
7935 |
System.out.println(header); |
7936 |
} |
7937 |
failures++; |
7938 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7939 |
',' + testStringValueOf(testData[i][1]) + |
7940 |
',' + result.testString() + |
7941 |
"}, // (128, zero) null only - instead of: " + testStringValueOf(testData[i][2])); |
7942 |
} |
7943 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
7944 |
left2.addPotentialNullInfoFrom(left1)). |
7945 |
testEquals(expected2, 128)) { |
7946 |
if (failures == 0) { |
7947 |
System.out.println(header); |
7948 |
} |
7949 |
failures++; |
7950 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
7951 |
',' + testStringValueOf(testData[i][1]) + |
7952 |
',' + result.testString() + |
7953 |
"}, // (128, zero 64) null only - instead of: " + testStringValueOf(testData[i][2])); |
7954 |
} |
7955 |
} |
1502 |
} |
7956 |
} |
1503 |
|
7957 |
if (printTablesAsNames) { |
1504 |
// null analysis -- try/finally |
7958 |
System.out.println("RECAP TABLE FOR ADD POTENTIAL"); |
1505 |
// origin: AssignmentTest#test017 |
7959 |
for (int i = 0; i < testData.length; i++) { |
1506 |
// REVIEW design choice |
7960 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " + " + |
1507 |
// See also test0174. The whole issue here is whether or not to detect |
7961 |
testSymbolicValueOf(testData[i][1]) + " -> " + |
1508 |
// premature exits. We follow JLS's conservative approach, which considers |
7962 |
testSymbolicValueOf(testData[i][2])); |
1509 |
// that the try block may exit before the assignment is completed. |
7963 |
} |
1510 |
// TODO (maxime) fix |
|
|
1511 |
public void _test0155_try_finally() { |
1512 |
this.runNegativeTest( |
1513 |
new String[] { |
1514 |
"X.java", |
1515 |
"public class X {\n" + |
1516 |
" void foo(X x) {\n" + |
1517 |
" x = this;\n" + |
1518 |
" try {\n" + |
1519 |
" x = null;\n" + |
1520 |
" } finally {\n" + |
1521 |
" if (x == null) {/* */}\n" + |
1522 |
" }\n" + |
1523 |
" }\n" + |
1524 |
"}\n", |
1525 |
}, |
1526 |
"" |
1527 |
); |
1528 |
} |
7964 |
} |
1529 |
|
7965 |
if (printTablesAsCodes) { |
1530 |
// null analysis -- try/catch |
7966 |
System.out.println("RECAP TABLE FOR ADD POTENTIAL"); |
1531 |
public void test0170_try_catch() { |
7967 |
for (int i = 0; i < testData.length; i++) { |
1532 |
this.runNegativeTest( |
7968 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
1533 |
new String[] { |
7969 |
testCodedValueOf(testData[i][1]) + " " + |
1534 |
"X.java", |
7970 |
testCodedValueOf(testData[i][2])); |
1535 |
"public class X {\n" + |
7971 |
} |
1536 |
" void foo() {\n" + |
|
|
1537 |
" Object o = null;\n" + |
1538 |
" try {\n" + |
1539 |
" System.out.println();\n" + // might throw a runtime exception |
1540 |
" o = new Object();\n" + |
1541 |
" }\n" + |
1542 |
" catch (Throwable t) {\n" + // catches everything |
1543 |
" return;\n" + // gets out |
1544 |
" }\n" + |
1545 |
" o.toString();\n" + // can't tell if o is null or not |
1546 |
" }\n" + |
1547 |
"}\n"}, |
1548 |
"" |
1549 |
); |
1550 |
} |
7972 |
} |
|
|
7973 |
if (printTruthMaps) { |
7974 |
for (int i = 0; i < 4; i++) { |
7975 |
System.out.println("======================================================"); |
7976 |
System.out.println("Truth map for addPotentialInitializationsFrom null bit " + (i + 1)); |
7977 |
System.out.println(); |
7978 |
} |
7979 |
} |
7980 |
assertTrue("nb of failures: " + failures, failures == 0); |
7981 |
} |
1551 |
|
7982 |
|
1552 |
// null analysis - try/catch |
7983 |
public void test2057_mergedWith() { |
1553 |
public void test0171_try_catch() { |
7984 |
long [][][] testData = { |
1554 |
this.runNegativeTest( |
7985 |
{{0,0,0,0},{0,0,0,0},{0,0,0,0}}, |
1555 |
new String[] { |
7986 |
{{0,0,0,0},{0,0,0,1},{0,0,0,1}}, |
1556 |
"X.java", |
7987 |
{{0,0,0,0},{0,0,1,0},{0,0,1,0}}, |
1557 |
"public class X {\n" + |
7988 |
{{0,0,0,0},{0,0,1,1},{0,0,1,1}}, |
1558 |
" boolean dummy;\n" + |
7989 |
{{0,0,0,0},{0,1,0,0},{0,0,1,0}}, |
1559 |
" void foo() {\n" + |
7990 |
{{0,0,0,0},{0,1,1,0},{0,0,1,0}}, |
1560 |
" Object o = new Object();\n" + |
7991 |
{{0,0,0,0},{1,0,0,1},{0,0,0,1}}, |
1561 |
" try {\n" + |
7992 |
{{0,0,0,0},{1,0,1,0},{0,0,1,0}}, |
1562 |
" System.out.println();\n" + |
7993 |
{{0,0,0,0},{1,0,1,1},{0,0,0,1}}, |
1563 |
" if (dummy) {\n" + |
7994 |
{{0,0,0,0},{1,1,0,0},{0,0,0,0}}, |
1564 |
" o = null;\n" + |
7995 |
{{0,0,0,0},{1,1,0,1},{0,0,0,1}}, |
1565 |
" throw new Exception();\n" + |
7996 |
{{0,0,0,1},{0,0,0,0},{0,0,0,1}}, |
1566 |
" }\n" + |
7997 |
{{0,0,0,1},{0,0,0,1},{0,0,0,1}}, |
1567 |
" }\n" + |
7998 |
{{0,0,0,1},{0,0,1,0},{0,0,1,1}}, |
1568 |
" catch (Exception e) {\n" + |
7999 |
{{0,0,0,1},{0,0,1,1},{0,0,1,1}}, |
1569 |
" o.toString();\n" + |
8000 |
{{0,0,0,1},{0,1,0,0},{0,0,1,1}}, |
1570 |
// quiet: println may throw a RuntimeException |
8001 |
{{0,0,0,1},{0,1,1,0},{0,0,1,1}}, |
1571 |
" }\n" + |
8002 |
{{0,0,0,1},{1,0,0,1},{0,0,0,1}}, |
1572 |
" }\n" + |
8003 |
{{0,0,0,1},{1,0,1,0},{0,0,1,1}}, |
1573 |
"}\n"}, |
8004 |
{{0,0,0,1},{1,0,1,1},{0,0,0,1}}, |
1574 |
"" |
8005 |
{{0,0,0,1},{1,1,0,0},{0,0,0,1}}, |
1575 |
); |
8006 |
{{0,0,0,1},{1,1,0,1},{0,0,0,1}}, |
|
|
8007 |
{{0,0,1,0},{0,0,0,0},{0,0,1,0}}, |
8008 |
{{0,0,1,0},{0,0,0,1},{0,0,1,1}}, |
8009 |
{{0,0,1,0},{0,0,1,0},{0,0,1,0}}, |
8010 |
{{0,0,1,0},{0,0,1,1},{0,0,1,1}}, |
8011 |
{{0,0,1,0},{0,1,0,0},{0,0,1,0}}, |
8012 |
{{0,0,1,0},{0,1,1,0},{0,0,1,0}}, |
8013 |
{{0,0,1,0},{1,0,0,1},{0,0,1,1}}, |
8014 |
{{0,0,1,0},{1,0,1,0},{0,0,1,0}}, |
8015 |
{{0,0,1,0},{1,0,1,1},{0,0,1,1}}, |
8016 |
{{0,0,1,0},{1,1,0,0},{0,0,1,0}}, |
8017 |
{{0,0,1,0},{1,1,0,1},{0,0,1,1}}, |
8018 |
{{0,0,1,1},{0,0,0,0},{0,0,1,1}}, |
8019 |
{{0,0,1,1},{0,0,0,1},{0,0,1,1}}, |
8020 |
{{0,0,1,1},{0,0,1,0},{0,0,1,1}}, |
8021 |
{{0,0,1,1},{0,0,1,1},{0,0,1,1}}, |
8022 |
{{0,0,1,1},{0,1,0,0},{0,0,1,1}}, |
8023 |
{{0,0,1,1},{0,1,1,0},{0,0,1,1}}, |
8024 |
{{0,0,1,1},{1,0,0,1},{0,0,1,1}}, |
8025 |
{{0,0,1,1},{1,0,1,0},{0,0,1,1}}, |
8026 |
{{0,0,1,1},{1,0,1,1},{0,0,1,1}}, |
8027 |
{{0,0,1,1},{1,1,0,0},{0,0,1,1}}, |
8028 |
{{0,0,1,1},{1,1,0,1},{0,0,1,1}}, |
8029 |
{{0,1,0,0},{0,0,0,0},{0,0,1,0}}, |
8030 |
{{0,1,0,0},{0,0,0,1},{0,0,1,1}}, |
8031 |
{{0,1,0,0},{0,0,1,0},{0,0,1,0}}, |
8032 |
{{0,1,0,0},{0,0,1,1},{0,0,1,1}}, |
8033 |
{{0,1,0,0},{0,1,0,0},{0,1,0,0}}, |
8034 |
{{0,1,0,0},{0,1,1,0},{0,1,1,0}}, |
8035 |
{{0,1,0,0},{1,0,0,1},{0,0,1,1}}, |
8036 |
{{0,1,0,0},{1,0,1,0},{0,1,1,0}}, |
8037 |
{{0,1,0,0},{1,0,1,1},{0,0,1,1}}, |
8038 |
{{0,1,0,0},{1,1,0,0},{0,0,1,0}}, |
8039 |
{{0,1,0,0},{1,1,0,1},{0,0,1,1}}, |
8040 |
{{0,1,1,0},{0,0,0,0},{0,0,1,0}}, |
8041 |
{{0,1,1,0},{0,0,0,1},{0,0,1,1}}, |
8042 |
{{0,1,1,0},{0,0,1,0},{0,0,1,0}}, |
8043 |
{{0,1,1,0},{0,0,1,1},{0,0,1,1}}, |
8044 |
{{0,1,1,0},{0,1,0,0},{0,1,1,0}}, |
8045 |
{{0,1,1,0},{0,1,1,0},{0,1,1,0}}, |
8046 |
{{0,1,1,0},{1,0,0,1},{0,0,1,1}}, |
8047 |
{{0,1,1,0},{1,0,1,0},{0,1,1,0}}, |
8048 |
{{0,1,1,0},{1,0,1,1},{0,0,1,1}}, |
8049 |
{{0,1,1,0},{1,1,0,0},{0,0,1,0}}, |
8050 |
{{0,1,1,0},{1,1,0,1},{0,0,1,1}}, |
8051 |
{{1,0,0,1},{0,0,0,0},{0,0,0,1}}, |
8052 |
{{1,0,0,1},{0,0,0,1},{0,0,0,1}}, |
8053 |
{{1,0,0,1},{0,0,1,0},{0,0,1,1}}, |
8054 |
{{1,0,0,1},{0,0,1,1},{0,0,1,1}}, |
8055 |
{{1,0,0,1},{0,1,0,0},{0,0,1,1}}, |
8056 |
{{1,0,0,1},{0,1,1,0},{0,0,1,1}}, |
8057 |
{{1,0,0,1},{1,0,0,1},{1,0,0,1}}, |
8058 |
{{1,0,0,1},{1,0,1,0},{0,0,1,1}}, |
8059 |
{{1,0,0,1},{1,0,1,1},{1,0,1,1}}, |
8060 |
{{1,0,0,1},{1,1,0,0},{1,1,0,1}}, |
8061 |
{{1,0,0,1},{1,1,0,1},{1,1,0,1}}, |
8062 |
{{1,0,1,0},{0,0,0,0},{0,0,1,0}}, |
8063 |
{{1,0,1,0},{0,0,0,1},{0,0,1,1}}, |
8064 |
{{1,0,1,0},{0,0,1,0},{0,0,1,0}}, |
8065 |
{{1,0,1,0},{0,0,1,1},{0,0,1,1}}, |
8066 |
{{1,0,1,0},{0,1,0,0},{0,1,1,0}}, |
8067 |
{{1,0,1,0},{0,1,1,0},{0,1,1,0}}, |
8068 |
{{1,0,1,0},{1,0,0,1},{0,0,1,1}}, |
8069 |
{{1,0,1,0},{1,0,1,0},{1,0,1,0}}, |
8070 |
{{1,0,1,0},{1,0,1,1},{0,0,1,1}}, |
8071 |
{{1,0,1,0},{1,1,0,0},{0,0,1,0}}, |
8072 |
{{1,0,1,0},{1,1,0,1},{0,0,1,1}}, |
8073 |
{{1,0,1,1},{0,0,0,0},{0,0,0,1}}, |
8074 |
{{1,0,1,1},{0,0,0,1},{0,0,0,1}}, |
8075 |
{{1,0,1,1},{0,0,1,0},{0,0,1,1}}, |
8076 |
{{1,0,1,1},{0,0,1,1},{0,0,1,1}}, |
8077 |
{{1,0,1,1},{0,1,0,0},{0,0,1,1}}, |
8078 |
{{1,0,1,1},{0,1,1,0},{0,0,1,1}}, |
8079 |
{{1,0,1,1},{1,0,0,1},{1,0,1,1}}, |
8080 |
{{1,0,1,1},{1,0,1,0},{0,0,1,1}}, |
8081 |
{{1,0,1,1},{1,0,1,1},{1,0,1,1}}, |
8082 |
{{1,0,1,1},{1,1,0,0},{0,0,0,1}}, |
8083 |
{{1,0,1,1},{1,1,0,1},{0,0,0,1}}, |
8084 |
{{1,1,0,0},{0,0,0,0},{0,0,0,0}}, |
8085 |
{{1,1,0,0},{0,0,0,1},{0,0,0,1}}, |
8086 |
{{1,1,0,0},{0,0,1,0},{0,0,1,0}}, |
8087 |
{{1,1,0,0},{0,0,1,1},{0,0,1,1}}, |
8088 |
{{1,1,0,0},{0,1,0,0},{0,0,1,0}}, |
8089 |
{{1,1,0,0},{0,1,1,0},{0,0,1,0}}, |
8090 |
{{1,1,0,0},{1,0,0,1},{1,1,0,1}}, |
8091 |
{{1,1,0,0},{1,0,1,0},{0,0,1,0}}, |
8092 |
{{1,1,0,0},{1,0,1,1},{0,0,0,1}}, |
8093 |
{{1,1,0,0},{1,1,0,0},{1,1,0,0}}, |
8094 |
{{1,1,0,0},{1,1,0,1},{1,1,0,1}}, |
8095 |
{{1,1,0,1},{0,0,0,0},{0,0,0,1}}, |
8096 |
{{1,1,0,1},{0,0,0,1},{0,0,0,1}}, |
8097 |
{{1,1,0,1},{0,0,1,0},{0,0,1,1}}, |
8098 |
{{1,1,0,1},{0,0,1,1},{0,0,1,1}}, |
8099 |
{{1,1,0,1},{0,1,0,0},{0,0,1,1}}, |
8100 |
{{1,1,0,1},{0,1,1,0},{0,0,1,1}}, |
8101 |
{{1,1,0,1},{1,0,0,1},{1,1,0,1}}, |
8102 |
{{1,1,0,1},{1,0,1,0},{0,0,1,1}}, |
8103 |
{{1,1,0,1},{1,0,1,1},{0,0,0,1}}, |
8104 |
{{1,1,0,1},{1,1,0,0},{1,1,0,1}}, |
8105 |
{{1,1,0,1},{1,1,0,1},{1,1,0,1}} |
8106 |
}; |
8107 |
int failures = 0; |
8108 |
long start; |
8109 |
if (combinationTestsloopsNb > 1) { |
8110 |
start = System.currentTimeMillis(); |
8111 |
} |
8112 |
String header = "mergedWith failures: "; |
8113 |
for (int l = 0; l < combinationTestsloopsNb ; l++) { |
8114 |
for (int i = 0; i < testData.length; i++) { |
8115 |
UnconditionalFlowInfoTestHarness result; |
8116 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8117 |
UnconditionalFlowInfoTestHarness. |
8118 |
testUnconditionalFlowInfo(testData[i][0]). |
8119 |
mergedWith( |
8120 |
UnconditionalFlowInfoTestHarness. |
8121 |
testUnconditionalFlowInfo(testData[i][1]))). |
8122 |
testEquals(UnconditionalFlowInfoTestHarness. |
8123 |
testUnconditionalFlowInfo(testData[i][2]))) { |
8124 |
if (failures == 0) { |
8125 |
System.out.println(header); |
8126 |
} |
8127 |
failures++; |
8128 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8129 |
',' + testStringValueOf(testData[i][1]) + |
8130 |
',' + result.testString() + |
8131 |
"}, // instead of: " + testStringValueOf(testData[i][2])); |
8132 |
} |
8133 |
} |
1576 |
} |
8134 |
} |
1577 |
|
8135 |
if (combinationTestsloopsNb > 1) { |
1578 |
// null analysis - try/catch |
8136 |
System.out.println("mergedWith\t\t\t" + combinationTestsloopsNb + "\t" + |
1579 |
public void test0172_try_catch() { |
8137 |
(System.currentTimeMillis() - start)); |
1580 |
this.runNegativeTest( |
8138 |
} |
1581 |
new String[] { |
8139 |
UnconditionalFlowInfoTestHarness |
1582 |
"X.java", |
8140 |
zero = UnconditionalFlowInfoTestHarness. |
1583 |
"public class X {\n" + |
8141 |
testUnconditionalFlowInfo(new long[] {0,0,0,0}), |
1584 |
" boolean dummy;\n" + |
8142 |
left1, right1, left2, right2, |
1585 |
" void foo() throws Exception {\n" + |
8143 |
expected1, expected2, result; |
1586 |
" Object o = new Object();\n" + |
8144 |
for (int i = 0; i < testData.length; i++) { |
1587 |
" try {\n" + |
8145 |
left1 = UnconditionalFlowInfoTestHarness. |
1588 |
" if (dummy) {\n" + |
8146 |
testUnconditionalFlowInfo(testData[i][0], 64); |
1589 |
" o = null;\n" + |
8147 |
left2 = UnconditionalFlowInfoTestHarness. |
1590 |
" throw new Exception();\n" + |
8148 |
testUnconditionalFlowInfo(testData[i][0], 128); |
1591 |
" }\n" + |
8149 |
right1 = UnconditionalFlowInfoTestHarness. |
1592 |
" }\n" + |
8150 |
testUnconditionalFlowInfo(testData[i][1], 64); |
1593 |
" catch (Exception e) {\n" + |
8151 |
right2 = UnconditionalFlowInfoTestHarness. |
1594 |
" }\n" + |
8152 |
testUnconditionalFlowInfo(testData[i][1], 128); |
1595 |
" if (o != null) {\n" + |
8153 |
expected1 = UnconditionalFlowInfoTestHarness. |
1596 |
// quiet: get out of try either through normal flow, leaves a new |
8154 |
testUnconditionalFlowInfo(testData[i][2], 64); |
1597 |
// object, or through Exception, leaves a null |
8155 |
expected2 = UnconditionalFlowInfoTestHarness. |
1598 |
" }\n" + |
8156 |
testUnconditionalFlowInfo(testData[i][2], 128); |
1599 |
" }\n" + |
8157 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
1600 |
"}\n"}, |
8158 |
left1.copy().mergedWith(right1)).testEquals(expected1)) { |
1601 |
"" |
8159 |
if (failures == 0) { |
1602 |
); |
8160 |
System.out.println(header); |
|
|
8161 |
} |
8162 |
failures++; |
8163 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8164 |
',' + testStringValueOf(testData[i][1]) + |
8165 |
',' + result.testString() + |
8166 |
"}, // (64, 64) - instead of: " + testStringValueOf(testData[i][2])); |
8167 |
} |
8168 |
if (testData[i][0][0] + testData[i][0][1] + |
8169 |
testData[i][0][2] + testData[i][0][3] == 0) { |
8170 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8171 |
zero.copy().mergedWith(right1)).testEquals(expected1)) { |
8172 |
if (failures == 0) { |
8173 |
System.out.println(header); |
8174 |
} |
8175 |
failures++; |
8176 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8177 |
',' + testStringValueOf(testData[i][1]) + |
8178 |
',' + result.testString() + |
8179 |
"}, // (zero, 64) - instead of: " + testStringValueOf(testData[i][2])); |
8180 |
} |
8181 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8182 |
right2.copy().mergedWith(right1)). |
8183 |
testEquals(expected1, 64)) { |
8184 |
if (failures == 0) { |
8185 |
System.out.println(header); |
8186 |
} |
8187 |
failures++; |
8188 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8189 |
',' + testStringValueOf(testData[i][1]) + |
8190 |
',' + result.testString() + |
8191 |
"}, // (zero 128, 64) - instead of: " + testStringValueOf(testData[i][2])); |
8192 |
} |
8193 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8194 |
zero.copy().mergedWith(right2)). |
8195 |
testEquals(expected2, 128)) { |
8196 |
if (failures == 0) { |
8197 |
System.out.println(header); |
8198 |
} |
8199 |
failures++; |
8200 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8201 |
',' + testStringValueOf(testData[i][1]) + |
8202 |
',' + result.testString() + |
8203 |
"}, // (zero, 128) - instead of: " + testStringValueOf(testData[i][2])); |
8204 |
} |
8205 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8206 |
right1.copy().mergedWith(right2)). |
8207 |
testEquals(expected2, 128)) { |
8208 |
if (failures == 0) { |
8209 |
System.out.println(header); |
8210 |
} |
8211 |
failures++; |
8212 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8213 |
',' + testStringValueOf(testData[i][1]) + |
8214 |
',' + result.testString() + |
8215 |
"}, // (zero 64, 128) - instead of: " + testStringValueOf(testData[i][2])); |
8216 |
} |
8217 |
} |
8218 |
if (testData[i][1][0] + testData[i][1][1] + |
8219 |
testData[i][1][2] + testData[i][1][3] == 0) { |
8220 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8221 |
left1.copy().mergedWith(zero)).testEquals(expected1)) { |
8222 |
if (failures == 0) { |
8223 |
System.out.println(header); |
8224 |
} |
8225 |
failures++; |
8226 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8227 |
',' + testStringValueOf(testData[i][1]) + |
8228 |
',' + result.testString() + |
8229 |
"}, // (64, zero) - instead of: " + testStringValueOf(testData[i][2])); |
8230 |
} |
8231 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8232 |
left1.mergedWith(left2)). |
8233 |
testEquals(expected1, 64)) { |
8234 |
if (failures == 0) { |
8235 |
System.out.println(header); |
8236 |
} |
8237 |
failures++; |
8238 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8239 |
',' + testStringValueOf(testData[i][1]) + |
8240 |
',' + result.testString() + |
8241 |
"}, // (64, zero 128) - instead of: " + testStringValueOf(testData[i][2])); |
8242 |
} |
8243 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8244 |
left2.copy().mergedWith(zero)). |
8245 |
testEquals(expected2, 128)) { |
8246 |
if (failures == 0) { |
8247 |
System.out.println(header); |
8248 |
} |
8249 |
failures++; |
8250 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8251 |
',' + testStringValueOf(testData[i][1]) + |
8252 |
',' + result.testString() + |
8253 |
"}, // (128, zero) - instead of: " + testStringValueOf(testData[i][2])); |
8254 |
} |
8255 |
if (!(result = (UnconditionalFlowInfoTestHarness) |
8256 |
left2.mergedWith(left1)). |
8257 |
testEquals(expected2, 128)) { |
8258 |
if (failures == 0) { |
8259 |
System.out.println(header); |
8260 |
} |
8261 |
failures++; |
8262 |
System.out.println("\t\t{" + testStringValueOf(testData[i][0]) + |
8263 |
',' + testStringValueOf(testData[i][1]) + |
8264 |
',' + result.testString() + |
8265 |
"}, // (128, zero 64) - instead of: " + testStringValueOf(testData[i][2])); |
8266 |
} |
8267 |
} |
8268 |
} |
8269 |
if (printTablesAsNames) { |
8270 |
System.out.println("RECAP TABLE FOR MERGE"); |
8271 |
for (int i = 0; i < testData.length; i++) { |
8272 |
System.out.println(testSymbolicValueOf(testData[i][0]) + " + " + |
8273 |
testSymbolicValueOf(testData[i][1]) + " -> " + |
8274 |
testSymbolicValueOf(testData[i][2])); |
8275 |
} |
8276 |
|
1603 |
} |
8277 |
} |
1604 |
|
8278 |
if (printTablesAsCodes) { |
1605 |
// null analysis - try/catch |
8279 |
System.out.println("RECAP TABLE FOR MERGE"); |
1606 |
public void test0173_try_catch() { |
8280 |
for (int i = 0; i < testData.length; i++) { |
1607 |
this.runNegativeTest( |
8281 |
System.out.println(testCodedValueOf(testData[i][0]) + " " + |
1608 |
new String[] { |
8282 |
testCodedValueOf(testData[i][1]) + " " + |
1609 |
"X.java", |
8283 |
testCodedValueOf(testData[i][2])); |
1610 |
"public class X {\n" + |
8284 |
} |
1611 |
" boolean dummy, other;\n" + |
|
|
1612 |
" void foo() {\n" + |
1613 |
" Object o = new Object();\n" + |
1614 |
" try {\n" + |
1615 |
" if (dummy) {\n" + |
1616 |
" if (other) {\n" + |
1617 |
" throw new LocalException();\n" + // may launch new exception |
1618 |
" }\n" + |
1619 |
" o = null;\n" + |
1620 |
" throw new LocalException();\n" + // must launch new exception |
1621 |
" }\n" + |
1622 |
" }\n" + |
1623 |
" catch (LocalException e) {\n" + |
1624 |
" o.toString();\n" + |
1625 |
// quiet: don't know the exact state when exception is launched |
1626 |
" }\n" + |
1627 |
" }\n" + |
1628 |
" class LocalException extends Exception {\n" + |
1629 |
" private static final long serialVersionUID = 1L;\n" + |
1630 |
" }\n" + |
1631 |
"}\n"}, |
1632 |
"" |
1633 |
); |
1634 |
} |
8285 |
} |
1635 |
|
8286 |
if (printTruthMaps) { |
1636 |
// null analysis - try/catch |
8287 |
for (int i = 0; i < 4; i++) { |
1637 |
// REVIEW the following series of try catch tests all relate to the finer |
8288 |
System.out.println("======================================================"); |
1638 |
// analysis of possible exception paths; such analysis |
8289 |
System.out.println("Truth map for mergedWith null bit " + (i + 1)); |
1639 |
// calls for a supplementary context for each condition |
8290 |
System.out.println(); |
1640 |
// (so as to sort out certain paths from hypothetical |
8291 |
} |
1641 |
// ones), which is due to be expensive. |
|
|
1642 |
// TODO (maxime) fix |
1643 |
public void _test0174_try_catch() { |
1644 |
this.runNegativeTest( |
1645 |
new String[] { |
1646 |
"X.java", |
1647 |
"public class X {\n" + |
1648 |
" void foo(Object o) throws Exception {\n" + |
1649 |
" try {\n" + |
1650 |
" o = null;\n" + |
1651 |
" throwLocalException();\n" + |
1652 |
" throw new Exception();\n" + |
1653 |
" }\n" + |
1654 |
" catch (LocalException e) {\n" + |
1655 |
" }\n" + |
1656 |
" if (o != null) {\n" + |
1657 |
// complain: only way to get out of try and get there is to go |
1658 |
// through throwLocalException, after the assignment |
1659 |
" }\n" + |
1660 |
" }\n" + |
1661 |
" class LocalException extends Exception {\n" + |
1662 |
" private static final long serialVersionUID = 1L;\n" + |
1663 |
" }\n" + |
1664 |
" void throwLocalException() throws LocalException {\n" + |
1665 |
" throw new LocalException();\n" + |
1666 |
" }\n" + |
1667 |
"}\n"}, |
1668 |
"WARN" |
1669 |
); |
1670 |
} |
8292 |
} |
|
|
8293 |
assertTrue("nb of failures: " + failures, failures == 0); |
8294 |
} |
1671 |
|
8295 |
|
1672 |
// null analysis - try/catch |
8296 |
// Use for coverage tests only. Needs specific instrumentation of code, |
1673 |
// TODO (maxime) fix |
8297 |
// that is controled by UnconditionalFlowInfo#coverageTestFlag. |
1674 |
public void _test0175_try_catch() { |
8298 |
// Note: coverage tests tend to fill the console with messages, and the |
1675 |
this.runNegativeTest( |
8299 |
// instrumented code is slower, so never release code with active |
1676 |
new String[] { |
8300 |
// coverage tests. |
1677 |
"X.java", |
8301 |
private static int coveragePointsNb = 46; |
1678 |
"public class X {\n" + |
8302 |
|
1679 |
" void foo() {\n" + |
8303 |
// Coverage by state transition tables methods. |
1680 |
" Object o = new Object();\n" + |
8304 |
public void test2998_coverage() { |
1681 |
" try {\n" + |
8305 |
if (UnconditionalFlowInfo.coverageTestFlag) { |
1682 |
" o = null;\n" + |
8306 |
// sanity check: need to be sure that the tests execute properly when not |
1683 |
" throwException();\n" + |
8307 |
// trying to check coverage |
1684 |
" }\n" + |
8308 |
UnconditionalFlowInfo.coverageTestId = 0; |
1685 |
" catch (Exception e) {\n" + |
8309 |
test0053_array(); |
1686 |
" o.toString();\n" + |
8310 |
test0070_type_reference(); |
1687 |
// complain: know o is null despite the lack of a definite assignment |
8311 |
test2050_markAsComparedEqualToNonNull(); |
1688 |
" }\n" + |
8312 |
test2051_markAsComparedEqualToNull(); |
1689 |
" }\n" + |
8313 |
test2052_markAsDefinitelyNonNull(); |
1690 |
" void throwException() throws Exception {\n" + |
8314 |
test2053_markAsDefinitelyNull(); |
1691 |
" throw new Exception();\n" + |
8315 |
test2054_markAsDefinitelyUnknown(); |
1692 |
" }\n" + |
8316 |
test2055_addInitializationsFrom(); |
1693 |
"}\n"}, |
8317 |
test2056_addPotentialInitializationsFrom(); |
1694 |
"WARN" |
8318 |
test2057_mergedWith(); |
1695 |
); |
8319 |
// coverage check |
|
|
8320 |
int failuresNb = 0; |
8321 |
for (int i = 1; i <= coveragePointsNb; i++) { |
8322 |
try { |
8323 |
UnconditionalFlowInfo.coverageTestId = i; |
8324 |
test0053_array(); |
8325 |
test0070_type_reference(); |
8326 |
test2050_markAsComparedEqualToNonNull(); |
8327 |
test2051_markAsComparedEqualToNull(); |
8328 |
test2052_markAsDefinitelyNonNull(); |
8329 |
test2053_markAsDefinitelyNull(); |
8330 |
test2054_markAsDefinitelyUnknown(); |
8331 |
test2055_addInitializationsFrom(); |
8332 |
test2056_addPotentialInitializationsFrom(); |
8333 |
test2057_mergedWith(); |
8334 |
} |
8335 |
catch (AssertionFailedError e) { |
8336 |
continue; |
8337 |
} |
8338 |
catch (AssertionFailedException e) { |
8339 |
continue; |
8340 |
} |
8341 |
failuresNb++; |
8342 |
System.out.println("Missing coverage point: " + i); |
8343 |
} |
8344 |
UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests |
8345 |
assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0); |
1696 |
} |
8346 |
} |
|
|
8347 |
} |
1697 |
|
8348 |
|
1698 |
// null analysis - try/catch |
8349 |
// Coverage by code samples. |
1699 |
// TODO (maxime) fix |
8350 |
public void test2999_coverage() { |
1700 |
public void _test0176_try_catch() { |
8351 |
if (UnconditionalFlowInfo.coverageTestFlag) { |
1701 |
this.runNegativeTest( |
8352 |
// sanity check: need to be sure that the tests execute properly when not |
1702 |
new String[] { |
8353 |
// trying to check coverage |
1703 |
"X.java", |
8354 |
UnconditionalFlowInfo.coverageTestId = 0; |
1704 |
"public class X {\n" + |
8355 |
test0001_simple_local(); |
1705 |
" void foo() {\n" + |
8356 |
test0053_array(); |
1706 |
" Object o = new Object();\n" + |
8357 |
test0070_type_reference(); |
1707 |
" try {\n" + |
8358 |
test0327_if_else(); |
1708 |
" o = null;\n" + |
8359 |
test0401_while(); |
1709 |
" throwException();\n" + |
8360 |
test0420_while(); |
1710 |
" }\n" + |
8361 |
test0509_try_finally_embedded(); |
1711 |
" catch (Throwable t) {\n" + |
8362 |
test2000_flow_info(); |
1712 |
" o.toString();\n" + |
8363 |
test2004_flow_info(); |
1713 |
// complain: know o is null despite the lack of a definite assignment |
8364 |
test2008_flow_info(); |
1714 |
" }\n" + |
8365 |
test2011_flow_info(); |
1715 |
" }\n" + |
8366 |
test2013_flow_info(); |
1716 |
" void throwException() throws Exception {\n" + |
8367 |
test2018_flow_info(); |
1717 |
" throw new Exception();\n" + |
8368 |
test2019_flow_info(); |
1718 |
" }\n" + |
8369 |
test2020_flow_info(); |
1719 |
"}\n"}, |
8370 |
// coverage check |
1720 |
"WARN" |
8371 |
int failuresNb = 0; |
1721 |
); |
8372 |
for (int i = 1; i <= coveragePointsNb; i++) { |
|
|
8373 |
if (i > 4 && i < 15 || |
8374 |
i > 15 && i < 19 || |
8375 |
i == 22 || |
8376 |
i == 23 || |
8377 |
i == 27 || |
8378 |
i == 28 || |
8379 |
i == 30 || |
8380 |
i == 33 || |
8381 |
i == 34 || |
8382 |
i == 38 || |
8383 |
i >= 43 |
8384 |
) { // TODO (maxime) complete coverage tests |
8385 |
continue; |
8386 |
} |
8387 |
try { |
8388 |
UnconditionalFlowInfo.coverageTestId = i; |
8389 |
test0001_simple_local(); |
8390 |
test0053_array(); |
8391 |
test0070_type_reference(); |
8392 |
test0327_if_else(); |
8393 |
test0401_while(); |
8394 |
test0420_while(); |
8395 |
test0509_try_finally_embedded(); |
8396 |
test2000_flow_info(); |
8397 |
test2004_flow_info(); |
8398 |
test2008_flow_info(); |
8399 |
test2011_flow_info(); |
8400 |
test2013_flow_info(); |
8401 |
test2018_flow_info(); |
8402 |
test2019_flow_info(); |
8403 |
test2020_flow_info(); |
8404 |
} |
8405 |
catch (AssertionFailedError e) { |
8406 |
continue; |
8407 |
} |
8408 |
catch (AssertionFailedException e) { |
8409 |
continue; |
8410 |
} |
8411 |
failuresNb++; |
8412 |
System.out.println("Missing coverage point: " + i); |
8413 |
} |
8414 |
UnconditionalFlowInfo.coverageTestId = 0; // reset for other tests |
8415 |
assertEquals(failuresNb + " missing coverage point(s)", failuresNb, 0); |
1722 |
} |
8416 |
} |
|
|
8417 |
} |
1723 |
|
8418 |
|
1724 |
// null analysis - try/catch |
8419 |
// only works for info coded on bit 0 - least significant |
1725 |
// TODO (maxime) fix |
8420 |
String testCodedValueOf(long[] data) { |
1726 |
public void _test0177_try_catch() { |
8421 |
StringBuffer result = new StringBuffer(4); |
1727 |
this.runNegativeTest( |
8422 |
for (int i = 0; i < data.length; i++) { |
1728 |
new String[] { |
8423 |
result.append(data[i] == 0 ? '0' : '1'); |
1729 |
"X.java", |
|
|
1730 |
"public class X {\n" + |
1731 |
" boolean dummy;\n" + |
1732 |
" void foo() {\n" + |
1733 |
" Object o = new Object();\n" + |
1734 |
" try {\n" + |
1735 |
" if (dummy) {\n" + |
1736 |
" o = null;\n" + |
1737 |
" throw new Exception();\n" + |
1738 |
" }\n" + |
1739 |
" }\n" + |
1740 |
" catch (Exception e) {\n" + |
1741 |
" o.toString();\n" + |
1742 |
// complain: know o is null despite the lack of definite assignment |
1743 |
" }\n" + |
1744 |
" }\n" + |
1745 |
"}\n"}, |
1746 |
"WARN" |
1747 |
); |
1748 |
} |
8424 |
} |
|
|
8425 |
return result.toString(); |
8426 |
} |
1749 |
|
8427 |
|
1750 |
// null analysis - try/catch |
8428 |
String testStringValueOf(long[] data) { |
1751 |
// TODO (maxime) fix |
8429 |
StringBuffer result = new StringBuffer(9); |
1752 |
public void _test0178_try_catch() { |
8430 |
result.append('{'); |
1753 |
this.runNegativeTest( |
8431 |
for (int j = 0; j < 4; j++) { |
1754 |
new String[] { |
8432 |
if (j > 0) { |
1755 |
"X.java", |
8433 |
result.append(','); |
1756 |
"public class X {\n" + |
8434 |
} |
1757 |
" boolean dummy;\n" + |
8435 |
result.append(data[j]); |
1758 |
" void foo() {\n" + |
|
|
1759 |
" Object o = new Object();\n" + |
1760 |
" try {\n" + |
1761 |
" if (dummy) {\n" + |
1762 |
" System.out.print(0);\n" + // may thow RuntimeException |
1763 |
" o = null;\n" + |
1764 |
" throw new LocalException();\n" + |
1765 |
" }\n" + |
1766 |
" }\n" + |
1767 |
" catch (LocalException e) {\n" + // doesn't catch RuntimeException |
1768 |
" o.toString();\n" + |
1769 |
// complain: know o is null despite the lack of definite assignment |
1770 |
" }\n" + |
1771 |
" }\n" + |
1772 |
" class LocalException extends Exception {\n" + |
1773 |
" private static final long serialVersionUID = 1L;\n" + |
1774 |
" }\n" + |
1775 |
"}\n"}, |
1776 |
"WARN" |
1777 |
); |
1778 |
} |
8436 |
} |
|
|
8437 |
result.append('}'); |
8438 |
return result.toString(); |
8439 |
} |
1779 |
|
8440 |
|
1780 |
// null analysis - try/catch |
8441 |
String testStringValueOf(long[][] data) { |
1781 |
// TODO (maxime) fix |
8442 |
StringBuffer result = new StringBuffer(25); |
1782 |
public void _test0179_try_catch() { |
8443 |
result.append('{'); |
1783 |
this.runNegativeTest( |
8444 |
for (int i = 0; i < 3; i++) { |
1784 |
new String[] { |
8445 |
if (i > 0) { |
1785 |
"X.java", |
8446 |
result.append(','); |
1786 |
"public class X {\n" + |
8447 |
} |
1787 |
" boolean dummy;\n" + |
8448 |
result.append('{'); |
1788 |
" void foo() {\n" + |
8449 |
for (int j = 0; j < 4; j++) { |
1789 |
" Object o = new Object();\n" + |
8450 |
if (j > 0) { |
1790 |
" try {\n" + |
8451 |
result.append(','); |
1791 |
" if (dummy) {\n" + |
8452 |
} |
1792 |
" o = null;\n" + |
8453 |
result.append(data[i][j]); |
1793 |
" throw new SubException();\n" + |
8454 |
} |
1794 |
" }\n" + |
8455 |
result.append('}'); |
1795 |
" }\n" + |
|
|
1796 |
" catch (LocalException e) {\n" + // must catch SubException |
1797 |
" o.toString();\n" + |
1798 |
// complain: know o is null despite the lack of definite assignment |
1799 |
" }\n" + |
1800 |
" }\n" + |
1801 |
" class LocalException extends Exception {\n" + |
1802 |
" private static final long serialVersionUID = 1L;\n" + |
1803 |
" }\n" + |
1804 |
" class SubException extends LocalException {\n" + |
1805 |
" private static final long serialVersionUID = 1L;\n" + |
1806 |
" }\n" + |
1807 |
"}\n"}, |
1808 |
"WARN" |
1809 |
); |
1810 |
} |
1811 |
|
1812 |
// null analysis -- do while |
1813 |
// TODO (maxime) fix |
1814 |
public void _test0201_do_while() { |
1815 |
this.runNegativeTest( |
1816 |
new String[] { |
1817 |
"X.java", |
1818 |
"public class X {\n" + |
1819 |
" void foo() {\n" + |
1820 |
" Object o = null;\n" + |
1821 |
" do {/* */}\n" + |
1822 |
" while (o.toString() != null);\n" + |
1823 |
// complain: NPE |
1824 |
" }\n" + |
1825 |
"}\n"}, |
1826 |
"----------\n" + |
1827 |
"1. WARNING in X.java (at line 5)\n" + |
1828 |
" while (o.toString() != null);\n" + |
1829 |
" ^\n" + |
1830 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
1831 |
"----------\n" |
1832 |
); |
1833 |
} |
8456 |
} |
|
|
8457 |
result.append('}'); |
8458 |
return result.toString(); |
8459 |
} |
1834 |
|
8460 |
|
1835 |
// null analysis -- do while |
8461 |
// only works for info coded on bit 0 - least significant |
1836 |
// TODO (maxime) fix |
8462 |
String testSymbolicValueOf(long[] data) { |
1837 |
public void _test0202_do_while() { |
8463 |
if (data[0] == 0) { |
1838 |
this.runNegativeTest( |
8464 |
if (data[1] == 0) { |
1839 |
new String[] { |
8465 |
if (data[2] == 0) { |
1840 |
"X.java", |
8466 |
if (data[3] == 0) { |
1841 |
"public class X {\n" + |
8467 |
return "start "; //$NON-NLS1$ |
1842 |
" void foo() {\n" + |
8468 |
} |
1843 |
" Object o = null;\n" + |
8469 |
else { |
1844 |
" do {/* */}\n" + |
8470 |
return "pot. nn/unknown "; //$NON-NLS1$ |
1845 |
" while (o != null);\n" + |
8471 |
} |
1846 |
// complain: get o null first time and forever |
8472 |
} |
1847 |
" }\n" + |
8473 |
else { |
1848 |
"}\n"}, |
8474 |
if (data[3] == 0) { |
1849 |
"----------\n" + |
8475 |
return "pot. null "; //$NON-NLS1$ |
1850 |
"1. WARNING in X.java (at line 5)\n" + |
8476 |
} |
1851 |
" while (o != null);\n" + |
8477 |
else { |
1852 |
" ^\n" + |
8478 |
return "pot. n/nn/unkn. "; //$NON-NLS1$ |
1853 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
8479 |
} |
1854 |
"----------\n" |
8480 |
} |
1855 |
); |
8481 |
} |
|
|
8482 |
else { |
8483 |
if (data[2] == 0) { |
8484 |
if (data[3] == 0) { |
8485 |
return "prot. null "; //$NON-NLS1$ |
8486 |
} |
8487 |
else { |
8488 |
return "0101 "; //$NON-NLS1$ |
8489 |
} |
8490 |
} |
8491 |
else { |
8492 |
if (data[3] == 0) { |
8493 |
return "prot. null + pot. null"; //$NON-NLS1$ |
8494 |
} |
8495 |
else { |
8496 |
return "0111 "; //$NON-NLS1$ |
8497 |
} |
8498 |
} |
8499 |
} |
1856 |
} |
8500 |
} |
1857 |
|
8501 |
else { |
1858 |
// null analysis -- do while |
8502 |
if (data[1] == 0) { |
1859 |
// TODO (maxime) fix |
8503 |
if (data[2] == 0) { |
1860 |
public void _test0203_do_while() { |
8504 |
if (data[3] == 0) { |
1861 |
this.runNegativeTest( |
8505 |
return "1000 "; //$NON-NLS1$ |
1862 |
new String[] { |
8506 |
} |
1863 |
"X.java", |
8507 |
else { |
1864 |
"public class X {\n" + |
8508 |
return "assigned non null "; //$NON-NLS1$ |
1865 |
" void foo() {\n" + |
8509 |
} |
1866 |
" Object o = null;\n" + |
8510 |
} |
1867 |
" do {\n" + |
8511 |
else { |
1868 |
" o = new Object();\n" + |
8512 |
if (data[3] == 0) { |
1869 |
" }\n" + |
8513 |
return "assigned null "; //$NON-NLS1$ |
1870 |
" while (o == null);\n" + |
8514 |
} |
1871 |
// complain: set it to non null before test, for each iteration |
8515 |
else { |
1872 |
" }\n" + |
8516 |
return "assigned unknown "; //$NON-NLS1$ |
1873 |
"}\n"}, |
8517 |
} |
1874 |
"----------\n" + |
8518 |
} |
1875 |
"1. WARNING in X.java (at line 7)\n" + |
8519 |
} |
1876 |
" while (o == null);\n" + |
8520 |
else { |
1877 |
" ^\n" + |
8521 |
if (data[2] == 0) { |
1878 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
8522 |
if (data[3] == 0) { |
1879 |
"----------\n" |
8523 |
return "protected non null "; //$NON-NLS1$ |
1880 |
); |
8524 |
} |
|
|
8525 |
else { |
8526 |
return "prot. nn + pot. nn/unknown"; //$NON-NLS1$ |
8527 |
} |
8528 |
} |
8529 |
else { |
8530 |
if (data[3] == 0) { |
8531 |
return "1110 "; //$NON-NLS1$ |
8532 |
} |
8533 |
else { |
8534 |
return "1111 "; //$NON-NLS1$ |
8535 |
} |
8536 |
} |
8537 |
} |
1881 |
} |
8538 |
} |
|
|
8539 |
} |
1882 |
|
8540 |
|
1883 |
// null analysis -- do while |
8541 |
private void printTruthMap(long data[][][], int bit) { |
1884 |
public void test0204_do_while() { |
8542 |
final int dimension = 16; |
1885 |
this.runNegativeTest( |
8543 |
printTruthMapHeader(); |
1886 |
new String[] { |
8544 |
char truthValues[][] = new char[dimension][dimension]; |
1887 |
"X.java", |
8545 |
int row, column; |
1888 |
"public class X {\n" + |
8546 |
for (row = 0; row < dimension; row++) { |
1889 |
" void foo() {\n" + |
8547 |
for (column = 0; column < dimension; column++) { |
1890 |
" Object o = null;\n" + |
8548 |
truthValues[row][column] = '.'; |
1891 |
" do {\n" + |
8549 |
} |
1892 |
" if (System.currentTimeMillis() > 10L) {\n" + |
|
|
1893 |
" o = new Object();\n" + |
1894 |
" }\n" + |
1895 |
" }\n" + |
1896 |
" while (o == null);\n" + |
1897 |
" }\n" + |
1898 |
"}\n"}, |
1899 |
"" |
1900 |
); |
1901 |
} |
8550 |
} |
1902 |
|
8551 |
String rows[] = { |
1903 |
// null analysis -- do while |
8552 |
"0000", |
1904 |
// TODO (maxime) fix |
8553 |
"0001", |
1905 |
public void _test0205_do_while() { |
8554 |
"0011", |
1906 |
this.runNegativeTest( |
8555 |
"0111", |
1907 |
new String[] { |
8556 |
"1111", |
1908 |
"X.java", |
8557 |
"1110", |
1909 |
"public class X {\n" + |
8558 |
"1100", |
1910 |
" boolean dummy;\n" + |
8559 |
"1000", |
1911 |
" void foo(Object o) {\n" + |
8560 |
"1010", |
1912 |
" o = null;\n" + |
8561 |
"1011", |
1913 |
" do {\n" + |
8562 |
"1001", |
1914 |
" // do nothing\n" + |
8563 |
"1101", |
1915 |
" }\n" + |
8564 |
"0101", |
1916 |
" while (dummy || o != null);\n" + |
8565 |
"0100", |
1917 |
" }\n" + |
8566 |
"0110", |
1918 |
"}\n"}, |
8567 |
"0010" |
1919 |
"----------\n" + |
8568 |
}; |
1920 |
"1. WARNING in X.java (at line 8)\n" + |
8569 |
if (false) { // checking row names |
1921 |
" while (dummy || o != null);\n" + |
8570 |
for (row = 0; row < dimension; row++) { |
1922 |
" ^\n" + |
8571 |
long [] state = new long [4]; |
1923 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
8572 |
for (int i = 0; i < 4; i++) { |
1924 |
"----------\n" |
8573 |
state[i] = rows[row].charAt(i) - '0'; |
1925 |
); |
8574 |
} |
|
|
8575 |
System.out.println(row + " " + rows[row] + " " + rankForState(state)); |
8576 |
} |
1926 |
} |
8577 |
} |
1927 |
|
8578 |
for (int i = 0; i < data.length; i++) { |
1928 |
// null analysis -- do while |
8579 |
truthValues[rankForState(data[i][0])][rankForState(data[i][1])] = |
1929 |
// TODO (maxime) fix |
8580 |
(char) ('0' + data[i][2][bit]); |
1930 |
public void _test0206_do_while() { |
8581 |
} |
1931 |
this.runNegativeTest( |
8582 |
for (row = 0; row < dimension; row++) { |
1932 |
new String[] { |
8583 |
StringBuffer line = new StringBuffer(120); |
1933 |
"X.java", |
8584 |
line.append(rows[row]); |
1934 |
"public class X {\n" + |
8585 |
line.append(" | "); |
1935 |
" void foo() {\n" + |
8586 |
for (column = 0; column < dimension; column++) { |
1936 |
" Object o = null,\n" + |
8587 |
line.append(truthValues[row][column]); |
1937 |
" u = new Object(),\n" + |
8588 |
line.append(' '); |
1938 |
" v = new Object();\n" + |
8589 |
} |
1939 |
" do {\n" + |
8590 |
System.out.println(line); |
1940 |
" if (v == null) {\n" + |
|
|
1941 |
" o = new Object();\n" + |
1942 |
" };\n" + |
1943 |
" if (u == null) {\n" + |
1944 |
" v = null;\n" + |
1945 |
" };\n" + |
1946 |
" u = null;\n" + |
1947 |
" }\n" + |
1948 |
" while (o == null);\n" + |
1949 |
" }\n" + |
1950 |
"}\n"}, |
1951 |
"" |
1952 |
); |
1953 |
} |
8591 |
} |
|
|
8592 |
} |
1954 |
|
8593 |
|
1955 |
// null analysis -- do while |
8594 |
private void printTruthMapHeader() { |
1956 |
// TODO (maxime) fix |
8595 |
System.out.println(" 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0"); |
1957 |
public void _test0207_do_while() { |
8596 |
System.out.println(" 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0"); |
1958 |
this.runNegativeTest( |
8597 |
System.out.println(" 0 0 1 1 1 1 0 0 1 1 0 0 0 0 1 1"); |
1959 |
new String[] { |
8598 |
System.out.println(" 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0"); |
1960 |
"X.java", |
8599 |
System.out.println(" --------------------------------"); |
1961 |
"public class X {\n" + |
8600 |
} |
1962 |
" boolean dummy;\n" + |
|
|
1963 |
" void foo() {\n" + |
1964 |
" Object o = null;\n" + |
1965 |
" do {\n" + |
1966 |
" o.toString();\n" + |
1967 |
// complain: NPE on first iteration |
1968 |
" o = new Object();\n" + |
1969 |
" }\n" + |
1970 |
" while (dummy);\n" + |
1971 |
" }\n" + |
1972 |
"}\n"}, |
1973 |
"WARN" |
1974 |
); |
1975 |
} |
1976 |
|
8601 |
|
1977 |
// null analysis -- do while |
8602 |
private int rankForState(long [] state) { |
1978 |
// TODO (maxime) fix |
8603 |
if (state[0] == 0) { |
1979 |
public void _test0208_do_while() { |
8604 |
if (state[1] == 0) { |
1980 |
this.runNegativeTest( |
8605 |
if (state[2] == 0) { |
1981 |
new String[] { |
8606 |
if (state[3] == 0) { |
1982 |
"X.java", |
8607 |
return 0; // 0000 |
1983 |
"public class X {\n" + |
8608 |
} |
1984 |
" boolean dummy;\n" + |
8609 |
else { |
1985 |
" void foo() {\n" + |
8610 |
return 1; // 0001 |
1986 |
" Object o = null;\n" + |
8611 |
} |
1987 |
" do {\n" + |
8612 |
} |
1988 |
" o = new Object();\n" + |
8613 |
else { |
1989 |
" }\n" + |
8614 |
if (state[3] == 0) { |
1990 |
" while (dummy);\n" + |
8615 |
return 15; // 0010 |
1991 |
" o.toString();\n" + |
8616 |
} |
1992 |
" }\n" + |
8617 |
else { |
1993 |
"}\n"}, |
8618 |
return 2; // 0011 |
1994 |
"" |
8619 |
} |
1995 |
); |
8620 |
} |
|
|
8621 |
} |
8622 |
else { |
8623 |
if (state[2] == 0) { |
8624 |
if (state[3] == 0) { |
8625 |
return 13; // 0100 |
8626 |
} |
8627 |
else { |
8628 |
return 12; // 0101 |
8629 |
} |
8630 |
} |
8631 |
else { |
8632 |
if (state[3] == 0) { |
8633 |
return 14; // 0110 |
8634 |
} |
8635 |
else { |
8636 |
return 3; // 0111 |
8637 |
} |
8638 |
} |
8639 |
} |
1996 |
} |
8640 |
} |
1997 |
|
8641 |
else { |
1998 |
// null analysis -- do while |
8642 |
if (state[1] == 0) { |
1999 |
public void test0209_do_while() { |
8643 |
if (state[2] == 0) { |
2000 |
this.runNegativeTest( |
8644 |
if (state[3] == 0) { |
2001 |
new String[] { |
8645 |
return 7; // 1000 |
2002 |
"X.java", |
8646 |
} |
2003 |
"public class X {\n" + |
8647 |
else { |
2004 |
" boolean dummy;\n" + |
8648 |
return 10; // 1001 |
2005 |
" void foo() {\n" + |
8649 |
} |
2006 |
" Object o = null;\n" + |
8650 |
} |
2007 |
" do { /* */ }\n" + |
8651 |
else { |
2008 |
" while (dummy);\n" + |
8652 |
if (state[3] == 0) { |
2009 |
" o.toString();\n" + |
8653 |
return 8; // 1010 |
2010 |
" }\n" + |
8654 |
} |
2011 |
"}\n"}, |
8655 |
else { |
2012 |
"----------\n" + |
8656 |
return 9; // 1011 |
2013 |
"1. WARNING in X.java (at line 7)\n" + |
8657 |
} |
2014 |
" o.toString();\n" + |
8658 |
} |
2015 |
" ^\n" + |
8659 |
} |
2016 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
8660 |
else { |
2017 |
"----------\n" |
8661 |
if (state[2] == 0) { |
2018 |
); |
8662 |
if (state[3] == 0) { |
|
|
8663 |
return 6; // 1100 |
8664 |
} |
8665 |
else { |
8666 |
return 11; // 1101 |
8667 |
} |
8668 |
} |
8669 |
else { |
8670 |
if (state[3] == 0) { |
8671 |
return 5; // 1110 |
8672 |
} |
8673 |
else { |
8674 |
return 4; // 1111 |
8675 |
} |
8676 |
} |
8677 |
} |
2019 |
} |
8678 |
} |
|
|
8679 |
} |
8680 |
} |
2020 |
|
8681 |
|
2021 |
// null analysis -- for |
8682 |
class TestLocalVariableBinding extends LocalVariableBinding { |
2022 |
// TODO (maxime) fix |
8683 |
final static char [] testName = {'t', 'e', 's', 't'}; |
2023 |
public void _test0221_for() { |
8684 |
TestLocalVariableBinding(int id) { |
2024 |
this.runNegativeTest( |
8685 |
super(testName, null, 0, false); |
2025 |
new String[] { |
8686 |
this.id = id; |
2026 |
"X.java", |
|
|
2027 |
"public class X {\n" + |
2028 |
" void foo() {\n" + |
2029 |
" Object o = null;\n" + |
2030 |
" for (;o.toString() != null;) {/* */}\n" + |
2031 |
// complain: NPE |
2032 |
" }\n" + |
2033 |
"}\n"}, |
2034 |
"----------\n" + |
2035 |
"1. WARNING in X.java (at line 4)\n" + |
2036 |
" for (;o.toString() != null;) {/* */}\n" + |
2037 |
" ^\n" + |
2038 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2039 |
"----------\n" |
2040 |
); |
2041 |
} |
8687 |
} |
|
|
8688 |
} |
2042 |
|
8689 |
|
2043 |
// null analysis -- for |
8690 |
/** |
2044 |
// TODO (maxime) fix |
8691 |
* A class meant to augment |
2045 |
public void _test0222_for() { |
8692 |
* @link{org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo} with |
2046 |
this.runNegativeTest( |
8693 |
* capabilities in the test domain. It especially provides factories to build |
2047 |
new String[] { |
8694 |
* fake flow info instances for use in state transition tables validation. |
2048 |
"X.java", |
8695 |
*/ |
2049 |
"public class X {\n" + |
8696 |
class UnconditionalFlowInfoTestHarness extends UnconditionalFlowInfo { |
2050 |
" void foo() {\n" + |
8697 |
private int testPosition; |
2051 |
" Object o = null;\n" + |
8698 |
|
2052 |
" for (;o != null;) {/* */}\n" + |
8699 |
/** |
2053 |
// complain: get o null first time and forever |
8700 |
* Return a fake unconditional flow info which bit fields represent the given |
2054 |
" }\n" + |
8701 |
* null bits for a local variable of id 0 within a class that would have no |
2055 |
"}\n"}, |
8702 |
* field. |
2056 |
"----------\n" + |
8703 |
* @param nullBits the bits that must be set, given in the same order as the |
2057 |
"1. WARNING in X.java (at line 4)\n" + |
8704 |
* nullAssignment* fields in UnconditionalFlowInfo definition; use 0 |
2058 |
" for (;o != null;) {/* */}\n" + |
8705 |
* for a bit that is not set, 1 else |
2059 |
" ^\n" + |
8706 |
* @return a fake unconditional flow info which bit fields represent the |
2060 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
8707 |
* null bits given in parameter |
2061 |
"----------\n" |
8708 |
*/ |
2062 |
); |
8709 |
public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( |
2063 |
} |
8710 |
long [] nullBits) { |
|
|
8711 |
return testUnconditionalFlowInfo(nullBits, 0); |
8712 |
} |
2064 |
|
8713 |
|
2065 |
// null analysis -- for |
8714 |
public FlowInfo copy() { |
2066 |
public void test0223_for() { |
8715 |
UnconditionalFlowInfoTestHarness copy = |
2067 |
this.runNegativeTest( |
8716 |
new UnconditionalFlowInfoTestHarness(); |
2068 |
new String[] { |
8717 |
copy.testPosition = this.testPosition; |
2069 |
"X.java", |
8718 |
copy.definiteInits = this.definiteInits; |
2070 |
"public class X {\n" + |
8719 |
copy.potentialInits = this.potentialInits; |
2071 |
" void foo() {\n" + |
8720 |
boolean hasNullInfo = (this.tagBits & NULL_FLAG_MASK) != 0; |
2072 |
" Object o = null;\n" + |
8721 |
if (hasNullInfo) { |
2073 |
" for (;o == null;) {\n" + |
8722 |
copy.nullAssignmentStatusBit1 = this.nullAssignmentStatusBit1; |
2074 |
// quiet: first iteration is sure to find it null, |
8723 |
copy.nullAssignmentStatusBit2 = this.nullAssignmentStatusBit2; |
2075 |
// but other iterations may change it |
8724 |
copy.nullAssignmentValueBit1 = this.nullAssignmentValueBit1; |
2076 |
" o = new Object();\n" + |
8725 |
copy.nullAssignmentValueBit2 = this.nullAssignmentValueBit2; |
2077 |
" }\n" + |
8726 |
} |
2078 |
" }\n" + |
8727 |
copy.tagBits = this.tagBits; |
2079 |
"}\n"}, |
8728 |
copy.maxFieldCount = this.maxFieldCount; |
2080 |
"" |
8729 |
if (this.extra != null) { |
2081 |
); |
8730 |
int length; |
|
|
8731 |
copy.extra = new long[extraLength][]; |
8732 |
System.arraycopy(this.extra[0], 0, |
8733 |
(copy.extra[0] = new long[length = extra[0].length]), 0, length); |
8734 |
System.arraycopy(this.extra[1], 0, |
8735 |
(copy.extra[1] = new long[length]), 0, length); |
8736 |
if (hasNullInfo) { |
8737 |
for (int j = 0; j < extraLength; j++) { |
8738 |
System.arraycopy(this.extra[j], 0, |
8739 |
(copy.extra[j] = new long[length]), 0, length); |
8740 |
} |
8741 |
} |
8742 |
else { |
8743 |
for (int j = 0; j < extraLength; j++) { |
8744 |
copy.extra[j] = new long[length]; |
8745 |
} |
8746 |
} |
2082 |
} |
8747 |
} |
|
|
8748 |
return copy; |
8749 |
} |
2083 |
|
8750 |
|
2084 |
// null analysis -- for |
8751 |
/** |
2085 |
public void test0224_for() { |
8752 |
* Return a fake unconditional flow info which bit fields represent the given |
2086 |
this.runNegativeTest( |
8753 |
* null bits for a local variable of id position within a class that would have |
2087 |
new String[] { |
8754 |
* no field. |
2088 |
"X.java", |
8755 |
* @param nullBits the bits that must be set, given in the same order as the |
2089 |
"public class X {\n" + |
8756 |
* nullAssignment* fields in UnconditionalFlowInfo definition; use 0 |
2090 |
" void foo() {\n" + |
8757 |
* for a bit that is not set, 1 else |
2091 |
" Object o = null;\n" + |
8758 |
* @param position the position of the variable within the bit fields; use |
2092 |
" for (;o == null;) {\n" + |
8759 |
* various values to test different parts of the bit fields, within |
2093 |
// quiet: first iteration is sure to find it null, |
8760 |
* or beyond BitCacheSize |
2094 |
// but other iterations may change it |
8761 |
* @return a fake unconditional flow info which bit fields represent the |
2095 |
" if (System.currentTimeMillis() > 10L) {\n" + |
8762 |
* null bits given in parameter |
2096 |
" o = new Object();\n" + |
8763 |
*/ |
2097 |
" }\n" + |
8764 |
public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( |
2098 |
" }\n" + |
8765 |
long [] nullBits, int position) { |
2099 |
" }\n" + |
8766 |
UnconditionalFlowInfoTestHarness result = |
2100 |
"}\n"}, |
8767 |
new UnconditionalFlowInfoTestHarness(); |
2101 |
"" |
8768 |
result.testPosition = position; |
2102 |
); |
8769 |
if (position < BitCacheSize) { |
|
|
8770 |
result.nullAssignmentStatusBit1 = nullBits[0] << position; |
8771 |
result.nullAssignmentStatusBit2 = nullBits[1] << position; |
8772 |
result.nullAssignmentValueBit1 = nullBits[2] << position; |
8773 |
result.nullAssignmentValueBit2 = nullBits[3] << position; |
8774 |
} |
8775 |
else { |
8776 |
int vectorIndex = (position / BitCacheSize) - 1, |
8777 |
length = vectorIndex + 1; |
8778 |
position %= BitCacheSize; |
8779 |
result.extra = new long[extraLength][]; |
8780 |
result.extra[0] = new long[length]; |
8781 |
result.extra[1] = new long[length]; |
8782 |
for (int j = 2; j < extraLength; j++) { |
8783 |
result.extra[j] = new long[length]; |
8784 |
result.extra[j][vectorIndex] = nullBits[j - 2] << |
8785 |
position; |
8786 |
} |
2103 |
} |
8787 |
} |
2104 |
|
8788 |
if ((nullBits[0] | nullBits[1] | nullBits[2] | nullBits[3]) != 0) { |
2105 |
// null analysis -- for |
8789 |
result.tagBits |= NULL_FLAG_MASK; |
2106 |
// TODO (maxime) fix |
|
|
2107 |
public void _test0225_for() { |
2108 |
this.runNegativeTest( |
2109 |
new String[] { |
2110 |
"X.java", |
2111 |
"public class X {\n" + |
2112 |
" boolean bar() {\n" + |
2113 |
" return true;\n" + |
2114 |
" }\n" + |
2115 |
" void foo(Object o) {\n" + |
2116 |
" for (;bar() && o == null;) {\n" + |
2117 |
" o.toString();\n" + // complain: NPE because of condition |
2118 |
" o = new Object();\n" + |
2119 |
" }\n" + |
2120 |
" }\n" + |
2121 |
"}\n"}, |
2122 |
"----------\n" + |
2123 |
"1. WARNING in X.java (at line 7)\n" + |
2124 |
" o.toString();\n" + |
2125 |
" ^\n" + |
2126 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2127 |
"----------\n" |
2128 |
); |
2129 |
} |
8790 |
} |
|
|
8791 |
result.maxFieldCount = 0; |
8792 |
return result; |
8793 |
} |
2130 |
|
8794 |
|
2131 |
// null analysis -- for |
8795 |
/** |
2132 |
public void test0227_for() { |
8796 |
* Return a fake unconditional flow info which bit fields represent the given |
2133 |
this.runNegativeTest( |
8797 |
* null bits for a pair of local variables of id position and position + |
2134 |
new String[] { |
8798 |
* extra * BitCacheSize within a class that would have no field. |
2135 |
"X.java", |
8799 |
* @param nullBits the bits that must be set, given in the same order as the |
2136 |
"public class X {\n" + |
8800 |
* nullAssignment* fields in UnconditionalFlowInfo definition; use 0 |
2137 |
" void foo(Object o) {\n" + |
8801 |
* for a bit that is not set, 1 else |
2138 |
" for (;o == null; o.toString()) {\n" + |
8802 |
* @param position the position of the variable within the bit fields; use |
2139 |
" o = new Object();\n" + |
8803 |
* various values to test different parts of the bit fields, within |
2140 |
" }\n" + |
8804 |
* or beyond BitCacheSize |
2141 |
" }\n" + |
8805 |
* @param extra the length of the allocated extra bit fields, if position is |
2142 |
"}\n"}, |
8806 |
* beyond BitCacheSize; unused otherwise; make sure it is big enough to |
2143 |
"" |
8807 |
* match position (that is, extra > position - BitCacheSize) |
2144 |
); |
8808 |
* @return a fake unconditional flow info which bit fields represent the |
|
|
8809 |
* null bits given in parameter |
8810 |
*/ |
8811 |
public static UnconditionalFlowInfoTestHarness testUnconditionalFlowInfo( |
8812 |
long [] nullBits, int position, int extra) { |
8813 |
UnconditionalFlowInfoTestHarness result = |
8814 |
new UnconditionalFlowInfoTestHarness(); |
8815 |
result.testPosition = position; |
8816 |
if (position < BitCacheSize) { |
8817 |
result.nullAssignmentStatusBit1 = nullBits[0] << position; |
8818 |
result.nullAssignmentStatusBit2 = nullBits[1] << position; |
8819 |
result.nullAssignmentValueBit1 = nullBits[2] << position; |
8820 |
result.nullAssignmentValueBit2 = nullBits[3] << position; |
8821 |
} |
8822 |
else { |
8823 |
int vectorIndex = (position / BitCacheSize) - 1, |
8824 |
length = extra / BitCacheSize; |
8825 |
position %= BitCacheSize; |
8826 |
result.extra = new long[extraLength][]; |
8827 |
result.extra[0] = new long[length]; |
8828 |
result.extra[1] = new long[length]; |
8829 |
for (int j = 2; j < extraLength; j++) { |
8830 |
result.extra[j] = new long[length]; |
8831 |
result.extra[j] [vectorIndex]= nullBits[j - 2] << position; |
8832 |
} |
8833 |
} |
8834 |
if (nullBits[1] != 0 || nullBits[3] != 0 || nullBits[0] != 0 || nullBits[2] != 0 ) { |
8835 |
// cascade better than nullBits[0] | nullBits[1] | nullBits[2] | nullBits[3] |
8836 |
// by 10%+ |
8837 |
// TODO (maxime) run stats to determine which is the better order |
8838 |
result.tagBits |= NULL_FLAG_MASK; |
2145 |
} |
8839 |
} |
|
|
8840 |
result.maxFieldCount = 0; |
8841 |
return result; |
8842 |
} |
2146 |
|
8843 |
|
2147 |
// null analysis -- for |
8844 |
/** |
2148 |
// TODO (maxime) fix |
8845 |
* Return true iff this flow info can be considered as equal to the one passed |
2149 |
public void _test0228_for() { |
8846 |
* in parameter. |
2150 |
this.runNegativeTest( |
8847 |
* @param other the flow info to compare to |
2151 |
new String[] { |
8848 |
* @return true iff this flow info compares equal to other |
2152 |
"X.java", |
8849 |
*/ |
2153 |
"public class X {\n" + |
8850 |
public boolean testEquals(UnconditionalFlowInfo other) { |
2154 |
" void foo(Object o) {\n" + |
8851 |
if (this.tagBits != other.tagBits) { |
2155 |
" for (;o == null; o.toString()) {\n" + |
8852 |
return false; |
2156 |
" }\n" + |
8853 |
} |
2157 |
" }\n" + |
8854 |
if (this.nullAssignmentStatusBit1 != other.nullAssignmentStatusBit1 || |
2158 |
"}\n"}, |
8855 |
this.nullAssignmentStatusBit2 != other.nullAssignmentStatusBit2 || |
2159 |
"----------\n" + |
8856 |
this.nullAssignmentValueBit1 != other.nullAssignmentValueBit1 || |
2160 |
"1. WARNING in X.java (at line 3)\n" + |
8857 |
this.nullAssignmentValueBit2 != other.nullAssignmentValueBit2) { |
2161 |
" for (;o == null; o.toString()) {\n" + |
8858 |
return false; |
2162 |
" ^\n" + |
8859 |
} |
2163 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
8860 |
int left = this.extra == null ? 0 : this.extra[0].length, |
2164 |
"----------\n" |
8861 |
right = other.extra == null ? 0 : other.extra[0].length, |
2165 |
); |
8862 |
both = 0, i; |
2166 |
} |
8863 |
if (left > right) { |
2167 |
|
8864 |
both = right; |
2168 |
// null analysis -- for |
8865 |
} |
2169 |
// TODO (maxime) fix |
8866 |
else { |
2170 |
public void _test0229_for() { |
8867 |
both = left; |
2171 |
this.runNegativeTest( |
8868 |
} |
2172 |
new String[] { |
8869 |
for (i = 0; i < both ; i++) { |
2173 |
"X.java", |
8870 |
if (this.extra[2][i] != |
2174 |
"public class X {\n" + |
8871 |
other.extra[2][i] || |
2175 |
" void foo(Object o) {\n" + |
8872 |
this.extra[3][i] != |
2176 |
" for (o.toString(); o == null;) { /* */ }\n" + // complain: protected then unchanged |
8873 |
other.extra[3][i] || |
2177 |
" }\n" + |
8874 |
this.extra[4][i] != |
2178 |
"}\n"}, |
8875 |
other.extra[4][i] || |
2179 |
"----------\n" + |
8876 |
this.extra[5][i] != |
2180 |
"1. WARNING in X.java (at line 3)\n" + |
8877 |
other.extra[5][i]) { |
2181 |
" for (o.toString(); o == null;) { /* */ }\n" + |
8878 |
return false; |
2182 |
" ^\n" + |
8879 |
} |
2183 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
|
|
2184 |
"----------\n" |
2185 |
); |
2186 |
} |
2187 |
|
2188 |
// null analysis -- for |
2189 |
public void test0230_for() { |
2190 |
this.runNegativeTest( |
2191 |
new String[] { |
2192 |
"X.java", |
2193 |
"public class X {\n" + |
2194 |
" boolean bar() {\n" + |
2195 |
" return true;\n" + |
2196 |
" }\n" + |
2197 |
" void foo(Object o) {\n" + |
2198 |
" o = null;\n" + |
2199 |
" for (o.toString(); bar();) {\n" + |
2200 |
" }\n" + |
2201 |
" }\n" + |
2202 |
"}\n"}, |
2203 |
"----------\n" + |
2204 |
"1. WARNING in X.java (at line 7)\n" + |
2205 |
" for (o.toString(); bar();) {\n" + |
2206 |
" ^\n" + |
2207 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2208 |
"----------\n" |
2209 |
); |
2210 |
} |
8880 |
} |
2211 |
|
8881 |
for (; i < left; i++) { |
2212 |
// null analysis -- for |
8882 |
if (this.extra[2][i] != 0 || |
2213 |
// TODO (maxime) fix |
8883 |
this.extra[3][i] != 0 || |
2214 |
public void _test0231_for() { |
8884 |
this.extra[4][i] != 0 || |
2215 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
8885 |
this.extra[5][i] != 0) { |
2216 |
this.runNegativeTest( |
8886 |
return false; |
2217 |
new String[] { |
|
|
2218 |
"X.java", |
2219 |
"public class X {\n" + |
2220 |
" void foo() {\n" + |
2221 |
" Object t[] = null;\n" + |
2222 |
" for (Object o : t) {/* */}\n" + |
2223 |
// complain: NPE |
2224 |
" }\n" + |
2225 |
"}\n"}, |
2226 |
"----------\n" + |
2227 |
"1. WARNING in X.java (at line 4)\n" + |
2228 |
" for (Object o : t) {/* */}\n" + |
2229 |
" ^\n" + |
2230 |
"The variable t can only be null; it was either set to null or checked for null when last used\n" + |
2231 |
"----------\n" |
2232 |
); |
2233 |
} |
2234 |
} |
2235 |
|
2236 |
// null analysis -- for |
2237 |
// TODO (maxime) fix |
2238 |
public void _test0232_for() { |
2239 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
2240 |
this.runNegativeTest( |
2241 |
new String[] { |
2242 |
"X.java", |
2243 |
"public class X {\n" + |
2244 |
" void foo() {\n" + |
2245 |
" Iterable i = null;\n" + |
2246 |
" for (Object o : i) {/* */}\n" + |
2247 |
// complain: NPE |
2248 |
" }\n" + |
2249 |
"}\n"}, |
2250 |
"----------\n" + |
2251 |
"1. WARNING in X.java (at line 4)\n" + |
2252 |
" for (Object o : i) {/* */}\n" + |
2253 |
" ^\n" + |
2254 |
"The variable i can only be null; it was either set to null or checked for null when last used\n" + |
2255 |
"----------\n" |
2256 |
); |
2257 |
} |
2258 |
} |
2259 |
|
2260 |
// null analysis -- for |
2261 |
public void test0233_for() { |
2262 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
2263 |
this.runNegativeTest( |
2264 |
new String[] { |
2265 |
"X.java", |
2266 |
"public class X {\n" + |
2267 |
" void foo() {\n" + |
2268 |
" Object t[] = new Object[1];\n" + |
2269 |
" for (Object o : t) {/* */}\n" + |
2270 |
" }\n" + |
2271 |
"}\n"}, |
2272 |
"" |
2273 |
); |
2274 |
} |
2275 |
} |
2276 |
|
2277 |
// null analysis -- for |
2278 |
public void test0234_for() { |
2279 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
2280 |
this.runNegativeTest( |
2281 |
new String[] { |
2282 |
"X.java", |
2283 |
"public class X {\n" + |
2284 |
" void foo() {\n" + |
2285 |
" Iterable i = new java.util.Vector<Object>();\n" + |
2286 |
" for (Object o : i) {/* */}\n" + |
2287 |
" }\n" + |
2288 |
"}\n"}, |
2289 |
"" |
2290 |
); |
2291 |
} |
2292 |
} |
2293 |
|
2294 |
// null analysis -- for |
2295 |
public void test0235_for() { |
2296 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
2297 |
this.runNegativeTest( |
2298 |
new String[] { |
2299 |
"X.java", |
2300 |
"public class X {\n" + |
2301 |
" void foo() {\n" + |
2302 |
" Iterable i = new java.util.Vector<Object>();\n" + |
2303 |
" Object flag = null;\n" + |
2304 |
" for (Object o : i) {\n" + |
2305 |
" flag = new Object();\n" + |
2306 |
" }\n" + |
2307 |
" flag.toString();\n" + |
2308 |
" }\n" + |
2309 |
"}\n"}, |
2310 |
"" |
2311 |
); |
2312 |
} |
8887 |
} |
2313 |
} |
8888 |
} |
2314 |
|
8889 |
for (; i < right; i++) { |
2315 |
// null analysis -- for |
8890 |
if (other.extra[2][i] != 0 || |
2316 |
// TODO (maxime) fix |
8891 |
other.extra[3][i] != 0 || |
2317 |
public void _test0236_for() { |
8892 |
other.extra[4][i] != 0 || |
2318 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
8893 |
other.extra[5][i] != 0) { |
2319 |
this.runNegativeTest( |
8894 |
return false; |
2320 |
new String[] { |
|
|
2321 |
"X.java", |
2322 |
"public class X {\n" + |
2323 |
" void foo() {\n" + |
2324 |
" Iterable i = new java.util.Vector<Object>();\n" + |
2325 |
" Object flag = null;\n" + |
2326 |
" for (Object o : i) { /* */ }\n" + |
2327 |
" flag.toString();\n" + |
2328 |
" }\n" + |
2329 |
"}\n"}, |
2330 |
"----------\n" + |
2331 |
"1. WARNING in X.java (at line 6)\n" + |
2332 |
" flag.toString();\n" + |
2333 |
" ^^^^\n" + |
2334 |
"The variable flag can only be null; it was either set to null or checked for null when last used\n" + |
2335 |
"----------\n" |
2336 |
); |
2337 |
} |
8895 |
} |
2338 |
} |
8896 |
} |
|
|
8897 |
return true; |
8898 |
} |
2339 |
|
8899 |
|
2340 |
// null analysis -- for |
8900 |
/** |
2341 |
public void test0237_for() { |
8901 |
* Return true iff this flow info can be considered as equal to the one passed |
2342 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
8902 |
* in parameter in respect with a single local variable which id would be |
2343 |
this.runNegativeTest( |
8903 |
* position in a class with no field. |
2344 |
new String[] { |
8904 |
* @param other the flow info to compare to |
2345 |
"X.java", |
8905 |
* @param position the position of the local to consider |
2346 |
"public class X {\n" + |
8906 |
* @return true iff this flow info compares equal to other for a given local |
2347 |
" void foo(boolean dummy) {\n" + |
8907 |
*/ |
2348 |
" Object flag = null;\n" + |
8908 |
public boolean testEquals(UnconditionalFlowInfo other, int position) { |
2349 |
" for (;dummy;) {\n" + |
8909 |
int vectorIndex = position / BitCacheSize - 1; |
2350 |
" flag = new Object();\n" + |
8910 |
if ((this.tagBits & other.tagBits & NULL_FLAG_MASK) == 0) { |
2351 |
" }\n" + |
8911 |
return true; |
2352 |
" flag.toString();\n" + |
8912 |
} |
2353 |
" }\n" + |
8913 |
long mask; |
2354 |
"}\n"}, |
8914 |
if (vectorIndex < 0) { |
2355 |
"" |
8915 |
return ((this.nullAssignmentStatusBit1 & (mask = (1L << position))) ^ |
2356 |
); |
8916 |
(other.nullAssignmentStatusBit1 & mask)) == 0 && |
|
|
8917 |
((this.nullAssignmentStatusBit2 & mask) ^ |
8918 |
(other.nullAssignmentStatusBit2 & mask)) == 0 && |
8919 |
((this.nullAssignmentValueBit1 & mask) ^ |
8920 |
(other.nullAssignmentValueBit1 & mask)) == 0 && |
8921 |
((this.nullAssignmentValueBit2 & mask) ^ |
8922 |
(other.nullAssignmentValueBit2 & mask)) == 0; |
8923 |
} |
8924 |
else { |
8925 |
int left = this.extra == null ? |
8926 |
0 : |
8927 |
this.extra[0].length; |
8928 |
int right = other.extra == null ? |
8929 |
0 : |
8930 |
other.extra[0].length; |
8931 |
int both = left < right ? left : right; |
8932 |
if (vectorIndex < both) { |
8933 |
return ((this.extra[2][vectorIndex] & |
8934 |
(mask = (1L << (position % BitCacheSize)))) ^ |
8935 |
(other.extra[2][vectorIndex] & mask)) == 0 && |
8936 |
((this.extra[3][vectorIndex] & mask) ^ |
8937 |
(other.extra[3][vectorIndex] & mask)) == 0 && |
8938 |
((this.extra[4][vectorIndex] & mask) ^ |
8939 |
(other.extra[4][vectorIndex] & mask)) == 0 && |
8940 |
((this.extra[5][vectorIndex] & mask) ^ |
8941 |
(other.extra[5][vectorIndex] & mask)) == 0; |
2357 |
} |
8942 |
} |
2358 |
} |
8943 |
if (vectorIndex < left) { |
2359 |
|
8944 |
return ((this.extra[2][vectorIndex] | |
2360 |
// null analysis -- for |
8945 |
this.extra[3][vectorIndex] | |
2361 |
// TODO (maxime) fix |
8946 |
this.extra[4][vectorIndex] | |
2362 |
public void _test0238_for() { |
8947 |
this.extra[5][vectorIndex]) & |
2363 |
if (COMPLIANCE_1_5.equals(this.complianceLevel)) { |
8948 |
(1L << (position % BitCacheSize))) == 0; |
2364 |
this.runNegativeTest( |
|
|
2365 |
new String[] { |
2366 |
"X.java", |
2367 |
"public class X {\n" + |
2368 |
" void foo(boolean dummy) {\n" + |
2369 |
" Object flag = null;\n" + |
2370 |
" for (;dummy;) { /* */ }\n" + |
2371 |
" flag.toString();\n" + |
2372 |
" }\n" + |
2373 |
"}\n"}, |
2374 |
"----------\n" + |
2375 |
"1. WARNING in X.java (at line 5)\n" + |
2376 |
" flag.toString();\n" + |
2377 |
" ^^^^\n" + |
2378 |
"The variable flag can only be null; it was either set to null or checked for null when last used\n" + |
2379 |
"----------\n" |
2380 |
); |
2381 |
} |
8949 |
} |
|
|
8950 |
return ((other.extra[2][vectorIndex] | |
8951 |
other.extra[3][vectorIndex] | |
8952 |
other.extra[4][vectorIndex] | |
8953 |
other.extra[5][vectorIndex]) & |
8954 |
(1L << (position % BitCacheSize))) == 0; |
2382 |
} |
8955 |
} |
2383 |
|
8956 |
} |
2384 |
// null analysis -- for |
|
|
2385 |
// origin: AssignmentTest#test019 |
2386 |
public void test0239_for() { |
2387 |
this.runNegativeTest( |
2388 |
new String[] { |
2389 |
"X.java", |
2390 |
"public class X {\n" + |
2391 |
" public static final char[] foo(char[] a, char c1, char c2) {\n" + |
2392 |
" char[] r = null;\n" + |
2393 |
" for (int i = 0, length = a.length; i < length; i++) {\n" + |
2394 |
" char c = a[i];\n" + |
2395 |
" if (c == c1) {\n" + |
2396 |
" if (r == null) {\n" + |
2397 |
" r = new char[length];\n" + |
2398 |
" }\n" + |
2399 |
" r[i] = c2;\n" + |
2400 |
" } else if (r != null) {\n" + |
2401 |
" r[i] = c;\n" + |
2402 |
" }\n" + |
2403 |
" }\n" + |
2404 |
" if (r == null) return a;\n" + |
2405 |
" return r;\n" + |
2406 |
" }\n" + |
2407 |
"}\n", |
2408 |
}, |
2409 |
""); |
2410 |
} |
2411 |
|
8957 |
|
2412 |
// null analysis -- for |
8958 |
/** |
2413 |
public void test0240_for_continue_break() { |
8959 |
* Return a string suitable for use as a representation of this flow info |
2414 |
this.runNegativeTest( |
8960 |
* within test series. |
2415 |
new String[] { |
8961 |
* @return a string suitable for use as a representation of this flow info |
2416 |
"X.java", |
8962 |
*/ |
2417 |
"public class X {\n" + |
8963 |
public String testString() { |
2418 |
" void foo() {\n" + |
8964 |
if (this == DEAD_END) { |
2419 |
" Object o = new Object();\n" + |
8965 |
return "FlowInfo.DEAD_END"; //$NON-NLS-1$ |
2420 |
" for (int i = 0; i < 10; i++) {\n" + |
|
|
2421 |
" if (o == null) {\n" + // complain: o cannot be null |
2422 |
" continue;\n" + |
2423 |
" }\n" + |
2424 |
" o = null;\n" + |
2425 |
" break;\n" + |
2426 |
" }\n" + |
2427 |
" }\n" + |
2428 |
"}\n", |
2429 |
}, |
2430 |
"----------\n" + |
2431 |
"1. WARNING in X.java (at line 5)\n" + |
2432 |
" if (o == null) {\n" + |
2433 |
" ^\n" + |
2434 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2435 |
"----------\n"); |
2436 |
} |
2437 |
|
2438 |
// null analysis -- switch |
2439 |
public void test0300_switch() { |
2440 |
this.runNegativeTest( |
2441 |
new String[] { |
2442 |
"X.java", |
2443 |
"public class X {\n" + |
2444 |
" int k;\n" + |
2445 |
" void foo() {\n" + |
2446 |
" Object o = null;\n" + |
2447 |
" switch (k) {\n" + |
2448 |
" case 0 :\n" + |
2449 |
" o = new Object();\n" + |
2450 |
" break;\n" + |
2451 |
" case 2 :\n" + |
2452 |
" return;\n" + |
2453 |
" }\n" + |
2454 |
" if(o == null) { /* */ }\n" + // quiet: don't know whether came from 0 or default |
2455 |
" }\n" + |
2456 |
"}\n"}, |
2457 |
"" |
2458 |
); |
2459 |
} |
8966 |
} |
|
|
8967 |
return testString(this.testPosition); |
8968 |
} |
2460 |
|
8969 |
|
2461 |
// null analysis -- switch |
8970 |
/** |
2462 |
public void test0301_switch() { |
8971 |
* Return a string suitable for use as a representation of this flow info |
2463 |
this.runNegativeTest( |
8972 |
* within test series. |
2464 |
new String[] { |
8973 |
* @param position a position to consider instead of this flow info default |
2465 |
"X.java", |
8974 |
* test position |
2466 |
"public class X {\n" + |
8975 |
* @return a string suitable for use as a representation of this flow info |
2467 |
" int k;\n" + |
8976 |
*/ |
2468 |
" void foo() {\n" + |
8977 |
public String testString(int position) { |
2469 |
" Object o = null;\n" + |
8978 |
if (this == DEAD_END) { |
2470 |
" switch (k) {\n" + |
8979 |
return "FlowInfo.DEAD_END"; //$NON-NLS-1$ |
2471 |
" case 0 :\n" + |
8980 |
} |
2472 |
" o = new Object();\n" + |
8981 |
if (position < BitCacheSize) { |
2473 |
" break;\n" + |
8982 |
return "{" + (this.nullAssignmentStatusBit1 >> position) //$NON-NLS-1$ |
2474 |
" default :\n" + |
8983 |
+ "," + (this.nullAssignmentStatusBit2 >> position) //$NON-NLS-1$ |
2475 |
" return;\n" + |
8984 |
+ "," + (this.nullAssignmentValueBit1 >> position) //$NON-NLS-1$ |
2476 |
" }\n" + |
8985 |
+ "," + (this.nullAssignmentValueBit2 >> position) //$NON-NLS-1$ |
2477 |
" if(o == null) { /* */ }\n" + // complain: only get there through 0, o non null |
8986 |
+ "}"; //$NON-NLS-1$ |
2478 |
" }\n" + |
8987 |
} |
2479 |
"}\n"}, |
8988 |
else { |
2480 |
"----------\n" + |
8989 |
int vectorIndex = position / BitCacheSize - 1, |
2481 |
"1. WARNING in X.java (at line 12)\n" + |
8990 |
shift = position % BitCacheSize; |
2482 |
" if(o == null) { /* */ }\n" + |
8991 |
return "{" + (this.extra[2][vectorIndex] //$NON-NLS-1$ |
2483 |
" ^\n" + |
8992 |
>> shift) |
2484 |
"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + |
8993 |
+ "," + (this.extra[3][vectorIndex] //$NON-NLS-1$ |
2485 |
"----------\n" |
8994 |
>> shift) |
2486 |
); |
8995 |
+ "," + (this.extra[4][vectorIndex] //$NON-NLS-1$ |
2487 |
} |
8996 |
>> shift) |
2488 |
|
8997 |
+ "," + (this.extra[5][vectorIndex] //$NON-NLS-1$ |
2489 |
// null analysis -- switch |
8998 |
>> shift) |
2490 |
public void test0302_switch() { |
8999 |
+ "}"; //$NON-NLS-1$ |
2491 |
this.runNegativeTest( |
|
|
2492 |
new String[] { |
2493 |
"X.java", |
2494 |
"public class X {\n" + |
2495 |
" int k;\n" + |
2496 |
" void foo() {\n" + |
2497 |
" Object o = null;\n" + |
2498 |
" switch (k) {\n" + |
2499 |
" case 0 :\n" + |
2500 |
" o.toString();\n" + // complain: o can only be null |
2501 |
" break;\n" + |
2502 |
" }\n" + |
2503 |
" }\n" + |
2504 |
"}\n"}, |
2505 |
"----------\n" + |
2506 |
"1. WARNING in X.java (at line 7)\n" + |
2507 |
" o.toString();\n" + |
2508 |
" ^\n" + |
2509 |
"The variable o can only be null; it was either set to null or checked for null when last used\n" + |
2510 |
"----------\n" |
2511 |
); |
2512 |
} |
2513 |
|
2514 |
// null analysis -- switch |
2515 |
public void test0303_switch() { |
2516 |
this.runNegativeTest( |
2517 |
new String[] { |
2518 |
"X.java", |
2519 |
"public class X {\n" + |
2520 |
" int k;\n" + |
2521 |
" void foo() {\n" + |
2522 |
" Object o = null;\n" + |
2523 |
" switch (k) {\n" + |
2524 |
" case 0 :\n" + |
2525 |
" o = new Object();\n" + |
2526 |
" case 1 :\n" + |
2527 |
" o.toString();\n" + // quiet: may come through 0 or 1 |
2528 |
" break;\n" + |
2529 |
" }\n" + |
2530 |
" }\n" + |
2531 |
"}\n", |
2532 |
}, |
2533 |
""); |
2534 |
} |
9000 |
} |
2535 |
|
9001 |
} |
2536 |
// flow info low-level validation |
|
|
2537 |
// TODO (maxime) try to cover with source level tests instead of intrusive code |
2538 |
} |
9002 |
} |