1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * Test that null pointer exceptions are thrown by the VM.
19  */
20 public class Main {
21   private int f;
main(String[] args)22   public static void main(String[] args) {
23     methodOne();
24   }
25 
methodOne()26   static void methodOne() {
27     methodTwo();
28   }
29 
callSpecial()30   private int callSpecial() {
31     return f;
32   }
33 
callFinal()34   final int callFinal() {
35     return f;
36   }
37 
methodTwo()38   static void methodTwo() {
39     NullPointerException npe = null;
40 
41     int thisLine = 41;
42 
43     new Object().getClass(); // Ensure compiled.
44     try {
45       ((Object) null).getClass();
46     } catch (NullPointerException e) {
47       npe = e;
48     }
49     check(npe, thisLine += 4);
50 
51     new Main().callSpecial();  // Ensure compiled.
52     try {
53       ((Main) null).callSpecial();  // Test invokespecial.
54     } catch (NullPointerException e) {
55       npe = e;
56     }
57     check(npe, thisLine += 8);
58 
59     new Main().callFinal();  // Ensure compiled.
60     try {
61       ((Main) null).callFinal();  // Test invokevirtual on final.
62     } catch (NullPointerException e) {
63       npe = e;
64     }
65     check(npe, thisLine += 8);
66 
67     try {
68       ((Value) null).objectField.toString();
69     } catch (NullPointerException e) {
70       npe = e;
71     }
72     check(npe, thisLine += 7);
73 
74     try {
75       useInt(((Value) null).intField);
76     } catch (NullPointerException e) {
77       npe = e;
78     }
79     check(npe, thisLine += 7);
80 
81     try {
82       useFloat(((Value) null).floatField);
83     } catch (NullPointerException e) {
84       npe = e;
85     }
86     check(npe, thisLine += 7);
87 
88     try {
89       useLong(((Value) null).longField);
90     } catch (NullPointerException e) {
91       npe = e;
92     }
93     check(npe, thisLine += 7);
94 
95     try {
96       useDouble(((Value) null).doubleField);
97     } catch (NullPointerException e) {
98       npe = e;
99     }
100     check(npe, thisLine += 7);
101 
102     try {
103       ((Value) null).objectField = "Fisk";
104     } catch (NullPointerException e) {
105       npe = e;
106     }
107     check(npe, thisLine += 7);
108 
109     try {
110       ((Value) null).intField = 42;
111     } catch (NullPointerException e) {
112       npe = e;
113     }
114     check(npe, thisLine += 7);
115 
116     try {
117       ((Value) null).floatField = 42.0F;
118     } catch (NullPointerException e) {
119       npe = e;
120     }
121     check(npe, thisLine += 7);
122 
123     try {
124       ((Value) null).longField = 42L;
125     } catch (NullPointerException e) {
126       npe = e;
127     }
128     check(npe, thisLine += 7);
129 
130     try {
131       ((Value) null).doubleField = 42.0d;
132     } catch (NullPointerException e) {
133       npe = e;
134     }
135     check(npe, thisLine += 7);
136 
137     try {
138       useInt(((Value) null).byteField);
139     } catch (NullPointerException e) {
140       npe = e;
141     }
142     check(npe, thisLine += 7);
143 
144     try {
145       if (((Value) null).booleanField) { }
146     } catch (NullPointerException e) {
147       npe = e;
148     }
149     check(npe, thisLine += 7);
150 
151     try {
152       useInt(((Value) null).charField);
153     } catch (NullPointerException e) {
154       npe = e;
155     }
156     check(npe, thisLine += 7);
157 
158     try {
159       useInt(((Value) null).shortField);
160     } catch (NullPointerException e) {
161       npe = e;
162     }
163     check(npe, thisLine += 7);
164 
165     try {
166       ((Value) null).byteField = 42;
167     } catch (NullPointerException e) {
168       npe = e;
169     }
170     check(npe, thisLine += 7);
171 
172     try {
173       ((Value) null).booleanField = true;
174     } catch (NullPointerException e) {
175       npe = e;
176     }
177     check(npe, thisLine += 7);
178 
179     try {
180       ((Value) null).charField = '\u0042';
181     } catch (NullPointerException e) {
182       npe = e;
183     }
184     check(npe, thisLine += 7);
185 
186     try {
187       ((Value) null).shortField = 42;
188     } catch (NullPointerException e) {
189       npe = e;
190     }
191     check(npe, thisLine += 7);
192 
193     try {
194       ((Value) null).volatileObjectField.toString();
195     } catch (NullPointerException e) {
196       npe = e;
197     }
198     check(npe, thisLine += 7);
199 
200     try {
201       ((Value) null).volatileObjectField = "Fisk";
202     } catch (NullPointerException e) {
203       npe = e;
204     }
205     check(npe, thisLine += 7);
206 
207     try {
208       useInt(((Value) null).volatileIntField);
209     } catch (NullPointerException e) {
210       npe = e;
211     }
212     check(npe, thisLine += 7);
213 
214     try {
215       ((Value) null).volatileIntField = 42;
216     } catch (NullPointerException e) {
217       npe = e;
218     }
219     check(npe, thisLine += 7);
220 
221     try {
222       useFloat(((Value) null).volatileFloatField);
223     } catch (NullPointerException e) {
224       npe = e;
225     }
226     check(npe, thisLine += 7);
227 
228     try {
229       ((Value) null).volatileFloatField = 42.0F;
230     } catch (NullPointerException e) {
231       npe = e;
232     }
233     check(npe, thisLine += 7);
234 
235     try {
236       useLong(((Value) null).volatileLongField);
237     } catch (NullPointerException e) {
238       npe = e;
239     }
240     check(npe, thisLine += 7);
241 
242     try {
243       ((Value) null).volatileLongField = 42L;
244     } catch (NullPointerException e) {
245       npe = e;
246     }
247     check(npe, thisLine += 7);
248 
249     try {
250       useDouble(((Value) null).volatileDoubleField);
251     } catch (NullPointerException e) {
252       npe = e;
253     }
254     check(npe, thisLine += 7);
255 
256     try {
257       ((Value) null).volatileDoubleField = 42.0d;
258     } catch (NullPointerException e) {
259       npe = e;
260     }
261     check(npe, thisLine += 7);
262 
263     try {
264       useInt(((Value) null).volatileByteField);
265     } catch (NullPointerException e) {
266       npe = e;
267     }
268     check(npe, thisLine += 7);
269 
270     try {
271       ((Value) null).volatileByteField = 42;
272     } catch (NullPointerException e) {
273       npe = e;
274     }
275     check(npe, thisLine += 7);
276 
277     try {
278       if (((Value) null).volatileBooleanField) { }
279     } catch (NullPointerException e) {
280       npe = e;
281     }
282     check(npe, thisLine += 7);
283 
284     try {
285       ((Value) null).volatileBooleanField = true;
286     } catch (NullPointerException e) {
287       npe = e;
288     }
289     check(npe, thisLine += 7);
290 
291     try {
292       useInt(((Value) null).volatileCharField);
293     } catch (NullPointerException e) {
294       npe = e;
295     }
296     check(npe, thisLine += 7);
297 
298     try {
299       ((Value) null).volatileCharField = '\u0042';
300     } catch (NullPointerException e) {
301       npe = e;
302     }
303     check(npe, thisLine += 7);
304 
305     try {
306       useInt(((Value) null).volatileShortField);
307     } catch (NullPointerException e) {
308       npe = e;
309     }
310     check(npe, thisLine += 7);
311 
312     try {
313       ((Value) null).volatileShortField = 42;
314     } catch (NullPointerException e) {
315       npe = e;
316     }
317     check(npe, thisLine += 7);
318 
319     try {
320       ((Object[]) null)[0].toString();
321     } catch (NullPointerException e) {
322       npe = e;
323     }
324     check(npe, thisLine += 7);
325 
326     try {
327       useInt(((int[]) null)[0]);
328     } catch (NullPointerException e) {
329       npe = e;
330     }
331     check(npe, thisLine += 7);
332 
333     try {
334       useFloat(((float[]) null)[0]);
335     } catch (NullPointerException e) {
336       npe = e;
337     }
338     check(npe, thisLine += 7);
339 
340     try {
341       useLong(((long[]) null)[0]);
342     } catch (NullPointerException e) {
343       npe = e;
344     }
345     check(npe, thisLine += 7);
346 
347     try {
348       useDouble(((double[]) null)[0]);
349     } catch (NullPointerException e) {
350       npe = e;
351     }
352     check(npe, thisLine += 7);
353 
354     try {
355       ((Object[]) null)[0] = "Fisk";
356     } catch (NullPointerException e) {
357       npe = e;
358     }
359     check(npe, thisLine += 7);
360 
361     try {
362       ((int[]) null)[0] = 42;
363     } catch (NullPointerException e) {
364       npe = e;
365     }
366     check(npe, thisLine += 7);
367 
368     try {
369       ((float[]) null)[0] = 42.0F;
370     } catch (NullPointerException e) {
371       npe = e;
372     }
373     check(npe, thisLine += 7);
374 
375     try {
376       ((long[]) null)[0] = 42L;
377     } catch (NullPointerException e) {
378       npe = e;
379     }
380     check(npe, thisLine += 7);
381 
382     try {
383       ((double[]) null)[0] = 42.0d;
384     } catch (NullPointerException e) {
385       npe = e;
386     }
387     check(npe, thisLine += 7);
388 
389     try {
390       useInt(((byte[]) null)[0]);
391     } catch (NullPointerException e) {
392       npe = e;
393     }
394     check(npe, thisLine += 7);
395 
396     try {
397       if (((boolean[]) null)[0]) { }
398     } catch (NullPointerException e) {
399       npe = e;
400     }
401     check(npe, thisLine += 7);
402 
403     try {
404       useInt(((char[]) null)[0]);
405     } catch (NullPointerException e) {
406       npe = e;
407     }
408     check(npe, thisLine += 7);
409 
410     try {
411       useInt(((short[]) null)[0]);
412     } catch (NullPointerException e) {
413       npe = e;
414     }
415     check(npe, thisLine += 7);
416 
417     try {
418       ((byte[]) null)[0] = 42;
419     } catch (NullPointerException e) {
420       npe = e;
421     }
422     check(npe, thisLine += 7);
423 
424     try {
425       ((boolean[]) null)[0] = true;
426     } catch (NullPointerException e) {
427       npe = e;
428     }
429     check(npe, thisLine += 7);
430 
431     try {
432       ((char[]) null)[0] = '\u0042';
433     } catch (NullPointerException e) {
434       npe = e;
435     }
436     check(npe, thisLine += 7);
437 
438     try {
439       ((short[]) null)[0] = 42;
440     } catch (NullPointerException e) {
441       npe = e;
442     }
443     check(npe, thisLine += 7);
444 
445     try {
446       useInt(((Object[]) null).length);
447     } catch (NullPointerException e) {
448       npe = e;
449     }
450     check(npe, thisLine += 7);
451 
452     try {
453       useInt(((int[]) null).length);
454     } catch (NullPointerException e) {
455       npe = e;
456     }
457     check(npe, thisLine += 7);
458 
459     try {
460       useInt(((float[]) null).length);
461     } catch (NullPointerException e) {
462       npe = e;
463     }
464     check(npe, thisLine += 7);
465 
466     try {
467       useInt(((long[]) null).length);
468     } catch (NullPointerException e) {
469       npe = e;
470     }
471     check(npe, thisLine += 7);
472 
473     try {
474       useInt(((double[]) null).length);
475     } catch (NullPointerException e) {
476       npe = e;
477     }
478     check(npe, thisLine += 7);
479 
480     try {
481       useInt(((byte[]) null).length);
482     } catch (NullPointerException e) {
483       npe = e;
484     }
485     check(npe, thisLine += 7);
486 
487     try {
488       useInt(((boolean[]) null).length);
489     } catch (NullPointerException e) {
490       npe = e;
491     }
492     check(npe, thisLine += 7);
493 
494     try {
495       useInt(((char[]) null).length);
496     } catch (NullPointerException e) {
497       npe = e;
498     }
499     check(npe, thisLine += 7);
500 
501     try {
502       useInt(((short[]) null).length);
503     } catch (NullPointerException e) {
504       npe = e;
505     }
506     check(npe, thisLine += 7);
507 
508     try {
509       Interface i = null;
510       i.methodInterface();  // Test null on invokeinterface.
511     } catch (NullPointerException e) {
512       npe = e;
513     }
514     check(npe, thisLine += 8);
515 
516     try {
517       Object o = null;
518       o.toString();  // Test null on invokevirtual.
519     } catch (NullPointerException e) {
520       npe = e;
521     }
522     check(npe, thisLine += 8);
523 
524     npe = null;
525     try {
526       String s = null;
527       try {
528         throw new AssertionError();
529       } finally {
530         // Cause an implicit NPE.
531         s.getClass();
532       }
533     } catch (NullPointerException e) {
534       npe = e;
535     }
536     check(npe, thisLine += 13);
537 
538     npe = null;
539     try {
540       String s = null;
541       try {
542         throw new AssertionError();
543       } catch (AssertionError ex) {
544       }
545       s.getClass();
546     } catch (NullPointerException e) {
547       npe = e;
548     }
549     check(npe, thisLine += 14);
550   }
551 
check(NullPointerException npe, int firstLine)552   static void check(NullPointerException npe, int firstLine) {
553     final boolean debug = false;
554     if (debug) {
555       System.out.print("Got to line ");
556       System.out.print(firstLine);
557       System.out.println();
558     }
559     StackTraceElement[] trace = npe.getStackTrace();
560     checkElement(trace[0], "Main", "methodTwo", "Main.java", firstLine);
561     checkElement(trace[1], "Main", "methodOne", "Main.java", 27);
562     checkElement(trace[2], "Main", "main", "Main.java", 23);
563   }
564 
checkElement(StackTraceElement element, String declaringClass, String methodName, String fileName, int lineNumber)565   static void checkElement(StackTraceElement element,
566                                   String declaringClass, String methodName,
567                                   String fileName, int lineNumber) {
568     assertEquals(declaringClass, element.getClassName());
569     assertEquals(methodName, element.getMethodName());
570     assertEquals(fileName, element.getFileName());
571     assertEquals(lineNumber, element.getLineNumber());
572   }
573 
assertEquals(Object expected, Object actual)574   static void assertEquals(Object expected, Object actual) {
575     if (!expected.equals(actual)) {
576       String msg = "Expected \"" + expected + "\" but got \"" + actual + "\"";
577       throw new AssertionError(msg);
578     }
579   }
580 
assertEquals(int expected, int actual)581   static void assertEquals(int expected, int actual) {
582     if (expected != actual) {
583       throw new AssertionError("Expected " + expected + " got " + actual);
584     }
585   }
586 
587   interface Interface {
methodInterface()588     void methodInterface();
589   }
590 
useInt(int i)591   static void useInt(int i) {
592   }
593 
useFloat(float f)594   static void useFloat(float f) {
595   }
596 
useDouble(double d)597   static void useDouble(double d) {
598   }
599 
useLong(long l)600   static void useLong(long l) {
601   }
602 
603   static class Value {
604     Object objectField;
605     int intField;
606     float floatField;
607     long longField;
608     double doubleField;
609     byte byteField;
610     boolean booleanField;
611     char charField;
612     short shortField;
613 
614     volatile Object volatileObjectField;
615     volatile int volatileIntField;
616     volatile float volatileFloatField;
617     volatile long volatileLongField;
618     volatile double volatileDoubleField;
619     volatile byte volatileByteField;
620     volatile boolean volatileBooleanField;
621     volatile char volatileCharField;
622     volatile short volatileShortField;
623   }
624 }
625