handling invalid ConstantValue attributes
Liam Miller-Cushon
cushon at google.com
Fri Nov 4 17:15:35 UTC 2016
Thanks. What do you think the best option is for handling out of range
constants? Should javac do narrowing conversions?
On Thu, Nov 3, 2016 at 4:46 PM, Jonathan Gibbons <
jonathan.gibbons at oracle.com> wrote:
> A corresponding RFE/enhancement to javap would be to report any such
> issues. It is already somewhat fault tolerant, and will print "???" or
> similar as needed, but more cross-referencing and checking could be done.
>
> -- Jon
>
>
> On 11/03/2016 03:52 PM, Alex Buckley wrote:
>
>> In Lib.class, the field A contains a ConstantValue attribute that is
>> ill-formed, since the attribute points to a CONSTANT_String c.p. entry that
>> is not appropriate for a Z-typed field (per JVMS8 4.7.2). A class file
>> reader such as javac must reject Lib.class on this basis.
>>
>> In Lib.class, the field B contains a ConstantValue attribute that is not
>> ill-formed, since the attribute points to a CONSTANT_Integer c.p. entry
>> that is appropriate for a Z-typed field. A class file reader such as javac
>> must not reject Lib.class on this basis. However, javac should handle an
>> out-of-band value in the CONSTANT_Integer c.p. entry as a
>> quality-of-implementation detail.
>>
>> Alex
>>
>> On 11/3/2016 3: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/20161104/1ba3ff72/attachment-0001.html>
More information about the compiler-dev
mailing list