diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index df9e10521d2..7e84d329d07 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -74,7 +74,7 @@ public class ExpressionCodegen extends JetVisitor { "DOUBLE_TYPE_INFO" }; - private final InstructionAdapter v; + private final InstructionAdapterEx v; private final FrameMap myMap; private final JetTypeMapper typeMapper; private final GenerationState state; @@ -93,7 +93,7 @@ public class ExpressionCodegen extends JetVisitor { this.typeMapper = state.getTypeMapper(); this.returnType = returnType; this.state = state; - this.v = new InstructionAdapter(v); + this.v = new InstructionAdapterEx(v); this.bindingContext = state.getBindingContext(); this.context = context; this.intrinsics = state.getIntrinsics(); @@ -1039,16 +1039,24 @@ public class ExpressionCodegen extends JetVisitor { Label end = new Label(); v.dup(); v.ifnull(ifnull); - gen(expression.getSelectorExpression()); + JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getReceiverExpression()); + StackValue propValue = genQualified(StackValue.onStack(typeMapper.mapType(receiverType)), expression.getSelectorExpression()); + Type type = propValue.type; + propValue.put(type, v); + if(JetTypeMapper.isPrimitive(type) && !type.equals(Type.VOID_TYPE)) { + v.valueOf(type); + type = typeMapper.boxType(type); + } v.goTo(end); + v.mark(ifnull); - // null is already on stack here after the dup - JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); - if (expressionType.equals(JetStandardClasses.getUnitType())) { - v.pop(); + v.pop(); + if(!propValue.type.equals(Type.VOID_TYPE)) { + v.aconst(null); } v.mark(end); - return StackValue.onStack(typeMapper.mapType(expressionType)); + + return StackValue.onStack(type); } @Override @@ -1138,10 +1146,20 @@ public class ExpressionCodegen extends JetVisitor { } private StackValue generateEquals(JetExpression left, JetExpression right, IElementType opToken) { - final Type leftType = expressionType(left); - final Type rightType = expressionType(right); - gen(left, leftType); - gen(right, rightType); + Type leftType = expressionType(left); + Type rightType = expressionType(right); + if(JetTypeMapper.isPrimitive(leftType) != JetTypeMapper.isPrimitive(rightType)) { + gen(left, leftType); + v.valueOf(leftType); + leftType = typeMapper.boxType(leftType); + gen(right, rightType); + v.valueOf(rightType); + rightType = typeMapper.boxType(rightType); + } + else { + gen(left, leftType); + gen(right, rightType); + } return generateEqualsForExpressionsOnStack(opToken, leftType, rightType); } diff --git a/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java b/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java index 66f68991feb..48c9c163486 100644 --- a/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java +++ b/idea/src/org/jetbrains/jet/codegen/InstructionAdapterEx.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.codegen; import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; diff --git a/idea/testData/codegen/regressions/kt247.jet b/idea/testData/codegen/regressions/kt247.jet new file mode 100644 index 00000000000..49637518d25 --- /dev/null +++ b/idea/testData/codegen/regressions/kt247.jet @@ -0,0 +1,38 @@ +fun t1() : Boolean { + val s1 : String? = "sff" + val s2 : String? = null + return s1?.length == 3 && s2?.length == null +} + +fun t2() : Boolean { + val c1: C? = C(1) + val c2: C? = null + return c1?.x == 1 && c2?.x == null +} + +fun t3() { + val d: D = D("s") + System.out?.println(d?.s) + System.out?.println(d?.s == "s") //prints true + System.out?.println(d) //ok +} + +fun t4() { + val e: E? = E() + System.out?.println(e?.foo() == e) //verify error + System.out?.println(e?.foo()) //verify error +} + +fun box() : String { + if(!t1 ()) return "fail" + if(!t2 ()) return "fail" + t3() + t4() + return "OK" +} + +class C(val x: Int) +class D(val s: String) +class E() { + fun foo() = 1 +} diff --git a/idea/tests/org/jetbrains/jet/codegen/Kt247Test.java b/idea/tests/org/jetbrains/jet/codegen/Kt247Test.java new file mode 100644 index 00000000000..ba64714ddd2 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/codegen/Kt247Test.java @@ -0,0 +1,7 @@ +package org.jetbrains.jet.codegen; + +public class Kt247Test extends CodegenTestCase { + public void testMe () throws Exception { + blackBoxFile("regressions/kt247.jet"); + } +}