KT-4152 Wrong postfix increment/decrement calculation

#KT-4152 Fixed
This commit is contained in:
Mikhael Bogdanov
2013-10-31 15:06:57 +04:00
parent 7857dc5ba9
commit ee2a30f34f
5 changed files with 152 additions and 35 deletions
@@ -3092,7 +3092,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
if (isPrimitiveNumberClassDescriptor(cls)) {
receiver.put(receiver.type, v);
JetExpression operand = expression.getBaseExpression();
if (operand instanceof JetReferenceExpression && asmType == Type.INT_TYPE) {
int index = indexOfLocal((JetReferenceExpression) operand);
@@ -3100,8 +3099,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.postIncrement(index, increment);
}
}
gen(operand, asmType); // old value
generateIncrement(increment, asmType, operand, receiver); // increment in-place
StackValue value = gen(expression.getBaseExpression());
value.dupReceiver(v);
Type type = expressionType(expression.getBaseExpression());
value.put(type, v);
pushReceiverAndValueViaDup(value, type);
genIncrement(asmType, increment, v);
value.store(asmType, v);
return StackValue.onStack(asmType); // old value
}
else {
@@ -3117,32 +3124,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type type = expressionType(expression.getBaseExpression());
value.put(type, v);
switch (value.receiverSize()) {
case 0:
dup(v, type);
break;
case 1:
if (type.getSize() == 2) {
v.dup2X1();
}
else {
v.dupX1();
}
break;
case 2:
if (type.getSize() == 2) {
v.dup2X2();
}
else {
v.dupX2();
}
break;
case -1:
throw new UnsupportedOperationException();
}
pushReceiverAndValueViaDup(value, type);
CallableMethod callableMethod = (CallableMethod) callable;
callableMethod.invokeWithNotNullAssertion(v, state, resolvedCall);
@@ -3152,12 +3134,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
}
private void generateIncrement(int increment, Type asmType, JetExpression operand, StackValue receiver) {
StackValue value = genQualified(receiver, operand);
value.dupReceiver(v);
value.put(asmType, v);
genIncrement(asmType, increment, v);
value.store(asmType, v);
private void pushReceiverAndValueViaDup(StackValue value, Type type) {
switch (value.receiverSize()) {
case 0:
dup(v, type);
break;
case 1:
if (type.getSize() == 2) {
v.dup2X1();
}
else {
v.dupX1();
}
break;
case 2:
if (type.getSize() == 2) {
v.dup2X2();
}
else {
v.dupX2();
}
break;
case -1:
throw new UnsupportedOperationException();
}
}
@Override
@@ -0,0 +1,29 @@
public var inc: Int = 0;
public var propInc: Int = 0
get() {++inc; return $propInc}
set(a: Int) {
++inc
$propInc = a
}
public var dec: Int = 0;
public var propDec: Int = 0;
get() { --dec; return $propDec}
set(a: Int) {
--dec
$propDec = a
}
fun box(): String {
++propInc
if (inc != 3) return "fail in prefix increment: ${inc} != 3"
if (propInc != 1) return "fail in prefix increment: ${propInc} != 1"
--propDec
if (dec != -3) return "fail in prefix decrement: ${dec} != -3"
if (propDec != -1) return "fail in prefix decrement: ${propDec} != -1"
return "OK"
}
@@ -0,0 +1,41 @@
class X(var value: Long)
fun X.inc(): X {
this.value++
return this
}
fun X.dec(): X {
this.value--
return this
}
class Z {
public var counter: Int = 0;
public var prop: X = X(0)
get() {
counter++; return $prop
}
set(a: X) {
counter++
$prop = a;
}
}
fun box(): String {
var z = Z()
z.prop++
if (z.counter != 2) return "fail in postfix increment: ${z.counter} != 2"
if (z.prop.value != 1.toLong()) return "fail in postfix increment: ${z.prop.value} != 1"
z = Z()
z.prop--
if (z.counter != 2) return "fail in postfix decrement: ${z.counter} != 2"
if (z.prop.value != -1.toLong()) return "fail in postfix decrement: ${z.prop.value} != -1"
return "OK"
}
@@ -0,0 +1,29 @@
public var inc: Int = 0;
public var propInc: Int = 0
get() {inc++; return $propInc}
set(a: Int) {
inc++
$propInc = a
}
public var dec: Int = 0;
public var propDec: Int = 0;
get() { dec--; return $propDec}
set(a: Int) {
dec--
$propDec = a
}
fun box(): String {
propInc++
if (inc != 2) return "fail in postfix increment: ${inc} != 2"
if (propInc != 1) return "fail in postfix increment: ${propInc} != 1"
propDec--
if (dec != -2) return "fail in postfix decrement: ${dec} != -2"
if (propDec != -1) return "fail in postfix decrement: ${propDec} != -1"
return "OK"
}
@@ -2704,6 +2704,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/intrinsics/longRangeWithExplicitDot.kt");
}
@TestMetadata("prefixIncDec.kt")
public void testPrefixIncDec() throws Exception {
doTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
}
@TestMetadata("rangeFromCollection.kt")
public void testRangeFromCollection() throws Exception {
doTest("compiler/testData/codegen/box/intrinsics/rangeFromCollection.kt");
@@ -3550,6 +3555,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/operatorConventions/assignmentOperations.kt");
}
@TestMetadata("incDecOnObject.kt")
public void testIncDecOnObject() throws Exception {
doTest("compiler/testData/codegen/box/operatorConventions/incDecOnObject.kt");
}
@TestMetadata("kt4152.kt")
public void testKt4152() throws Exception {
doTest("compiler/testData/codegen/box/operatorConventions/kt4152.kt");
}
@TestMetadata("compiler/testData/codegen/box/operatorConventions/compareTo")
public static class CompareTo extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInCompareTo() throws Exception {