handling invalid ConstantValue attributes

Liam Miller-Cushon cushon at google.com
Thu Nov 3 22:26:25 UTC 2016


javac silently accepts class files containing ConstantValue attributes of
the incorrect
type, or outside of the allowed ranges for int, short, char, byte, and
booleans.

I expected javac to either reject the invalid bytecode, or convert the
constants to
their canonical representation (e.g. constant booleans should always be 0
or 1).

ecj rejects constants with the wrong type, and normalizes values outside of
the
expected range.

I couldn't find anything in the spec for this, is it up to the
implementation? Would it
be possible to change javac's behaviour here?

=== Dump.java
import java.nio.file.Files;
import java.nio.file.Paths;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

public class Dump {

  public static void main(String[] args) throws Exception {
    Files.write(Paths.get("Lib.class"), dump());
  }

  static byte[] dump() {
    ClassWriter cw = new ClassWriter(0);
    cw.visit(52, Opcodes.ACC_SUPER, "Lib", null, "java/lang/Object", null);
    cw.visitField(
        Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC, "A",
"Z", null, "hello");
    cw.visitField(
        Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC, "B",
"Z", null, 2);
    cw.visitEnd();
    return cw.toByteArray();
  }
}
===

=== Test.java
class Test {
  static final boolean ONE = Lib.A;
  static final boolean TWO = Lib.B;
}
===

=== Test2.java
class Test2 {
  static final boolean ONE = Lib.A || true;
}
===


$ javac -cp asm-debug-all-5.1.jar Dump.java
$ java -cp asm-debug-all-5.1.jar:. Dump
$ javac Test.java
$ javap -v Test
...
  static final boolean ONE;
    descriptor: Z
    flags: ACC_STATIC, ACC_FINAL
    ConstantValue: String hello

  static final boolean TWO;
    descriptor: Z
    flags: ACC_STATIC, ACC_FINAL
    ConstantValue: int 2

$ javac Test2.java
...
java.lang.AssertionError: java.lang.ClassCastException: java.lang.String
(in module: java.base) cannot be cast to java.lang.Number (in module:
java.base)
at com.sun.tools.javac.code.Symbol$VarSymbol.getConstValue(jdk.compiler at 9-ea
/Symbol.java:1530)
at com.sun.tools.javac.comp.Attr.visitVarDef(jdk.compiler at 9-ea
/Attr.java:1122)
...
Caused by: java.lang.ClassCastException: java.lang.String (in module:
java.base) cannot be cast to java.lang.Number (in module: java.base)
at com.sun.tools.javac.comp.ConstFold.intValue(jdk.compiler at 9-ea
/ConstFold.java:71)
at com.sun.tools.javac.comp.ConstFold.fold2(jdk.compiler at 9-ea
/ConstFold.java:187)
at com.sun.tools.javac.comp.Attr.visitBinary(jdk.compiler at 9-ea
/Attr.java:3211)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20161103/37d1674f/attachment-0001.html>


More information about the compiler-dev mailing list