KT-4152 Wrong postfix increment/decrement calculation
#KT-4152 Fixed
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user