RFR; JDK-8214031: Assertion error in value break statement with conditional operator in switch expression
Jan Lahoda
jan.lahoda at oracle.com
Tue Nov 27 20:21:56 UTC 2018
Hi,
javac does not handle switch expressions that return booleans correctly.
According to the spec, javac should track definite [un]assignment when
true/false for switch expressions, but fails to do so. Moreover, for
more complex code, like:
int v = ...;
int x;
boolean b = switch (v) {
case 0: x = 12; break true;
case 1: x = 13; break true;
default: break false;
} && x == 12;
The current switch expression desugaring is not powerful enough to
generate valid bytecode for this input. The issue is that the current
desugaring will translate the switch expression into code like:
(
boolean $result;
switch (v) {
case 0: x = 12; $result = true; break;
case 1: x = 13; $result = true; break;
default: $result = false; break;
}
$result //"return" expression
) && x == 12
But by assigning the true/false result to a variable, we are loosing
track of which variables are assigned (when true/false) and which are
not. The bytecode needs to ensure the "x == 12" is jumped over when the
switch expression's value is false, and that, I believe, is not possible
when desugaring in Lower.
So, the proposed fix is to avoid desugaring in Lower, letting switch
expressions go to Gen and produce bytecode for them, including handling
them in Gen.genCond for true/false switch expressions. This is mostly
modelled after the conditional expression handling. Some generalizations
in Lower are required as well, to handle String and enum switch
expressions. Handling of definite assignment in Flow is fixed as well.
JBS: https://bugs.openjdk.java.net/browse/JDK-8214031
Webrev: http://cr.openjdk.java.net/~jlahoda/8214031/webrev.00/
Any feedback is welcome!
Thanks,
Jan
More information about the compiler-dev
mailing list