KT-16536 Wrong IR generated for '++x'
Make psi2ir confirm to JVM BE behavior for prefix increment/decrement. TODO reconsider after design decision (in 1.2?).
This commit is contained in:
+2
-3
@@ -75,9 +75,8 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
|||||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||||
opCall.setExplicitReceiverValue(irLValue)
|
opCall.setExplicitReceiverValue(irLValue)
|
||||||
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
|
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
|
||||||
val temporary = defineTemporary(irOpCall)
|
+irLValue.store(irOpCall)
|
||||||
+irLValue.store(irGet(temporary))
|
+irLValue.load()
|
||||||
+irGet(temporary)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-9
@@ -20,8 +20,6 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
||||||
import org.jetbrains.kotlin.psi2ir.intermediate.CallBuilder
|
|
||||||
import org.jetbrains.kotlin.psi2ir.intermediate.argumentsCount
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class LValueWithGetterAndSetterCalls(
|
class LValueWithGetterAndSetterCalls(
|
||||||
@@ -37,20 +35,13 @@ class LValueWithGetterAndSetterCalls(
|
|||||||
getterCall?.descriptor ?: setterCall?.descriptor ?:
|
getterCall?.descriptor ?: setterCall?.descriptor ?:
|
||||||
throw AssertionError("Call-based LValue should have either a getter or a setter call")
|
throw AssertionError("Call-based LValue should have either a getter or a setter call")
|
||||||
|
|
||||||
private var getterInstantiated = false
|
|
||||||
private var setterInstantiated = false
|
|
||||||
|
|
||||||
override fun load(): IrExpression {
|
override fun load(): IrExpression {
|
||||||
if (getterCall == null) throw AssertionError("No getter call for $descriptor")
|
if (getterCall == null) throw AssertionError("No getter call for $descriptor")
|
||||||
if (getterInstantiated) throw AssertionError("Getter for $descriptor has already been instantiated")
|
|
||||||
getterInstantiated = true
|
|
||||||
return callGenerator.generateCall(startOffset, endOffset, getterCall, origin)
|
return callGenerator.generateCall(startOffset, endOffset, getterCall, origin)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun store(irExpression: IrExpression): IrExpression {
|
override fun store(irExpression: IrExpression): IrExpression {
|
||||||
if (setterCall == null) throw AssertionError("No setter call for $descriptor")
|
if (setterCall == null) throw AssertionError("No setter call for $descriptor")
|
||||||
if (setterInstantiated) throw AssertionError("Setter for $descriptor has already been instantiated")
|
|
||||||
setterInstantiated = true
|
|
||||||
setterCall.irValueArgumentsByIndex[setterCall.argumentsCount - 1] = irExpression
|
setterCall.irValueArgumentsByIndex[setterCall.argumentsCount - 1] = irExpression
|
||||||
return callGenerator.generateCall(startOffset, endOffset, setterCall, origin)
|
return callGenerator.generateCall(startOffset, endOffset, setterCall, origin)
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-41
@@ -29,20 +29,16 @@ FILE /incrementDecrement.kt
|
|||||||
CONST Int type=kotlin.Int value='0'
|
CONST Int type=kotlin.Int value='0'
|
||||||
VAR val x1: kotlin.Int
|
VAR val x1: kotlin.Int
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_INCR
|
BLOCK type=kotlin.Int origin=PREFIX_INCR
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp0: kotlin.Int
|
SET_VAR 'x: Int' type=kotlin.Unit origin=PREFIX_INCR
|
||||||
CALL 'inc(): Int' type=kotlin.Int origin=PREFIX_INCR
|
CALL 'inc(): Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
$this: GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_INCR
|
$this: GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
SET_VAR 'x: Int' type=kotlin.Unit origin=PREFIX_INCR
|
GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
GET_VAR 'tmp0: Int' type=kotlin.Int origin=null
|
|
||||||
GET_VAR 'tmp0: Int' type=kotlin.Int origin=null
|
|
||||||
VAR val x2: kotlin.Int
|
VAR val x2: kotlin.Int
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp1: kotlin.Int
|
SET_VAR 'x: Int' type=kotlin.Unit origin=PREFIX_DECR
|
||||||
CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
$this: GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_DECR
|
$this: GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
SET_VAR 'x: Int' type=kotlin.Unit origin=PREFIX_DECR
|
GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
|
|
||||||
GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
|
|
||||||
FUN public fun testVarPostfix(): kotlin.Unit
|
FUN public fun testVarPostfix(): kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
VAR var x: kotlin.Int
|
VAR var x: kotlin.Int
|
||||||
@@ -68,21 +64,17 @@ FILE /incrementDecrement.kt
|
|||||||
VAR val p1: kotlin.Int
|
VAR val p1: kotlin.Int
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_INCR
|
BLOCK type=kotlin.Int origin=PREFIX_INCR
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_INCR
|
BLOCK type=kotlin.Int origin=PREFIX_INCR
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp0: kotlin.Int
|
|
||||||
CALL 'inc(): Int' type=kotlin.Int origin=PREFIX_INCR
|
|
||||||
$this: CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_INCR
|
|
||||||
CALL '<set-p>(Int): Unit' type=kotlin.Unit origin=PREFIX_INCR
|
CALL '<set-p>(Int): Unit' type=kotlin.Unit origin=PREFIX_INCR
|
||||||
<set-?>: GET_VAR 'tmp0: Int' type=kotlin.Int origin=null
|
<set-?>: CALL 'inc(): Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
GET_VAR 'tmp0: Int' type=kotlin.Int origin=null
|
$this: CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
|
CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
VAR val p2: kotlin.Int
|
VAR val p2: kotlin.Int
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp1: kotlin.Int
|
|
||||||
CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
|
||||||
$this: CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_DECR
|
|
||||||
CALL '<set-p>(Int): Unit' type=kotlin.Unit origin=PREFIX_DECR
|
CALL '<set-p>(Int): Unit' type=kotlin.Unit origin=PREFIX_DECR
|
||||||
<set-?>: GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
|
<set-?>: CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
|
$this: CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
|
CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
FUN public fun testPropPostfix(): kotlin.Unit
|
FUN public fun testPropPostfix(): kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
VAR val p1: kotlin.Int
|
VAR val p1: kotlin.Int
|
||||||
@@ -97,12 +89,10 @@ FILE /incrementDecrement.kt
|
|||||||
VAR val p2: kotlin.Int
|
VAR val p2: kotlin.Int
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp1: kotlin.Int
|
|
||||||
CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
|
||||||
$this: CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_DECR
|
|
||||||
CALL '<set-p>(Int): Unit' type=kotlin.Unit origin=PREFIX_DECR
|
CALL '<set-p>(Int): Unit' type=kotlin.Unit origin=PREFIX_DECR
|
||||||
<set-?>: GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
|
<set-?>: CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
|
$this: CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
|
CALL '<get-p>(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
FUN public fun testArrayPrefix(): kotlin.Unit
|
FUN public fun testArrayPrefix(): kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
VAR val a1: kotlin.Int
|
VAR val a1: kotlin.Int
|
||||||
@@ -111,32 +101,32 @@ FILE /incrementDecrement.kt
|
|||||||
CALL '<get-arr>(): IntArray' type=kotlin.IntArray origin=GET_PROPERTY
|
CALL '<get-arr>(): IntArray' type=kotlin.IntArray origin=GET_PROPERTY
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp1_index0: kotlin.Int
|
VAR IR_TEMPORARY_VARIABLE val tmp1_index0: kotlin.Int
|
||||||
CONST Int type=kotlin.Int value='0'
|
CONST Int type=kotlin.Int value='0'
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp2: kotlin.Int
|
|
||||||
CALL 'inc(): Int' type=kotlin.Int origin=PREFIX_INCR
|
|
||||||
$this: CALL 'get(Int): Int' type=kotlin.Int origin=PREFIX_INCR
|
|
||||||
$this: GET_VAR 'tmp0_array: IntArray' type=kotlin.IntArray origin=null
|
|
||||||
index: GET_VAR 'tmp1_index0: Int' type=kotlin.Int origin=null
|
|
||||||
CALL 'set(Int, Int): Unit' type=kotlin.Unit origin=PREFIX_INCR
|
CALL 'set(Int, Int): Unit' type=kotlin.Unit origin=PREFIX_INCR
|
||||||
$this: GET_VAR 'tmp0_array: IntArray' type=kotlin.IntArray origin=null
|
$this: GET_VAR 'tmp0_array: IntArray' type=kotlin.IntArray origin=null
|
||||||
index: GET_VAR 'tmp1_index0: Int' type=kotlin.Int origin=null
|
index: GET_VAR 'tmp1_index0: Int' type=kotlin.Int origin=null
|
||||||
value: GET_VAR 'tmp2: Int' type=kotlin.Int origin=null
|
value: CALL 'inc(): Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
GET_VAR 'tmp2: Int' type=kotlin.Int origin=null
|
$this: CALL 'get(Int): Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
|
$this: GET_VAR 'tmp0_array: IntArray' type=kotlin.IntArray origin=null
|
||||||
|
index: GET_VAR 'tmp1_index0: Int' type=kotlin.Int origin=null
|
||||||
|
CALL 'get(Int): Int' type=kotlin.Int origin=PREFIX_INCR
|
||||||
|
$this: GET_VAR 'tmp0_array: IntArray' type=kotlin.IntArray origin=null
|
||||||
|
index: GET_VAR 'tmp1_index0: Int' type=kotlin.Int origin=null
|
||||||
VAR val a2: kotlin.Int
|
VAR val a2: kotlin.Int
|
||||||
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
BLOCK type=kotlin.Int origin=PREFIX_DECR
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp3_array: kotlin.IntArray
|
VAR IR_TEMPORARY_VARIABLE val tmp2_array: kotlin.IntArray
|
||||||
CALL '<get-arr>(): IntArray' type=kotlin.IntArray origin=GET_PROPERTY
|
CALL '<get-arr>(): IntArray' type=kotlin.IntArray origin=GET_PROPERTY
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp4_index0: kotlin.Int
|
VAR IR_TEMPORARY_VARIABLE val tmp3_index0: kotlin.Int
|
||||||
CONST Int type=kotlin.Int value='0'
|
CONST Int type=kotlin.Int value='0'
|
||||||
VAR IR_TEMPORARY_VARIABLE val tmp5: kotlin.Int
|
|
||||||
CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
|
||||||
$this: CALL 'get(Int): Int' type=kotlin.Int origin=PREFIX_DECR
|
|
||||||
$this: GET_VAR 'tmp3_array: IntArray' type=kotlin.IntArray origin=null
|
|
||||||
index: GET_VAR 'tmp4_index0: Int' type=kotlin.Int origin=null
|
|
||||||
CALL 'set(Int, Int): Unit' type=kotlin.Unit origin=PREFIX_DECR
|
CALL 'set(Int, Int): Unit' type=kotlin.Unit origin=PREFIX_DECR
|
||||||
$this: GET_VAR 'tmp3_array: IntArray' type=kotlin.IntArray origin=null
|
$this: GET_VAR 'tmp2_array: IntArray' type=kotlin.IntArray origin=null
|
||||||
index: GET_VAR 'tmp4_index0: Int' type=kotlin.Int origin=null
|
index: GET_VAR 'tmp3_index0: Int' type=kotlin.Int origin=null
|
||||||
value: GET_VAR 'tmp5: Int' type=kotlin.Int origin=null
|
value: CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
GET_VAR 'tmp5: Int' type=kotlin.Int origin=null
|
$this: CALL 'get(Int): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
|
$this: GET_VAR 'tmp2_array: IntArray' type=kotlin.IntArray origin=null
|
||||||
|
index: GET_VAR 'tmp3_index0: Int' type=kotlin.Int origin=null
|
||||||
|
CALL 'get(Int): Int' type=kotlin.Int origin=PREFIX_DECR
|
||||||
|
$this: GET_VAR 'tmp2_array: IntArray' type=kotlin.IntArray origin=null
|
||||||
|
index: GET_VAR 'tmp3_index0: Int' type=kotlin.Int origin=null
|
||||||
FUN public fun testArrayPostfix(): kotlin.Unit
|
FUN public fun testArrayPostfix(): kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
VAR val a1: kotlin.Int
|
VAR val a1: kotlin.Int
|
||||||
|
|||||||
Reference in New Issue
Block a user