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


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!


More information about the compiler-dev mailing list