/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Test that null pointer exceptions are thrown by the VM. */ public class Main { private int f; public static void main(String[] args) { methodOne(); } static void methodOne() { methodTwo(); } private int callSpecial() { return f; } final int callFinal() { return f; } static void methodTwo() { NullPointerException npe = null; int thisLine = 41; new Object().getClass(); // Ensure compiled. try { ((Object) null).getClass(); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 4); new Main().callSpecial(); // Ensure compiled. try { ((Main) null).callSpecial(); // Test invokespecial. } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 8); new Main().callFinal(); // Ensure compiled. try { ((Main) null).callFinal(); // Test invokevirtual on final. } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 8); try { ((Value) null).objectField.toString(); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).intField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useFloat(((Value) null).floatField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useLong(((Value) null).longField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useDouble(((Value) null).doubleField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).objectField = "Fisk"; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).intField = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).floatField = 42.0F; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).longField = 42L; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).doubleField = 42.0d; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).byteField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { if (((Value) null).booleanField) { } } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).charField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).shortField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).byteField = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).booleanField = true; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).charField = '\u0042'; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).shortField = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileObjectField.toString(); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileObjectField = "Fisk"; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).volatileIntField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileIntField = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useFloat(((Value) null).volatileFloatField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileFloatField = 42.0F; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useLong(((Value) null).volatileLongField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileLongField = 42L; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useDouble(((Value) null).volatileDoubleField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileDoubleField = 42.0d; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).volatileByteField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileByteField = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { if (((Value) null).volatileBooleanField) { } } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileBooleanField = true; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).volatileCharField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileCharField = '\u0042'; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Value) null).volatileShortField); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Value) null).volatileShortField = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Object[]) null)[0].toString(); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((int[]) null)[0]); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useFloat(((float[]) null)[0]); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useLong(((long[]) null)[0]); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useDouble(((double[]) null)[0]); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((Object[]) null)[0] = "Fisk"; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((int[]) null)[0] = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((float[]) null)[0] = 42.0F; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((long[]) null)[0] = 42L; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((double[]) null)[0] = 42.0d; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((byte[]) null)[0]); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { if (((boolean[]) null)[0]) { } } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((char[]) null)[0]); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((short[]) null)[0]); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((byte[]) null)[0] = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((boolean[]) null)[0] = true; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((char[]) null)[0] = '\u0042'; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { ((short[]) null)[0] = 42; } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((Object[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((int[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((float[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((long[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((double[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((byte[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((boolean[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((char[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { useInt(((short[]) null).length); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 7); try { Interface i = null; i.methodInterface(); // Test null on invokeinterface. } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 8); try { Object o = null; o.toString(); // Test null on invokevirtual. } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 8); npe = null; try { String s = null; try { throw new AssertionError(); } finally { // Cause an implicit NPE. s.getClass(); } } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 13); npe = null; try { String s = null; try { throw new AssertionError(); } catch (AssertionError ex) { } s.getClass(); } catch (NullPointerException e) { npe = e; } check(npe, thisLine += 14); } static void check(NullPointerException npe, int firstLine) { final boolean debug = false; if (debug) { System.out.print("Got to line "); System.out.print(firstLine); System.out.println(); } StackTraceElement[] trace = npe.getStackTrace(); checkElement(trace[0], "Main", "methodTwo", "Main.java", firstLine); checkElement(trace[1], "Main", "methodOne", "Main.java", 27); checkElement(trace[2], "Main", "main", "Main.java", 23); } static void checkElement(StackTraceElement element, String declaringClass, String methodName, String fileName, int lineNumber) { assertEquals(declaringClass, element.getClassName()); assertEquals(methodName, element.getMethodName()); assertEquals(fileName, element.getFileName()); assertEquals(lineNumber, element.getLineNumber()); } static void assertEquals(Object expected, Object actual) { if (!expected.equals(actual)) { String msg = "Expected \"" + expected + "\" but got \"" + actual + "\""; throw new AssertionError(msg); } } static void assertEquals(int expected, int actual) { if (expected != actual) { throw new AssertionError("Expected " + expected + " got " + actual); } } interface Interface { void methodInterface(); } static void useInt(int i) { } static void useFloat(float f) { } static void useDouble(double d) { } static void useLong(long l) { } static class Value { Object objectField; int intField; float floatField; long longField; double doubleField; byte byteField; boolean booleanField; char charField; short shortField; volatile Object volatileObjectField; volatile int volatileIntField; volatile float volatileFloatField; volatile long volatileLongField; volatile double volatileDoubleField; volatile byte volatileByteField; volatile boolean volatileBooleanField; volatile char volatileCharField; volatile short volatileShortField; } }