JVM_IR: discard results of nonexhaustive whens' branches

This commit is contained in:
pyos
2019-10-16 15:53:50 +02:00
committed by max-kammerer
parent cfa9950c22
commit d1f25d1c26
2 changed files with 8 additions and 8 deletions
@@ -585,6 +585,10 @@ class ExpressionCodegen(
SwitchGenerator(expression, data, this).generate()?.let { return it } SwitchGenerator(expression, data, this).generate()?.let { return it }
val endLabel = Label() val endLabel = Label()
val exhaustive = expression.branches.any { it.condition.isTrueConst() }
assert(exhaustive || expression.type.isUnit() || expression.type.isNothing()) {
"non-exhaustive conditional should return Unit: ${expression.dump()}"
}
for (branch in expression.branches) { for (branch in expression.branches) {
val elseLabel = Label() val elseLabel = Label()
if (branch.condition.isFalseConst() || branch.condition.isTrueConst()) { if (branch.condition.isFalseConst() || branch.condition.isTrueConst()) {
@@ -600,7 +604,9 @@ class ExpressionCodegen(
branch.condition.accept(this, data).coerceToBoolean().jumpIfFalse(elseLabel) branch.condition.accept(this, data).coerceToBoolean().jumpIfFalse(elseLabel)
} }
val result = branch.result.accept(this, data).coerce(expression.type).materialized val result = branch.result.accept(this, data).coerce(expression.type).materialized
if (branch.condition.isTrueConst()) { if (!exhaustive) {
result.discard()
} else if (branch.condition.isTrueConst()) {
// The rest of the expression is dead code. // The rest of the expression is dead code.
mv.mark(endLabel) mv.mark(endLabel)
return result return result
@@ -608,11 +614,8 @@ class ExpressionCodegen(
mv.goTo(endLabel) mv.goTo(endLabel)
mv.mark(elseLabel) mv.mark(elseLabel)
} }
// Produce the default value for the type. Doesn't really matter right now, as non-exhaustive
// conditionals cannot be used as expressions.
val result = defaultValue(expression.type).materialized
mv.mark(endLabel) mv.mark(endLabel)
return result return immaterialUnitValue
} }
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: BlockInfo): PromisedValue { override fun visitTypeOperator(expression: IrTypeOperatorCall, data: BlockInfo): PromisedValue {
@@ -18,6 +18,3 @@ inline fun inlineCall(predicate: (String?) -> Boolean): Boolean {
// 0 LINENUMBER 7 // 0 LINENUMBER 7
// 0 LINENUMBER 8 // 0 LINENUMBER 8
// 1 LINENUMBER 9 // 1 LINENUMBER 9
// Not actually inlined, so there is a LINENUMBER 7 because the if's body is not considered dead.
// IGNORE_BACKEND: JVM_IR