| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // This test broke dart2js. | 5 // This test broke dart2js. |
| 6 // A compiler must not construct a critical edge on this program. | 6 // A compiler must not construct a critical edge on this program. |
| 7 // |
| 8 // In particular we have to watch out for: |
| 9 // - the while-loop branch going to the body-block and to the exit-block, and |
| 10 // - the exit-block having as incoming the condition-block and the |
| 11 // break-blocks. |
| 12 // |
| 13 // Triggering the bug is relatively hard, since pushing instructions back the |
| 14 // exit-block to the incoming blocks is not guaranteed to trigger an error. |
| 15 // Dart2js frequently ended up with update-assignments just before the |
| 16 // condition: |
| 17 // for (int i = 0; state = state0, i < 10; i++) { |
| 18 // if (..) { state = 1; } |
| 19 // ... |
| 20 // } |
| 21 // use(state); |
| 22 // |
| 23 // In this case the "state" variable was assigned before the loop and then |
| 24 // reassigned before the break. The exit-block pushed the assignment back |
| 25 // to its incoming blocks and that's why the "state = state0" assignment ended |
| 26 // up just before the condition. |
| 27 // Note that the assignment was executed at every iteration instead of just |
| 28 // when exiting the loop. |
| 29 // This repeated assignments don't have any negative effect unless the state |
| 30 // variable is also assigned and used inside the loop-body. It turns out that |
| 31 // this is very rare and needs some tricks to make happen. |
| 7 | 32 |
| 8 import "package:expect/expect.dart"; | 33 import "package:expect/expect.dart"; |
| 9 | 34 |
| 10 String parse(String uri) { | 35 String parse(String uri) { |
| 11 int index = 0; | 36 int index = 0; |
| 12 int char = -1; | 37 int char = -1; |
| 13 | 38 |
| 14 void parseAuth() { | 39 void parseAuth() { |
| 15 index; | 40 index; |
| 16 char; | 41 char; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 32 if (state == 1) { | 57 if (state == 1) { |
| 33 print(char == 1234); | 58 print(char == 1234); |
| 34 print(index == uri.length); | 59 print(index == uri.length); |
| 35 } | 60 } |
| 36 return "bad"; | 61 return "bad"; |
| 37 } | 62 } |
| 38 | 63 |
| 39 main() { | 64 main() { |
| 40 Expect.equals("good", parse("dart:_foreign_helper")); | 65 Expect.equals("good", parse("dart:_foreign_helper")); |
| 41 } | 66 } |
| OLD | NEW |