Add null check to CheckVirtualMethod

There was a runtime SIGSEGV that should have been a check jni
failure.

Also added regression test.

Bug: 16320699

(cherry picked from commit 167350d9c781c5e3893714bb26ab5cb1c4abf6b4)

Change-Id: I7edea6af6517f1e5628678e824b8307daf491418
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index 99277a0..b0f8e22 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -228,7 +228,10 @@
     }
     if (invoke != kStatic) {
       mirror::Object* o = soa.Decode<mirror::Object*>(jobj);
-      if (!o->InstanceOf(m->GetDeclaringClass())) {
+      if (o == nullptr) {
+        AbortF("can't call %s on null object", PrettyMethod(m).c_str());
+        return false;
+      } else if (!o->InstanceOf(m->GetDeclaringClass())) {
         AbortF("can't call %s on instance of %s", PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str());
         return false;
       }
@@ -292,7 +295,10 @@
       return false;
     }
     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
-    if (!o->InstanceOf(m->GetDeclaringClass())) {
+    if (o == nullptr) {
+      AbortF("can't call %s on null object", PrettyMethod(m).c_str());
+      return false;
+    } else if (!o->InstanceOf(m->GetDeclaringClass())) {
       AbortF("can't call %s on instance of %s", PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str());
       return false;
     }
diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc
index 844d14a..b236ede 100644
--- a/runtime/jni_internal_test.cc
+++ b/runtime/jni_internal_test.cc
@@ -746,6 +746,21 @@
   GetMethodIdBadArgumentTest(true);
 }
 
+TEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
+  jclass jlobject = env_->FindClass("java/lang/Object");
+  jmethodID method;
+
+  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
+  method = env_->GetMethodID(jlobject, "<init>", "()V");
+  EXPECT_NE(nullptr, method);
+  EXPECT_FALSE(env_->ExceptionCheck());
+
+  // Null object to CallVoidMethod.
+  CheckJniAbortCatcher check_jni_abort_catcher;
+  env_->CallVoidMethod(nullptr, method);
+  check_jni_abort_catcher.Check("null");
+}
+
 TEST_F(JniInternalTest, GetStaticMethodID) {
   jclass jlobject = env_->FindClass("java/lang/Object");
   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");