handling invalid ConstantValue attributes
Jonathan Gibbons
jonathan.gibbons at oracle.com
Thu Nov 3 22:35:22 UTC 2016
Well, javac should never give a stacktrace, so any time that it does is
worthy of a bug report.
-- Jon
On 11/03/2016 03:26 PM, Liam Miller-Cushon wrote:
> 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/e270eed3/attachment.html>
More information about the compiler-dev
mailing list