Commit b334fef1 authored by Remi Forax's avatar Remi Forax
Browse files

Merge branch 'abstract-and-strcitfp-are-illegal-until-v17' into 'master'

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

See merge request !322
parents 70aa68b5 6fed94a5
Pipeline #14218 passed with stage
in 6 minutes
...@@ -430,7 +430,8 @@ public class CheckClassAdapter extends ClassVisitor { ...@@ -430,7 +430,8 @@ public class CheckClassAdapter extends ClassVisitor {
final String signature, final String signature,
final String[] exceptions) { final String[] exceptions) {
checkState(); checkState();
checkAccess( checkMethodAccess(
version,
access, access,
Opcodes.ACC_PUBLIC Opcodes.ACC_PUBLIC
| Opcodes.ACC_PRIVATE | Opcodes.ACC_PRIVATE
...@@ -555,6 +556,23 @@ public class CheckClassAdapter extends ClassVisitor { ...@@ -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. * Checks that the given name is a fully qualified name, using dots.
* *
......
...@@ -484,7 +484,7 @@ public class CheckMethodAdapter extends MethodVisitor { ...@@ -484,7 +484,7 @@ public class CheckMethodAdapter extends MethodVisitor {
checkUnqualifiedName(version, name, "name"); checkUnqualifiedName(version, name, "name");
} }
CheckClassAdapter.checkAccess( 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); super.visitParameter(name, access);
} }
......
...@@ -360,6 +360,30 @@ public class CheckClassAdapterTest extends AsmTest implements Opcodes { ...@@ -360,6 +360,30 @@ public class CheckClassAdapterTest extends AsmTest implements Opcodes {
assertEquals("LC;I: error at index 3", exception.getMessage()); 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 @Test
public void testVisitMethod_illegalSignature() { public void testVisitMethod_illegalSignature() {
CheckClassAdapter checkClassAdapter = new CheckClassAdapter(null); 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