diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 93fa780e4cd..4963404afdd 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -12991,6 +12991,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/increment"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("argumentWithSideEffects.kt") + public void testArgumentWithSideEffects() throws Exception { + runTest("compiler/testData/codegen/box/increment/argumentWithSideEffects.kt"); + } + @TestMetadata("arrayElement.kt") public void testArrayElement() throws Exception { runTest("compiler/testData/codegen/box/increment/arrayElement.kt"); diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt index f24a93bb760..f4d4edf9b3d 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/BaseConverter.kt @@ -115,6 +115,12 @@ open class BaseConverter( return null } + override val LighterASTNode?.arrayExpression: LighterASTNode? + get() = this?.getFirstChildExpression() + + override val LighterASTNode?.indexExpressions: List? + get() = this?.getLastChildExpression()?.getChildrenAsArray()?.filterNotNull()?.filter { it.isExpression() } + fun LighterASTNode.getParent(): LighterASTNode? { return tree.getParent(this) } diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index b9f7c91539f..42679a3f8c2 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -132,6 +132,12 @@ class RawFirBuilder( override val PsiElement?.selectorExpression: PsiElement? get() = (this as? KtQualifiedExpression)?.selectorExpression + override val PsiElement?.arrayExpression: PsiElement? + get() = (this as? KtArrayAccessExpression)?.arrayExpression + + override val PsiElement?.indexExpressions: List? + get() = (this as? KtArrayAccessExpression)?.indexExpressions + private val KtModifierListOwner.visibility: Visibility get() = with(modifierList) { when { diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt index cf28bd644b4..47e292ce35b 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.txt @@ -57,14 +57,18 @@ FILE: unary.kt } public? final? fun test3(arr: Array): R|kotlin/Unit| { lval x1: = { - lval : = arr#.get#(IntegerLiteral(0)) - arr#.set#(IntegerLiteral(0), R|/|.inc#()) + lval : = arr# + lval : = IntegerLiteral(0) + lval : = R|/|.get#(R|/|) + R|/|.set#(R|/|, R|/|.inc#()) R|/| } lval x2: = { - lval : = arr#.get#(IntegerLiteral(1)).inc#() - arr#.set#(IntegerLiteral(1), R|/|) + lval : = arr# + lval : = IntegerLiteral(1) + lval : = R|/|.get#(R|/|).inc#() + R|/|.set#(R|/|, R|/|) R|/| } @@ -80,14 +84,18 @@ FILE: unary.kt } public? final? fun test4(y: Y): R|kotlin/Unit| { lval x1: = { - lval : = y#.arr#.get#(IntegerLiteral(0)) - y#.arr#.set#(IntegerLiteral(0), R|/|.inc#()) + lval : = y#.arr# + lval : = IntegerLiteral(0) + lval : = R|/|.get#(R|/|) + R|/|.set#(R|/|, R|/|.inc#()) R|/| } lval x2: = { - lval : = y#.arr#.get#(IntegerLiteral(1)).inc#() - y#.arr#.set#(IntegerLiteral(1), R|/|) + lval : = y#.arr# + lval : = IntegerLiteral(1) + lval : = R|/|.get#(R|/|).inc#() + R|/|.set#(R|/|, R|/|) R|/| } diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 70d71f8f653..00c770a6b51 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -55,6 +55,8 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte abstract fun T.getChildNodeByType(type: IElementType): T? abstract val T?.receiverExpression: T? abstract val T?.selectorExpression: T? + abstract val T?.arrayExpression: T? + abstract val T?.indexExpressions: List? /**** Class name utils ****/ inline fun withChildClassName( @@ -435,6 +437,17 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte ) } + if (unwrappedArgument.elementType == ARRAY_ACCESS_EXPRESSION) { + return generateIncrementOrDecrementBlockForArrayAccess( + baseExpression, + operationReference, + unwrappedArgument, + callName, + prefix, + convert + ) + } + return buildBlock { val baseSource = baseExpression?.toFirSourceElement() val desugaredSource = baseSource?.fakeElement(FirFakeSourceElementKind.DesugaredIncrementOrDecrement) @@ -623,6 +636,147 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte } } + /** + * given: + * a[b, c]++ + * + * result: + * { + * val = a + * val = b + * val = c + * val = .get(b, c) + * .set(b, c, .inc()) + * ^ + * } + * + * given: + * ++a[b, c] + * + * result: + * { + * val = a + * val = b + * val = c + * val = .get(b, c).inc() + * .set(b, c, ) + * ^ + * } + * + */ + private fun generateIncrementOrDecrementBlockForArrayAccess( + baseExpression: T, + operationReference: T?, + argument: T, + callName: Name, + prefix: Boolean, + convert: T.() -> FirExpression + ): FirExpression { + return buildBlock { + val baseSource = baseExpression?.toFirSourceElement() + val desugaredSource = baseSource?.fakeElement(FirFakeSourceElementKind.DesugaredIncrementOrDecrement) + source = desugaredSource + + val array = argument.arrayExpression + val indices = argument.indexExpressions + requireNotNull(indices) { "No indices in ${baseExpression.asText}" } + + val arrayVariable = generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + array?.toFirSourceElement(), + Name.special(""), + array?.convert() ?: buildErrorExpression { + source = argument.toFirSourceElement() + diagnostic = ConeSimpleDiagnostic("No array expression", DiagnosticKind.Syntax) + } + ).also { statements += it } + + val indexVariables = indices.mapIndexed { i, index -> + generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + index.toFirSourceElement(), + Name.special(""), + index.convert() + ).also { statements += it } + } + + val firArgument = buildFunctionCall { + source = desugaredSource + calleeReference = buildSimpleNamedReference { + source = argument?.toFirSourceElement() + name = OperatorNameConventions.GET + } + explicitReceiver = generateResolvedAccessExpression(arrayVariable.source, arrayVariable) + argumentList = buildArgumentList { + for (indexVar in indexVariables) { + arguments += generateResolvedAccessExpression(indexVar.source, indexVar) + } + } + } + + // initialValueVar is only used for postfix increment/decrement (stores the argument value before increment/decrement). + val initialValueVar = generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + desugaredSource, + Name.special(""), + firArgument + ) + + // resultInitializer is the expression for `argument.inc()` + val resultInitializer = buildFunctionCall { + source = desugaredSource + calleeReference = buildSimpleNamedReference { + source = operationReference?.toFirSourceElement() + name = callName + } + explicitReceiver = if (prefix) { + firArgument + } else { + generateResolvedAccessExpression(desugaredSource, initialValueVar) + } + } + + // resultVar is only used for prefix increment/decrement. + val resultVar = generateTemporaryVariable( + this@BaseFirBuilder.baseSession, + desugaredSource, + Name.special(""), + resultInitializer + ) + + fun appendAssignment() { + statements += buildFunctionCall { + source = desugaredSource + calleeReference = buildSimpleNamedReference { + source = argument.toFirSourceElement() + name = OperatorNameConventions.SET + } + explicitReceiver = generateResolvedAccessExpression(arrayVariable.source, arrayVariable) + argumentList = buildArgumentList { + for (indexVar in indexVariables) { + arguments += generateResolvedAccessExpression(indexVar.source, indexVar) + } + arguments += if (prefix) { + generateResolvedAccessExpression(source, resultVar) + } else { + resultInitializer + } + } + } + } + + if (prefix) { + statements += resultVar + appendAssignment() + statements += generateResolvedAccessExpression(desugaredSource, resultVar) + } else { + statements += initialValueVar + appendAssignment() + statements += generateResolvedAccessExpression(desugaredSource, initialValueVar) + } + } + } + private fun FirQualifiedAccessBuilder.initializeLValue( left: T?, convertQualified: T.() -> FirQualifiedAccess? diff --git a/compiler/testData/codegen/box/increment/argumentWithSideEffects.kt b/compiler/testData/codegen/box/increment/argumentWithSideEffects.kt new file mode 100644 index 00000000000..81ed5602a52 --- /dev/null +++ b/compiler/testData/codegen/box/increment/argumentWithSideEffects.kt @@ -0,0 +1,51 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// Currently fails because prefix increment only calls getter once. +var log = "" + +fun logged(value: T): T = + value.also { log += "$value;" } + +fun doTest(id: String, expected: Int, expectedLog: String, test: () -> Int) { + log = "" + val actual = test() + if (actual != expected) throw AssertionError("$id expected: $expected, actual: $actual") + if (log != expectedLog) throw AssertionError("$id expectedLog: $expectedLog, actual: $log") +} + +object A { + var x = 0 + get() = field.also { log += "get-A.x;" } + set(value: Int) { + log += "set-A.x;" + field = value + } + +} + +fun getA() = A.also { log += "getA();" } + +object B { + var x = 0 + + operator fun get(i1: Int, i2: Int, i3: Int): Int = x.also { log += "get-B($i1, $i2, $i3);" } + + operator fun set(i1: Int, i2: Int, i3: Int, value: Int) { + log += "set-B($i1, $i2, $i3, $value);" + x = value + } +} + +fun getB() = B.also { log += "getB();" } + +fun box(): String { + // NOTE: Getter is currently called twice for prefix increment; 1st for initial value, 2nd for return value. See KT-42077. + doTest("++getA().x", 1, "getA();get-A.x;set-A.x;get-A.x;") { ++getA().x } + doTest("getA().x--", 1, "getA();get-A.x;set-A.x;") { getA().x-- } + + doTest("++getB()[1, 2, 3]", 1, "getB();1;2;3;get-B(1, 2, 3);set-B(1, 2, 3, 1);get-B(1, 2, 3);") { + ++getB()[logged(1), logged(2), logged(3)] + } + doTest("getB()[1, 2, 3].x--", 1, "getB();1;2;3;get-B(1, 2, 3);set-B(1, 2, 3, 0);") { getB()[logged(1), logged(2), logged(3)]-- } + + return "OK" +} diff --git a/compiler/testData/codegen/box/increment/classVarargGetSetEvaluationOrder.kt b/compiler/testData/codegen/box/increment/classVarargGetSetEvaluationOrder.kt index 304a9f091d0..4f8c3c03d2d 100644 --- a/compiler/testData/codegen/box/increment/classVarargGetSetEvaluationOrder.kt +++ b/compiler/testData/codegen/box/increment/classVarargGetSetEvaluationOrder.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR -// Currently fails as the indices (`va`) are evaluated twice (on get and set). var log = "" fun logged(value: String) = diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/InconsistentGetSet.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/InconsistentGetSet.fir.kt index 7050051b223..006149d17ce 100644 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/InconsistentGetSet.fir.kt +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/InconsistentGetSet.fir.kt @@ -18,8 +18,8 @@ object MismatchingTypes { } fun testMismatchingTypes() { - ++MismatchingTypes[0] - MismatchingTypes[0]++ + ++MismatchingTypes[0] + MismatchingTypes[0]++ MismatchingTypes[0] += 1 } @@ -34,8 +34,8 @@ object MismatchingArities2 { } fun testMismatchingArities() { - ++MismatchingArities1[0] - MismatchingArities1[0]++ + ++MismatchingArities1[0] + MismatchingArities1[0]++ MismatchingArities1[0] += 1 ++MismatchingArities2[0] diff --git a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.fir.txt b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.fir.txt index 5844f003d83..577a5c920a0 100644 --- a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.fir.txt +++ b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.fir.txt @@ -77,16 +77,19 @@ FILE fqName: fileName:/arrayAugmentedAssignment1.kt FUN name:testMember visibility:public modality:FINAL <> (c:.C) returnType:kotlin.Unit VALUE_PARAMETER name:c index:0 type:.C BLOCK_BODY - VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] - CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in .C' type=kotlin.IntArray origin=GET_PROPERTY - $this: GET_VAR 'c: .C declared in .testMember' type=.C origin=null - index: CONST Int type=kotlin.Int value=0 - CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in .C' type=kotlin.IntArray origin=GET_PROPERTY + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.IntArray [val] + CALL 'public final fun (): kotlin.IntArray declared in .C' type=kotlin.IntArray origin=GET_PROPERTY $this: GET_VAR 'c: .C declared in .testMember' type=.C origin=null - index: CONST Int type=kotlin.Int value=0 + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=0 + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] + CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_4: kotlin.IntArray [val] declared in .testMember' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testMember' type=kotlin.Int origin=null + CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_4: kotlin.IntArray [val] declared in .testMember' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testMember' type=kotlin.Int origin=null value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testMember' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testMember' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testMember' type=kotlin.Int origin=null + GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testMember' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt b/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt index 10cf9fa2ca4..54f47566392 100644 --- a/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt +++ b/compiler/testData/ir/irText/expressions/complexAugmentedAssignment.fir.txt @@ -118,64 +118,62 @@ FILE fqName: fileName:/complexAugmentedAssignment.kt BLOCK_BODY VAR name:i type:kotlin.Int [var] CONST Int type=kotlin.Int value=0 - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] - CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: GET_VAR 'a: kotlin.IntArray declared in .test1' type=kotlin.IntArray origin=null - index: BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] - GET_VAR 'var i: kotlin.Int [var] declared in .test1' type=kotlin.Int origin=null - SET_VAR 'var i: kotlin.Int [var] declared in .test1' type=kotlin.Unit origin=EQ - CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null - GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null - CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null - $this: GET_VAR 'a: kotlin.IntArray declared in .test1' type=kotlin.IntArray origin=null - index: BLOCK type=kotlin.Int origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.IntArray [val] + GET_VAR 'a: kotlin.IntArray declared in .test1' type=kotlin.IntArray origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] + BLOCK type=kotlin.Int origin=null VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] GET_VAR 'var i: kotlin.Int [var] declared in .test1' type=kotlin.Int origin=null SET_VAR 'var i: kotlin.Int [var] declared in .test1' type=kotlin.Unit origin=EQ CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null GET_VAR 'val tmp_2: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val] + CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_0: kotlin.IntArray [val] declared in .test1' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null + $this: GET_VAR 'val tmp_0: kotlin.IntArray [val] declared in .test1' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_3: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null + GET_VAR 'val tmp_3: kotlin.Int [val] declared in .test1' type=kotlin.Int origin=null FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY - VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:.X1 [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:.X1 [val] GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1 - VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] CALL 'public final fun (): kotlin.Int declared in .X1' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR 'val tmp_3: .X1 [val] declared in .test2' type=.X1 origin=null + $this: GET_VAR 'val tmp_4: .X1 [val] declared in .test2' type=.X1 origin=null CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1' type=kotlin.Unit origin=EQ - $this: GET_VAR 'val tmp_3: .X1 [val] declared in .test2' type=.X1 origin=null + $this: GET_VAR 'val tmp_4: .X1 [val] declared in .test2' type=.X1 origin=null : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_4: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:.X1.X2 [val] + GET_VAR 'val tmp_5: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:.X1.X2 [val] GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2 - VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val] CALL 'public final fun (): kotlin.Int declared in .X1.X2' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR 'val tmp_5: .X1.X2 [val] declared in .test2' type=.X1.X2 origin=null + $this: GET_VAR 'val tmp_6: .X1.X2 [val] declared in .test2' type=.X1.X2 origin=null CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1.X2' type=kotlin.Unit origin=EQ - $this: GET_VAR 'val tmp_5: .X1.X2 [val] declared in .test2' type=.X1.X2 origin=null + $this: GET_VAR 'val tmp_6: .X1.X2 [val] declared in .test2' type=.X1.X2 origin=null : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_7: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_6: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:.X1.X2.X3 [val] + GET_VAR 'val tmp_7: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:.X1.X2.X3 [val] GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.X1.X2.X3 - VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.Int [val] CALL 'public final fun (): kotlin.Int declared in .X1.X2.X3' type=kotlin.Int origin=GET_PROPERTY - $this: GET_VAR 'val tmp_7: .X1.X2.X3 [val] declared in .test2' type=.X1.X2.X3 origin=null + $this: GET_VAR 'val tmp_8: .X1.X2.X3 [val] declared in .test2' type=.X1.X2.X3 origin=null CALL 'public final fun (: kotlin.Int): kotlin.Unit declared in .X1.X2.X3' type=kotlin.Unit origin=EQ - $this: GET_VAR 'val tmp_7: .X1.X2.X3 [val] declared in .test2' type=.X1.X2.X3 origin=null + $this: GET_VAR 'val tmp_8: .X1.X2.X3 [val] declared in .test2' type=.X1.X2.X3 origin=null : CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_8: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_9: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_8: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null + GET_VAR 'val tmp_9: kotlin.Int [val] declared in .test2' type=kotlin.Int origin=null CLASS CLASS name:B modality:FINAL visibility:public superTypes:[kotlin.Any] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.B CONSTRUCTOR visibility:public <> (s:kotlin.Int) returnType:.B [primary] diff --git a/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt b/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt index 4a1b091522b..40649dcdb01 100644 --- a/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt +++ b/compiler/testData/ir/irText/expressions/incrementDecrement.fir.txt @@ -97,51 +97,67 @@ FILE fqName: fileName:/incrementDecrement.kt BLOCK_BODY VAR name:a1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.IntArray [val] + CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=0 + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 + $this: GET_VAR 'val tmp_3: kotlin.IntArray [val] declared in .testArrayPrefix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 - value: GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null - GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_3: kotlin.IntArray [val] declared in .testArrayPrefix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + value: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null VAR name:a2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.IntArray [val] + CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=0 + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Int [val] CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 + $this: GET_VAR 'val tmp_6: kotlin.IntArray [val] declared in .testArrayPrefix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_7: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 - value: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null - GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_6: kotlin.IntArray [val] declared in .testArrayPrefix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_7: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + value: GET_VAR 'val tmp_8: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null + GET_VAR 'val tmp_8: kotlin.Int [val] declared in .testArrayPrefix' type=kotlin.Int origin=null FUN name:testArrayPostfix visibility:public modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY VAR name:a1 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.IntArray [val] + CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY + VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=0 + VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Int [val] CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 + $this: GET_VAR 'val tmp_9: kotlin.IntArray [val] declared in .testArrayPostfix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_10: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 + $this: GET_VAR 'val tmp_9: kotlin.IntArray [val] declared in .testArrayPostfix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_10: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null - GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_11: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + GET_VAR 'val tmp_11: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null VAR name:a2 type:kotlin.Int [val] BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_12 type:kotlin.IntArray [val] + CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY + VAR IR_TEMPORARY_VARIABLE name:tmp_13 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=0 + VAR IR_TEMPORARY_VARIABLE name:tmp_14 type:kotlin.Int [val] CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 + $this: GET_VAR 'val tmp_12: kotlin.IntArray [val] declared in .testArrayPostfix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_13: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null - $this: CALL 'public final fun (): kotlin.IntArray declared in ' type=kotlin.IntArray origin=GET_PROPERTY - index: CONST Int type=kotlin.Int value=0 + $this: GET_VAR 'val tmp_12: kotlin.IntArray [val] declared in .testArrayPostfix' type=kotlin.IntArray origin=null + index: GET_VAR 'val tmp_13: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null value: CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null - GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_14: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null + GET_VAR 'val tmp_14: kotlin.Int [val] declared in .testArrayPostfix' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/expressions/kt28456.fir.txt b/compiler/testData/ir/irText/expressions/kt28456.fir.txt index 5a7610de446..a80278e7e80 100644 --- a/compiler/testData/ir/irText/expressions/kt28456.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt28456.fir.txt @@ -43,37 +43,43 @@ FILE fqName: fileName:/kt28456.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun testPostfixIncrement (a: .A): kotlin.Int declared in ' BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.A [val] + GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=1 + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=2 + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val] CALL 'public final fun get (vararg xs: kotlin.Int): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null - $receiver: GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null + $receiver: GET_VAR 'val tmp_0: .A [val] declared in .testPostfixIncrement' type=.A origin=null xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int - CONST Int type=kotlin.Int value=1 - CONST Int type=kotlin.Int value=2 + GET_VAR 'val tmp_1: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null + GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null - $receiver: GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null - i: CONST Int type=kotlin.Int value=1 - j: CONST Int type=kotlin.Int value=2 + $receiver: GET_VAR 'val tmp_0: .A [val] declared in .testPostfixIncrement' type=.A origin=null + i: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null + j: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null v: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null + GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null FUN name:testCompoundAssignment visibility:public modality:FINAL <> (a:.A) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:.A BLOCK_BODY BLOCK type=kotlin.Unit origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:.A [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:.A [val] GET_VAR 'a: .A declared in .testCompoundAssignment' type=.A origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val] CONST Int type=kotlin.Int value=1 - VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] CONST Int type=kotlin.Int value=2 CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null - $receiver: GET_VAR 'val tmp_1: .A [val] declared in .testCompoundAssignment' type=.A origin=null - i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null - j: GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null + $receiver: GET_VAR 'val tmp_4: .A [val] declared in .testCompoundAssignment' type=.A origin=null + i: GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null + j: GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null v: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public final fun get (vararg xs: kotlin.Int): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null - $receiver: GET_VAR 'val tmp_1: .A [val] declared in .testCompoundAssignment' type=.A origin=null + $receiver: GET_VAR 'val tmp_4: .A [val] declared in .testCompoundAssignment' type=.A origin=null xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int - GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null - GET_VAR 'val tmp_3: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null + GET_VAR 'val tmp_5: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null + GET_VAR 'val tmp_6: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null other: CONST Int type=kotlin.Int value=10 diff --git a/compiler/testData/ir/irText/expressions/kt28456b.fir.txt b/compiler/testData/ir/irText/expressions/kt28456b.fir.txt index d226c14deb0..7a4782dd25a 100644 --- a/compiler/testData/ir/irText/expressions/kt28456b.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt28456b.fir.txt @@ -56,29 +56,33 @@ FILE fqName: fileName:/kt28456b.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun testPostfixIncrement (a: .A): kotlin.Int declared in ' BLOCK type=kotlin.Int origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.A [val] + GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=1 + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null - $receiver: GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null - i: CONST Int type=kotlin.Int value=1 + $receiver: GET_VAR 'val tmp_0: .A [val] declared in .testPostfixIncrement' type=.A origin=null + i: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null - $receiver: GET_VAR 'a: .A declared in .testPostfixIncrement' type=.A origin=null - i: CONST Int type=kotlin.Int value=1 + $receiver: GET_VAR 'val tmp_0: .A [val] declared in .testPostfixIncrement' type=.A origin=null + i: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null v: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null + GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testPostfixIncrement' type=kotlin.Int origin=null FUN name:testCompoundAssignment visibility:public modality:FINAL <> (a:.A) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:.A BLOCK_BODY BLOCK type=kotlin.Unit origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:.A [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:.A [val] GET_VAR 'a: .A declared in .testCompoundAssignment' type=.A origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] CONST Int type=kotlin.Int value=1 CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null - $receiver: GET_VAR 'val tmp_1: .A [val] declared in .testCompoundAssignment' type=.A origin=null - i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null + $receiver: GET_VAR 'val tmp_3: .A [val] declared in .testCompoundAssignment' type=.A origin=null + i: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null v: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null $this: CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null - $receiver: GET_VAR 'val tmp_1: .A [val] declared in .testCompoundAssignment' type=.A origin=null - i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null + $receiver: GET_VAR 'val tmp_3: .A [val] declared in .testCompoundAssignment' type=.A origin=null + i: GET_VAR 'val tmp_4: kotlin.Int [val] declared in .testCompoundAssignment' type=kotlin.Int origin=null other: CONST Int type=kotlin.Int value=10 diff --git a/compiler/testData/ir/irText/expressions/kt36956.fir.txt b/compiler/testData/ir/irText/expressions/kt36956.fir.txt index 14a66bfe638..8b7f8aa22ab 100644 --- a/compiler/testData/ir/irText/expressions/kt36956.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt36956.fir.txt @@ -58,16 +58,20 @@ FILE fqName: fileName:/kt36956.kt FIELD PROPERTY_BACKING_FIELD name:aInt type:kotlin.Float visibility:private [final,static] EXPRESSION_BODY BLOCK type=kotlin.Float origin=null - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Float [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.A [val] + CALL 'public final fun (): .A declared in ' type=.A origin=GET_PROPERTY + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=1 + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Float [val] CALL 'public final fun get (i: kotlin.Int): T of .A [operator] declared in .A' type=kotlin.Float origin=null - $this: CALL 'public final fun (): .A declared in ' type=.A origin=GET_PROPERTY - i: CONST Int type=kotlin.Int value=1 + $this: GET_VAR 'val tmp_0: .A [val] declared in .aInt' type=.A origin=null + i: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .aInt' type=kotlin.Int origin=null CALL 'public final fun set (i: kotlin.Int, v: T of .A): kotlin.Unit [operator] declared in .A' type=kotlin.Unit origin=null - $this: CALL 'public final fun (): .A declared in ' type=.A origin=GET_PROPERTY - i: CONST Int type=kotlin.Int value=1 + $this: GET_VAR 'val tmp_0: .A [val] declared in .aInt' type=.A origin=null + i: GET_VAR 'val tmp_1: kotlin.Int [val] declared in .aInt' type=kotlin.Int origin=null v: CALL 'public final fun dec (): kotlin.Float [operator] declared in kotlin.Float' type=kotlin.Float origin=null - $this: GET_VAR 'val tmp_0: kotlin.Float [val] declared in .aInt' type=kotlin.Float origin=null - GET_VAR 'val tmp_0: kotlin.Float [val] declared in .aInt' type=kotlin.Float origin=null + $this: GET_VAR 'val tmp_2: kotlin.Float [val] declared in .aInt' type=kotlin.Float origin=null + GET_VAR 'val tmp_2: kotlin.Float [val] declared in .aInt' type=kotlin.Float origin=null FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Float correspondingProperty: PROPERTY name:aInt visibility:public modality:FINAL [val] BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/lambdaInCAO.fir.txt b/compiler/testData/ir/irText/expressions/lambdaInCAO.fir.txt index d8a59aca01d..e801946f7fd 100644 --- a/compiler/testData/ir/irText/expressions/lambdaInCAO.fir.txt +++ b/compiler/testData/ir/irText/expressions/lambdaInCAO.fir.txt @@ -31,22 +31,22 @@ FILE fqName: fileName:/lambdaInCAO.kt FUN name:test3 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:kotlin.Any BLOCK_BODY - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] - CALL 'public final fun get (index: kotlin.Function0): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null - $receiver: GET_VAR 'a: kotlin.Any declared in .test3' type=kotlin.Any origin=null - index: FUN_EXPR type=kotlin.Function0 origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): kotlin.Unit declared in .test3' - GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit - CALL 'public final fun set (index: kotlin.Function0, value: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null - $receiver: GET_VAR 'a: kotlin.Any declared in .test3' type=kotlin.Any origin=null - index: FUN_EXPR type=kotlin.Function0 origin=LAMBDA + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any [val] + GET_VAR 'a: kotlin.Any declared in .test3' type=kotlin.Any origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Function0 [val] + FUN_EXPR type=kotlin.Function0 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): kotlin.Unit declared in .test3' GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val] + CALL 'public final fun get (index: kotlin.Function0): kotlin.Int [operator] declared in ' type=kotlin.Int origin=null + $receiver: GET_VAR 'val tmp_0: kotlin.Any [val] declared in .test3' type=kotlin.Any origin=null + index: GET_VAR 'val tmp_1: kotlin.Function0 [val] declared in .test3' type=kotlin.Function0 origin=null + CALL 'public final fun set (index: kotlin.Function0, value: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=null + $receiver: GET_VAR 'val tmp_0: kotlin.Any [val] declared in .test3' type=kotlin.Any origin=null + index: GET_VAR 'val tmp_1: kotlin.Function0 [val] declared in .test3' type=kotlin.Function0 origin=null value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test3' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in .test3' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test3' type=kotlin.Int origin=null + GET_VAR 'val tmp_2: kotlin.Int [val] declared in .test3' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt index 004669d3b28..d7c526ea61c 100644 --- a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt +++ b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.fir.txt @@ -96,38 +96,30 @@ FILE fqName:test fileName:/safeCallWithIncrementDecrement.kt FUN name:testArrayAccess visibility:public modality:FINAL <> (nc:test.C?) returnType:kotlin.Unit VALUE_PARAMETER name:nc index:0 type:test.C? BLOCK_BODY - VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val] - CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in test' type=kotlin.Int origin=null - $receiver: BLOCK type=kotlin.Int? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:test.C? [val] - GET_VAR 'nc: test.C? declared in test.testArrayAccess' type=test.C? origin=null - WHEN type=kotlin.Int? origin=null - BRANCH - if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_5: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null - arg1: CONST Null type=kotlin.Nothing? value=null - then: CONST Null type=kotlin.Nothing? value=null - BRANCH - if: CONST Boolean type=kotlin.Boolean value=true - then: CALL 'public final fun (): kotlin.Int declared in test' type=kotlin.Int origin=GET_PROPERTY - $receiver: GET_VAR 'val tmp_5: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null - index: CONST Int type=kotlin.Int value=0 - CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in test' type=kotlin.Unit origin=null - $receiver: BLOCK type=kotlin.Int? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:test.C? [val] + VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int? [val] + BLOCK type=kotlin.Int? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:test.C? [val] GET_VAR 'nc: test.C? declared in test.testArrayAccess' type=test.C? origin=null WHEN type=kotlin.Int? origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_6: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null + arg0: GET_VAR 'val tmp_5: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Null type=kotlin.Nothing? value=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public final fun (): kotlin.Int declared in test' type=kotlin.Int origin=GET_PROPERTY - $receiver: GET_VAR 'val tmp_6: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null - index: CONST Int type=kotlin.Int value=0 + $receiver: GET_VAR 'val tmp_5: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val] + CONST Int type=kotlin.Int value=0 + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val] + CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in test' type=kotlin.Int origin=null + $receiver: GET_VAR 'val tmp_4: kotlin.Int? [val] declared in test.testArrayAccess' type=kotlin.Int? origin=null + index: GET_VAR 'val tmp_6: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null + CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in test' type=kotlin.Unit origin=null + $receiver: GET_VAR 'val tmp_4: kotlin.Int? [val] declared in test.testArrayAccess' type=kotlin.Int? origin=null + index: GET_VAR 'val tmp_6: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: GET_VAR 'val tmp_4: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_7: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - GET_VAR 'val tmp_4: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null + GET_VAR 'val tmp_7: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 628c60e731e..f8590c8bdce 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -14386,6 +14386,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/increment"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("argumentWithSideEffects.kt") + public void testArgumentWithSideEffects() throws Exception { + runTest("compiler/testData/codegen/box/increment/argumentWithSideEffects.kt"); + } + @TestMetadata("arrayElement.kt") public void testArrayElement() throws Exception { runTest("compiler/testData/codegen/box/increment/arrayElement.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 7f975927a43..9c124a90170 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -14386,6 +14386,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/increment"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("argumentWithSideEffects.kt") + public void testArgumentWithSideEffects() throws Exception { + runTest("compiler/testData/codegen/box/increment/argumentWithSideEffects.kt"); + } + @TestMetadata("arrayElement.kt") public void testArrayElement() throws Exception { runTest("compiler/testData/codegen/box/increment/arrayElement.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index d1b1639583f..817f14e9310 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -12991,6 +12991,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/increment"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("argumentWithSideEffects.kt") + public void testArgumentWithSideEffects() throws Exception { + runTest("compiler/testData/codegen/box/increment/argumentWithSideEffects.kt"); + } + @TestMetadata("arrayElement.kt") public void testArrayElement() throws Exception { runTest("compiler/testData/codegen/box/increment/arrayElement.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index da22ec016e3..61449d23d54 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -11136,6 +11136,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/increment"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } + @TestMetadata("argumentWithSideEffects.kt") + public void testArgumentWithSideEffects() throws Exception { + runTest("compiler/testData/codegen/box/increment/argumentWithSideEffects.kt"); + } + @TestMetadata("arrayElement.kt") public void testArrayElement() throws Exception { runTest("compiler/testData/codegen/box/increment/arrayElement.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 4ffca35082c..99aac50de71 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -11136,6 +11136,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/increment"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @TestMetadata("argumentWithSideEffects.kt") + public void testArgumentWithSideEffects() throws Exception { + runTest("compiler/testData/codegen/box/increment/argumentWithSideEffects.kt"); + } + @TestMetadata("arrayElement.kt") public void testArrayElement() throws Exception { runTest("compiler/testData/codegen/box/increment/arrayElement.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 2ed8d7900fa..b5a96bd1e9d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11201,6 +11201,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/increment"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @TestMetadata("argumentWithSideEffects.kt") + public void testArgumentWithSideEffects() throws Exception { + runTest("compiler/testData/codegen/box/increment/argumentWithSideEffects.kt"); + } + @TestMetadata("arrayElement.kt") public void testArrayElement() throws Exception { runTest("compiler/testData/codegen/box/increment/arrayElement.kt");