JVM_IR: discard results of nonexhaustive whens' branches
This commit is contained in:
+8
-5
@@ -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
|
|
||||||
|
|||||||
Reference in New Issue
Block a user