diff options
| author | 2024-08-29 12:57:14 +0000 | |
|---|---|---|
| committer | 2024-09-24 10:15:56 +0000 | |
| commit | 63b8399f3f144769260d93a7a985233e5ac5b910 (patch) | |
| tree | 2d46e0d91f2df79a80f9ed80cdcb49c08e7de9f6 /test/2280-const-method-handle-validation/src | |
| parent | 0b8cc45c57bd0d13901e2c1d15f74c8b562fb2d2 (diff) | |
Add more validation for const-method-handle.
Making it closer to JVMS 4.4.8 and 5.4.3.5. The RI rejects certain
constructions at the class verification stage, hence there are
separate classes for MethodHandle-s targeting <init> and <clinit>
methods. In these cases The RI throws ClassFormatError during class
load, but currently we do validations only when actual MethodHandle
object is constructed, that's is the reason why test code has
ICCE | CFE in catch blocks. That will be addressed in the
upcoming CLs.
This should not cause any compat issues as even if some of these
MethodHandle were constructed successfully, their invocation
leads to runtime crashes.
Bug: 297147201
Test: ./art/test/testrunner/testrunner.py --host --64 --jvm -b
Change-Id: I551b04e3c00ffc8bcdeac4760d9ac4b3bb7b2aff
Diffstat (limited to 'test/2280-const-method-handle-validation/src')
23 files changed, 1387 insertions, 0 deletions
diff --git a/test/2280-const-method-handle-validation/src/InvokeConstructor.java b/test/2280-const-method-handle-validation/src/InvokeConstructor.java new file mode 100644 index 0000000000..4ca22b8e0c --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeConstructor.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class InvokeConstructor { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + public static void runTests() { + try { + InvokeConstructorForInstanceMethod.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + InvokeConstructorForClassInitializer.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + InvokeConstructorForStaticMethod.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + } +} diff --git a/test/2280-const-method-handle-validation/src/InvokeConstructorForClassInitializer.java b/test/2280-const-method-handle-validation/src/InvokeConstructorForClassInitializer.java new file mode 100644 index 0000000000..d326e484a5 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeConstructorForClassInitializer.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeConstructorForClassInitializer { + + private static int STATIC_FIELD = 1; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.NEW_INVOKE_SPECIAL, + owner = "InvokeConstructorForClassInitializer", + fieldOrMethodName = "<clinit>", + descriptor = "()V") + private static MethodHandle forClassInitializer() { + unreachable(); + return null; + } + + public static void runTests() { + forClassInitializer(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeConstructorForInstanceMethod.java b/test/2280-const-method-handle-validation/src/InvokeConstructorForInstanceMethod.java new file mode 100644 index 0000000000..4b9536515a --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeConstructorForInstanceMethod.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeConstructorForInstanceMethod { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.NEW_INVOKE_SPECIAL, + owner = "java/lang/Object", + fieldOrMethodName = "hashCode", + descriptor = "()I") + private static MethodHandle forInstanceMethod() { + unreachable(); + return null; + } + + public static void runTests() { + forInstanceMethod(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeConstructorForStaticMethod.java b/test/2280-const-method-handle-validation/src/InvokeConstructorForStaticMethod.java new file mode 100644 index 0000000000..d447b7025e --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeConstructorForStaticMethod.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeConstructorForStaticMethod { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.NEW_INVOKE_SPECIAL, + owner = "InvokeConstructorForStaticMethod", + fieldOrMethodName = "unreachable", + descriptor = "()V") + private static MethodHandle forStaticMethod() { + unreachable(); + return null; + } + + public static void runTests() { + forStaticMethod(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInstance.java b/test/2280-const-method-handle-validation/src/InvokeInstance.java new file mode 100644 index 0000000000..0c8ad69470 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInstance.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInstance { + + private int instanceField; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_VIRTUAL, + owner = "InvokeInstance", + fieldOrMethodName = "unreachable", + descriptor = "()V") + private static MethodHandle forStaticMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_VIRTUAL, + owner = "java/util/List", + fieldOrMethodName = "size", + descriptor = "()I") + private static MethodHandle forInterfaceMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_VIRTUAL, + owner = "Main", + fieldOrMethodName = "instanceMethod", + descriptor = "()V") + private static MethodHandle inaccessibleInstanceMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_VIRTUAL, + owner = "Main", + fieldOrMethodName = "staticMethod", + descriptor = "()V") + private static MethodHandle inaccessibleStaticMethod() { + unreachable(); + return null; + } + + public static void runTests() { + try { + forStaticMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + forInterfaceMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + InvokeInstanceForConstructor.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + InvokeInstanceForClassInitializer.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + inaccessibleInstanceMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleStaticMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInstanceForClassInitializer.java b/test/2280-const-method-handle-validation/src/InvokeInstanceForClassInitializer.java new file mode 100644 index 0000000000..e648ce037e --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInstanceForClassInitializer.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInstanceForClassInitializer { + + private static int STATIC_FIELD = 1; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_VIRTUAL, + owner = "InvokeInstanceForClassInitializer", + fieldOrMethodName = "<clinit>", + descriptor = "()V") + private static MethodHandle forClassInitializer() { + unreachable(); + return null; + } + + public static void runTests() { + forClassInitializer(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInstanceForConstructor.java b/test/2280-const-method-handle-validation/src/InvokeInstanceForConstructor.java new file mode 100644 index 0000000000..8d662628e5 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInstanceForConstructor.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInstanceForConstructor { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_VIRTUAL, + owner = "InvokeInstanceForConstructor", + fieldOrMethodName = "<init>", + descriptor = "()V") + private static MethodHandle forConstructor() { + unreachable(); + return null; + } + + public static void runTests() { + forConstructor(); + } +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInterface.java b/test/2280-const-method-handle-validation/src/InvokeInterface.java new file mode 100644 index 0000000000..602eef3ce0 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInterface.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInterface { + + private int instanceField; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_INTERFACE, + owner = "InvokeInterface", + fieldOrMethodName = "unreachable", + descriptor = "()V") + private static MethodHandle forStaticMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_INTERFACE, + owner = "java/lang/Object", + fieldOrMethodName = "hashCode", + descriptor = "()I") + private static MethodHandle forInstanceMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_INTERFACE, + owner = "Main$I", + fieldOrMethodName = "privateMethod", + descriptor = "()V", + ownerIsInterface = true) + private static MethodHandle inaccessiblePrivateInterfaceMethod() { + unreachable(); + return null; + } + + public static void runTests() { + try { + InvokeInterfaceForStaticMethod.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + InvokeInterfaceForInstanceMethod.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + InvokeInterfaceForConstructor.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + InvokeInterfaceForClassInitializer.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + inaccessiblePrivateInterfaceMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInterfaceForClassInitializer.java b/test/2280-const-method-handle-validation/src/InvokeInterfaceForClassInitializer.java new file mode 100644 index 0000000000..a837a7a066 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInterfaceForClassInitializer.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInterfaceForClassInitializer { + + private static int STATIC_FIELD = 1; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_INTERFACE, + owner = "InvokeInterfaceForClassInitializer", + fieldOrMethodName = "<clinit>", + descriptor = "()V") + private static MethodHandle forClassInitializer() { + unreachable(); + return null; + } + + public static void runTests() { + forClassInitializer(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInterfaceForConstructor.java b/test/2280-const-method-handle-validation/src/InvokeInterfaceForConstructor.java new file mode 100644 index 0000000000..0306f2831f --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInterfaceForConstructor.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInterfaceForConstructor { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_INTERFACE, + owner = "InvokeInterfaceForConstructor", + fieldOrMethodName = "<init>", + descriptor = "()V") + private static MethodHandle forConstructor() { + unreachable(); + return null; + } + + public static void runTests() { + forConstructor(); + } +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInterfaceForInstanceMethod.java b/test/2280-const-method-handle-validation/src/InvokeInterfaceForInstanceMethod.java new file mode 100644 index 0000000000..0a6ca3b73a --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInterfaceForInstanceMethod.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInterfaceForInstanceMethod { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_INTERFACE, + owner = "java/lang/Object", + fieldOrMethodName = "hashCode", + descriptor = "()I") + private static MethodHandle forInstanceMethod() { + unreachable(); + return null; + } + + public static void runTests() { + forInstanceMethod(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeInterfaceForStaticMethod.java b/test/2280-const-method-handle-validation/src/InvokeInterfaceForStaticMethod.java new file mode 100644 index 0000000000..1a66eb2909 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeInterfaceForStaticMethod.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeInterfaceForStaticMethod { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_INTERFACE, + owner = "InvokeInterfaceForStaticMethod", + fieldOrMethodName = "unreachable", + descriptor = "()V") + private static MethodHandle forStaticMethod() { + unreachable(); + return null; + } + + public static void runTests() { + forStaticMethod(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeSpecial.java b/test/2280-const-method-handle-validation/src/InvokeSpecial.java new file mode 100644 index 0000000000..f861fc77cb --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeSpecial.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeSpecial { + + private int instanceField; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + public void method() {} + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_SPECIAL, + owner = "InvokeSpecial", + fieldOrMethodName = "unreachable", + descriptor = "()V") + private static MethodHandle forStaticMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_SPECIAL, + owner = "java/util/List", + fieldOrMethodName = "size", + descriptor = "()I") + private static MethodHandle forInterfaceMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_SPECIAL, + owner = "Main", + fieldOrMethodName = "instanceMethod", + descriptor = "()V") + private static MethodHandle inaccessiblePrivateMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_SPECIAL, + owner = "Main", + fieldOrMethodName = "staticMethod", + descriptor = "()V") + private static MethodHandle inaccessibleStaticMethod() { + unreachable(); + return null; + } + + public static void runTests() { + try { + forStaticMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + // TODO(b/297147201): runtime crashes here. + /* + try { + forInterfaceMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + */ + + // TODO(b/297147201): runtime does not throw exception here. + /* + try { + InvokeSpecialForConstructor.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + */ + + try { + InvokeSpecialForClassInitializer.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + inaccessibleStaticMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeSpecialForClassInitializer.java b/test/2280-const-method-handle-validation/src/InvokeSpecialForClassInitializer.java new file mode 100644 index 0000000000..9258b79593 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeSpecialForClassInitializer.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeSpecialForClassInitializer { + + private static int STATIC_FIELD = 1; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_SPECIAL, + owner = "InvokeSpecialForClassInitializer", + fieldOrMethodName = "<clinit>", + descriptor = "()V") + private static MethodHandle forClassInitializer() { + unreachable(); + return null; + } + + public static void runTests() { + forClassInitializer(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeSpecialForConstructor.java b/test/2280-const-method-handle-validation/src/InvokeSpecialForConstructor.java new file mode 100644 index 0000000000..c87509bf57 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeSpecialForConstructor.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeSpecialForConstructor { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_SPECIAL, + owner = "InvokeSpecialForConstructor", + fieldOrMethodName = "<init>", + descriptor = "()V") + private static MethodHandle forClassInitializer() { + unreachable(); + return null; + } + + public static void runTests() { + forClassInitializer(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeStatic.java b/test/2280-const-method-handle-validation/src/InvokeStatic.java new file mode 100644 index 0000000000..638630145b --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeStatic.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeStatic { + private int instanceField; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + public void method() {} + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_STATIC, + owner = "InvokeStatic", + fieldOrMethodName = "method", + descriptor = "()V") + private static MethodHandle forInstanceMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_STATIC, + owner = "java/util/List", + fieldOrMethodName = "size", + descriptor = "()I") + private static MethodHandle forInterfaceMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_STATIC, + owner = "Main", + fieldOrMethodName = "instanceMethod", + descriptor = "()V") + private static MethodHandle inaccessibleInstanceMethod() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_STATIC, + owner = "Main", + fieldOrMethodName = "staticMethod", + descriptor = "()V") + private static MethodHandle inaccessibleStaticMethod() { + unreachable(); + return null; + } + + public static void runTests() { + try { + forInstanceMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + forInterfaceMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + InvokeStaticForConstructor.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + InvokeStaticForClassInitializer.runTests(); + unreachable(); + } catch (IncompatibleClassChangeError | ClassFormatError expected) {} + + try { + inaccessibleInstanceMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleStaticMethod(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeStaticForClassInitializer.java b/test/2280-const-method-handle-validation/src/InvokeStaticForClassInitializer.java new file mode 100644 index 0000000000..ebce0ee3d2 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeStaticForClassInitializer.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeStaticForClassInitializer { + + private static int STATIC_FIELD = 1; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_STATIC, + owner = "InvokeStaticForClassInitializer", + fieldOrMethodName = "<clinit>", + descriptor = "()V") + private static MethodHandle forClassInitializer() { + unreachable(); + return null; + } + + public static void runTests() { + forClassInitializer(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/InvokeStaticForConstructor.java b/test/2280-const-method-handle-validation/src/InvokeStaticForConstructor.java new file mode 100644 index 0000000000..7ad189815a --- /dev/null +++ b/test/2280-const-method-handle-validation/src/InvokeStaticForConstructor.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class InvokeStaticForConstructor { + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INVOKE_STATIC, + owner = "InvokeStaticForConstructor", + fieldOrMethodName = "<init>", + descriptor = "()V") + private static MethodHandle forConstructor() { + unreachable(); + return null; + } + + public static void runTests() { + forConstructor(); + } + +} diff --git a/test/2280-const-method-handle-validation/src/Main.java b/test/2280-const-method-handle-validation/src/Main.java new file mode 100644 index 0000000000..21713ec5c4 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/Main.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + private interface I { + public void method(); + + private void privateMethod() {} + + default void defaultMethod() {} + } + + private int privateField; + private static int PRIVATE_STATIC_FIELD; + + private void instanceMethod() {} + private static void staticMethod() {} + + public static void main(String[] args) { + PlainGet.runTests(); + PlainPut.runTests(); + StaticGet.runTests(); + StaticPut.runTests(); + + InvokeInstance.runTests(); + InvokeStatic.runTests(); + InvokeInterface.runTests(); + InvokeSpecial.runTests(); + InvokeConstructor.runTests(); + } +} diff --git a/test/2280-const-method-handle-validation/src/PlainGet.java b/test/2280-const-method-handle-validation/src/PlainGet.java new file mode 100644 index 0000000000..0b880e5744 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/PlainGet.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class PlainGet { + + private static int STATIC_FIELD; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_GET, + owner = "PlainGet", + fieldOrMethodName = "STATIC_FIELD", + descriptor = "I") + private static MethodHandle forStaticField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_GET, + owner = "Main", + fieldOrMethodName = "privateField", + descriptor = "I") + private static MethodHandle inaccessibleInstanceField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_GET, + owner = "Main", + fieldOrMethodName = "PRIVATE_STATIC_FIELD", + descriptor = "I") + private static MethodHandle inaccessibleStaticField() { + unreachable(); + return null; + } + + public static void runTests() { + try { + forStaticField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleInstanceField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleStaticField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} diff --git a/test/2280-const-method-handle-validation/src/PlainPut.java b/test/2280-const-method-handle-validation/src/PlainPut.java new file mode 100644 index 0000000000..4c5d2833c0 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/PlainPut.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class PlainPut { + + private final int finalField = 2; + private static int STATIC_FIELD; + private static final int STATIC_FINAL_FIELD = 1; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_PUT, + owner = "PlainGet", + fieldOrMethodName = "STATIC_FIELD", + descriptor = "I") + private static MethodHandle forStaticField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_PUT, + owner = "PlainGet", + fieldOrMethodName = "finalField", + descriptor = "I") + private static MethodHandle forFinalField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_PUT, + owner = "PlainGet", + fieldOrMethodName = "STATIC_FINAL_FIELD", + descriptor = "I") + private static MethodHandle forStaticFinalField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_PUT, + owner = "Main", + fieldOrMethodName = "privateField", + descriptor = "I") + private static MethodHandle inaccessibleInstanceField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.INSTANCE_PUT, + owner = "Main", + fieldOrMethodName = "PRIVATE_STATIC_FIELD", + descriptor = "I") + private static MethodHandle inaccessibleStaticField() { + unreachable(); + return null; + } + + public static void runTests() { + try { + forStaticField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + forFinalField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + forStaticFinalField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleInstanceField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleStaticField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} diff --git a/test/2280-const-method-handle-validation/src/StaticGet.java b/test/2280-const-method-handle-validation/src/StaticGet.java new file mode 100644 index 0000000000..8f42db91aa --- /dev/null +++ b/test/2280-const-method-handle-validation/src/StaticGet.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class StaticGet { + + private int instanceField; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_GET, + owner = "StaticGet", + fieldOrMethodName = "instanceField", + descriptor = "I") + private static MethodHandle forInstanceField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_GET, + owner = "Main", + fieldOrMethodName = "privateField", + descriptor = "I") + private static MethodHandle inaccessibleInstanceField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_GET, + owner = "Main", + fieldOrMethodName = "PRIVATE_STATIC_FIELD", + descriptor = "I") + private static MethodHandle inaccessibleStaticField() { + unreachable(); + return null; + } + + public static void runTests() { + try { + forInstanceField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleInstanceField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleStaticField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} diff --git a/test/2280-const-method-handle-validation/src/StaticPut.java b/test/2280-const-method-handle-validation/src/StaticPut.java new file mode 100644 index 0000000000..ef57baabd4 --- /dev/null +++ b/test/2280-const-method-handle-validation/src/StaticPut.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.invoke.MethodHandle; + +import annotations.ConstantMethodHandle; + +public class StaticPut { + + private int instanceField; + private final int finalInstanceField = 1; + private static final int STATIC_FINAL_FIELD = 2; + + private static void unreachable() { + throw new AssertionError("unreachable!"); + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_PUT, + owner = "StaticPut", + fieldOrMethodName = "instanceField", + descriptor = "I") + private static MethodHandle forInstanceField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_PUT, + owner = "StaticPut", + fieldOrMethodName = "finalInstanceField", + descriptor = "I") + private static MethodHandle forFinalInstanceField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_PUT, + owner = "StaticPut", + fieldOrMethodName = "STATIC_FINAL_FIELD", + descriptor = "I") + private static MethodHandle forFinalStaticField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_PUT, + owner = "Main", + fieldOrMethodName = "privateField", + descriptor = "I") + private static MethodHandle inaccessibleInstanceField() { + unreachable(); + return null; + } + + @ConstantMethodHandle( + kind = ConstantMethodHandle.STATIC_PUT, + owner = "Main", + fieldOrMethodName = "PRIVATE_STATIC_FIELD", + descriptor = "I") + private static MethodHandle inaccessibleStaticField() { + unreachable(); + return null; + } + + public static void runTests() { + try { + forInstanceField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + forFinalInstanceField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + forFinalStaticField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleInstanceField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + + try { + inaccessibleStaticField(); + unreachable(); + } catch (IncompatibleClassChangeError expected) {} + } + +} |