Fix CFG problem for 'when' in Konan

If type of 'when' expression is 'Nothing', it should be kept that way
even if the expression itself is implicitly coerced to Unit.
This commit is contained in:
Dmitry Petrov
2017-06-21 15:27:13 +03:00
parent 1f34dfabd5
commit 2b3043bf9f
3 changed files with 14 additions and 8 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.psi2ir.generators package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.whenComma import org.jetbrains.kotlin.ir.builders.whenComma
import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.IrVariable
@@ -85,12 +86,17 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
scope.createTemporaryVariable(statementGenerator.generateExpression(it), "subject") scope.createTemporaryVariable(statementGenerator.generateExpression(it), "subject")
} }
val inferredType = getInferredTypeWithImplicitCastsOrFail(expression)
// TODO relies on ControlFlowInformationProvider, get rid of it // TODO relies on ControlFlowInformationProvider, get rid of it
val resultType = val isUsedAsExpression = context.bindingContext[BindingContext.USED_AS_EXPRESSION, expression] ?: false
if (context.bindingContext[BindingContext.USED_AS_EXPRESSION, expression] ?: false)
getInferredTypeWithImplicitCastsOrFail(expression) val resultType = when {
else isUsedAsExpression -> inferredType
context.builtIns.unitType KotlinBuiltIns.isNothing(inferredType) -> inferredType
else -> context.builtIns.unitType
}
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrStatementOrigin.WHEN) val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrStatementOrigin.WHEN)
+1 -1
View File
@@ -5,7 +5,7 @@ CONTENT
1 FUN public fun toString(grade: kotlin.String): kotlin.String 1 FUN public fun toString(grade: kotlin.String): kotlin.String
2 GET_VAR 'value-parameter grade: String' type=kotlin.String origin=null 2 GET_VAR 'value-parameter grade: String' type=kotlin.String origin=null
3 VAR IR_TEMPORARY_VARIABLE val tmp0_subject: kotlin.String 3 VAR IR_TEMPORARY_VARIABLE val tmp0_subject: kotlin.String
4 WHEN type=kotlin.Unit origin=WHEN 4 WHEN type=kotlin.Nothing origin=WHEN
5 GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null 5 GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null
6 CONST String type=kotlin.String value='A' 6 CONST String type=kotlin.String value='A'
OUTGOING -> BB 1, 5 OUTGOING -> BB 1, 5
+2 -2
View File
@@ -2,10 +2,10 @@ FILE /whenReturn.kt
FUN public fun toString(grade: kotlin.String): kotlin.String FUN public fun toString(grade: kotlin.String): kotlin.String
VALUE_PARAMETER value-parameter grade: kotlin.String VALUE_PARAMETER value-parameter grade: kotlin.String
BLOCK_BODY BLOCK_BODY
BLOCK type=kotlin.Unit origin=WHEN BLOCK type=kotlin.Nothing origin=WHEN
VAR IR_TEMPORARY_VARIABLE val tmp0_subject: kotlin.String VAR IR_TEMPORARY_VARIABLE val tmp0_subject: kotlin.String
GET_VAR 'value-parameter grade: String' type=kotlin.String origin=null GET_VAR 'value-parameter grade: String' type=kotlin.String origin=null
WHEN type=kotlin.Unit origin=WHEN WHEN type=kotlin.Nothing origin=WHEN
BRANCH BRANCH
if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ if: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null arg0: GET_VAR 'tmp0_subject: String' type=kotlin.String origin=null