|  | // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | // This test broke dart2js. | 
|  | // A compiler must not construct a critical edge on this program. | 
|  | // | 
|  | // In particular we have to watch out for: | 
|  | //  - the while-loop branch going to the body-block and to the exit-block, and | 
|  | //  - the exit-block having as incoming the condition-block and the | 
|  | //    break-blocks. | 
|  | // | 
|  | // Triggering the bug is relatively hard, since pushing instructions back the | 
|  | // exit-block to the incoming blocks is not guaranteed to trigger an error. | 
|  | // Dart2js frequently ended up with update-assignments just before the | 
|  | // condition: | 
|  | //    for (int i = 0; state = state0, i < 10; i++) { | 
|  | //      if (..) { state = 1; } | 
|  | //      ... | 
|  | //    } | 
|  | //    use(state); | 
|  | // | 
|  | // In this case the "state" variable was assigned before the loop and then | 
|  | // reassigned before the break. The exit-block pushed the assignment back | 
|  | // to its incoming blocks and that's why the "state = state0" assignment ended | 
|  | // up just before the condition. | 
|  | // Note that the assignment was executed at every iteration instead of just | 
|  | // when exiting the loop. | 
|  | // This repeated assignments don't have any negative effect unless the state | 
|  | // variable is also assigned and used inside the loop-body. It turns out that | 
|  | // this is very rare and needs some tricks to make happen. | 
|  |  | 
|  | import "package:expect/expect.dart"; | 
|  |  | 
|  | String parse(String uri) { | 
|  | int index = 0; | 
|  | int char = -1; | 
|  |  | 
|  | void parseAuth() { | 
|  | index; | 
|  | char; | 
|  | } | 
|  |  | 
|  | int state = 0; | 
|  | while (true) { | 
|  | char = uri.codeUnitAt(index); | 
|  | if (char == 1234) { | 
|  | state = (index == 0) ? 1 : 2; | 
|  | break; | 
|  | } | 
|  | if (char == 0x3A) { | 
|  | return "good"; | 
|  | } | 
|  | index++; | 
|  | } | 
|  |  | 
|  | if (state == 1) { | 
|  | print(char == 1234); | 
|  | print(index == uri.length); | 
|  | } | 
|  | return "bad"; | 
|  | } | 
|  |  | 
|  | main() { | 
|  | Expect.equals("good", parse("dart:_foreign_helper")); | 
|  | } |