Commit 6fed94a5 authored by Remi Forax's avatar Remi Forax
Browse files

a method with access flags ACC_ABSTRACT and ACC_STRICT is illegal if version less than V17

parent 70aa68b5
......@@ -430,7 +430,8 @@ public class CheckClassAdapter extends ClassVisitor {
final String signature,
final String[] exceptions) {
checkState();
checkAccess(
checkMethodAccess(
version,
access,
Opcodes.ACC_PUBLIC
| Opcodes.ACC_PRIVATE
......@@ -555,6 +556,23 @@ public class CheckClassAdapter extends ClassVisitor {
}
}
/**
* Checks that the given access flags do not contain invalid flags for a method. This method also
* checks that mutually incompatible flags are not set simultaneously.
*
* @param version the class version.
* @param access the method access flags to be checked.
* @param possibleAccess the valid access flags.
*/
private static void checkMethodAccess(
final int version, final int access, final int possibleAccess) {
checkAccess(access, possibleAccess);
if ((version & 0xFFFF) < Opcodes.V17
&& Integer.bitCount(access & (Opcodes.ACC_STRICT | Opcodes.ACC_ABSTRACT)) > 1) {
throw new IllegalArgumentException("strictfp and abstract are mutually exclusive: " + access);
}
}
/**
* Checks that the given name is a fully qualified name, using dots.
*
......
......@@ -484,7 +484,7 @@ public class CheckMethodAdapter extends MethodVisitor {
checkUnqualifiedName(version, name, "name");
}
CheckClassAdapter.checkAccess(
access, Opcodes.ACC_FINAL + Opcodes.ACC_MANDATED + Opcodes.ACC_SYNTHETIC);
access, Opcodes.ACC_FINAL | Opcodes.ACC_MANDATED | Opcodes.ACC_SYNTHETIC);
super.visitParameter(name, access);
}
......
......@@ -360,6 +360,30 @@ public class CheckClassAdapterTest extends AsmTest implements Opcodes {
assertEquals("LC;I: error at index 3", exception.getMessage());
}
@Test
public void testVisitMethod_illegalAccessFlagSet() {
CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
checkClassAdapter.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
Executable visitMethod =
() -> checkClassAdapter.visitMethod(ACC_ABSTRACT | ACC_STRICT, "m", "()V", null, null);
Exception exception = assertThrows(IllegalArgumentException.class, visitMethod);
assertEquals("strictfp and abstract are mutually exclusive: 3072", exception.getMessage());
}
@Test
public void testVisitMethod_legalAccessFlagSet_V17() {
// Java 17 allows to mix ACC_ABSTRACT and ACC_STRICT because ACC_STRICT is ignored
CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
checkClassAdapter.visit(V17, ACC_PUBLIC, "C", null, "java/lang/Object", null);
Executable visitMethod =
() -> checkClassAdapter.visitMethod(ACC_ABSTRACT | ACC_STRICT, "m", "()V", null, null);
assertDoesNotThrow(visitMethod);
}
@Test
public void testVisitMethod_illegalSignature() {
CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment