diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-05-27 12:24:26 +0300 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-05-27 12:24:26 +0300 |
commit | 7ecd98bca6a4aa28de4e406bd27712007768647a (patch) | |
tree | 92af2288ddb3594a1502656a2800b710b121b047 | |
parent | ae6724527d2798b49e9c2cede536af48b3c9d962 (diff) | |
download | scala-7ecd98bca6a4aa28de4e406bd27712007768647a.tar.gz scala-7ecd98bca6a4aa28de4e406bd27712007768647a.tar.bz2 scala-7ecd98bca6a4aa28de4e406bd27712007768647a.zip |
SI-8625 fix unreachability analysis for boolean expressions
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 13 | ||||
-rw-r--r-- | test/files/pos/t8625.scala | 5 |
2 files changed, 15 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 0da66d43f7..0ad3c2c76b 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -1424,11 +1424,18 @@ abstract class GenICode extends SubComponent { def genZandOrZor(and: Boolean): Boolean = { val ctxInterm = ctx.newBlock() - val branchesReachable = if (and) genCond(lhs, ctx, ctxInterm, elseCtx) + val lhsBranchesReachable = if (and) genCond(lhs, ctx, ctxInterm, elseCtx) else genCond(lhs, ctx, thenCtx, ctxInterm) - ctxInterm.bb killUnless branchesReachable + // If lhs is known to throw, we can kill the just created ctxInterm. + ctxInterm.bb killUnless lhsBranchesReachable - genCond(rhs, ctxInterm, thenCtx, elseCtx) + val rhsBranchesReachable = genCond(rhs, ctxInterm, thenCtx, elseCtx) + + // Reachable means "it does not always throw", i.e. "it might not throw". + // In an expression (a && b) or (a || b), the b branch might not be evaluated. + // Such an expression is therefore known to throw only if both expressions throw. Or, + // successors are reachable if either of the two is reachable (SI-8625). + lhsBranchesReachable || rhsBranchesReachable } def genRefEq(isEq: Boolean) = { val f = genEqEqPrimitive(lhs, rhs, ctx) _ diff --git a/test/files/pos/t8625.scala b/test/files/pos/t8625.scala new file mode 100644 index 0000000000..95c4b0dbcd --- /dev/null +++ b/test/files/pos/t8625.scala @@ -0,0 +1,5 @@ +object Test { + def f1(a: Boolean, b: Boolean) = (a || ???) && (b || ???) + def f2(a: Boolean, b: Boolean) = (a || ???) && b + def f3(a: Boolean, b: Boolean) = (a && ???) || b +} |