test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/NullPointerExceptionTest.java
changeset 58664 e3618c902d17
equal deleted inserted replaced
58663:11a574b352d0 58664:e3618c902d17
       
     1 /*
       
     2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * Copyright (c) 2019 SAP SE. All rights reserved.
       
     4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     5  *
       
     6  * This code is free software; you can redistribute it and/or modify it
       
     7  * under the terms of the GNU General Public License version 2 only, as
       
     8  * published by the Free Software Foundation.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    21  * or visit www.oracle.com if you need additional information or have any
       
    22  * questions.
       
    23  */
       
    24 
       
    25 /**
       
    26  * @test
       
    27  * @summary Test extended NullPointerException message for
       
    28  *   classfiles generated with debug information. In this case the name
       
    29  *   of the variable containing the array is printed.
       
    30  * @bug 8218628
       
    31  * @modules java.base/java.lang:open
       
    32  *          java.base/jdk.internal.org.objectweb.asm
       
    33  * @library /test/lib
       
    34  * @compile -g NullPointerExceptionTest.java
       
    35  * @run main/othervm -XX:MaxJavaStackTraceDepth=1 -XX:+ShowCodeDetailsInExceptionMessages NullPointerExceptionTest hasDebugInfo
       
    36  */
       
    37 /**
       
    38  * @test
       
    39  * @summary Test extended NullPointerException message for class
       
    40  *   files generated without debugging information. The message lists
       
    41  *   detailed information about the entity that is null.
       
    42  * @bug 8218628
       
    43  * @modules java.base/java.lang:open
       
    44  *          java.base/jdk.internal.org.objectweb.asm
       
    45  * @library /test/lib
       
    46  * @compile NullPointerExceptionTest.java
       
    47  * @run main/othervm -XX:MaxJavaStackTraceDepth=1 -XX:+ShowCodeDetailsInExceptionMessages NullPointerExceptionTest
       
    48  */
       
    49 
       
    50 import java.io.ByteArrayInputStream;
       
    51 import java.io.ByteArrayOutputStream;
       
    52 import java.io.ObjectInputStream;
       
    53 import java.io.ObjectOutputStream;
       
    54 import java.lang.invoke.MethodHandles.Lookup;
       
    55 import java.util.ArrayList;
       
    56 
       
    57 import jdk.internal.org.objectweb.asm.ClassWriter;
       
    58 import jdk.internal.org.objectweb.asm.Label;
       
    59 import jdk.internal.org.objectweb.asm.MethodVisitor;
       
    60 import jdk.test.lib.Asserts;
       
    61 
       
    62 import static java.lang.invoke.MethodHandles.lookup;
       
    63 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
       
    64 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
       
    65 import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL;
       
    66 import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
       
    67 import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
       
    68 import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD;
       
    69 import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
       
    70 import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
       
    71 import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_2;
       
    72 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
       
    73 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
       
    74 import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
       
    75 import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
       
    76 import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
       
    77 
       
    78 /**
       
    79  * Tests NullPointerExceptions
       
    80  */
       
    81 public class NullPointerExceptionTest {
       
    82 
       
    83     // Some fields used in the test.
       
    84     static Object nullStaticField;
       
    85     NullPointerExceptionTest nullInstanceField;
       
    86     static int[][][][] staticArray;
       
    87     static long[][] staticLongArray = new long[1000][];
       
    88     DoubleArrayGen dag;
       
    89     ArrayList<String> names = new ArrayList<>();
       
    90     ArrayList<String> curr;
       
    91     static boolean hasDebugInfo = false;
       
    92 
       
    93     static {
       
    94         staticArray       = new int[1][][][];
       
    95         staticArray[0]    = new int[1][][];
       
    96         staticArray[0][0] = new int[1][];
       
    97     }
       
    98 
       
    99     public static void checkMessage(Throwable t, String expression,
       
   100                                     String obtainedMsg, String expectedMsg) {
       
   101         System.out.println("\nSource code:\n  " + expression + "\n\nOutput:");
       
   102         t.printStackTrace(System.out);
       
   103         if (obtainedMsg != expectedMsg && // E.g. both are null.
       
   104             !obtainedMsg.equals(expectedMsg)) {
       
   105             System.out.println("expected msg: " + expectedMsg);
       
   106             Asserts.assertEquals(expectedMsg, obtainedMsg);
       
   107         }
       
   108         System.out.println("\n----");
       
   109     }
       
   110 
       
   111     public static void main(String[] args) throws Exception {
       
   112         NullPointerExceptionTest t = new NullPointerExceptionTest();
       
   113         if (args.length > 0) {
       
   114             hasDebugInfo = true;
       
   115         }
       
   116 
       
   117         System.out.println("Tests for the first part of the message:");
       
   118         System.out.println("========================================\n");
       
   119 
       
   120         // Test the message printed for the failed action.
       
   121         t.testFailedAction();
       
   122 
       
   123         System.out.println("Tests for the second part of the message:");
       
   124         System.out.println("=========================================\n");
       
   125         // Test the method printed for the null entity.
       
   126         t.testNullEntity();
       
   127 
       
   128         System.out.println("Further tests:");
       
   129         System.out.println("==============\n");
       
   130 
       
   131         // Test if parameters are used in the code.
       
   132         // This is relevant if there is no debug information.
       
   133         t.testParameters();
       
   134 
       
   135         // Test that no message is printed for exceptions
       
   136         // allocated explicitly.
       
   137         t.testCreation();
       
   138 
       
   139         // Test that no message is printed for exceptions
       
   140         // thrown in native methods.
       
   141         t.testNative();
       
   142 
       
   143         // Test that two calls to getMessage() return the same
       
   144         // message.
       
   145         // It is a design decision that it returns two different
       
   146         // String objects.
       
   147         t.testSameMessage();
       
   148 
       
   149         // Test serialization.
       
   150         // It is a design decision that after serialization the
       
   151         // the message is lost.
       
   152         t.testSerialization();
       
   153 
       
   154         // Test that messages are printed for code generated
       
   155         // on-the-fly.
       
   156         t.testGeneratedCode();
       
   157 
       
   158         // Some more interesting complex messages.
       
   159         t.testComplexMessages();
       
   160     }
       
   161 
       
   162     // Helper method to cause test case.
       
   163     private double callWithTypes(String[][] dummy1, int[][][] dummy2, float dummy3, long dummy4, short dummy5,
       
   164                                  boolean dummy6, byte dummy7, double dummy8, char dummy9) {
       
   165         return 0.0;
       
   166     }
       
   167 
       
   168     @SuppressWarnings("null")
       
   169     public void testFailedAction() {
       
   170         int[]     ia1 = null;
       
   171         float[]   fa1 = null;
       
   172         Object[]  oa1 = null;
       
   173         boolean[] za1 = null;
       
   174         byte[]    ba1 = null;
       
   175         char[]    ca1 = null;
       
   176         short[]   sa1 = null;
       
   177         long[]    la1 = null;
       
   178         double[]  da1 = null;
       
   179 
       
   180         // iaload
       
   181         try {
       
   182             int val = ia1[0];
       
   183             System.out.println(val);
       
   184             Asserts.fail();
       
   185         } catch (NullPointerException e) {
       
   186             checkMessage(e, "int val = ia1[0];", e.getMessage(),
       
   187                          "Cannot load from int array because " +
       
   188                          (hasDebugInfo ? "\"ia1\"" : "\"<local1>\"") + " is null");
       
   189         }
       
   190         // faload
       
   191         try {
       
   192             float val = fa1[0];
       
   193             System.out.println(val);
       
   194             Asserts.fail();
       
   195         } catch (NullPointerException e) {
       
   196             checkMessage(e, "float val = fa1[0];", e.getMessage(),
       
   197                          "Cannot load from float array because " +
       
   198                          (hasDebugInfo ? "\"fa1\"" : "\"<local2>\"") + " is null");
       
   199         }
       
   200         // aaload
       
   201         try {
       
   202             Object val = oa1[0];
       
   203             System.out.println(val);
       
   204             Asserts.fail();
       
   205         } catch (NullPointerException e) {
       
   206             checkMessage(e, "Object val = oa1[0];", e.getMessage(),
       
   207                          "Cannot load from object array because " +
       
   208                          (hasDebugInfo ? "\"oa1\"" : "\"<local3>\"") + " is null");
       
   209         }
       
   210         // baload (boolean)
       
   211         try {
       
   212             boolean val = za1[0];
       
   213             System.out.println(val);
       
   214             Asserts.fail();
       
   215         } catch (NullPointerException e) {
       
   216             checkMessage(e, "boolean val = za1[0];", e.getMessage(),
       
   217                          "Cannot load from byte/boolean array because " +
       
   218                          (hasDebugInfo ? "\"za1\"" : "\"<local4>\"") + " is null");
       
   219         }
       
   220         // baload (byte)
       
   221         try {
       
   222             byte val = ba1[0];
       
   223             System.out.println(val);
       
   224             Asserts.fail();
       
   225         } catch (NullPointerException e) {
       
   226             checkMessage(e, "byte val = ba1[0];", e.getMessage(),
       
   227                          "Cannot load from byte/boolean array because " +
       
   228                          (hasDebugInfo ? "\"ba1\"" : "\"<local5>\"") + " is null");
       
   229         }
       
   230         // caload
       
   231         try {
       
   232             char val = ca1[0];
       
   233             System.out.println(val);
       
   234             Asserts.fail();
       
   235         } catch (NullPointerException e) {
       
   236             checkMessage(e, "char val = ca1[0];", e.getMessage(),
       
   237                          "Cannot load from char array because " +
       
   238                          (hasDebugInfo ? "\"ca1\"" : "\"<local6>\"") + " is null");
       
   239         }
       
   240         // saload
       
   241         try {
       
   242             short val = sa1[0];
       
   243             System.out.println(val);
       
   244             Asserts.fail();
       
   245         } catch (NullPointerException e) {
       
   246             checkMessage(e, "short val = sa1[0];", e.getMessage(),
       
   247                          "Cannot load from short array because " +
       
   248                          (hasDebugInfo ? "\"sa1\"" : "\"<local7>\"") + " is null");
       
   249         }
       
   250         // laload
       
   251         try {
       
   252             long val = la1[0];
       
   253             System.out.println(val);
       
   254             Asserts.fail();
       
   255         } catch (NullPointerException e) {
       
   256             checkMessage(e, "long val = la1[0];", e.getMessage(),
       
   257                          "Cannot load from long array because " +
       
   258                          (hasDebugInfo ? "\"la1\"" : "\"<local8>\"") + " is null");
       
   259         }
       
   260         // daload
       
   261         try {
       
   262             double val = da1[0];
       
   263             System.out.println(val);
       
   264             Asserts.fail();
       
   265         } catch (NullPointerException e) {
       
   266             checkMessage(e, "double val = da1[0];", e.getMessage(),
       
   267                          "Cannot load from double array because " +
       
   268                          (hasDebugInfo ? "\"da1\"" : "\"<local9>\"") + " is null");
       
   269         }
       
   270 
       
   271         // iastore
       
   272         try {
       
   273             ia1[0] = 0;
       
   274             System.out.println(ia1[0]);
       
   275             Asserts.fail();
       
   276         } catch (NullPointerException e) {
       
   277             checkMessage(e, "ia1[0] = 0;", e.getMessage(),
       
   278                          "Cannot store to int array because " +
       
   279                          (hasDebugInfo ? "\"ia1\"" : "\"<local1>\"") + " is null");
       
   280         }
       
   281         // fastore
       
   282         try {
       
   283             fa1[0] = 0.7f;
       
   284             System.out.println(fa1[0]);
       
   285             Asserts.fail();
       
   286         } catch (NullPointerException e) {
       
   287             checkMessage(e, "fa1[0] = 0.7f;", e.getMessage(),
       
   288                          "Cannot store to float array because " +
       
   289                          (hasDebugInfo ? "\"fa1\"" : "\"<local2>\"") + " is null");
       
   290         }
       
   291         // aastore
       
   292         try {
       
   293             oa1[0] = new Object();
       
   294             System.out.println(oa1[0]);
       
   295             Asserts.fail();
       
   296         } catch (NullPointerException e) {
       
   297             checkMessage(e, "oa1[0] = new Object();", e.getMessage(),
       
   298                          "Cannot store to object array because " +
       
   299                          (hasDebugInfo ? "\"oa1\"" : "\"<local3>\"") + " is null");
       
   300         }
       
   301         // bastore (boolean)
       
   302         try {
       
   303             za1[0] = false;
       
   304             System.out.println(za1[0]);
       
   305             Asserts.fail();
       
   306         } catch (NullPointerException e) {
       
   307             checkMessage(e, "za1[0] = false;", e.getMessage(),
       
   308                          "Cannot store to byte/boolean array because " +
       
   309                          (hasDebugInfo ? "\"za1\"" : "\"<local4>\"") + " is null");
       
   310         }
       
   311         // bastore (byte)
       
   312         try {
       
   313             ba1[0] = 0;
       
   314             System.out.println(ba1[0]);
       
   315             Asserts.fail();
       
   316         } catch (NullPointerException e) {
       
   317             checkMessage(e, "ba1[0] = 0;", e.getMessage(),
       
   318                          "Cannot store to byte/boolean array because " +
       
   319                          (hasDebugInfo ? "\"ba1\"" : "\"<local5>\"") + " is null");
       
   320         }
       
   321         // castore
       
   322         try {
       
   323             ca1[0] = 0;
       
   324             System.out.println(ca1[0]);
       
   325             Asserts.fail();
       
   326         } catch (NullPointerException e) {
       
   327             checkMessage(e, "ca1[0] = 0;", e.getMessage(),
       
   328                          "Cannot store to char array because " +
       
   329                          (hasDebugInfo ? "\"ca1\"" : "\"<local6>\"") + " is null");
       
   330         }
       
   331         // sastore
       
   332         try {
       
   333             sa1[0] = 0;
       
   334             System.out.println(sa1[0]);
       
   335             Asserts.fail();
       
   336         } catch (NullPointerException e) {
       
   337             checkMessage(e, "sa1[0] = 0;", e.getMessage(),
       
   338                          "Cannot store to short array because " +
       
   339                          (hasDebugInfo ? "\"sa1\"" : "\"<local7>\"") + " is null");
       
   340         }
       
   341         // lastore
       
   342         try {
       
   343             la1[0] = 0;
       
   344             System.out.println(la1[0]);
       
   345             Asserts.fail();
       
   346         } catch (NullPointerException e) {
       
   347             checkMessage(e, "la1[0] = 0;", e.getMessage(),
       
   348                          "Cannot store to long array because " +
       
   349                          (hasDebugInfo ? "\"la1\"" : "\"<local8>\"") + " is null");
       
   350         }
       
   351         // dastore
       
   352         try {
       
   353             da1[0] = 0;
       
   354             System.out.println(da1[0]);
       
   355             Asserts.fail();
       
   356         } catch (NullPointerException e) {
       
   357             checkMessage(e, "da1[0] = 0;", e.getMessage(),
       
   358                          "Cannot store to double array because " +
       
   359                          (hasDebugInfo ? "\"da1\"" : "\"<local9>\"") + " is null");
       
   360         }
       
   361 
       
   362         // arraylength
       
   363         try {
       
   364             int val = za1.length;
       
   365             System.out.println(val);
       
   366             Asserts.fail();
       
   367         } catch (NullPointerException e) {
       
   368             checkMessage(e, " int val = za1.length;", e.getMessage(),
       
   369                          "Cannot read the array length because " +
       
   370                          (hasDebugInfo ? "\"za1\"" : "\"<local4>\"") + " is null");
       
   371         }
       
   372         // athrow
       
   373         try {
       
   374             RuntimeException exc = null;
       
   375             throw exc;
       
   376         } catch (NullPointerException e) {
       
   377             checkMessage(e, "throw exc;", e.getMessage(),
       
   378                          "Cannot throw exception because " +
       
   379                          (hasDebugInfo ? "\"exc\"" : "\"<local10>\"") + " is null");
       
   380         }
       
   381         // monitorenter
       
   382         try {
       
   383             synchronized (nullInstanceField) {
       
   384                 // desired
       
   385             }
       
   386         } catch (NullPointerException e) {
       
   387             checkMessage(e, "synchronized (nullInstanceField) { ... }", e.getMessage(),
       
   388                          "Cannot enter synchronized block because " +
       
   389                          "\"this.nullInstanceField\" is null");
       
   390         }
       
   391         // monitorexit
       
   392         // No test available
       
   393 
       
   394         // getfield
       
   395         try {
       
   396             Object val = nullInstanceField.nullInstanceField;
       
   397             System.out.println(val);
       
   398             Asserts.fail();
       
   399         } catch (NullPointerException e) {
       
   400             checkMessage(e, "Object val = nullInstanceField.nullInstanceField;", e.getMessage(),
       
   401                          "Cannot read field \"nullInstanceField\" because " +
       
   402                          "\"this.nullInstanceField\" is null");
       
   403         }
       
   404         // putfield
       
   405         try {
       
   406             nullInstanceField.nullInstanceField = new NullPointerExceptionTest();
       
   407             System.out.println(nullInstanceField.nullInstanceField);
       
   408             Asserts.fail();
       
   409         } catch (NullPointerException e) {
       
   410             checkMessage(e, "nullInstanceField.nullInstanceField = new NullPointerExceptionTest();", e.getMessage(),
       
   411                          "Cannot assign field \"nullInstanceField\" because " +
       
   412                          "\"this.nullInstanceField\" is null");
       
   413         }
       
   414         // invokevirtual
       
   415         try {
       
   416             String val = nullInstanceField.toString();
       
   417             System.out.println(val);
       
   418             Asserts.fail();
       
   419         } catch (NullPointerException e) {
       
   420             checkMessage(e, "String val = nullInstanceField.toString();", e.getMessage(),
       
   421                          "Cannot invoke \"Object.toString()\" because " +
       
   422                          "\"this.nullInstanceField\" is null");
       
   423         }
       
   424         // invokeinterface
       
   425         try {
       
   426             NullPointerExceptionTest obj = this;
       
   427             Object val = obj.dag.getArray();
       
   428             Asserts.assertNull(val);
       
   429             Asserts.fail();
       
   430         } catch (NullPointerException e) {
       
   431             checkMessage(e, "Object val = obj.dag.getArray();", e.getMessage(),
       
   432                          "Cannot invoke \"NullPointerExceptionTest$DoubleArrayGen.getArray()\" because " +
       
   433                          (hasDebugInfo ? "\"obj" : "\"<local10>") + ".dag\" is null");
       
   434         }
       
   435         // invokespecial
       
   436         G g = null;
       
   437         try {
       
   438             byte[] classBytes = G.generateSub2GTestClass();
       
   439             Lookup lookup = lookup();
       
   440             Class<?> clazz = lookup.defineClass(classBytes);
       
   441             g = (G) clazz.getDeclaredConstructor().newInstance();
       
   442         } catch (Exception e) {
       
   443             e.printStackTrace();
       
   444             Asserts.fail("Generating class Sub2G failed.");
       
   445         }
       
   446         try {
       
   447             g.m2("Beginning");
       
   448         } catch (NullPointerException e) {
       
   449             checkMessage(e, "return super.m2(x).substring(2); // ... where super is null by bytecode manipulation.", e.getMessage(),
       
   450                          "Cannot invoke \"G.m2(String)\" because \"null\" is null");
       
   451         }
       
   452         // Test parameter and return types
       
   453         try {
       
   454             boolean val = (nullInstanceField.callWithTypes(null, null, 0.0f, 0L, (short)0, false, (byte)0, 0.0, 'x') == 0.0);
       
   455             Asserts.assertTrue(val);
       
   456             Asserts.fail();
       
   457         } catch (NullPointerException e) {
       
   458             checkMessage(e, "boolean val = (nullInstanceField.callWithTypes(null, null, 0.0f, 0L, (short)0, false, (byte)0, 0.0, 'x') == 0.0);", e.getMessage(),
       
   459                          "Cannot invoke \"NullPointerExceptionTest.callWithTypes(String[][], int[][][], float, long, short, boolean, byte, double, char)\" because " +
       
   460                          "\"this.nullInstanceField\" is null");
       
   461         }
       
   462     }
       
   463 
       
   464     static void test_iload() {
       
   465         int i0 = 0;
       
   466         int i1 = 1;
       
   467         int i2 = 2;
       
   468         int i3 = 3;
       
   469         @SuppressWarnings("unused")
       
   470         int i4 = 4;
       
   471         int i5 = 5;
       
   472 
       
   473         int[][] a = new int[6][];
       
   474 
       
   475         // iload_0
       
   476         try {
       
   477             a[i0][0] = 77;
       
   478             Asserts.fail();
       
   479         } catch (NullPointerException e) {
       
   480             checkMessage(e, "a[i0][0] = 77;", e.getMessage(),
       
   481                          "Cannot store to int array because " +
       
   482                          (hasDebugInfo ? "\"a[i0]\"" : "\"<local6>[<local0>]\"") + " is null");
       
   483         }
       
   484         // iload_1
       
   485         try {
       
   486             a[i1][0] = 77;
       
   487             Asserts.fail();
       
   488         } catch (NullPointerException e) {
       
   489             checkMessage(e, "a[i1][0] = 77;", e.getMessage(),
       
   490                          "Cannot store to int array because " +
       
   491                          (hasDebugInfo ? "\"a[i1]\"" : "\"<local6>[<local1>]\"") + " is null");
       
   492         }
       
   493         // iload_2
       
   494         try {
       
   495             a[i2][0] = 77;
       
   496             Asserts.fail();
       
   497         } catch (NullPointerException e) {
       
   498             checkMessage(e, "a[i2][0] = 77;", e.getMessage(),
       
   499                          "Cannot store to int array because " +
       
   500                          (hasDebugInfo ? "\"a[i2]\"" : "\"<local6>[<local2>]\"") + " is null");
       
   501         }
       
   502         // iload_3
       
   503         try {
       
   504             a[i3][0] = 77;
       
   505             Asserts.fail();
       
   506         } catch (NullPointerException e) {
       
   507             checkMessage(e, "a[i3][0] = 77;", e.getMessage(),
       
   508                          "Cannot store to int array because " +
       
   509                          (hasDebugInfo ? "\"a[i3]\"" : "\"<local6>[<local3>]\"") + " is null");
       
   510         }
       
   511         // iload
       
   512         try {
       
   513             a[i5][0] = 77;
       
   514             Asserts.fail();
       
   515         } catch (NullPointerException e) {
       
   516             checkMessage(e, "a[i5][0] = 77;", e.getMessage(),
       
   517                          "Cannot store to int array because " +
       
   518                          (hasDebugInfo ? "\"a[i5]\"" : "\"<local6>[<local5>]\"") + " is null");
       
   519         }
       
   520     }
       
   521 
       
   522     // Other datatyes than int are not needed.
       
   523     // If we implement l2d and similar bytecodes, we can print
       
   524     // long expressions as array indexes. Then these here could
       
   525     // be used.
       
   526     static void test_lload() {
       
   527         long long0 = 0L;  // l0 looks like 10. Therefore long0.
       
   528         long long1 = 1L;
       
   529         long long2 = 2L;
       
   530         long long3 = 3L;
       
   531         @SuppressWarnings("unused")
       
   532         long long4 = 4L;
       
   533         long long5 = 5L;
       
   534 
       
   535         int[][] a = new int[6][];
       
   536 
       
   537         // lload_0
       
   538         try {
       
   539             a[(int)long0][0] = 77;
       
   540             Asserts.fail();
       
   541         } catch (NullPointerException e) {
       
   542             checkMessage(e, "a[(int)long0][0] = 77;", e.getMessage(),
       
   543                          "Cannot store to int array because " +
       
   544                          (hasDebugInfo ? "\"a[...]\"" : "\"<local12>[...]\"") + " is null");
       
   545         }
       
   546         // lload_1
       
   547         try {
       
   548             a[(int)long1][0] = 77;
       
   549             Asserts.fail();
       
   550         } catch (NullPointerException e) {
       
   551             checkMessage(e, "a[(int)long1][0] = 77;", e.getMessage(),
       
   552                          "Cannot store to int array because " +
       
   553                          (hasDebugInfo ? "\"a[...]\"" : "\"<local12>[...]\"") + " is null");
       
   554         }
       
   555         // lload_2
       
   556         try {
       
   557             a[(int)long2][0] = 77;
       
   558             Asserts.fail();
       
   559         } catch (NullPointerException e) {
       
   560             checkMessage(e, "a[(int)long2][0] = 77;", e.getMessage(),
       
   561                          "Cannot store to int array because " +
       
   562                          (hasDebugInfo ? "\"a[...]\"" : "\"<local12>[...]\"") + " is null");
       
   563         }
       
   564         // lload_3
       
   565         try {
       
   566             a[(int)long3][0] = 77;
       
   567             Asserts.fail();
       
   568         } catch (NullPointerException e) {
       
   569             checkMessage(e, "a[(int)long3][0] = 77;", e.getMessage(),
       
   570                          "Cannot store to int array because " +
       
   571                          (hasDebugInfo ? "\"a[...]\"" : "\"<local12>[...]\"") + " is null");
       
   572         }
       
   573         // lload
       
   574         try {
       
   575             a[(int)long5][0] = 77;
       
   576             Asserts.fail();
       
   577         } catch (NullPointerException e) {
       
   578             checkMessage(e, "a[(int)long5][0] = 77;", e.getMessage(),
       
   579                          "Cannot store to int array because " +
       
   580                          (hasDebugInfo ? "\"a[...]\"" : "\"<local12>[...]\"") + " is null");
       
   581         }
       
   582     }
       
   583 
       
   584     static void test_fload() {
       
   585         float f0 = 0.0f;
       
   586         float f1 = 1.0f;
       
   587         float f2 = 2.0f;
       
   588         float f3 = 3.0f;
       
   589         @SuppressWarnings("unused")
       
   590         float f4 = 4.0f;
       
   591         float f5 = 5.0f;
       
   592 
       
   593         int[][] a = new int[6][];
       
   594 
       
   595         // fload_0
       
   596         try {
       
   597             a[(int)f0][0] = 77;
       
   598             Asserts.fail();
       
   599         } catch (NullPointerException e) {
       
   600             checkMessage(e, "a[(int)f0][0] = 77;", e.getMessage(),
       
   601                          "Cannot store to int array because " +
       
   602                          (hasDebugInfo ? "\"a[...]\"" : "\"<local6>[...]\"") + " is null");
       
   603         }
       
   604         // fload_1
       
   605         try {
       
   606             a[(int)f1][0] = 77;
       
   607             Asserts.fail();
       
   608         } catch (NullPointerException e) {
       
   609             checkMessage(e, "a[(int)f1][0] = 77;", e.getMessage(),
       
   610                          "Cannot store to int array because " +
       
   611                          (hasDebugInfo ? "\"a[...]\"" : "\"<local6>[...]\"") + " is null");
       
   612         }
       
   613         // fload_2
       
   614         try {
       
   615             a[(int)f2][0] = 77;
       
   616             Asserts.fail();
       
   617         } catch (NullPointerException e) {
       
   618             checkMessage(e, "a[(int)f2][0] = 77;", e.getMessage(),
       
   619                          "Cannot store to int array because " +
       
   620                          (hasDebugInfo ? "\"a[...]\"" : "\"<local6>[...]\"") + " is null");
       
   621         }
       
   622         // fload_3
       
   623         try {
       
   624             a[(int)f3][0] = 77;
       
   625             Asserts.fail();
       
   626         } catch (NullPointerException e) {
       
   627             checkMessage(e, "a[(int)f3][0] = 77;", e.getMessage(),
       
   628                          "Cannot store to int array because " +
       
   629                          (hasDebugInfo ? "\"a[...]\"" : "\"<local6>[...]\"") + " is null");
       
   630         }
       
   631         // fload
       
   632         try {
       
   633             a[(int)f5][0] = 77;
       
   634             Asserts.fail();
       
   635         } catch (NullPointerException e) {
       
   636             checkMessage(e, "a[(int)f5][0] = 77;", e.getMessage(),
       
   637                          "Cannot store to int array because " +
       
   638                          (hasDebugInfo ? "\"a[...]\"" : "\"<local6>[...]\"") + " is null");
       
   639         }
       
   640     }
       
   641 
       
   642     @SuppressWarnings("null")
       
   643     static void test_aload() {
       
   644         F f0 = null;
       
   645         F f1 = null;
       
   646         F f2 = null;
       
   647         F f3 = null;
       
   648         @SuppressWarnings("unused")
       
   649         F f4 = null;
       
   650         F f5 = null;
       
   651 
       
   652         // aload_0
       
   653         try {
       
   654             f0.i = 33;
       
   655             Asserts.fail();
       
   656         } catch (NullPointerException e) {
       
   657             checkMessage(e, "f0.i = 33;", e.getMessage(),
       
   658                          "Cannot assign field \"i\" because " +
       
   659                          (hasDebugInfo ? "\"f0\"" : "\"<local0>\"") + " is null");
       
   660         }
       
   661         // aload_1
       
   662         try {
       
   663             f1.i = 33;
       
   664             Asserts.fail();
       
   665         } catch (NullPointerException e) {
       
   666             checkMessage(e, "f1.i = 33;", e.getMessage(),
       
   667                          "Cannot assign field \"i\" because " +
       
   668                          (hasDebugInfo ? "\"f1\"" : "\"<local1>\"") + " is null");
       
   669         }
       
   670         // aload_2
       
   671         try {
       
   672             f2.i = 33;
       
   673             Asserts.fail();
       
   674         } catch (NullPointerException e) {
       
   675             checkMessage(e, "f2.i = 33;", e.getMessage(),
       
   676                          "Cannot assign field \"i\" because " +
       
   677                          (hasDebugInfo ? "\"f2\"" : "\"<local2>\"") + " is null");
       
   678         }
       
   679         // aload_3
       
   680         try {
       
   681             f3.i = 33;
       
   682             Asserts.fail();
       
   683         } catch (NullPointerException e) {
       
   684             checkMessage(e, "f3.i = 33;", e.getMessage(),
       
   685                          "Cannot assign field \"i\" because " +
       
   686                          (hasDebugInfo ? "\"f3\"" : "\"<local3>\"") + " is null");
       
   687         }
       
   688         // aload
       
   689         try {
       
   690             f5.i = 33;
       
   691             Asserts.fail();
       
   692         } catch (NullPointerException e) {
       
   693             checkMessage(e, "f5.i = 33;", e.getMessage(),
       
   694                          "Cannot assign field \"i\" because " +
       
   695                          (hasDebugInfo ? "\"f5\"" : "\"<local5>\"") + " is null");
       
   696         }
       
   697     }
       
   698 
       
   699     // Helper class for test cases.
       
   700     class A {
       
   701         public B to_b;
       
   702         public B getB() { return to_b; }
       
   703     }
       
   704 
       
   705     // Helper class for test cases.
       
   706     class B {
       
   707         public C to_c;
       
   708         public B to_b;
       
   709         public C getC() { return to_c; }
       
   710         public B getBfromB() { return to_b; }
       
   711     }
       
   712 
       
   713     // Helper class for test cases.
       
   714     class C {
       
   715         public D to_d;
       
   716         public D getD() { return to_d; }
       
   717     }
       
   718 
       
   719     // Helper class for test cases.
       
   720     class D {
       
   721         public int num;
       
   722         public int[][] ar;
       
   723     }
       
   724 
       
   725 
       
   726     @SuppressWarnings("null")
       
   727     public void testArrayChasing() {
       
   728         int[][][][][][] a = null;
       
   729         try {
       
   730             a[0][0][0][0][0][0] = 99;
       
   731             Asserts.fail();
       
   732         } catch (NullPointerException e) {
       
   733             checkMessage(e, "a[0][0][0][0][0] = 99; // a is null", e.getMessage(),
       
   734                          "Cannot load from object array because " +
       
   735                          (hasDebugInfo ? "\"a\"" : "\"<local1>\"") + " is null");
       
   736         }
       
   737         a = new int[1][][][][][];
       
   738         try {
       
   739             a[0][0][0][0][0][0] = 99;
       
   740             Asserts.fail();
       
   741         } catch (NullPointerException e) {
       
   742             checkMessage(e, "a[0][0][0][0][0] = 99; // a[0] is null", e.getMessage(),
       
   743                          "Cannot load from object array because " +
       
   744                          (hasDebugInfo ? "\"a[0]\"" : "\"<local1>[0]\"") + " is null");
       
   745         }
       
   746         a[0] = new int[1][][][][];
       
   747         try {
       
   748             a[0][0][0][0][0][0] = 99;
       
   749             Asserts.fail();
       
   750         } catch (NullPointerException e) {
       
   751             checkMessage(e, "a[0][0][0][0][0] = 99; // a[0][0] is null", e.getMessage(),
       
   752                          "Cannot load from object array because " +
       
   753                          (hasDebugInfo ? "\"a[0][0]\"" : "\"<local1>[0][0]\"") + " is null");
       
   754         }
       
   755         a[0][0] = new int[1][][][];
       
   756         try {
       
   757             a[0][0][0][0][0][0] = 99;
       
   758             Asserts.fail();
       
   759         } catch (NullPointerException e) {
       
   760             checkMessage(e, "a[0][0][0][0][0] = 99; // a[0][0][0] is null", e.getMessage(),
       
   761                          "Cannot load from object array because " +
       
   762                          (hasDebugInfo ? "\"a[0][0][0]\"" : "\"<local1>[0][0][0]\"") + " is null");
       
   763         }
       
   764         try {
       
   765             System.out.println(a[0][0][0].length);
       
   766             Asserts.fail();
       
   767         } catch (NullPointerException e) {
       
   768             checkMessage(e, "a[0][0][0].length; // a[0][0][0] is null", e.getMessage(),
       
   769                          "Cannot read the array length because " +
       
   770                          (hasDebugInfo ? "\"a[0][0][0]\"" : "\"<local1>[0][0][0]\"") + " is null");
       
   771         }
       
   772         a[0][0][0] = new int[1][][];
       
   773         try {
       
   774             a[0][0][0][0][0][0] = 99;
       
   775             Asserts.fail();
       
   776         } catch (NullPointerException e) {
       
   777             checkMessage(e, "a[0][0][0][0][0] = 99; // a[0][0][0][0] is null", e.getMessage(),
       
   778                          "Cannot load from object array because " +
       
   779                          (hasDebugInfo ? "\"a[0][0][0][0]\"" : "\"<local1>[0][0][0][0]\"") + " is null");
       
   780         }
       
   781         a[0][0][0][0] = new int[1][];
       
   782         // Reaching max recursion depth. Prints <array>.
       
   783         try {
       
   784             a[0][0][0][0][0][0] = 99;
       
   785             Asserts.fail();
       
   786         } catch (NullPointerException e) {
       
   787             checkMessage(e, "a[0][0][0][0][0] = 99; // a[0][0][0][0][0] is null", e.getMessage(),
       
   788                          "Cannot store to int array because " +
       
   789                          "\"<array>[0][0][0][0][0]\" is null");
       
   790         }
       
   791         a[0][0][0][0][0] = new int[1];
       
   792         try {
       
   793             a[0][0][0][0][0][0] = 99;
       
   794         } catch (NullPointerException e) {
       
   795             Asserts.fail();
       
   796         }
       
   797     }
       
   798 
       
   799     @SuppressWarnings("null")
       
   800     public void testPointerChasing() {
       
   801         A a = null;
       
   802         try {
       
   803             a.to_b.to_c.to_d.num = 99;
       
   804             Asserts.fail();
       
   805         } catch (NullPointerException e) {
       
   806             checkMessage(e, "a.to_b.to_c.to_d.num = 99; // a is null", e.getMessage(),
       
   807                          "Cannot read field \"to_b\" because " +
       
   808                          (hasDebugInfo ? "\"a\"" : "\"<local1>\"") + " is null");
       
   809         }
       
   810         a = new A();
       
   811         try {
       
   812             a.to_b.to_c.to_d.num = 99;
       
   813             Asserts.fail();
       
   814         } catch (NullPointerException e) {
       
   815             checkMessage(e, "a.to_b.to_c.to_d.num = 99; // a.to_b is null", e.getMessage(),
       
   816                          "Cannot read field \"to_c\" because " +
       
   817                          (hasDebugInfo ? "\"a.to_b\"" : "\"<local1>.to_b\"") + " is null");
       
   818         }
       
   819         a.to_b = new B();
       
   820         try {
       
   821             a.to_b.to_c.to_d.num = 99;
       
   822             Asserts.fail();
       
   823         } catch (NullPointerException e) {
       
   824             checkMessage(e, "a.to_b.to_c.to_d.num = 99; // a.to_b.to_c is null", e.getMessage(),
       
   825                          "Cannot read field \"to_d\" because " +
       
   826                          (hasDebugInfo ? "\"a.to_b.to_c\"" : "\"<local1>.to_b.to_c\"") + " is null");
       
   827         }
       
   828         a.to_b.to_c = new C();
       
   829         try {
       
   830             a.to_b.to_c.to_d.num = 99;
       
   831             Asserts.fail();
       
   832         } catch (NullPointerException e) {
       
   833             checkMessage(e, "a.to_b.to_c.to_d.num = 99; // a.to_b.to_c.to_d is null", e.getMessage(),
       
   834                          "Cannot assign field \"num\" because " +
       
   835                          (hasDebugInfo ? "\"a.to_b.to_c.to_d\"" : "\"<local1>.to_b.to_c.to_d\"") + " is null");
       
   836         }
       
   837     }
       
   838 
       
   839     @SuppressWarnings("null")
       
   840     public void testMethodChasing() {
       
   841         A a = null;
       
   842         try {
       
   843             a.getB().getBfromB().getC().getD().num = 99;
       
   844             Asserts.fail();
       
   845         } catch (NullPointerException e) {
       
   846             checkMessage(e, "a.getB().getBfromB().getC().getD().num = 99; // a is null", e.getMessage(),
       
   847                          "Cannot invoke \"NullPointerExceptionTest$A.getB()\" because " +
       
   848                          (hasDebugInfo ? "\"a" : "\"<local1>") + "\" is null");
       
   849         }
       
   850         a = new A();
       
   851         try {
       
   852             a.getB().getBfromB().getC().getD().num = 99;
       
   853             Asserts.fail();
       
   854         } catch (NullPointerException e) {
       
   855             checkMessage(e, "a.getB().getBfromB().getC().getD().num = 99; // a.getB() is null", e.getMessage(),
       
   856                          "Cannot invoke \"NullPointerExceptionTest$B.getBfromB()\" because " +
       
   857                          "the return value of \"NullPointerExceptionTest$A.getB()\" is null");
       
   858         }
       
   859         a.to_b = new B();
       
   860         try {
       
   861             a.getB().getBfromB().getC().getD().num = 99;
       
   862             Asserts.fail();
       
   863         } catch (NullPointerException e) {
       
   864             checkMessage(e, "a.getB().getBfromB().getC().getD().num = 99; // a.getB().getBfromB() is null", e.getMessage(),
       
   865                          "Cannot invoke \"NullPointerExceptionTest$B.getC()\" because " +
       
   866                          "the return value of \"NullPointerExceptionTest$B.getBfromB()\" is null");
       
   867         }
       
   868         a.to_b.to_b = new B();
       
   869         try {
       
   870             a.getB().getBfromB().getC().getD().num = 99;
       
   871             Asserts.fail();
       
   872         } catch (NullPointerException e) {
       
   873             checkMessage(e, "a.getB().getBfromB().getC().getD().num = 99; // a.getB().getBfromB().getC() is null", e.getMessage(),
       
   874                          "Cannot invoke \"NullPointerExceptionTest$C.getD()\" because " +
       
   875                          "the return value of \"NullPointerExceptionTest$B.getC()\" is null");
       
   876         }
       
   877         a.to_b.to_b.to_c = new C();
       
   878         try {
       
   879             a.getB().getBfromB().getC().getD().num = 99;
       
   880             Asserts.fail();
       
   881         } catch (NullPointerException e) {
       
   882             checkMessage(e, "a.getB().getBfromB().getC().getD().num = 99; // a.getB().getBfromB().getC().getD() is null", e.getMessage(),
       
   883                          "Cannot assign field \"num\" because " +
       
   884                          "the return value of \"NullPointerExceptionTest$C.getD()\" is null");
       
   885         }
       
   886     }
       
   887 
       
   888     @SuppressWarnings("null")
       
   889     public void testMixedChasing() {
       
   890         A a = null;
       
   891         try {
       
   892             a.getB().getBfromB().to_c.to_d.ar[0][0] = 99;
       
   893             Asserts.fail();
       
   894         } catch (NullPointerException e) {
       
   895             checkMessage(e, "a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a is null", e.getMessage(),
       
   896                          "Cannot invoke \"NullPointerExceptionTest$A.getB()\" because " +
       
   897                          (hasDebugInfo ? "\"a\"" : "\"<local1>\"") + " is null");
       
   898         }
       
   899         a = new A();
       
   900         try {
       
   901             a.getB().getBfromB().to_c.to_d.ar[0][0] = 99;
       
   902             Asserts.fail();
       
   903         } catch (NullPointerException e) {
       
   904             checkMessage(e, "a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB() is null", e.getMessage(),
       
   905                          "Cannot invoke \"NullPointerExceptionTest$B.getBfromB()\" because " +
       
   906                          "the return value of \"NullPointerExceptionTest$A.getB()\" is null");
       
   907         }
       
   908         a.to_b = new B();
       
   909         try {
       
   910             a.getB().getBfromB().to_c.to_d.ar[0][0] = 99;
       
   911             Asserts.fail();
       
   912         } catch (NullPointerException e) {
       
   913             checkMessage(e, "a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB() is null", e.getMessage(),
       
   914                          "Cannot read field \"to_c\" because " +
       
   915                          "the return value of \"NullPointerExceptionTest$B.getBfromB()\" is null");
       
   916         }
       
   917         a.to_b.to_b = new B();
       
   918         try {
       
   919             a.getB().getBfromB().to_c.to_d.ar[0][0] = 99;
       
   920             Asserts.fail();
       
   921         } catch (NullPointerException e) {
       
   922             checkMessage(e, "a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c is null", e.getMessage(),
       
   923                          "Cannot read field \"to_d\" because " +
       
   924                          "\"NullPointerExceptionTest$B.getBfromB().to_c\" is null");
       
   925         }
       
   926         a.to_b.to_b.to_c = new C();
       
   927         try {
       
   928             a.getB().getBfromB().to_c.to_d.ar[0][0] = 99;
       
   929             Asserts.fail();
       
   930         } catch (NullPointerException e) {
       
   931             checkMessage(e, "a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c.to_d is null", e.getMessage(),
       
   932                          "Cannot read field \"ar\" because " +
       
   933                          "\"NullPointerExceptionTest$B.getBfromB().to_c.to_d\" is null");
       
   934         }
       
   935         a.to_b.to_b.to_c.to_d = new D();
       
   936         try {
       
   937             a.getB().getBfromB().to_c.to_d.ar[0][0] = 99;
       
   938             Asserts.fail();
       
   939         } catch (NullPointerException e) {
       
   940             checkMessage(e, "a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c.to_d.ar is null", e.getMessage(),
       
   941                          "Cannot load from object array because " +
       
   942                          "\"NullPointerExceptionTest$B.getBfromB().to_c.to_d.ar\" is null");
       
   943         }
       
   944         try {
       
   945             a.getB().getBfromB().getC().getD().ar[0][0] = 99;
       
   946             Asserts.fail();
       
   947         } catch (NullPointerException e) {
       
   948             checkMessage(e, "a.getB().getBfromB().getC().getD().ar[0][0] = 99; // a.getB().getBfromB().getC().getD().ar is null", e.getMessage(),
       
   949                          "Cannot load from object array because " +
       
   950                          "\"NullPointerExceptionTest$C.getD().ar\" is null");
       
   951         }
       
   952         a.to_b.to_b.to_c.to_d.ar = new int[1][];
       
   953         try {
       
   954             a.getB().getBfromB().to_c.to_d.ar[0][0] = 99;
       
   955             Asserts.fail();
       
   956         } catch (NullPointerException e) {
       
   957             checkMessage(e, "a.getB().getBfromB().to_c.to_d.ar[0][0] = 99; // a.getB().getBfromB().to_c.to_d.ar[0] is null", e.getMessage(),
       
   958                          "Cannot store to int array because " +
       
   959                          "\"NullPointerExceptionTest$B.getBfromB().to_c.to_d.ar[0]\" is null");
       
   960         }
       
   961         try {
       
   962             a.getB().getBfromB().getC().getD().ar[0][0] = 99;
       
   963             Asserts.fail();
       
   964         } catch (NullPointerException e) {
       
   965             checkMessage(e, "a.getB().getBfromB().getC().getD().ar[0][0] = 99; // a.getB().getBfromB().getC().getD().ar[0] is null", e.getMessage(),
       
   966                          "Cannot store to int array because " +
       
   967                          "\"NullPointerExceptionTest$C.getD().ar[0]\" is null");
       
   968         }
       
   969     }
       
   970 
       
   971     // Helper method to cause test case.
       
   972     private Object returnNull(String[][] dummy1, int[][][] dummy2, float dummy3) {
       
   973         return null;
       
   974     }
       
   975 
       
   976     // Helper method to cause test case.
       
   977     private NullPointerExceptionTest returnMeAsNull(Throwable dummy1, int dummy2, char dummy3) {
       
   978         return null;
       
   979     }
       
   980 
       
   981     // Helper interface for test cases.
       
   982     static interface DoubleArrayGen {
       
   983         public double[] getArray();
       
   984     }
       
   985 
       
   986     // Helper class for test cases.
       
   987     static class DoubleArrayGenImpl implements DoubleArrayGen {
       
   988         @Override
       
   989         public double[] getArray() {
       
   990             return null;
       
   991         }
       
   992     }
       
   993 
       
   994     // Helper class for test cases.
       
   995     static class NullPointerGenerator {
       
   996         public static Object nullReturner(boolean dummy1) {
       
   997             return null;
       
   998         }
       
   999 
       
  1000         public Object returnMyNull(double dummy1, long dummy2, short dummy3) {
       
  1001             return null;
       
  1002         }
       
  1003     }
       
  1004 
       
  1005     // Helper method to cause test case.
       
  1006     public void ImplTestLoadedFromMethod(DoubleArrayGen gen) {
       
  1007         try {
       
  1008             (gen.getArray())[0] = 1.0;
       
  1009             Asserts.fail();
       
  1010         } catch (NullPointerException e) {
       
  1011             checkMessage(e, "(gen.getArray())[0] = 1.0;", e.getMessage(),
       
  1012                          "Cannot store to double array because " +
       
  1013                          "the return value of \"NullPointerExceptionTest$DoubleArrayGen.getArray()\" is null");
       
  1014         }
       
  1015     }
       
  1016 
       
  1017     public void testNullEntity() {
       
  1018         int[][] a = new int[820][];
       
  1019 
       
  1020         test_iload();
       
  1021         test_lload();
       
  1022         test_fload();
       
  1023         // test_dload();
       
  1024         test_aload();
       
  1025         // aload_0: 'this'
       
  1026         try {
       
  1027             this.nullInstanceField.nullInstanceField = new NullPointerExceptionTest();
       
  1028             Asserts.fail();
       
  1029         } catch (NullPointerException e) {
       
  1030             checkMessage(e, "this.nullInstanceField.nullInstanceField = new NullPointerExceptionTest();", e.getMessage(),
       
  1031                          "Cannot assign field \"nullInstanceField\" because \"this.nullInstanceField\" is null");
       
  1032         }
       
  1033 
       
  1034         // aconst_null
       
  1035         try {
       
  1036             throw null;
       
  1037         } catch (NullPointerException e) {
       
  1038             checkMessage(e, "throw null;", e.getMessage(),
       
  1039                          "Cannot throw exception because \"null\" is null");
       
  1040         }
       
  1041         // iconst_0
       
  1042         try {
       
  1043             a[0][0] = 77;
       
  1044             Asserts.fail();
       
  1045         } catch (NullPointerException e) {
       
  1046             checkMessage(e, "a[0][0] = 77;", e.getMessage(),
       
  1047                          "Cannot store to int array because " +
       
  1048                          (hasDebugInfo ? "\"a[0]\"" : "\"<local1>[0]\"") + " is null");
       
  1049         }
       
  1050         // iconst_1
       
  1051         try {
       
  1052             a[1][0] = 77;
       
  1053             Asserts.fail();
       
  1054         } catch (NullPointerException e) {
       
  1055             checkMessage(e, "a[1][0] = 77;", e.getMessage(),
       
  1056                          "Cannot store to int array because " +
       
  1057                          (hasDebugInfo ? "\"a[1]\"" : "\"<local1>[1]\"") + " is null");
       
  1058         }
       
  1059         // iconst_2
       
  1060         try {
       
  1061             a[2][0] = 77;
       
  1062             Asserts.fail();
       
  1063         } catch (NullPointerException e) {
       
  1064             checkMessage(e, "a[2][0] = 77;", e.getMessage(),
       
  1065                          "Cannot store to int array because " +
       
  1066                          (hasDebugInfo ? "\"a[2]\"" : "\"<local1>[2]\"") + " is null");
       
  1067         }
       
  1068         // iconst_3
       
  1069         try {
       
  1070             a[3][0] = 77;
       
  1071             Asserts.fail();
       
  1072         } catch (NullPointerException e) {
       
  1073             checkMessage(e, "a[3][0] = 77;", e.getMessage(),
       
  1074                          "Cannot store to int array because " +
       
  1075                          (hasDebugInfo ? "\"a[3]\"" : "\"<local1>[3]\"") + " is null");
       
  1076         }
       
  1077         // iconst_4
       
  1078         try {
       
  1079             a[4][0] = 77;
       
  1080             Asserts.fail();
       
  1081         } catch (NullPointerException e) {
       
  1082             checkMessage(e, "a[4][0] = 77;", e.getMessage(),
       
  1083                          "Cannot store to int array because " +
       
  1084                          (hasDebugInfo ? "\"a[4]\"" : "\"<local1>[4]\"") + " is null");
       
  1085         }
       
  1086         // iconst_5
       
  1087         try {
       
  1088             a[5][0] = 77;
       
  1089             Asserts.fail();
       
  1090         } catch (NullPointerException e) {
       
  1091             checkMessage(e, "a[5][0] = 77;", e.getMessage(),
       
  1092                          "Cannot store to int array because " +
       
  1093                          (hasDebugInfo ? "\"a[5]\"" : "\"<local1>[5]\"") + " is null");
       
  1094         }
       
  1095         // long --> iconst
       
  1096         try {
       
  1097             a[(int)0L][0] = 77;
       
  1098             Asserts.fail();
       
  1099         } catch (NullPointerException e) {
       
  1100             checkMessage(e, "a[(int)0L][0] = 77;", e.getMessage(),
       
  1101                          "Cannot store to int array because " +
       
  1102                          (hasDebugInfo ? "\"a[0]\"" : "\"<local1>[0]\"") + " is null");
       
  1103         }
       
  1104         // bipush
       
  1105         try {
       
  1106             a[139 /*0x77*/][0] = 77;
       
  1107             Asserts.fail();
       
  1108         } catch (NullPointerException e) {
       
  1109             checkMessage(e, "a[139][0] = 77;", e.getMessage(),
       
  1110                          "Cannot store to int array because " +
       
  1111                          (hasDebugInfo ? "\"a[139]\"" : "\"<local1>[139]\"") + " is null");
       
  1112         }
       
  1113         // sipush
       
  1114         try {
       
  1115             a[819 /*0x333*/][0] = 77;
       
  1116             Asserts.fail();
       
  1117         } catch (NullPointerException e) {
       
  1118             checkMessage(e, "a[819][0] = 77;", e.getMessage(),
       
  1119                          "Cannot store to int array because " +
       
  1120                          (hasDebugInfo ? "\"a[819]\"" : "\"<local1>[819]\"") + " is null");
       
  1121         }
       
  1122 
       
  1123         // aaload, with recursive descend.
       
  1124         testArrayChasing();
       
  1125 
       
  1126         // getstatic
       
  1127         try {
       
  1128             boolean val = (((float[]) nullStaticField)[0] == 1.0f);
       
  1129             Asserts.assertTrue(val);
       
  1130             Asserts.fail();
       
  1131         } catch (NullPointerException e) {
       
  1132             checkMessage(e, "boolean val = (((float[]) nullStaticField)[0] == 1.0f);", e.getMessage(),
       
  1133                          "Cannot load from float array because \"NullPointerExceptionTest.nullStaticField\" is null");
       
  1134         }
       
  1135 
       
  1136         // getfield, with recursive descend.
       
  1137         testPointerChasing();
       
  1138 
       
  1139         // invokestatic
       
  1140         try {
       
  1141             char val = ((char[]) NullPointerGenerator.nullReturner(false))[0];
       
  1142             System.out.println(val);
       
  1143             Asserts.fail();
       
  1144         } catch (NullPointerException e) {
       
  1145             checkMessage(e, "char val = ((char[]) NullPointerGenerator.nullReturner(false))[0];", e.getMessage(),
       
  1146                          "Cannot load from char array because " +
       
  1147                          "the return value of \"NullPointerExceptionTest$NullPointerGenerator.nullReturner(boolean)\" is null");
       
  1148         }
       
  1149         // invokevirtual
       
  1150         try {
       
  1151             char val = ((char[]) (new NullPointerGenerator().returnMyNull(1, 1, (short) 1)))[0];
       
  1152             System.out.println(val);
       
  1153             Asserts.fail();
       
  1154         } catch (NullPointerException e) {
       
  1155             checkMessage(e, "char val = ((char[]) (new NullPointerGenerator().returnMyNull(1, 1, (short) 1)))[0];", e.getMessage(),
       
  1156                          "Cannot load from char array because " +
       
  1157                          "the return value of \"NullPointerExceptionTest$NullPointerGenerator.returnMyNull(double, long, short)\" is null");
       
  1158         }
       
  1159         // Call with array arguments.
       
  1160         try {
       
  1161             double val = ((double[]) returnNull(null, null, 1f))[0];
       
  1162             System.out.println(val);
       
  1163             Asserts.fail();
       
  1164         } catch (NullPointerException e) {
       
  1165             checkMessage(e, "double val = ((double[]) returnNull(null, null, 1f))[0];", e.getMessage(),
       
  1166                          "Cannot load from double array because " +
       
  1167                          "the return value of \"NullPointerExceptionTest.returnNull(String[][], int[][][], float)\" is null");
       
  1168         }
       
  1169         // invokespecial
       
  1170         try {
       
  1171             SubG g = new SubG();
       
  1172             g.m2("Beginning");
       
  1173         } catch (NullPointerException e) {
       
  1174             checkMessage(e, "return super.m2(x).substring(2);", e.getMessage(),
       
  1175                          "Cannot invoke \"String.substring(int)\" because " +
       
  1176                          "the return value of \"G.m2(String)\" is null");
       
  1177         }
       
  1178         // invokeinterface
       
  1179         ImplTestLoadedFromMethod(new DoubleArrayGenImpl());
       
  1180         try {
       
  1181             returnMeAsNull(null, 1, 'A').dag = new DoubleArrayGenImpl();
       
  1182             Asserts.fail();
       
  1183         } catch (NullPointerException e) {
       
  1184             checkMessage(e, "returnMeAsNull(null, 1, 'A').dag = new DoubleArrayGenImpl();", e.getMessage(),
       
  1185                          "Cannot assign field \"dag\" because " +
       
  1186                          "the return value of \"NullPointerExceptionTest.returnMeAsNull(java.lang.Throwable, int, char)\" is null");
       
  1187         }
       
  1188         testMethodChasing();
       
  1189 
       
  1190         // Mixed recursive descend.
       
  1191         testMixedChasing();
       
  1192     }
       
  1193 
       
  1194     // Assure 64 parameters are printed as 'parameteri'.
       
  1195     public String manyParameters(
       
  1196         int  i1, int  i2, int  i3, int  i4, int  i5, int  i6, int  i7, int  i8, int  i9, int i10,
       
  1197         int i11, int i12, int i13, int i14, int i15, int i16, int i17, int i18, int i19, int i20,
       
  1198         int i21, int i22, int i23, int i24, int i25, int i26, int i27, int i28, int i29, int i30,
       
  1199         int i31, int i32, int i33, int i34, int i35, int i36, int i37, int i38, int i39, int i40,
       
  1200         int i41, int i42, int i43, int i44, int i45, int i46, int i47, int i48, int i49, int i50,
       
  1201         int i51, int i52, int i53, int i54, int i55, int i56, int i57, int i58, int i59, int i60,
       
  1202         int i61, int i62, int i63, int i64, int i65, int i66, int i67, int i68, int i69, int i70) {
       
  1203         String[][][][] ar5 = new String[1][1][1][1];
       
  1204         int[][][] idx3 = new int[1][1][1];
       
  1205         int[][]   idx2 = new int[1][1];
       
  1206         return ar5[i70]
       
  1207                   [idx2[i65][i64]]
       
  1208                   [idx3[i63][i62][i47]]
       
  1209                   [idx3[idx2[i33][i32]][i31][i17]]
       
  1210                   .substring(2);
       
  1211     }
       
  1212 
       
  1213     // The double placeholder takes two slots on the stack.
       
  1214     public void testParametersTestMethod(A a, double placeholder, B b, Integer i) throws Exception {
       
  1215         try {
       
  1216             a.to_b.to_c.to_d.num = 99;
       
  1217             Asserts.fail();
       
  1218         } catch (NullPointerException e) {
       
  1219             checkMessage(e, "a.to_b.to_c.to_d.num = 99; // to_c is null, a is a parameter.", e.getMessage(),
       
  1220                          "Cannot read field \"to_d\" because \"" +
       
  1221                          (hasDebugInfo ? "a" : "<parameter1>") + ".to_b.to_c\" is null");
       
  1222         }
       
  1223 
       
  1224         try {
       
  1225             b.to_c.to_d.num = 99;
       
  1226             Asserts.fail();
       
  1227         } catch (NullPointerException e) {
       
  1228             checkMessage(e, "b.to_c.to_d.num = 99; // b is null and b is a parameter.", e.getMessage(),
       
  1229                          "Cannot read field \"to_c\" because " +
       
  1230                          // We expect number '3' for the parameter.
       
  1231                          (hasDebugInfo ? "\"b\"" : "\"<parameter3>\"") + " is null");
       
  1232         }
       
  1233 
       
  1234 
       
  1235         try {
       
  1236             @SuppressWarnings("unused")
       
  1237             int my_i = i;
       
  1238         }  catch (NullPointerException e) {
       
  1239             checkMessage(e, "int my_i = i; // i is a parameter of type Integer.",  e.getMessage(),
       
  1240                          "Cannot invoke \"java.lang.Integer.intValue()\" because " +
       
  1241                          (hasDebugInfo ? "\"i\"" : "\"<parameter4>\"") + " is null");
       
  1242         }
       
  1243 
       
  1244         // If no debug information is available, only 64 parameters (this and i1 through i63)
       
  1245         // will be reported in the message as 'parameteri'. Others will be reported as 'locali'.
       
  1246         try {
       
  1247             manyParameters(0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
  1248                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
  1249                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
  1250                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
  1251                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
  1252                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       
  1253                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
       
  1254             } catch (NullPointerException e) {
       
  1255                 checkMessage(e, "return ar5[i70][idx2[i65][i64]][idx3[i63][i62][i47]][idx3[idx2[i33][i32]][i31][i17]].substring(2);", e.getMessage(),
       
  1256                              "Cannot invoke \"String.substring(int)\" because " +
       
  1257                              (hasDebugInfo ?
       
  1258                                "\"ar5[i70][idx2[i65][i64]][idx3[i63][i62][i47]][idx3[idx2[i33][i32]][i31][i17]]\"" :
       
  1259                                "\"<local71>[<local70>][<local73>[<local65>][<local64>]][<local72>[<parameter63>][<parameter62>]" +
       
  1260                                   "[<parameter47>]][<local72>[<local73>[<parameter33>][<parameter32>]][<parameter31>][<parameter17>]]\"") +
       
  1261                              " is null");
       
  1262             }
       
  1263     }
       
  1264 
       
  1265 
       
  1266     public void testParameters() throws Exception {
       
  1267         A a = new A();
       
  1268         a.to_b = new B();
       
  1269         testParametersTestMethod(a, 0.0, null, null);
       
  1270     }
       
  1271 
       
  1272 
       
  1273     public void testCreation() throws Exception {
       
  1274         // If allocated with new, the message should not be generated.
       
  1275         Asserts.assertNull(new NullPointerException().getMessage());
       
  1276         String msg = new String("A pointless message");
       
  1277         Asserts.assertTrue(new NullPointerException(msg).getMessage() == msg);
       
  1278 
       
  1279         // If created via reflection, the message should not be generated.
       
  1280         Exception ex = NullPointerException.class.getDeclaredConstructor().newInstance();
       
  1281         Asserts.assertNull(ex.getMessage());
       
  1282     }
       
  1283 
       
  1284     public void testNative() throws Exception {
       
  1285         // If NPE is thrown in a native method, the message should
       
  1286         // not be generated.
       
  1287         try {
       
  1288             Class.forName(null);
       
  1289             Asserts.fail();
       
  1290         } catch (NullPointerException e) {
       
  1291             Asserts.assertNull(e.getMessage());
       
  1292         }
       
  1293 
       
  1294     }
       
  1295 
       
  1296     // Test we get the same message calling npe.getMessage() twice.
       
  1297     @SuppressWarnings("null")
       
  1298     public void testSameMessage() throws Exception {
       
  1299         Object null_o = null;
       
  1300         String expectedMsg =
       
  1301             "Cannot invoke \"Object.hashCode()\" because " +
       
  1302             (hasDebugInfo ? "\"null_o" : "\"<local1>") + "\" is null";
       
  1303 
       
  1304         try {
       
  1305             null_o.hashCode();
       
  1306             Asserts.fail();
       
  1307         } catch (NullPointerException e) {
       
  1308             String msg1 = e.getMessage();
       
  1309             checkMessage(e, "null_o.hashCode()", msg1, expectedMsg);
       
  1310             String msg2 = e.getMessage();
       
  1311             Asserts.assertTrue(msg1.equals(msg2));
       
  1312             // It was decided that getMessage should generate the
       
  1313             // message anew on every call, so this does not hold.
       
  1314             //Asserts.assertTrue(msg1 == msg2);
       
  1315             Asserts.assertFalse(msg1 == msg2);
       
  1316         }
       
  1317     }
       
  1318 
       
  1319     @SuppressWarnings("null")
       
  1320     public void testSerialization() throws Exception {
       
  1321         // NPE without message.
       
  1322         Object o1 = new NullPointerException();
       
  1323         ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
       
  1324         ObjectOutputStream oos1 = new ObjectOutputStream(bos1);
       
  1325         oos1.writeObject(o1);
       
  1326         ByteArrayInputStream bis1 = new ByteArrayInputStream(bos1.toByteArray());
       
  1327         ObjectInputStream ois1 = new ObjectInputStream(bis1);
       
  1328         Exception ex1 = (Exception) ois1.readObject();
       
  1329         Asserts.assertNull(ex1.getMessage());
       
  1330 
       
  1331         // NPE with custom message.
       
  1332         String msg2 = "A useless message";
       
  1333         Object o2 = new NullPointerException(msg2);
       
  1334         ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
       
  1335         ObjectOutputStream oos2 = new ObjectOutputStream(bos2);
       
  1336         oos2.writeObject(o2);
       
  1337         ByteArrayInputStream bis2 = new ByteArrayInputStream(bos2.toByteArray());
       
  1338         ObjectInputStream ois2 = new ObjectInputStream(bis2);
       
  1339         Exception ex2 = (Exception) ois2.readObject();
       
  1340         Asserts.assertEquals(ex2.getMessage(), msg2);
       
  1341 
       
  1342         // NPE with generated message.
       
  1343         Object null_o3 = null;
       
  1344         Object o3 = null;
       
  1345         String msg3 = null;
       
  1346         try {
       
  1347             int hc = null_o3.hashCode();
       
  1348             System.out.println(hc);
       
  1349             Asserts.fail();
       
  1350         } catch (NullPointerException npe3) {
       
  1351             o3 = npe3;
       
  1352             msg3 = npe3.getMessage();
       
  1353             checkMessage(npe3, "int hc = null_o3.hashCode();", msg3,
       
  1354                          "Cannot invoke \"Object.hashCode()\" because " +
       
  1355                          (hasDebugInfo ? "\"null_o3\"" : "\"<local14>\"") + " is null");
       
  1356         }
       
  1357         ByteArrayOutputStream bos3 = new ByteArrayOutputStream();
       
  1358         ObjectOutputStream oos3 = new ObjectOutputStream(bos3);
       
  1359         oos3.writeObject(o3);
       
  1360         ByteArrayInputStream bis3 = new ByteArrayInputStream(bos3.toByteArray());
       
  1361         ObjectInputStream ois3 = new ObjectInputStream(bis3);
       
  1362         Exception ex3 = (Exception) ois3.readObject();
       
  1363         // It was decided that getMessage should not store the
       
  1364         // message in Throwable.detailMessage or implement writeReplace(),
       
  1365         // thus it can not be recovered by serialization.
       
  1366         //Asserts.assertEquals(ex3.getMessage(), msg3);
       
  1367         Asserts.assertEquals(ex3.getMessage(), null);
       
  1368     }
       
  1369 
       
  1370     static int index17 = 17;
       
  1371     int getIndex17() { return 17; };
       
  1372 
       
  1373     @SuppressWarnings({ "unused", "null" })
       
  1374     public void testComplexMessages() {
       
  1375         try {
       
  1376             staticLongArray[0][0] = 2L;
       
  1377             Asserts.fail();
       
  1378         } catch (NullPointerException e) {
       
  1379             checkMessage(e, "staticLongArray[0][0] = 2L;", e.getMessage(),
       
  1380                          "Cannot store to long array because " +
       
  1381                          "\"NullPointerExceptionTest.staticLongArray[0]\" is null");
       
  1382         }
       
  1383 
       
  1384         try {
       
  1385             NullPointerExceptionTest obj = this;
       
  1386             Object val = obj.dag.getArray().clone();
       
  1387             Asserts.assertNull(val);
       
  1388             Asserts.fail();
       
  1389         } catch (NullPointerException e) {
       
  1390             checkMessage(e, "Object val = obj.dag.getArray().clone();", e.getMessage(),
       
  1391                          "Cannot invoke \"NullPointerExceptionTest$DoubleArrayGen.getArray()\" because " +
       
  1392                          (hasDebugInfo ? "\"obj" : "\"<local1>") + ".dag\" is null");
       
  1393         }
       
  1394         try {
       
  1395             int indexes[] = new int[1];
       
  1396             NullPointerExceptionTest[] objs = new NullPointerExceptionTest[] {this};
       
  1397             Object val = objs[indexes[0]].nullInstanceField.returnNull(null, null, 1f);
       
  1398             Asserts.assertNull(val);
       
  1399             Asserts.fail();
       
  1400         } catch (NullPointerException e) {
       
  1401             checkMessage(e, "Object val = objs[indexes[0]].nullInstanceField.returnNull(null, null, 1f);", e.getMessage(),
       
  1402                          "Cannot invoke \"NullPointerExceptionTest.returnNull(String[][], int[][][], float)\" because " +
       
  1403                          (hasDebugInfo ? "\"objs[indexes" : "\"<local2>[<local1>") + "[0]].nullInstanceField\" is null");
       
  1404         }
       
  1405 
       
  1406         try {
       
  1407             int indexes[] = new int[1];
       
  1408             NullPointerExceptionTest[][] objs =
       
  1409                 new NullPointerExceptionTest[][] {new NullPointerExceptionTest[] {this}};
       
  1410             synchronized (objs[indexes[0]][0].nullInstanceField) {
       
  1411                 Asserts.fail();
       
  1412             }
       
  1413         } catch (NullPointerException e) {
       
  1414             checkMessage(e, "synchronized (objs[indexes[0]][0].nullInstanceField) { ... }", e.getMessage(),
       
  1415                          "Cannot enter synchronized block because " +
       
  1416                          (hasDebugInfo ? "\"objs[indexes" : "\"<local2>[<local1>" ) + "[0]][0].nullInstanceField\" is null");
       
  1417         }
       
  1418 
       
  1419         try {
       
  1420             // If we can get the value from more than one bci, we cannot know which one
       
  1421             // is null. Make sure we don't print the wrong value.
       
  1422             String s = null;
       
  1423             @SuppressWarnings("unused")
       
  1424             byte[] val = (Math.random() < 0.5 ? s : (new String[1])[0]).getBytes();
       
  1425         } catch (NullPointerException e) {
       
  1426             checkMessage(e, "byte[] val = (Math.random() < 0.5 ? s : (new String[1])[0]).getBytes();", e.getMessage(),
       
  1427                          "Cannot invoke \"String.getBytes()\"");
       
  1428         }
       
  1429 
       
  1430         try {
       
  1431             // If we can get the value from more than one bci, we cannot know which one
       
  1432             // is null. Make sure we don't print the wrong value.  Also make sure if
       
  1433             // we don't print the failed action we don't print a string at all.
       
  1434             int[][] a = new int[1][];
       
  1435             int[][] b = new int[2][];
       
  1436             long index = 0;
       
  1437             @SuppressWarnings("unused")
       
  1438             int val = (Math.random() < 0.5 ? a[(int)index] : b[(int)index])[13];
       
  1439         } catch (NullPointerException e) {
       
  1440             checkMessage(e, "int val = (Math.random() < 0.5 ? a[(int)index] : b[(int)index])[13]", e.getMessage(),
       
  1441                          "Cannot load from int array");
       
  1442         }
       
  1443 
       
  1444         try {
       
  1445             // If we can get the value from more than one bci, we cannot know which one
       
  1446             // is null. Make sure we don't print the wrong value.  Also make sure if
       
  1447             // we don't print the failed action we don't print a string at all.
       
  1448             int[][] a = new int[1][];
       
  1449             int[][] b = new int[2][];
       
  1450             long index = 0;
       
  1451             int val = (Math.random() < 0.5 ? a : b)[(int)index][13];
       
  1452         } catch (NullPointerException e) {
       
  1453             checkMessage(e, "int val = (Math.random() < 0.5 ? a : b)[(int)index][13]", e.getMessage(),
       
  1454                          "Cannot load from int array because \"<array>[...]\" is null");
       
  1455         }
       
  1456 
       
  1457         try {
       
  1458             C c1 = new C();
       
  1459             C c2 = new C();
       
  1460             (Math.random() < 0.5 ? c1 : c2).to_d.num = 77;
       
  1461         } catch (NullPointerException e) {
       
  1462             checkMessage(e, "(Math.random() < 0.5 ? c1 : c2).to_d.num = 77;", e.getMessage(),
       
  1463                          "Cannot assign field \"num\" because \"to_d\" is null");
       
  1464         }
       
  1465 
       
  1466         // Static variable as array index.
       
  1467         try {
       
  1468             staticLongArray[index17][0] = 2L;
       
  1469         }  catch (NullPointerException e) {
       
  1470             checkMessage(e, "staticLongArray[index17][0] = 2L;",  e.getMessage(),
       
  1471                          "Cannot store to long array because " +
       
  1472                          "\"NullPointerExceptionTest.staticLongArray[NullPointerExceptionTest.index17]\" is null");
       
  1473         }
       
  1474 
       
  1475         // Method call as array index.
       
  1476         try {
       
  1477             staticLongArray[getIndex17()][0] = 2L;
       
  1478         }  catch (NullPointerException e) {
       
  1479             checkMessage(e, "staticLongArray[getIndex17()][0] = 2L;",  e.getMessage(),
       
  1480                          "Cannot store to long array because " +
       
  1481                          "\"NullPointerExceptionTest.staticLongArray[NullPointerExceptionTest.getIndex17()]\" is null");
       
  1482         }
       
  1483 
       
  1484         // Unboxing.
       
  1485         Integer a = null;
       
  1486         try {
       
  1487             int b = a;
       
  1488         }  catch (NullPointerException e) {
       
  1489             checkMessage(e, "Integer a = null; int b = a;",  e.getMessage(),
       
  1490                          "Cannot invoke \"java.lang.Integer.intValue()\" because " +
       
  1491                          (hasDebugInfo ? "\"a\"" : "\"<local1>\"") + " is null");
       
  1492         }
       
  1493 
       
  1494         // Unboxing by hand. Has the same message as above.
       
  1495         try {
       
  1496             int b = a.intValue();
       
  1497         }  catch (NullPointerException e) {
       
  1498             checkMessage(e, "Integer a = null; int b = a.intValue();",  e.getMessage(),
       
  1499                          "Cannot invoke \"java.lang.Integer.intValue()\" because " +
       
  1500                          (hasDebugInfo ? "\"a\"" : "\"<local1>\"") + " is null");
       
  1501         }
       
  1502     }
       
  1503 
       
  1504     // Generates:
       
  1505     // class E implements E0 {
       
  1506     //     public int throwNPE(F f) {
       
  1507     //         return f.i;
       
  1508     //     }
       
  1509     //     public void throwNPE_reuseStackSlot1(String s1) {
       
  1510     //         System.out.println(s1.substring(1));
       
  1511     //         String s1_2 = null; // Reuses slot 1.
       
  1512     //         System.out.println(s1_2.substring(1));
       
  1513     //     }
       
  1514     //     public void throwNPE_reuseStackSlot4(String s1, String s2, String s3, String s4) {
       
  1515     //         System.out.println(s4.substring(1));
       
  1516     //         String s4_2 = null;  // Reuses slot 4.
       
  1517     //         System.out.println(s4_2.substring(1));
       
  1518     //     }
       
  1519     // }
       
  1520     //
       
  1521     // This code was adapted from output of
       
  1522     //   java jdk.internal.org.objectweb.asm.util.ASMifier E0.class
       
  1523     static byte[] generateTestClass() {
       
  1524         ClassWriter cw = new ClassWriter(0);
       
  1525         MethodVisitor mv;
       
  1526 
       
  1527         cw.visit(50, ACC_SUPER, "E", null, "java/lang/Object", new String[] { "E0" });
       
  1528 
       
  1529         {
       
  1530             mv = cw.visitMethod(0, "<init>", "()V", null, null);
       
  1531             mv.visitCode();
       
  1532             mv.visitVarInsn(ALOAD, 0);
       
  1533             mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
       
  1534             mv.visitInsn(RETURN);
       
  1535             mv.visitMaxs(1, 1);
       
  1536             mv.visitEnd();
       
  1537         }
       
  1538 
       
  1539         {
       
  1540             mv = cw.visitMethod(ACC_PUBLIC, "throwNPE", "(LF;)I", null, null);
       
  1541             mv.visitCode();
       
  1542             Label label0 = new Label();
       
  1543             mv.visitLabel(label0);
       
  1544             mv.visitLineNumber(118, label0);
       
  1545             mv.visitVarInsn(ALOAD, 1);
       
  1546             mv.visitFieldInsn(GETFIELD, "F", "i", "I");
       
  1547             mv.visitInsn(IRETURN);
       
  1548             Label label1 = new Label();
       
  1549             mv.visitLabel(label1);
       
  1550             mv.visitLocalVariable("this", "LE;", null, label0, label1, 0);
       
  1551             mv.visitLocalVariable("f", "LE;", null, label0, label1, 1);
       
  1552             mv.visitMaxs(1, 2);
       
  1553             mv.visitEnd();
       
  1554         }
       
  1555 
       
  1556         {
       
  1557             mv = cw.visitMethod(ACC_PUBLIC, "throwNPE_reuseStackSlot1", "(Ljava/lang/String;)V", null, null);
       
  1558             mv.visitCode();
       
  1559             Label label0 = new Label();
       
  1560             mv.visitLabel(label0);
       
  1561             mv.visitLineNumber(7, label0);
       
  1562             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
  1563             mv.visitVarInsn(ALOAD, 1);
       
  1564             mv.visitInsn(ICONST_1);
       
  1565             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(I)Ljava/lang/String;", false);
       
  1566             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
       
  1567             Label label1 = new Label();
       
  1568             mv.visitLabel(label1);
       
  1569             mv.visitLineNumber(8, label1);
       
  1570             mv.visitInsn(ACONST_NULL);
       
  1571             mv.visitVarInsn(ASTORE, 1);
       
  1572             Label label2 = new Label();
       
  1573             mv.visitLabel(label2);
       
  1574             mv.visitLineNumber(9, label2);
       
  1575             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
  1576             mv.visitVarInsn(ALOAD, 1);
       
  1577             mv.visitInsn(ICONST_1);
       
  1578             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(I)Ljava/lang/String;", false);
       
  1579             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
       
  1580             Label label3 = new Label();
       
  1581             mv.visitLabel(label3);
       
  1582             mv.visitLineNumber(10, label3);
       
  1583             mv.visitInsn(RETURN);
       
  1584             mv.visitMaxs(3, 3);
       
  1585             mv.visitEnd();
       
  1586         }
       
  1587 
       
  1588         {
       
  1589             mv = cw.visitMethod(ACC_PUBLIC, "throwNPE_reuseStackSlot4", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", null, null);
       
  1590             mv.visitCode();
       
  1591             Label label0 = new Label();
       
  1592             mv.visitLabel(label0);
       
  1593             mv.visitLineNumber(12, label0);
       
  1594             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
  1595             mv.visitVarInsn(ALOAD, 4);
       
  1596             mv.visitInsn(ICONST_1);
       
  1597             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(I)Ljava/lang/String;", false);
       
  1598             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
       
  1599             Label label1 = new Label();
       
  1600             mv.visitLabel(label1);
       
  1601             mv.visitLineNumber(13, label1);
       
  1602             mv.visitInsn(ACONST_NULL);
       
  1603             mv.visitVarInsn(ASTORE, 4);
       
  1604             Label label2 = new Label();
       
  1605             mv.visitLabel(label2);
       
  1606             mv.visitLineNumber(14, label2);
       
  1607             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
  1608             mv.visitVarInsn(ALOAD, 4);
       
  1609             mv.visitInsn(ICONST_1);
       
  1610             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(I)Ljava/lang/String;", false);
       
  1611             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
       
  1612             Label label3 = new Label();
       
  1613             mv.visitLabel(label3);
       
  1614             mv.visitLineNumber(15, label3);
       
  1615             mv.visitInsn(RETURN);
       
  1616             mv.visitMaxs(3, 6);
       
  1617             mv.visitEnd();
       
  1618         }
       
  1619 
       
  1620         cw.visitEnd();
       
  1621 
       
  1622         return cw.toByteArray();
       
  1623     }
       
  1624 
       
  1625     // Assign to a parameter.
       
  1626     // Without debug information, this will print "parameter1" if a NPE
       
  1627     // is raised in the first line because null was passed to the method.
       
  1628     // It will print "local1" if a NPE is raised in line three.
       
  1629     public void assign_to_parameter(String s1) {
       
  1630         System.out.println(s1.substring(1));
       
  1631         s1 = null;
       
  1632         System.out.println(s1.substring(2));
       
  1633     }
       
  1634 
       
  1635     // Tests that a class generated on the fly is handled properly.
       
  1636     public void testGeneratedCode() throws Exception {
       
  1637         byte[] classBytes = generateTestClass();
       
  1638         Lookup lookup = lookup();
       
  1639         Class<?> clazz = lookup.defineClass(classBytes);
       
  1640         E0 e = (E0) clazz.getDeclaredConstructor().newInstance();
       
  1641         try {
       
  1642             e.throwNPE(null);
       
  1643         } catch (NullPointerException ex) {
       
  1644             checkMessage(ex, "return f.i;",
       
  1645                          ex.getMessage(),
       
  1646                          "Cannot read field \"i\" because \"f\" is null");
       
  1647         }
       
  1648 
       
  1649         // Optimized bytecode can reuse local variable slots for several
       
  1650         // local variables.
       
  1651         // If there is no variable name information, we print 'parameteri'
       
  1652         // if a parameter maps to a local slot. Once a local slot has been
       
  1653         // written, we don't know any more whether it was written as the
       
  1654         // corresponding parameter, or whether another local has been
       
  1655         // mapped to the slot. So we don't want to print 'parameteri' any
       
  1656         // more, but 'locali'. Similary for 'this'.
       
  1657 
       
  1658         // Expect message saying "parameter0".
       
  1659         try {
       
  1660             e.throwNPE_reuseStackSlot1(null);
       
  1661         } catch (NullPointerException ex) {
       
  1662             checkMessage(ex, "s1.substring(1)",
       
  1663                          ex.getMessage(),
       
  1664                          "Cannot invoke \"String.substring(int)\" because \"<parameter1>\" is null");
       
  1665         }
       
  1666         // Expect message saying "local0".
       
  1667         try {
       
  1668             e.throwNPE_reuseStackSlot1("aa");
       
  1669         } catch (NullPointerException ex) {
       
  1670             checkMessage(ex, "s1_2.substring(1)",
       
  1671                          ex.getMessage(),
       
  1672                          "Cannot invoke \"String.substring(int)\" because \"<local1>\" is null");
       
  1673         }
       
  1674         // Expect message saying "parameter4".
       
  1675         try {
       
  1676             e.throwNPE_reuseStackSlot4("aa", "bb", "cc", null);
       
  1677         } catch (NullPointerException ex) {
       
  1678             checkMessage(ex, "s4.substring(1)",
       
  1679                          ex.getMessage(),
       
  1680                          "Cannot invoke \"String.substring(int)\" because \"<parameter4>\" is null");
       
  1681         }
       
  1682         // Expect message saying "local4".
       
  1683         try {
       
  1684             e.throwNPE_reuseStackSlot4("aa", "bb", "cc", "dd");
       
  1685         } catch (NullPointerException ex) {
       
  1686             checkMessage(ex, "s4_2.substring(1)",
       
  1687                          ex.getMessage(),
       
  1688                          "Cannot invoke \"String.substring(int)\" because \"<local4>\" is null");
       
  1689         }
       
  1690 
       
  1691         // Unfortunately, with the fix for optimized code as described above
       
  1692         // we don't write 'parameteri' any more after the parameter variable
       
  1693         // has been assigned.
       
  1694 
       
  1695         if (!hasDebugInfo) {
       
  1696             // Expect message saying "parameter1".
       
  1697             try {
       
  1698                 assign_to_parameter(null);
       
  1699             } catch (NullPointerException ex) {
       
  1700                 checkMessage(ex, "s1.substring(1)",
       
  1701                              ex.getMessage(),
       
  1702                              "Cannot invoke \"String.substring(int)\" because \"<parameter1>\" is null");
       
  1703             }
       
  1704             // The message says "local1" although "parameter1" would be correct.
       
  1705             try {
       
  1706                 assign_to_parameter("aaa");
       
  1707             } catch (NullPointerException ex) {
       
  1708                 checkMessage(ex, "s1.substring(2)",
       
  1709                              ex.getMessage(),
       
  1710                              "Cannot invoke \"String.substring(int)\" because \"<local1>\" is null");
       
  1711             }
       
  1712         }
       
  1713     }
       
  1714 }
       
  1715 
       
  1716 // Helper interface for test cases needed for generateTestClass().
       
  1717 interface E0 {
       
  1718     public int  throwNPE(F f);
       
  1719     public void throwNPE_reuseStackSlot1(String s1);
       
  1720     public void throwNPE_reuseStackSlot4(String s1, String s2, String s3, String s4);
       
  1721 }
       
  1722 
       
  1723 // Helper class for test cases needed for generateTestClass().
       
  1724 class F {
       
  1725     int i;
       
  1726 }
       
  1727 
       
  1728 // For invokespecial test cases.
       
  1729 class G {
       
  1730     public String m2(String x) {
       
  1731         return null;
       
  1732     }
       
  1733 
       
  1734     // This generates the following class:
       
  1735     //
       
  1736     // class Sub2G extends G {
       
  1737     //   public String m2(String x) {
       
  1738     //       super = null;  // Possible in raw bytecode.
       
  1739     //       return super.m2(x).substring(2);  // Uses invokespecial.
       
  1740     //   }
       
  1741     // }
       
  1742     //
       
  1743     // This code was adapted from output of
       
  1744     //   java jdk.internal.org.objectweb.asm.util.ASMifier Sub2G.class
       
  1745     static byte[] generateSub2GTestClass() {
       
  1746         ClassWriter cw = new ClassWriter(0);
       
  1747         MethodVisitor mv;
       
  1748 
       
  1749         cw.visit(50, ACC_SUPER, "Sub2G", null, "G", null);
       
  1750 
       
  1751         {
       
  1752             mv = cw.visitMethod(0, "<init>", "()V", null, null);
       
  1753             mv.visitCode();
       
  1754             mv.visitVarInsn(ALOAD, 0);
       
  1755             mv.visitMethodInsn(INVOKESPECIAL, "G", "<init>", "()V", false);
       
  1756             mv.visitInsn(RETURN);
       
  1757             mv.visitMaxs(1, 1);
       
  1758             mv.visitEnd();
       
  1759         }
       
  1760         {
       
  1761             mv = cw.visitMethod(ACC_PUBLIC, "m2", "(Ljava/lang/String;)Ljava/lang/String;", null, null);
       
  1762             mv.visitCode();
       
  1763             mv.visitInsn(ACONST_NULL);   // Will cause NPE.
       
  1764             mv.visitVarInsn(ALOAD, 1);
       
  1765             mv.visitMethodInsn(INVOKESPECIAL, "G", "m2", "(Ljava/lang/String;)Ljava/lang/String;", false);
       
  1766             mv.visitInsn(ICONST_2);
       
  1767             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "substring", "(I)Ljava/lang/String;", false);
       
  1768             mv.visitInsn(ARETURN);
       
  1769             mv.visitMaxs(2, 2);
       
  1770             mv.visitEnd();
       
  1771         }
       
  1772 
       
  1773         cw.visitEnd();
       
  1774 
       
  1775         return cw.toByteArray();
       
  1776     }
       
  1777 }
       
  1778 class SubG extends G {
       
  1779     public String m2(String x) {
       
  1780         return super.m2(x).substring(2);
       
  1781     }
       
  1782 }