Fix coroutine-related VerifyError
The problem was that we spilled the `origin` variable (see test) as Object, because we determined the type of merge(null, String) incorrectly. #KT-15973 Fixed
This commit is contained in:
+4
-5
@@ -72,13 +72,9 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
|
||||
|
||||
@Override
|
||||
public BasicValue newOperation(@NotNull AbstractInsnNode insn) throws AnalyzerException {
|
||||
if (insn.getOpcode() == Opcodes.ACONST_NULL) {
|
||||
return newValue(Type.getObjectType("java/lang/Object"));
|
||||
}
|
||||
|
||||
switch (insn.getOpcode()) {
|
||||
case ACONST_NULL:
|
||||
return newValue(Type.getObjectType("null"));
|
||||
return NULL_VALUE;
|
||||
case ICONST_M1:
|
||||
case ICONST_0:
|
||||
case ICONST_1:
|
||||
@@ -362,6 +358,9 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
|
||||
// if merge of two references then `lub` is java/lang/Object
|
||||
// arrays also are BasicValues with reference type's
|
||||
if (isReference(v) && isReference(w)) {
|
||||
if (v == NULL_VALUE) return newValue(w.getType());
|
||||
if (w == NULL_VALUE) return newValue(v.getType());
|
||||
|
||||
return StrictBasicValue.REFERENCE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -45,6 +45,9 @@ open class StrictBasicValue(type: Type?) : BasicValue(type) {
|
||||
val SHORT_VALUE = StrictBasicValue(Type.SHORT_TYPE)
|
||||
@JvmField
|
||||
val REFERENCE_VALUE = StrictBasicValue(Type.getObjectType("java/lang/Object"))
|
||||
|
||||
@JvmField
|
||||
val NULL_VALUE = StrictBasicValue(Type.getObjectType("java/lang/Object"))
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
@@ -60,4 +63,9 @@ open class StrictBasicValue(type: Type?) : BasicValue(type) {
|
||||
}
|
||||
|
||||
override fun hashCode() = (type?.hashCode() ?: 0)
|
||||
|
||||
override fun toString(): String {
|
||||
if (this === UNINITIALIZED_VALUE) return "."
|
||||
return super.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
var res = ""
|
||||
|
||||
suspend fun foo(y: A?): String {
|
||||
val origin: String? = y?.z
|
||||
if (origin != null) {
|
||||
baz(origin)
|
||||
baz(origin)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
suspend fun baz(y: String): Unit = suspendCoroutineOrReturn { x ->
|
||||
res += y[res.length]
|
||||
x.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
class A(val z: String)
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
result = foo(A("OK"))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
@kotlin.Metadata
|
||||
public final class A {
|
||||
private final @org.jetbrains.annotations.NotNull field z: java.lang.String
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
public final @org.jetbrains.annotations.NotNull method getZ(): java.lang.String
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class CoroutineUtilKt {
|
||||
public final static @org.jetbrains.annotations.NotNull method handleExceptionContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.experimental.Continuation
|
||||
public final static @org.jetbrains.annotations.NotNull method handleResultContinuation(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): kotlin.coroutines.experimental.Continuation
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public class EmptyContinuation {
|
||||
public final static field Companion: EmptyContinuation.Companion
|
||||
private final @org.jetbrains.annotations.NotNull field context: kotlin.coroutines.experimental.CoroutineContext
|
||||
inner class EmptyContinuation/Companion
|
||||
public @synthetic.kotlin.jvm.GeneratedByJvmOverloads method <init>(): void
|
||||
public method <init>(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.CoroutineContext): void
|
||||
public synthetic method <init>(p0: kotlin.coroutines.experimental.CoroutineContext, p1: int, p2: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.experimental.CoroutineContext
|
||||
public method resume(@org.jetbrains.annotations.Nullable p0: java.lang.Object): void
|
||||
public method resumeWithException(@org.jetbrains.annotations.NotNull p0: java.lang.Throwable): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final static class EmptyContinuation/Companion {
|
||||
inner class EmptyContinuation/Companion
|
||||
private method <init>(): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class MergeNullAndStringKt {
|
||||
private static @org.jetbrains.annotations.NotNull field res: java.lang.String
|
||||
public final static @org.jetbrains.annotations.Nullable method baz(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
|
||||
public final static @org.jetbrains.annotations.Nullable method foo(@org.jetbrains.annotations.Nullable p0: A, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.NotNull method getRes(): java.lang.String
|
||||
public final static method setRes(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
|
||||
}
|
||||
+6
@@ -4799,6 +4799,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mergeNullAndString.kt")
|
||||
public void testMergeNullAndString() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/mergeNullAndString.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multipleInvokeCalls.kt")
|
||||
public void testMultipleInvokeCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multipleInvokeCalls.kt");
|
||||
|
||||
@@ -4799,6 +4799,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mergeNullAndString.kt")
|
||||
public void testMergeNullAndString() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/mergeNullAndString.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multipleInvokeCalls.kt")
|
||||
public void testMultipleInvokeCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multipleInvokeCalls.kt");
|
||||
|
||||
@@ -4799,6 +4799,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mergeNullAndString.kt")
|
||||
public void testMergeNullAndString() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/mergeNullAndString.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multipleInvokeCalls.kt")
|
||||
public void testMultipleInvokeCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multipleInvokeCalls.kt");
|
||||
|
||||
@@ -5490,6 +5490,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("mergeNullAndString.kt")
|
||||
public void testMergeNullAndString() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/mergeNullAndString.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multipleInvokeCalls.kt")
|
||||
public void testMultipleInvokeCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/multipleInvokeCalls.kt");
|
||||
|
||||
Reference in New Issue
Block a user