summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Almaz Mingaleev <mingaleev@google.com> 2024-09-20 11:13:12 +0000
committer Almaz Mingaleev <mingaleev@google.com> 2024-09-20 14:16:25 +0000
commit6b7fc69a6a5ffcfa16b7511f6a04635c105543db (patch)
tree190396b34f9e41fd2ed1e601bf8c1ad58ce64c60
parent68742f619ed4475de413ced479aa2517bf3fd93a (diff)
Check receiver for null in invokeExact intrinsic.
Bug: 297147201 Test: ./art/test/testrunner/testrunner.py --host --64 --optimizing --jvm -b Change-Id: I6633bdab20b13335afccfe0506f6b91391c19fe3
-rw-r--r--compiler/optimizing/intrinsics_x86_64.cc3
-rw-r--r--test/2277-methodhandle-invokeexact/src/Main.java23
2 files changed, 24 insertions, 2 deletions
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index d085d2c469..bd6d6d1889 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -4162,6 +4162,9 @@ void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke)
CpuRegister receiver = locations->InAt(1).AsRegister<CpuRegister>();
+ __ testl(receiver, receiver);
+ __ j(kEqual, slow_path->GetEntryLabel());
+
// Using vtable_index register as temporary in subtype check. It will be overridden later.
// If `method` is an interface method this check will fail.
CpuRegister vtable_index = locations->GetTemp(0).AsRegister<CpuRegister>();
diff --git a/test/2277-methodhandle-invokeexact/src/Main.java b/test/2277-methodhandle-invokeexact/src/Main.java
index 9a52885c8f..bb8c5fec01 100644
--- a/test/2277-methodhandle-invokeexact/src/Main.java
+++ b/test/2277-methodhandle-invokeexact/src/Main.java
@@ -32,6 +32,25 @@ public class Main {
$noinline$testMethodHandleFromOtherDex();
Multi.$noinline$testMHFromMain(OPTIONAL_GET);
$noinline$testWithArgs();
+ $noinline$nullchecks();
+ }
+
+ private static void $noinline$nullchecks() throws Throwable {
+ try {
+ VOID_METHOD.invokeExact((A) null);
+ unreachable("Receiver is null, should throw NPE");
+ } catch (NullPointerException expected) {}
+
+ try {
+ VOID_METHOD.invokeExact((Main) null);
+ unreachable("Should throw WMTE: input is of wrong type");
+ } catch (WrongMethodTypeException expected) {}
+
+ try {
+ MethodHandle mh = null;
+ mh.invokeExact();
+ unreachable("MethodHandle object is null, should throw NPE");
+ } catch (NullPointerException expected) {}
}
private static void $noinline$testMethodHandleFromOtherDex() throws Throwable {
@@ -59,7 +78,7 @@ public class Main {
try {
INTERFACE_DEFAULT_METHOD.invokeExact(new A());
unreachable("MethodHandle's type is (Main$I)V, but callsite is (Main$A)V");
- } catch (WrongMethodTypeException ignored) {}
+ } catch (WrongMethodTypeException expected) {}
INTERFACE_DEFAULT_METHOD.invokeExact((I) new A());
assertEquals("I.defaultMethod", STATUS);
@@ -88,7 +107,7 @@ public class Main {
try {
RETURN_INT.invokeExact(new A());
unreachable("MethodHandle's type is (Main$A)I, but callsite type is (Main$A)V");
- } catch (WrongMethodTypeException ignored) {}
+ } catch (WrongMethodTypeException expected) {}
String returnedString = (String) STATIC_METHOD.invokeExact(new A());
assertEquals("staticMethod", returnedString);