From 63b16e14d84adb3246f32af0567aa55f18865945 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 28 Feb 2017 16:28:38 +0300 Subject: [PATCH] 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?). --- .../psi2ir/generators/AssignmentGenerator.kt | 5 +- .../LValueWithGetterAndSetterCalls.kt | 9 --- .../irText/expressions/incrementDecrement.txt | 72 ++++++++----------- 3 files changed, 33 insertions(+), 53 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt index 62c2dbf9f38..537e52c792a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt @@ -75,9 +75,8 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen val opCall = statementGenerator.pregenerateCall(opResolvedCall) opCall.setExplicitReceiverValue(irLValue) val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin) - val temporary = defineTemporary(irOpCall) - +irLValue.store(irGet(temporary)) - +irGet(temporary) + +irLValue.store(irOpCall) + +irLValue.load() } } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt index 020a6bf6fd3..47a916b0eaa 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt @@ -20,8 +20,6 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin 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 class LValueWithGetterAndSetterCalls( @@ -37,20 +35,13 @@ class LValueWithGetterAndSetterCalls( getterCall?.descriptor ?: setterCall?.descriptor ?: 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 { 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) } override fun store(irExpression: IrExpression): IrExpression { 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 return callGenerator.generateCall(startOffset, endOffset, setterCall, origin) } diff --git a/compiler/testData/ir/irText/expressions/incrementDecrement.txt b/compiler/testData/ir/irText/expressions/incrementDecrement.txt index 86d0cea3b2c..0f03c9dfff0 100644 --- a/compiler/testData/ir/irText/expressions/incrementDecrement.txt +++ b/compiler/testData/ir/irText/expressions/incrementDecrement.txt @@ -29,20 +29,16 @@ FILE /incrementDecrement.kt CONST Int type=kotlin.Int value='0' VAR val x1: kotlin.Int 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 $this: GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_INCR - SET_VAR 'x: Int' type=kotlin.Unit origin=PREFIX_INCR - GET_VAR 'tmp0: Int' type=kotlin.Int origin=null - GET_VAR 'tmp0: Int' type=kotlin.Int origin=null + GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_INCR VAR val x2: kotlin.Int 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 $this: GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_DECR - SET_VAR 'x: Int' type=kotlin.Unit origin=PREFIX_DECR - GET_VAR 'tmp1: Int' type=kotlin.Int origin=null - GET_VAR 'tmp1: Int' type=kotlin.Int origin=null + GET_VAR 'x: Int' type=kotlin.Int origin=PREFIX_DECR FUN public fun testVarPostfix(): kotlin.Unit BLOCK_BODY VAR var x: kotlin.Int @@ -68,21 +64,17 @@ FILE /incrementDecrement.kt VAR val p1: kotlin.Int 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 '(): Int' type=kotlin.Int origin=PREFIX_INCR CALL '(Int): Unit' type=kotlin.Unit origin=PREFIX_INCR - : GET_VAR 'tmp0: Int' type=kotlin.Int origin=null - GET_VAR 'tmp0: Int' type=kotlin.Int origin=null + : CALL 'inc(): Int' type=kotlin.Int origin=PREFIX_INCR + $this: CALL '(): Int' type=kotlin.Int origin=PREFIX_INCR + CALL '(): Int' type=kotlin.Int origin=PREFIX_INCR VAR val p2: kotlin.Int 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 '(): Int' type=kotlin.Int origin=PREFIX_DECR CALL '(Int): Unit' type=kotlin.Unit origin=PREFIX_DECR - : GET_VAR 'tmp1: Int' type=kotlin.Int origin=null - GET_VAR 'tmp1: Int' type=kotlin.Int origin=null + : CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR + $this: CALL '(): Int' type=kotlin.Int origin=PREFIX_DECR + CALL '(): Int' type=kotlin.Int origin=PREFIX_DECR FUN public fun testPropPostfix(): kotlin.Unit BLOCK_BODY VAR val p1: kotlin.Int @@ -97,12 +89,10 @@ FILE /incrementDecrement.kt VAR val p2: kotlin.Int 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 '(): Int' type=kotlin.Int origin=PREFIX_DECR CALL '(Int): Unit' type=kotlin.Unit origin=PREFIX_DECR - : GET_VAR 'tmp1: Int' type=kotlin.Int origin=null - GET_VAR 'tmp1: Int' type=kotlin.Int origin=null + : CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR + $this: CALL '(): Int' type=kotlin.Int origin=PREFIX_DECR + CALL '(): Int' type=kotlin.Int origin=PREFIX_DECR FUN public fun testArrayPrefix(): kotlin.Unit BLOCK_BODY VAR val a1: kotlin.Int @@ -111,32 +101,32 @@ FILE /incrementDecrement.kt CALL '(): IntArray' type=kotlin.IntArray origin=GET_PROPERTY VAR IR_TEMPORARY_VARIABLE val tmp1_index0: kotlin.Int 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 $this: GET_VAR 'tmp0_array: IntArray' type=kotlin.IntArray origin=null index: GET_VAR 'tmp1_index0: Int' type=kotlin.Int origin=null - value: GET_VAR 'tmp2: Int' type=kotlin.Int origin=null - GET_VAR 'tmp2: Int' type=kotlin.Int origin=null + value: 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 '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 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 '(): 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' - 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 - $this: GET_VAR 'tmp3_array: IntArray' type=kotlin.IntArray origin=null - index: GET_VAR 'tmp4_index0: Int' type=kotlin.Int origin=null - value: GET_VAR 'tmp5: Int' type=kotlin.Int origin=null - GET_VAR 'tmp5: Int' type=kotlin.Int origin=null + $this: GET_VAR 'tmp2_array: IntArray' type=kotlin.IntArray origin=null + index: GET_VAR 'tmp3_index0: Int' type=kotlin.Int origin=null + value: CALL 'dec(): Int' type=kotlin.Int origin=PREFIX_DECR + $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 BLOCK_BODY VAR val a1: kotlin.Int