diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 2d719a3c26e..5f30fb424cc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1881,10 +1881,10 @@ public class ExpressionCodegen extends JetVisitor { private StackValue generateIn(JetBinaryExpression expression) { JetExpression expr = expression.getLeft(); + boolean inverted = expression.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN; if (isIntRangeExpr(expression.getRight())) { StackValue leftValue = StackValue.expression(Type.INT_TYPE, expression.getLeft(), this); JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getRight(); - boolean inverted = expression.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN; getInIntRange(leftValue, rangeExpression, inverted); } else { @@ -1904,6 +1904,9 @@ public class ExpressionCodegen extends JetVisitor { v.pop(); } invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v); + if (inverted) { + invertBoolean(); + } } return StackValue.onStack(Type.BOOLEAN_TYPE); } @@ -1943,8 +1946,7 @@ public class ExpressionCodegen extends JetVisitor { v.and(Type.INT_TYPE); if (inverted) { - v.iconst(1); - v.xor(Type.INT_TYPE); + invertBoolean(); } } @@ -2042,8 +2044,7 @@ public class ExpressionCodegen extends JetVisitor { if (!leftNullable) { v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); if (opToken == JetTokens.EXCLEQ) { - v.iconst(1); - v.xor(Type.INT_TYPE); + invertBoolean(); } } else { @@ -2055,8 +2056,7 @@ public class ExpressionCodegen extends JetVisitor { v.ifnull(leftNull); v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) { - v.iconst(1); - v.xor(Type.INT_TYPE); + invertBoolean(); } Label end = new Label(); v.goTo(end); @@ -2080,8 +2080,7 @@ public class ExpressionCodegen extends JetVisitor { v.ifnull(leftNull); v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) { - v.iconst(1); - v.xor(Type.INT_TYPE); + invertBoolean(); } Label end = new Label(); v.goTo(end); @@ -3035,14 +3034,18 @@ The "returned" value of try expression with no finally is either the last expres while (rangeExpression instanceof JetParenthesizedExpression) { rangeExpression = ((JetParenthesizedExpression)rangeExpression).getExpression(); } + boolean inverted = conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN; if (isIntRangeExpr(rangeExpression)) { - getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN); + getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, inverted); } else { FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference()); genToJVMStack(rangeExpression); new StackValue.Local(subjectLocal, subjectType).put(TYPE_OBJECT, v); invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v); + if(inverted) { + invertBoolean(); + } } return StackValue.onStack(Type.BOOLEAN_TYPE); } @@ -3065,6 +3068,11 @@ The "returned" value of try expression with no finally is either the last expres subjectIsNullable, nextEntry); } + private void invertBoolean() { + v.iconst(1); + v.xor(Type.INT_TYPE); + } + private boolean isIntRangeExpr(JetExpression rangeExpression) { if (rangeExpression instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) rangeExpression; diff --git a/compiler/testData/codegen/regressions/kt2417.kt b/compiler/testData/codegen/regressions/kt2417.kt new file mode 100644 index 00000000000..42214b38016 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt2417.kt @@ -0,0 +1,25 @@ +import java.util.HashSet + +fun box() : String{ + val set = HashSet() + set.add("foo") + val t1 = "foo" in set // returns true, valid + if(!t1) return "fail1" + val t2 = "foo" !in set // returns true, invalid + if(t2) return "fail2" + val t3 = "bar" in set // returns false, valid + if(t3) return "fail3" + val t4 = "bar" !in set // return false, invalid + if(!t4) return "fail4" + val t5 = when("foo") { + in set -> true + else -> false + } + if(!t5) return "fail5" + val t6 = when("foo") { + !in set -> true + else -> false + } + if(t6) return "fail6" + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index ff85bdea642..46b7220e934 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -508,4 +508,9 @@ public class ClassGenTest extends CodegenTestCase { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxMultiFile("regressions/kt1845_1.kt", "regressions/kt1845_2.kt"); } + + public void testKt2417() { + createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); + blackBoxFile("regressions/kt2417.kt"); + } }