Put default value to vars iff they are not boxed

#KT-24672 Fixed
This commit is contained in:
Ilmir Usmanov
2019-01-14 15:47:18 +03:00
parent 62322dec5c
commit 76e9b574cd
12 changed files with 235 additions and 11 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
@@ -4041,7 +4041,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
else if (property.hasModifier(KtTokens.LATEINIT_KEYWORD)) {
initializeLocalVariable(property, null);
}
else if (!property.isVar()) {
else {
initializeLocalVariableWithFakeDefaultValue(property);
}
@@ -4194,10 +4194,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
private void initializeLocalVariableWithFakeDefaultValue(@NotNull KtProperty variableDeclaration) {
LocalVariableDescriptor variableDescriptor = (LocalVariableDescriptor) getVariableDescriptorNotNull(variableDeclaration);
// For this kind of variables we generate boxes, i.e. we regard them as
if (isCapturedInClosureWithExactlyOnceEffect(bindingContext, variableDescriptor)) return;
// Boxed variables already have a value
if (isBoxedLocalCapturedInClosure(bindingContext, variableDescriptor)) return;
assert !variableDeclaration.isVar() && !variableDeclaration.hasDelegateExpressionOrInitializer() &&
assert !variableDeclaration.hasDelegateExpressionOrInitializer() &&
!variableDescriptor.isLateInit() : variableDeclaration.getText() + " in not variable declaration without initializer";
KotlinType kotlinType = variableDescriptor.getType();
@@ -0,0 +1,12 @@
// IGNORE_BACKEND: JVM_IR
fun test(): java.lang.Integer {
var c: java.lang.Integer
run {
c = java.lang.Integer(1)
}
return c
}
// 1 ASTORE 0
// 1 LOCALVARIABLE c Lkotlin/jvm/internal/Ref\$ObjectRef; L1 L11 0
@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@ExperimentalContracts
fun test(): Char {
var c: Char
doIt {
c = ' '
}
return c
}
@ExperimentalContracts
fun doIt(block: () -> Unit) {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
}
// 0 ISTORE 0
// 1 LOCALVARIABLE c Lkotlin/jvm/internal/Ref\$CharRef; L1 L3 0
@@ -0,0 +1,18 @@
// IGNORE_BACKEND: JVM_IR
inline fun <reified T> foo(default: T): T {
var t: T
run {
t = default
}
return t
}
fun test() {
foo(0.0f)
}
// two in foo and two in test
// 2 ASTORE 2
// 1 LOCALVARIABLE t\$iv Lkotlin/jvm/internal/Ref\$ObjectRef; L3 L13 2
@@ -0,0 +1,16 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.random.Random
fun test(): Char {
var c: Char
if (Random.nextBoolean()) {
c = '1'
} else {
c = '2'
}
return c
}
// 3 ISTORE 0
// 1 LOCALVARIABLE c C L1 L7 0
@@ -0,0 +1,16 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.random.Random
fun test(): Char {
var c: Char
if (Random.nextBoolean())
c = '1'
else
c = '2'
return c
}
// 3 ISTORE 0
// 1 LOCALVARIABLE c C L1 L5 0
@@ -0,0 +1,12 @@
// IGNORE_BACKEND: JVM_IR
fun test(): UInt {
var c: UInt
run {
c = 1u
}
return c
}
// 1 ASTORE 0
// 1 LOCALVARIABLE c Lkotlin/jvm/internal/Ref\$IntRef; L1 L11 0
@@ -0,0 +1,23 @@
// IGNORE_BACKEND: JVM_IR
fun test(): Char {
var c: Char
val l = Any()
val l1 = Any()
val l2 = Any()
val l3 = Any()
val l4 = Any()
val l5 = Any()
val l6 = Any()
val l7 = Any()
val l8 = Any()
val l11 = Any()
val l12 = Any()
val l13 = Any()
val l14 = Any()
c = '1'
return c
}
// 2 ISTORE 0
// 1 LOCALVARIABLE c C L1 L16 0
@@ -0,0 +1,22 @@
// IGNORE_BACKEND: JVM_IR
fun test(i: Int): Char {
var c: Char
when (i) {
1 -> c = '1'
2 -> c = '2'
3 -> c = '3'
4 -> c = '4'
5 -> c = '5'
6 -> c = '6'
7 -> c = '7'
8 -> c = '8'
9 -> c = '9'
0 -> c = '0'
else -> c = ' '
}
return c
}
// 12 ISTORE 1
// 1 LOCALVARIABLE c C L1 L16 1
@@ -2612,31 +2612,61 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/boxing.kt");
}
@TestMetadata("boxingVar.kt")
public void testBoxingVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/boxingVar.kt");
}
@TestMetadata("contract.kt")
public void testContract() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/contract.kt");
}
@TestMetadata("contractVar.kt")
public void testContractVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/contractVar.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/generics.kt");
}
@TestMetadata("genericsVar.kt")
public void testGenericsVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/genericsVar.kt");
}
@TestMetadata("ifStatement.kt")
public void testIfStatement() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatement.kt");
}
@TestMetadata("ifStatementVar.kt")
public void testIfStatementVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatementVar.kt");
}
@TestMetadata("ifStatementWithoutBlock.kt")
public void testIfStatementWithoutBlock() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatementWithoutBlock.kt");
}
@TestMetadata("ifStatementWithoutBlockVar.kt")
public void testIfStatementWithoutBlockVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatementWithoutBlockVar.kt");
}
@TestMetadata("inlineClass.kt")
public void testInlineClass() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClass.kt");
}
@TestMetadata("inlineClassVar.kt")
public void testInlineClassVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClassVar.kt");
}
@TestMetadata("lateinit.kt")
public void testLateinit() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/lateinit.kt");
@@ -2647,20 +2677,30 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/run.kt");
}
@TestMetadata("runVar.kt")
public void testRunVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/runVar.kt");
}
@TestMetadata("singleBlock.kt")
public void testSingleBlock() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/singleBlock.kt");
}
@TestMetadata("var.kt")
public void testVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/var.kt");
@TestMetadata("singleBlockVar.kt")
public void testSingleBlockVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/singleBlockVar.kt");
}
@TestMetadata("whenStatement.kt")
public void testWhenStatement() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/whenStatement.kt");
}
@TestMetadata("whenStatementVar.kt")
public void testWhenStatementVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/whenStatementVar.kt");
}
}
@TestMetadata("compiler/testData/codegen/bytecodeText/multifileClasses")
@@ -2612,31 +2612,61 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/boxing.kt");
}
@TestMetadata("boxingVar.kt")
public void testBoxingVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/boxingVar.kt");
}
@TestMetadata("contract.kt")
public void testContract() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/contract.kt");
}
@TestMetadata("contractVar.kt")
public void testContractVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/contractVar.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/generics.kt");
}
@TestMetadata("genericsVar.kt")
public void testGenericsVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/genericsVar.kt");
}
@TestMetadata("ifStatement.kt")
public void testIfStatement() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatement.kt");
}
@TestMetadata("ifStatementVar.kt")
public void testIfStatementVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatementVar.kt");
}
@TestMetadata("ifStatementWithoutBlock.kt")
public void testIfStatementWithoutBlock() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatementWithoutBlock.kt");
}
@TestMetadata("ifStatementWithoutBlockVar.kt")
public void testIfStatementWithoutBlockVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/ifStatementWithoutBlockVar.kt");
}
@TestMetadata("inlineClass.kt")
public void testInlineClass() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClass.kt");
}
@TestMetadata("inlineClassVar.kt")
public void testInlineClassVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/inlineClassVar.kt");
}
@TestMetadata("lateinit.kt")
public void testLateinit() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/lateinit.kt");
@@ -2647,20 +2677,30 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/run.kt");
}
@TestMetadata("runVar.kt")
public void testRunVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/runVar.kt");
}
@TestMetadata("singleBlock.kt")
public void testSingleBlock() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/singleBlock.kt");
}
@TestMetadata("var.kt")
public void testVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/var.kt");
@TestMetadata("singleBlockVar.kt")
public void testSingleBlockVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/singleBlockVar.kt");
}
@TestMetadata("whenStatement.kt")
public void testWhenStatement() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/whenStatement.kt");
}
@TestMetadata("whenStatementVar.kt")
public void testWhenStatementVar() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/localInitializationLVT/whenStatementVar.kt");
}
}
@TestMetadata("compiler/testData/codegen/bytecodeText/multifileClasses")