Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2017 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 public class Main {
     18   static Main obj;
     19   // Make 'doCheck' volatile to prevent optimizations
     20   // in $noinline$bar like LICM that could hoist the null check
     21   // out of the loop.
     22   static volatile boolean doCheck = true;
     23 
     24   float floatField;
     25   int intField;
     26 
     27   public static void main(String[] args) {
     28     try {
     29       $noinline$bar();
     30       throw new Error("Expected NPE");
     31     } catch (NullPointerException e) {
     32       check(e, 29, 52, "$noinline$bar");
     33     }
     34 
     35     try {
     36       $noinline$foo();
     37       throw new Error("Expected NPE");
     38     } catch (NullPointerException e) {
     39       check(e, 36, 44, "$noinline$foo");
     40     }
     41   }
     42 
     43   public static float $noinline$foo() {
     44     int v1 = obj.intField;
     45     float v2 = obj.floatField;
     46     return v2;
     47   }
     48 
     49   public static float $noinline$bar() {
     50     float a = 0;
     51     while (doCheck) {
     52       float f = obj.floatField;
     53       int i = obj.intField;
     54       a = (float)i + f;
     55     }
     56     return a;
     57   }
     58 
     59   static void check(NullPointerException npe, int mainLine, int methodLine, String methodName) {
     60     StackTraceElement[] trace = npe.getStackTrace();
     61     checkElement(trace[0], "Main", methodName, "Main.java", methodLine);
     62     checkElement(trace[1], "Main", "main", "Main.java", mainLine);
     63   }
     64 
     65   static void checkElement(StackTraceElement element,
     66                            String declaringClass, String methodName,
     67                            String fileName, int lineNumber) {
     68     assertEquals(declaringClass, element.getClassName());
     69     assertEquals(methodName, element.getMethodName());
     70     assertEquals(fileName, element.getFileName());
     71     assertEquals(lineNumber, element.getLineNumber());
     72   }
     73 
     74   static void assertEquals(Object expected, Object actual) {
     75     if (!expected.equals(actual)) {
     76       String msg = "Expected \"" + expected + "\" but got \"" + actual + "\"";
     77       throw new AssertionError(msg);
     78     }
     79   }
     80 
     81   static void assertEquals(int expected, int actual) {
     82     if (expected != actual) {
     83       throw new AssertionError("Expected " + expected + " got " + actual);
     84     }
     85   }
     86 }
     87