Skip to content

"Incompatible expression types" or verification errors when using ternary expressions with null in one branch #90

@JoshRosen

Description

@JoshRosen

Attempting to compile

Integer result = false ? null : 1;

with ScriptEvaluator results in

org.codehaus.commons.compiler.CompileException: Line 1, Column 24: Incompatible expression types "void" and "int"
  org.codehaus.janino.UnitCompiler.compileError(UnitCompiler.java:11877)
  org.codehaus.janino.UnitCompiler.getType2(UnitCompiler.java:6912)
  org.codehaus.janino.UnitCompiler.access$15600(UnitCompiler.java:218)
  org.codehaus.janino.UnitCompiler$22$2.visitConditionalExpression(UnitCompiler.java:6438)
  org.codehaus.janino.UnitCompiler$22$2.visitConditionalExpression(UnitCompiler.java:6414)
  org.codehaus.janino.Java$ConditionalExpression.accept(Java.java:4570)
  org.codehaus.janino.UnitCompiler$22.visitRvalue(UnitCompiler.java:6414)
  org.codehaus.janino.UnitCompiler$22.visitRvalue(UnitCompiler.java:6393)
  org.codehaus.janino.Java$Rvalue.accept(Java.java:4171)
  org.codehaus.janino.UnitCompiler.getType(UnitCompiler.java:6393)
  org.codehaus.janino.UnitCompiler.compileGetValue(UnitCompiler.java:5585)
  org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:2581)
  org.codehaus.janino.UnitCompiler.access$2700(UnitCompiler.java:218)
  org.codehaus.janino.UnitCompiler$6.visitLocalVariableDeclarationStatement(UnitCompiler.java:1506)
  org.codehaus.janino.UnitCompiler$6.visitLocalVariableDeclarationStatement(UnitCompiler.java:1490)
  org.codehaus.janino.Java$LocalVariableDeclarationStatement.accept(Java.java:3577)
  org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1490)
  org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:1570)
  org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:3398)
  org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1360)
  org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:1333)
  org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:825)
  org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:435)
  org.codehaus.janino.UnitCompiler.access$400(UnitCompiler.java:218)
  org.codehaus.janino.UnitCompiler$2.visitPackageMemberClassDeclaration(UnitCompiler.java:414)
  org.codehaus.janino.UnitCompiler$2.visitPackageMemberClassDeclaration(UnitCompiler.java:409)
  org.codehaus.janino.Java$PackageMemberClassDeclaration.accept(Java.java:1417)
  org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:409)
  org.codehaus.janino.UnitCompiler.compileUnit(UnitCompiler.java:381)
  org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:237)
  org.codehaus.janino.SimpleCompiler.compileToClassLoader(SimpleCompiler.java:466)
  org.codehaus.janino.ClassBodyEvaluator.compileToClass(ClassBodyEvaluator.java:313)
  org.codehaus.janino.ScriptEvaluator.cook2(ScriptEvaluator.java:725)
  org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:714)
  org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:661)
  org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:629)
  org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:207)
  org.codehaus.commons.compiler.Cookable.cook(Cookable.java:80)
  org.codehaus.commons.compiler.Cookable.cook(Cookable.java:75)

with Janino 3.0.12.

Also, compiling

boolean cond;
Integer result = cond ? null : 1;

generates bytecode that triggers a verification error:

java.lang.VerifyError: Bad local variable type
Exception Details:
  Location:
    SC.eval0()V @0: iload_0
  Reason:
    Type top (current frame, locals[0]) is not assignable to integer
  Current Frame:
    bci: @0
    flags: { }
    locals: { }
    stack: { }
  Bytecode:
    0x0000000: 1a99 0007 01a7 0004 044c b1

  java.lang.Class.getDeclaredMethods0(Native Method)
  java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
  java.lang.Class.getDeclaredMethods(Class.java:1975)
  org.codehaus.janino.ScriptEvaluator.cook2(ScriptEvaluator.java:746)
  org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:714)
  org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:661)
  org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:629)
  org.codehaus.janino.SimpleCompiler.cook(SimpleCompiler.java:207)
  org.codehaus.commons.compiler.Cookable.cook(Cookable.java:80)
  org.codehaus.commons.compiler.Cookable.cook(Cookable.java:75)

This is a simplified version of a problem that we encountered when generating code in Apache Spark: apache/spark#24636 (comment)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions