| // 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")); |
| } |