diff options
author | 2024-09-20 11:13:12 +0000 | |
---|---|---|
committer | 2024-09-20 14:16:25 +0000 | |
commit | 6b7fc69a6a5ffcfa16b7511f6a04635c105543db (patch) | |
tree | 190396b34f9e41fd2ed1e601bf8c1ad58ce64c60 | |
parent | 68742f619ed4475de413ced479aa2517bf3fd93a (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.cc | 3 | ||||
-rw-r--r-- | test/2277-methodhandle-invokeexact/src/Main.java | 23 |
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); |