Implicit NPE support when no exception given to throw.

This change adds support for creating an implicit NPE when throw is used
without giving an exception object. It extends the CatchTest to check
the functionality is correct. It also weakens a too strong assertion
about when an address lies within code.

Change-Id: I33742cce4deb31b4e0e9b7bd386f78e8cba3e53a
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 712a3a0..c1e666e 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -239,6 +239,7 @@
   CompileVirtualMethod(NULL, "java.lang.Throwable","fillInStackTrace","()Ljava/lang/Throwable;");
   CompileDirectMethod(NULL, "java.lang.Throwable","nativeFillInStackTrace","()Ljava/lang/Object;");
   AssertStaticIntMethod(1579, LoadDex("IntMath"), "IntMath", "catchBlock", "(I)I", 1000);
+  AssertStaticIntMethod(7777, LoadDex("IntMath"), "IntMath", "catchBlock", "(I)I", 7000);
 }
 
 TEST_F(CompilerTest, CatchTestNoThrow) {
diff --git a/src/object.cc b/src/object.cc
index 6490797..63c9237 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -579,8 +579,14 @@
     // assume that this is some initial value that will always lie in code
     return true;
   } else {
+#if defined(__arm__)
+    pc &= ~0x1;  // clear any possible thumb instruction mode bit
+#endif
     uint32_t rel_offset = pc - reinterpret_cast<uintptr_t>(GetCodeArray()->GetData());
-    return rel_offset < static_cast<uint32_t>(GetCodeArray()->GetLength());
+    // Strictly the following test should be a less-than, however, if the last
+    // instruction is a call to an exception throw we may see return addresses
+    // that are 1 beyond the end of code.
+    return rel_offset <= static_cast<uint32_t>(GetCodeArray()->GetLength());
   }
 }
 
diff --git a/src/thread.cc b/src/thread.cc
index 69fb3ba..e1207d0 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -68,6 +68,10 @@
   // Place a special frame at the TOS that will save all callee saves
   *sp = thread->CalleeSaveMethod();
   thread->SetTopOfStack(sp, 0);
+  if (exception == NULL) {
+    thread->ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
+    exception = thread->GetException();
+  }
   thread->DeliverException(exception);
 }
 
diff --git a/test/IntMath/IntMath.java b/test/IntMath/IntMath.java
index 4c445b7..bffa894 100644
--- a/test/IntMath/IntMath.java
+++ b/test/IntMath/IntMath.java
@@ -103,10 +103,19 @@
         throw new NullPointerException();
     }
 
+    static void throwImplicitNullPointerException() {
+      throw null;
+    }
+
     static int catchBlock(int x) {
         try {
-            x += 123;
-            throwNullPointerException();
+            if (x == 1000) {
+                x += 123;
+                throwNullPointerException();
+            } else {
+                x += 321;
+                throwImplicitNullPointerException();
+            }
         } catch (NullPointerException npe) {
             x += 456;
         }