Some test cases for switch expression

Brian Goetz brian.goetz at oracle.com
Mon Apr 16 17:43:18 UTC 2018


Here's another test, this time for fallthrough in expression switch.

class N5 {
     public void m(int x) {
         int y = switch (x) {
             case 0: // fallthrough OK
                 System.out.println("0");
             case 1: // fallthrough NOT OK -- error expected
                 System.out.println("1");
             case 2 -> 0;
             default -> 1;
         };
     }
}

The test compiles, though I'd like an error at the second fallthrough, 
enforcing the rule that you can fall through from a 
SwitchBlockStatementGroup into another SBSG, but not from a SBSG into a 
SwitchBlockClause, but not from a colon arm into an "arrow" arm.  (I 
don't blame the implementation, as the spec draft doesn't yet have 
language for this.)  This amounts to an assertion that an SBC must be 
unreachable from a preceding SBSG.








On 4/16/2018 1:14 PM, Brian Goetz wrote:
> I wrote up some simple (negative) test cases for switch expressions. 
> Found one bug and a few places where we might want to firm up the 
> error messages.
>
> // Negative test
> // sswitch, for-loop embedded in eswitch, where ss to break out of es
>
> class N1 {
>     int m(int x) {
>         return switch (x) {
>         case 0:
>             switch (x) {
>             case 0: break 1; // illegal
>             }
>             break 0;
>         default -> -1;
>         };
>     }
>
>     int n(int x) {
>         return switch (x) {
>         case 0:
>             for (int i=0; i<10; i++) {
>                 break 1; // illegal
>             }
>             break 0;
>         default -> -1;
>         };
>     }
> }
>
> This compiles fine, so this is a bug -- the break-e out of the 
> embedded switch and for-loop is illegal.
>
> // Negative test
> // Warn on ambiguity between label and variable in eswitch/sswitch break
>
> class N2 {
>     public int m(int x) {
>         int label = 0;
>
>         label:
>         do {
>             return switch (x) {
>             case 1: break label; // warning expected
>             };
>         } while (false);
>     }
>
>     public void n(int x) {
>         int label = 0;
>
>         label:
>         do {
>             int y = switch (x) {
>                 case 0:
>                     switch (x) {
>                         case 1: break label; // warning expected
>                     };
>                     break 0;
>                 case 1:
>                     break label; // warning expected
>             };
>         } while (false);
>     }
> }
>
> This gives the expected (3) warnings.
>
> // Negative test
> // sswitch in eswitch in loop, attempt to break through eswitch
> // equivalent with lambda, for comparison of diagnostics
>
> class N3 {
>     void m(int x) {
>         loop:
>         while (true) {
>             int y = switch (x) {
>             case 0:
>             switch (x) {
>             case 0: break loop;
>             }
>             };
>         }
>     }
>
>     void n(int x) {
>         loop:
>         while (true) {
>             Runnable r = () -> {
>                 switch (x) {
>                 case 0: break loop;
>                 }
>             };
>         }
>     }
> }
>
> This gives the expected (2) errors, but the messages are different:
>
> N3.java:12: error: break is jumping outside of the enclosing switch 
> expression
>             case 0: break loop;
>                     ^
> N3.java:23: error: undefined label: loop
>                 case 0: break loop;
>                         ^
> 2 errors
>
> // Negative test
> // eswitch embedded in sswitch, where es attempts to break out of ss
>
> class N4 {
>     void m(int x) {
>         sw:
>         switch (x) {
>         case 0:
>             int y = switch (x) {
>                 case 0: break;         // error
>                 case 1: break sw;      // error
>             };
>         }
>     }
>
>     // same with lambda
>     void m(int x) {
>         sw:
>         switch (x) {
>         case 0:
>             Runnable r1 = () -> { break; };
>             Runnable r2 = () -> { break sw; };
>         }
>     }
> }
>
> This gives the expected errors, though again the error messages are 
> not the same as with the corresponding lambdas, and the errors for the 
> lambda cases are also not entirely consistent with each other:
>
> N4.java:10: error: break is missing a value to return from switch 
> expression
>                 case 0: break;         // error
>                         ^
> N4.java:11: error: break is jumping outside of the enclosing switch 
> expression
>                 case 1: break sw;      // error
>                         ^
> N4.java:21: error: break outside switch or loop
>             Runnable r1 = () -> { break; };
>                                   ^
> N4.java:22: error: undefined label: sw
>             Runnable r2 = () -> { break sw; };
>                                   ^
>
>
>



More information about the amber-dev mailing list