Reified 'as?' produces nullable result
Previously, this was treated as a regular CHECKCAST, causing KT-22410. #Fixed KT-22410 Target versions 1.2.30
This commit is contained in:
@@ -261,7 +261,7 @@ val MethodInsnNode.reificationArgument: ReificationArgument?
|
||||
return ReificationArgument(parameterName, nullable, arrayDepth)
|
||||
}
|
||||
|
||||
private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
|
||||
val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
|
||||
previous?.previous?.intConstant?.let {
|
||||
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
||||
}
|
||||
|
||||
+16
-4
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.optimization.nullCheck
|
||||
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.codegen.inline.operationKind
|
||||
import org.jetbrains.kotlin.codegen.optimization.boxing.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
|
||||
@@ -24,6 +26,7 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.isPseudo
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
|
||||
@@ -53,16 +56,25 @@ class NullabilityInterpreter : OptimizationBasicInterpreter() {
|
||||
val defaultResult = super.unaryOperation(insn, value)
|
||||
val resultType = defaultResult?.type
|
||||
|
||||
return when {
|
||||
insn.opcode == Opcodes.CHECKCAST ->
|
||||
value
|
||||
insn.opcode == Opcodes.NEWARRAY || insn.opcode == Opcodes.ANEWARRAY ->
|
||||
return when (insn.opcode) {
|
||||
Opcodes.CHECKCAST ->
|
||||
if (insn.isReifiedSafeAs())
|
||||
StrictBasicValue(resultType)
|
||||
else
|
||||
value
|
||||
Opcodes.NEWARRAY, Opcodes.ANEWARRAY ->
|
||||
NotNullBasicValue(resultType)
|
||||
else ->
|
||||
defaultResult
|
||||
}
|
||||
}
|
||||
|
||||
private fun AbstractInsnNode.isReifiedSafeAs(): Boolean {
|
||||
val marker = previous as? MethodInsnNode ?: return false
|
||||
return ReifiedTypeInliner.isOperationReifiedMarker(marker)
|
||||
&& marker.operationKind == ReifiedTypeInliner.OperationKind.SAFE_AS
|
||||
}
|
||||
|
||||
override fun naryOperation(insn: AbstractInsnNode, values: List<BasicValue>): BasicValue? {
|
||||
val defaultResult = super.naryOperation(insn, values)
|
||||
val resultType = defaultResult?.type
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
fun box(): String {
|
||||
defineFunc<String>()
|
||||
|
||||
func(1)
|
||||
|
||||
return if (testedEquals) "OK" else "Fail"
|
||||
}
|
||||
|
||||
var func: (Any) -> Unit = {}
|
||||
|
||||
var testedEquals = false
|
||||
|
||||
inline fun <reified T> defineFunc() {
|
||||
func = {
|
||||
val nullable = it as? T
|
||||
|
||||
if (nullable == null)
|
||||
testedEquals = true
|
||||
}
|
||||
}
|
||||
Generated
+6
@@ -12672,6 +12672,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt22410.kt")
|
||||
public void testKt22410() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7774.kt")
|
||||
public void testKt7774() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt");
|
||||
|
||||
+6
@@ -12672,6 +12672,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt22410.kt")
|
||||
public void testKt22410() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7774.kt")
|
||||
public void testKt7774() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt");
|
||||
|
||||
+6
@@ -12672,6 +12672,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt22410.kt")
|
||||
public void testKt22410() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7774.kt")
|
||||
public void testKt7774() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt");
|
||||
|
||||
+6
@@ -13776,6 +13776,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt22410.kt")
|
||||
public void testKt22410() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt22410.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt7774.kt")
|
||||
public void testKt7774() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullCheckOptimization/kt7774.kt");
|
||||
|
||||
Reference in New Issue
Block a user