1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker public class Main { 18*795d594fSAndroid Build Coastguard Worker static Main obj; 19*795d594fSAndroid Build Coastguard Worker // Make 'doCheck' volatile to prevent optimizations 20*795d594fSAndroid Build Coastguard Worker // in $noinline$bar like LICM that could hoist the null check 21*795d594fSAndroid Build Coastguard Worker // out of the loop. 22*795d594fSAndroid Build Coastguard Worker static volatile boolean doCheck = true; 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker float floatField; 25*795d594fSAndroid Build Coastguard Worker int intField; 26*795d594fSAndroid Build Coastguard Worker main(String[] args)27*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 28*795d594fSAndroid Build Coastguard Worker try { 29*795d594fSAndroid Build Coastguard Worker $noinline$bar(); 30*795d594fSAndroid Build Coastguard Worker throw new Error("Expected NPE"); 31*795d594fSAndroid Build Coastguard Worker } catch (NullPointerException e) { 32*795d594fSAndroid Build Coastguard Worker check(e, 29, 52, "$noinline$bar"); 33*795d594fSAndroid Build Coastguard Worker } 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker try { 36*795d594fSAndroid Build Coastguard Worker $noinline$foo(); 37*795d594fSAndroid Build Coastguard Worker throw new Error("Expected NPE"); 38*795d594fSAndroid Build Coastguard Worker } catch (NullPointerException e) { 39*795d594fSAndroid Build Coastguard Worker check(e, 36, 44, "$noinline$foo"); 40*795d594fSAndroid Build Coastguard Worker } 41*795d594fSAndroid Build Coastguard Worker } 42*795d594fSAndroid Build Coastguard Worker $noinline$foo()43*795d594fSAndroid Build Coastguard Worker public static float $noinline$foo() { 44*795d594fSAndroid Build Coastguard Worker int v1 = obj.intField; 45*795d594fSAndroid Build Coastguard Worker float v2 = obj.floatField; 46*795d594fSAndroid Build Coastguard Worker return v2; 47*795d594fSAndroid Build Coastguard Worker } 48*795d594fSAndroid Build Coastguard Worker $noinline$bar()49*795d594fSAndroid Build Coastguard Worker public static float $noinline$bar() { 50*795d594fSAndroid Build Coastguard Worker float a = 0; 51*795d594fSAndroid Build Coastguard Worker while (doCheck) { 52*795d594fSAndroid Build Coastguard Worker float f = obj.floatField; 53*795d594fSAndroid Build Coastguard Worker int i = obj.intField; 54*795d594fSAndroid Build Coastguard Worker a = (float)i + f; 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker return a; 57*795d594fSAndroid Build Coastguard Worker } 58*795d594fSAndroid Build Coastguard Worker check(NullPointerException npe, int mainLine, int methodLine, String methodName)59*795d594fSAndroid Build Coastguard Worker static void check(NullPointerException npe, int mainLine, int methodLine, String methodName) { 60*795d594fSAndroid Build Coastguard Worker StackTraceElement[] trace = npe.getStackTrace(); 61*795d594fSAndroid Build Coastguard Worker checkElement(trace[0], "Main", methodName, "Main.java", methodLine); 62*795d594fSAndroid Build Coastguard Worker checkElement(trace[1], "Main", "main", "Main.java", mainLine); 63*795d594fSAndroid Build Coastguard Worker } 64*795d594fSAndroid Build Coastguard Worker checkElement(StackTraceElement element, String declaringClass, String methodName, String fileName, int lineNumber)65*795d594fSAndroid Build Coastguard Worker static void checkElement(StackTraceElement element, 66*795d594fSAndroid Build Coastguard Worker String declaringClass, String methodName, 67*795d594fSAndroid Build Coastguard Worker String fileName, int lineNumber) { 68*795d594fSAndroid Build Coastguard Worker assertEquals(declaringClass, element.getClassName()); 69*795d594fSAndroid Build Coastguard Worker assertEquals(methodName, element.getMethodName()); 70*795d594fSAndroid Build Coastguard Worker assertEquals(fileName, element.getFileName()); 71*795d594fSAndroid Build Coastguard Worker assertEquals(lineNumber, element.getLineNumber()); 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker assertEquals(Object expected, Object actual)74*795d594fSAndroid Build Coastguard Worker static void assertEquals(Object expected, Object actual) { 75*795d594fSAndroid Build Coastguard Worker if (!expected.equals(actual)) { 76*795d594fSAndroid Build Coastguard Worker String msg = "Expected \"" + expected + "\" but got \"" + actual + "\""; 77*795d594fSAndroid Build Coastguard Worker throw new AssertionError(msg); 78*795d594fSAndroid Build Coastguard Worker } 79*795d594fSAndroid Build Coastguard Worker } 80*795d594fSAndroid Build Coastguard Worker assertEquals(int expected, int actual)81*795d594fSAndroid Build Coastguard Worker static void assertEquals(int expected, int actual) { 82*795d594fSAndroid Build Coastguard Worker if (expected != actual) { 83*795d594fSAndroid Build Coastguard Worker throw new AssertionError("Expected " + expected + " got " + actual); 84*795d594fSAndroid Build Coastguard Worker } 85*795d594fSAndroid Build Coastguard Worker } 86*795d594fSAndroid Build Coastguard Worker } 87