diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 9c72de95925..f47afb4ae47 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2088,6 +2088,22 @@ public class ExpressionCodegen extends JetVisitor { @Override public StackValue visitPostfixExpression(JetPostfixExpression expression, StackValue receiver) { + if(expression.getOperationReference().getReferencedNameElementType() == JetTokens.EXCLEXCL) { + JetExpression baseExpression = expression.getBaseExpression(); + JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, baseExpression); + StackValue base = genQualified(receiver, baseExpression); + if(type != null && type.isNullable()) { + base.put(base.type, v); + v.dup(); + Label ok = new Label(); + v.ifnonnull(ok); + v.invokestatic("jet/runtime/Intrinsics", "throwNpe", "()V"); + v.mark(ok); + return StackValue.onStack(base.type); + } + else + return base; + } DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); if (op instanceof FunctionDescriptor) { final Type asmType = expressionType(expression); @@ -2153,7 +2169,7 @@ public class ExpressionCodegen extends JetVisitor { } } } - throw new UnsupportedOperationException("Don't know how to generate this prefix expression"); + throw new UnsupportedOperationException("Don't know how to generate this postfix expression"); } private void generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand, StackValue receiver) { diff --git a/compiler/testData/codegen/regressions/kt628.kt b/compiler/testData/codegen/regressions/kt628.kt new file mode 100644 index 00000000000..32ff6d416f8 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt628.kt @@ -0,0 +1,48 @@ +class A() { + fun action() = "OK" + + fun infix(a: String) = "O" + a + + val property = "OK" + + val a : A + get() = A() +} + +fun test1() = A()!!.property +fun test2() = (A() as A?)!!.property +fun test3() = A()!!.action() +fun test4() = (A() as A?)!!.action() +fun test5() = (null as A?)!!.action() +fun test6() = A().a.a!!.action() +fun test7() = 10!!.plus(11) +fun test8() = (10 as Int?)!!.plus(11) +fun test9() = A()!! infix "K" +fun test10() = (A() as A?) !! infix "K" +fun test11() = (A() as A?) !! infix("K") +fun test12() = A()!! infix ("K") + +fun box() : String { + if(test1() != "OK") return "fail" + if(test2() != "OK") return "fail" + if(test3() != "OK") return "fail" + if(test4() != "OK") return "fail" + + try { + test5() + return "fail" + } + catch(e: NullPointerException) { // + } + + if(test6() != "OK") return "fail" + if(test7() != 21) return "fail" + if(test8() != 21) return "fail" + + if(test9() != "OK") return "fail" + if(test10() != "OK") return "fail" + if(test11() != "OK") return "fail" + if(test12() != "OK") return "fail" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index ece95738d98..c77fc11498b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -286,4 +286,8 @@ public class ControlStructuresTest extends CodegenTestCase { public void testKt998() throws Exception { blackBoxFile("regressions/kt998.kt"); } + + public void testKt628() throws Exception { + blackBoxFile("regressions/kt628.kt"); + } }