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 64e32c91094..f981cd33acf 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 @@ -16403,6 +16403,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testTrivialInstanceOf() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt"); } + + @TestMetadata("varModifiedAfterCheck.kt") + public void testVarModifiedAfterCheck() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt"); + } } @TestMetadata("compiler/testData/codegen/box/objectIntrinsics") diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt index c68dec9dc7e..c0807599876 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/TypeOperatorLowering.kt @@ -20,13 +20,11 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin -import org.jetbrains.kotlin.ir.expressions.IrTypeOperator -import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid @@ -142,7 +140,7 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil val (startOffset, endOffset) = expression.extents() val source = sourceViewFor(parent as IrDeclaration).subSequence(startOffset, endOffset).toString() - irLetS(expression.argument.transformVoid()) { valueSymbol -> + fun checkExpressionValue(valueSymbol: IrValueSymbol): IrExpression = irComposite(resultType = expression.type) { +irCall(checkExpressionValueIsNotNull).apply { putValueArgument(0, irGet(valueSymbol.owner)) @@ -150,6 +148,14 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil } +irGet(valueSymbol.owner) } + + val argument = expression.argument.transformVoid() + if (argument is IrGetValue) { + checkExpressionValue(argument.symbol) + } else { + irLetS(argument) { valueSymbol -> + checkExpressionValue(valueSymbol) + } } } diff --git a/compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt b/compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt new file mode 100644 index 00000000000..aad874c2115 --- /dev/null +++ b/compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt @@ -0,0 +1,59 @@ +// TARGET_BACKEND: JVM +// FILE: varModifiedAfterCheck.kt +fun implicitCheck(s: String) {} + +fun test1() { + var a = J.foo() + val b = a + a = J.bar() + if (b != null) { + if (a != null) { + throw AssertionError("a: $a") + } + } +} + +fun test2() { + var a = J.foo() + val b = a + if (b != null) { + a = J.bar() + if (a != null) { + throw AssertionError("a: $a") + } + } +} + +fun test3() { + var a = J.foo() + val b = a + a = J.bar() + implicitCheck(b) + if (a != null) { + throw AssertionError("a: $a") + } +} + +fun test4() { + var a = J.foo() + val b = a + implicitCheck(b) + a = J.bar() + if (a != null) { + throw AssertionError("a: $a") + } +} + +fun box(): String { + test1() + test2() + test3() + test4() + return "OK" +} + +// FILE: J.java +public class J { + public static String foo() { return ""; } + public static String bar() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNull.kt b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNull.kt index 72554570669..758216e51e3 100644 --- a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNull.kt +++ b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNull.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// TODO KT-36813 Support code generated by JVM_IR in redundant null check optimization // FILE: j/J.java package j; diff --git a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNullTwice.kt b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNullTwice.kt index d1140e00437..ff2f16e7fda 100644 --- a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNullTwice.kt +++ b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/expressionValueIsNotNullTwice.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// TODO KT-36813 Support code generated by JVM_IR in redundant null check optimization // FILE: j/J.java package j; diff --git a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/notNullExpressionValueTwice_1_4.kt b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/notNullExpressionValueTwice_1_4.kt index e4af280eb96..6cfa2e956a5 100644 --- a/compiler/testData/codegen/bytecodeText/nullCheckOptimization/notNullExpressionValueTwice_1_4.kt +++ b/compiler/testData/codegen/bytecodeText/nullCheckOptimization/notNullExpressionValueTwice_1_4.kt @@ -1,6 +1,4 @@ // !API_VERSION: LATEST -// IGNORE_BACKEND: JVM_IR -// TODO KT-36813 Support code generated by JVM_IR in redundant null check optimization // FILE: j/J.java package j; diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 4c6c9ba0317..04852d64fb8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -17548,6 +17548,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testTrivialInstanceOf() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt"); } + + @TestMetadata("varModifiedAfterCheck.kt") + public void testVarModifiedAfterCheck() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt"); + } } @TestMetadata("compiler/testData/codegen/box/objectIntrinsics") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index cc42e36f58e..15812206a97 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -17548,6 +17548,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testTrivialInstanceOf() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt"); } + + @TestMetadata("varModifiedAfterCheck.kt") + public void testVarModifiedAfterCheck() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt"); + } } @TestMetadata("compiler/testData/codegen/box/objectIntrinsics") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 33d18b2a19d..6cc81419924 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -16403,6 +16403,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testTrivialInstanceOf() throws Exception { runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt"); } + + @TestMetadata("varModifiedAfterCheck.kt") + public void testVarModifiedAfterCheck() throws Exception { + runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt"); + } } @TestMetadata("compiler/testData/codegen/box/objectIntrinsics")