KT-14581 Make FixStackAnalyzer tolerant to uninitialized values
This commit is contained in:
+12
-2
@@ -31,9 +31,15 @@ import java.util.List;
|
||||
import static org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue.*;
|
||||
|
||||
public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implements Opcodes {
|
||||
private final boolean tolerantToUninitializedValues;
|
||||
|
||||
public OptimizationBasicInterpreter(boolean tolerantToUninitializedValues) {
|
||||
super(ASM5);
|
||||
this.tolerantToUninitializedValues = tolerantToUninitializedValues;
|
||||
}
|
||||
|
||||
public OptimizationBasicInterpreter() {
|
||||
super(ASM5);
|
||||
this(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -355,7 +361,11 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
|
||||
) {
|
||||
if (v.equals(w)) return v;
|
||||
|
||||
if (v == StrictBasicValue.UNINITIALIZED_VALUE || w == StrictBasicValue.UNINITIALIZED_VALUE) {
|
||||
if (tolerantToUninitializedValues) {
|
||||
if (v == StrictBasicValue.UNINITIALIZED_VALUE) return w;
|
||||
if (w == StrictBasicValue.UNINITIALIZED_VALUE) return v;
|
||||
}
|
||||
else if (v == StrictBasicValue.UNINITIALIZED_VALUE || w == StrictBasicValue.UNINITIALIZED_VALUE) {
|
||||
return StrictBasicValue.UNINITIALIZED_VALUE;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ internal class FixStackAnalyzer(
|
||||
owner: String,
|
||||
methodNode: MethodNode,
|
||||
val context: FixStackContext
|
||||
) : MethodAnalyzer<BasicValue>(owner, methodNode, OptimizationBasicInterpreter()) {
|
||||
) : MethodAnalyzer<BasicValue>(owner, methodNode, OptimizationBasicInterpreter(/* tolerantToUninitializedValues = */true)) {
|
||||
val savedStacks = hashMapOf<AbstractInsnNode, List<BasicValue>>()
|
||||
var maxExtraStackSize = 0; private set
|
||||
|
||||
|
||||
+4
@@ -44,6 +44,10 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
|
||||
}
|
||||
|
||||
private fun allocateNewHandle(numRestoreStackMarkers: Int, saveStackMarker: AbstractInsnNode, savedStackValues: List<BasicValue>): SavedStackDescriptor {
|
||||
if (savedStackValues.any { it.type == null }) {
|
||||
throw AssertionError("Uninitialized value on stack at ${methodNode.instructions.indexOf(saveStackMarker)}")
|
||||
}
|
||||
|
||||
val firstUnusedLocalVarIndex = getFirstUnusedLocalVariableIndex()
|
||||
val savedStackDescriptor = SavedStackDescriptor(savedStackValues, firstUnusedLocalVarIndex)
|
||||
updateMaxLocals(savedStackDescriptor.firstUnusedLocalVarIndex)
|
||||
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
fun box(): String {
|
||||
val ok: String? = "OK"
|
||||
var res = ""
|
||||
|
||||
do {
|
||||
res += ok ?: break
|
||||
} while (false)
|
||||
|
||||
return res
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
fun box(): String {
|
||||
var i = 0
|
||||
do continue while (i++ < 3)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fun foo(x: String): String {
|
||||
var y: String
|
||||
do {
|
||||
y = x
|
||||
} while (y != x.bar(x))
|
||||
return y
|
||||
}
|
||||
|
||||
inline fun String.bar(other: String) = this
|
||||
|
||||
fun box(): String = foo("OK")
|
||||
+18
@@ -4156,12 +4156,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("breakInDoWhile.kt")
|
||||
public void testBreakInDoWhile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/breakInDoWhile.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("breakInExpr.kt")
|
||||
public void testBreakInExpr() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/breakInExpr.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("continueInDoWhile.kt")
|
||||
public void testContinueInDoWhile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/continueInDoWhile.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("continueInExpr.kt")
|
||||
public void testContinueInExpr() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/continueInExpr.kt");
|
||||
@@ -4180,6 +4192,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14581.kt")
|
||||
public void testKt14581() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt14581.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9022And.kt")
|
||||
public void testKt9022And() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt9022And.kt");
|
||||
|
||||
@@ -4156,12 +4156,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("breakInDoWhile.kt")
|
||||
public void testBreakInDoWhile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/breakInDoWhile.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("breakInExpr.kt")
|
||||
public void testBreakInExpr() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/breakInExpr.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("continueInDoWhile.kt")
|
||||
public void testContinueInDoWhile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/continueInDoWhile.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("continueInExpr.kt")
|
||||
public void testContinueInExpr() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/continueInExpr.kt");
|
||||
@@ -4180,6 +4192,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14581.kt")
|
||||
public void testKt14581() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt14581.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9022And.kt")
|
||||
public void testKt9022And() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt9022And.kt");
|
||||
|
||||
+24
@@ -5140,12 +5140,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("breakInDoWhile.kt")
|
||||
public void testBreakInDoWhile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/breakInDoWhile.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("breakInExpr.kt")
|
||||
public void testBreakInExpr() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/breakInExpr.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("continueInDoWhile.kt")
|
||||
public void testContinueInDoWhile() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/continueInDoWhile.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("continueInExpr.kt")
|
||||
public void testContinueInExpr() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/continueInExpr.kt");
|
||||
@@ -5164,6 +5176,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14581.kt")
|
||||
public void testKt14581() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt14581.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9022And.kt")
|
||||
public void testKt9022And() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/kt9022And.kt");
|
||||
@@ -7088,6 +7106,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13557.kt")
|
||||
public void testKt13557() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localVal.kt")
|
||||
public void testLocalVal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");
|
||||
|
||||
Reference in New Issue
Block a user