Migrate language_2/exception to NNBD.
Change-Id: I0f758fce0af79be77b2fc885afcc3bd17d9fb55e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142701
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Leaf Petersen <leafp@google.com>
Auto-Submit: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
diff --git a/tests/language/exception/catch_liveness_test.dart b/tests/language/exception/catch_liveness_test.dart
new file mode 100644
index 0000000..df9a3dd
--- /dev/null
+++ b/tests/language/exception/catch_liveness_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, 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.
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+foo() => 1;
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+throwException() => throw 'x';
+
+main() {
+ var x = 10;
+ var e2 = null;
+ try {
+ var t = foo();
+ throwException();
+ print(t);
+ x = 3;
+ } catch (e) {
+ Expect.equals(10, x);
+ e2 = e;
+ }
+ Expect.equals(10, x);
+ Expect.equals('x', e2);
+}
diff --git a/tests/language/exception/code_after_try_is_executed_test.dart b/tests/language/exception/code_after_try_is_executed_test.dart
new file mode 100644
index 0000000..57ffd84
--- /dev/null
+++ b/tests/language/exception/code_after_try_is_executed_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2012, 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.
+// Test that the runtime still runs the code after a try/catch. The
+// test cannot use Expect.throws, because Expect.throws uses the same
+// pattern.
+
+import "package:expect/expect.dart";
+
+main() {
+ var exception;
+ try {
+ throw 'foo';
+ } on String catch (ex) {
+ exception = ex;
+ }
+ Expect.isTrue(exception is String);
+ throw 'foo'; //# 01: runtime error
+}
diff --git a/tests/language/exception/exception_test.dart b/tests/language/exception/exception_test.dart
new file mode 100644
index 0000000..86c2206
--- /dev/null
+++ b/tests/language/exception/exception_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2011, 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.
+
+import "package:expect/expect.dart";
+
+class ExceptionTest {
+ static testMain() {
+ int i = 0;
+ try {
+ throw "Hello";
+ } on String catch (s) {
+ print(s);
+ i += 10;
+ }
+
+ try {
+ throw "bye";
+ } on String catch (s) {
+ print(s);
+ i += 10;
+ }
+ Expect.equals(20, i);
+
+ bool correctCatch = false;
+ try {
+ // This throws NullThrownError
+ throw (null as dynamic);
+ } on String catch (s) {
+ correctCatch = false;
+ } on NullThrownError catch (e) {
+ correctCatch = true;
+ } catch (x) {
+ correctCatch = false;
+ }
+ Expect.isTrue(correctCatch);
+ }
+}
+
+main() {
+ ExceptionTest.testMain();
+}
diff --git a/tests/language/exception/finally10_test.dart b/tests/language/exception/finally10_test.dart
new file mode 100644
index 0000000..dfe47b5
--- /dev/null
+++ b/tests/language/exception/finally10_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a catch block that throws.
+
+import "package:expect/expect.dart";
+
+class A {
+ var field;
+ start() {}
+ stop() {
+ field = 42;
+ }
+}
+
+class B {
+ var totalCompileTime = new A();
+ var runCompiler = new Object();
+
+ run() {
+ totalCompileTime.start();
+ try {
+ throw 'foo';
+ } catch (exception) {
+ // Use [runCompiler] twice to ensure it will have a local
+ // variable.
+ runCompiler.toString();
+ runCompiler.toString();
+ rethrow;
+ } finally {
+ totalCompileTime.stop();
+ }
+ }
+}
+
+main() {
+ var b = new B();
+ try {
+ b.run();
+ throw 'Expected exception';
+ } catch (exception) {
+ // Expected exception.
+ }
+
+ Expect.equals(42, b.totalCompileTime.field);
+}
diff --git a/tests/language/exception/finally11_test.dart b/tests/language/exception/finally11_test.dart
new file mode 100644
index 0000000..dbe7288
--- /dev/null
+++ b/tests/language/exception/finally11_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a nested try block.
+
+import "package:expect/expect.dart";
+
+class A {
+ var field;
+ start() {}
+ stop() {
+ field = 42;
+ }
+}
+
+class B {
+ var totalCompileTime = new A();
+ var runCompiler = new Object();
+
+ run() {
+ totalCompileTime.start();
+ try {
+ throw 'foo';
+ } catch (exception) {
+ try {
+ // Use [runCompiler] twice to ensure it will have a local
+ // variable.
+ runCompiler.toString();
+ runCompiler.toString();
+ } catch (exception) {}
+ rethrow;
+ } finally {
+ totalCompileTime.stop();
+ }
+ }
+}
+
+main() {
+ var b = new B();
+ try {
+ b.run();
+ throw 'Expected exception';
+ } catch (exception) {
+ // Expected exception.
+ }
+
+ Expect.equals(42, b.totalCompileTime.field);
+}
diff --git a/tests/language/exception/finally12_test.dart b/tests/language/exception/finally12_test.dart
new file mode 100644
index 0000000..e4f56a0
--- /dev/null
+++ b/tests/language/exception/finally12_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a nested try block.
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo() {
+ var b = a == 8; // This should not be GVN'ed.
+ while (!b) {
+ try {
+ try {} finally {
+ a = 8;
+ break;
+ }
+ } finally {
+ return a == 8;
+ }
+ }
+}
+
+main() {
+ Expect.isTrue(foo());
+}
diff --git a/tests/language/exception/finally1_test.dart b/tests/language/exception/finally1_test.dart
new file mode 100644
index 0000000..0e8510a
--- /dev/null
+++ b/tests/language/exception/finally1_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1() {
+ try {
+ int j;
+ j = func();
+ i = 1;
+ return i; // Value of i on return is 1.
+ } finally {
+ i = i + 800; // Should get executed on return.
+ }
+ return i + 200; // Should not get executed.
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class ExecuteFinally1Test {
+ static testMain() {
+ Helper obj = new Helper();
+ Expect.equals(1, obj.f1());
+ Expect.equals(801, obj.i);
+ }
+}
+
+main() {
+ ExecuteFinally1Test.testMain();
+}
diff --git a/tests/language/exception/finally2_test.dart b/tests/language/exception/finally2_test.dart
new file mode 100644
index 0000000..fd64f69
--- /dev/null
+++ b/tests/language/exception/finally2_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1() {
+ try {
+ int j;
+ j = func();
+ try {
+ i = 1;
+ return i; // Value of i is 1 on return.
+ } finally {
+ i = i + 400; // Should get executed when we return.
+ }
+ i = 2; // Should not get executed.
+ return i;
+ } finally {
+ i = i + 800; // Should get executed when we return.
+ }
+ return i + 200; // Should not get executed.
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class ExecuteFinally2Test {
+ static testMain() {
+ Helper obj = new Helper();
+ Expect.equals(1, obj.f1());
+ Expect.equals(1201, obj.i);
+ }
+}
+
+main() {
+ ExecuteFinally2Test.testMain();
+}
diff --git a/tests/language/exception/finally3_test.dart b/tests/language/exception/finally3_test.dart
new file mode 100644
index 0000000..c36ba0f
--- /dev/null
+++ b/tests/language/exception/finally3_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1() {
+ try {
+ try {
+ int j;
+ j = func();
+ L1:
+ while (i <= 0) {
+ if (i == 0) {
+ try {
+ i = 1;
+ func();
+ try {
+ int j;
+ j = func();
+ while (j < 50) {
+ j += func();
+ if (j > 30) {
+ continue L1; // Break out of nested try blocks.
+ }
+ }
+ i = 200000; // Should not get executed.
+ } finally {
+ i = i + 200; // Should get executed when we break out.
+ }
+ } finally {
+ i = i + 400; // Should get executed when we break out.
+ }
+ }
+ }
+ } finally {
+ i = i + 800; // Should get executed as normal control flow.
+ }
+ return i; // Value of i should be 1401.
+ } finally {
+ i = i + 1600; // Should get executed as part of return above.
+ }
+ i = i + 2000000; // Should not get executed.
+ return 1;
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class ExecuteFinally3Test {
+ static testMain() {
+ Helper obj = new Helper();
+ Expect.equals(1401, obj.f1());
+ Expect.equals(3001, obj.i);
+ }
+}
+
+main() {
+ ExecuteFinally3Test.testMain();
+}
diff --git a/tests/language/exception/finally4_test.dart b/tests/language/exception/finally4_test.dart
new file mode 100644
index 0000000..fcc308c
--- /dev/null
+++ b/tests/language/exception/finally4_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1() {
+ try {
+ int j;
+ j = func();
+ i = 1;
+ } finally {
+ i = i + 10;
+ }
+ return i + 200; // Should return here with i = 211.
+ try {
+ int j;
+ j = func();
+ } finally {
+ i = i + 10; // Should not get executed as part of return above.
+ }
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class ExecuteFinally4Test {
+ static testMain() {
+ Helper obj = new Helper();
+ Expect.equals(211, obj.f1());
+ Expect.equals(11, obj.i);
+ }
+}
+
+main() {
+ ExecuteFinally4Test.testMain();
+}
diff --git a/tests/language/exception/finally5_test.dart b/tests/language/exception/finally5_test.dart
new file mode 100644
index 0000000..09cbdc15
--- /dev/null
+++ b/tests/language/exception/finally5_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1(int param) {
+ if (param == 0) {
+ try {
+ int j;
+ j = func();
+ try {
+ i = 1;
+ return i; // Value of i is 1 on return.
+ } finally {
+ i = i + 400; // Should get executed when we return.
+ }
+ i = 2; // Should not get executed.
+ return i;
+ } finally {
+ i = i + 800; // Should get executed when we return.
+ }
+ return i + 200; // Should not get executed.
+ }
+ try {
+ int j;
+ j = func();
+ try {
+ i = 4;
+ return i; // Value of i is 1 on return.
+ } finally {
+ i = i + 100; // Should get executed when we return.
+ }
+ i = 2; // Should not get executed.
+ return i;
+ } finally {
+ i = i + 200; // Should get executed when we return.
+ }
+ return i + 200; // Should not get executed.
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class ExecuteFinally5Test {
+ static testMain() {
+ Helper obj = new Helper();
+ Expect.equals(1, obj.f1(0));
+ Expect.equals(1201, obj.i);
+ Expect.equals(4, obj.f1(1));
+ Expect.equals(304, obj.i);
+ }
+}
+
+main() {
+ ExecuteFinally5Test.testMain();
+}
diff --git a/tests/language/exception/finally6_test.dart b/tests/language/exception/finally6_test.dart
new file mode 100644
index 0000000..e9c5ea5
--- /dev/null
+++ b/tests/language/exception/finally6_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1() {
+ try {
+ try {
+ int j;
+ j = func();
+ L1:
+ while (i <= 0) {
+ if (i == 0) {
+ try {
+ i = 1;
+ func();
+ try {
+ int j;
+ j = func();
+ L1:
+ while (j < 50) {
+ j += func();
+ if (j > 30) {
+ break L1; // Break out of nested try blocks.
+ }
+ }
+ i += 200000; // Should get executed.
+ } finally {
+ i = i + 200; // Should get executed as normal control flow.
+ }
+ } finally {
+ i = i + 400; // Should get executed as normal control flow.
+ }
+ }
+ }
+ } finally {
+ i = i + 800; // Should get executed as normal control flow.
+ }
+ return i; // Value of i should be 201401.
+ } finally {
+ i = i + 1600; // Should get executed as part of return above.
+ }
+ i = i + 2000000; // Should not get executed.
+ return 1;
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class ExecuteFinally6Test {
+ static testMain() {
+ Helper obj = new Helper();
+ Expect.equals(201401, obj.f1());
+ Expect.equals(203001, obj.i);
+ }
+}
+
+main() {
+ ExecuteFinally6Test.testMain();
+}
diff --git a/tests/language/exception/finally7_test.dart b/tests/language/exception/finally7_test.dart
new file mode 100644
index 0000000..afa6a67
--- /dev/null
+++ b/tests/language/exception/finally7_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing execution of finally blocks after an exception
+// is thrown from inside a local function capturing a variable.
+
+import "package:expect/expect.dart";
+
+class MyException {
+ const MyException(String message) : message_ = message;
+ final String message_;
+}
+
+class Helper {
+ static int f1(int k) {
+ var b;
+ try {
+ var a = new List<dynamic>.filled(10, null);
+ int i = 0;
+ while (i < 10) {
+ int j = i;
+ a[i] = () {
+ if (j == 5) {
+ throw new MyException("Test for exception being thrown");
+ }
+ k += 10;
+ return j;
+ };
+ if (i == 0) {
+ b = a[i];
+ }
+ i++;
+ }
+ for (int i = 0; i < 10; i++) {
+ a[i]();
+ }
+ } on MyException catch (exception) {
+ k += 100;
+ print(exception.message_);
+ b();
+ } finally {
+ k += 1000;
+ b();
+ }
+ return k;
+ }
+}
+
+class ExecuteFinally7Test {
+ static testMain() {
+ Expect.equals(1171, Helper.f1(1));
+ }
+}
+
+main() {
+ ExecuteFinally7Test.testMain();
+}
diff --git a/tests/language/exception/finally8_test.dart b/tests/language/exception/finally8_test.dart
new file mode 100644
index 0000000..c697eee
--- /dev/null
+++ b/tests/language/exception/finally8_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2011, 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 ensures that the finally block executes correctly when
+// there are throw, break and return statements in the finally block.
+
+import "package:expect/expect.dart";
+
+class Hello {
+ static var sum;
+
+ static foo() {
+ sum = 0;
+ try {
+ sum += 1;
+ return 'hi';
+ } finally {
+ sum += 1;
+ throw 'ball';
+ sum += 1;
+ }
+ }
+
+ static foo1() {
+ bool loop = true;
+ sum = 0;
+ L:
+ while (loop) {
+ try {
+ sum += 1;
+ return 'hi';
+ } finally {
+ sum += 1;
+ break L;
+ sum += 1;
+ }
+ }
+ }
+
+ static foo2() {
+ bool loop = true;
+ sum = 0;
+ try {
+ sum += 1;
+ return 'hi';
+ } finally {
+ sum += 1;
+ return 10;
+ sum += 1;
+ }
+ }
+
+ static foo3() {
+ sum = 0;
+ try {
+ sum += 1;
+ return 'hi';
+ } finally {
+ sum += 1;
+ return 10;
+ sum += 1;
+ }
+ }
+
+ static void main() {
+ foo1();
+ Expect.equals(2, sum);
+ foo2();
+ Expect.equals(2, sum);
+ foo3();
+ Expect.equals(2, sum);
+ try {
+ foo();
+ } catch (e) {}
+ Expect.equals(2, sum);
+ }
+}
+
+main() {
+ Hello.main();
+}
diff --git a/tests/language/exception/finally9_test.dart b/tests/language/exception/finally9_test.dart
new file mode 100644
index 0000000..5513466
--- /dev/null
+++ b/tests/language/exception/finally9_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2011, 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 ensures that the finally block executes correctly when
+// there are throw, break and return statements in the finally block.
+
+import "package:expect/expect.dart";
+
+class Hello {
+ static var sum;
+
+ static foo() {
+ sum = 0;
+ try {
+ sum += 1;
+ return 'hi';
+ } catch (e) {
+ sum += 1;
+ throw 'ball';
+ sum += 1;
+ } finally {
+ sum += 1;
+ throw 'ball';
+ sum += 1;
+ }
+ }
+
+ static foo1() {
+ bool loop = true;
+ sum = 0;
+ L:
+ while (loop) {
+ try {
+ sum += 1;
+ return 'hi';
+ } catch (ex) {
+ sum += 1;
+ } finally {
+ try {
+ L1:
+ while (loop) {
+ sum += 1;
+ break L;
+ sum += 1;
+ }
+ } catch (ex) {
+ sum += 1;
+ } finally {
+ sum += 1;
+ }
+ }
+ }
+ }
+
+ static void main() {
+ foo1();
+ Expect.equals(3, sum);
+ try {
+ foo();
+ } catch (e) {
+ // Ignore.
+ }
+ Expect.equals(2, sum);
+ }
+}
+
+main() {
+ Hello.main();
+}
diff --git a/tests/language/exception/finally_test.dart b/tests/language/exception/finally_test.dart
new file mode 100644
index 0000000..9277416
--- /dev/null
+++ b/tests/language/exception/finally_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2012, 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.
+
+import "package:expect/expect.dart";
+
+// Test for a bug in dart2js where the update of a field in a try
+// block would not be seen by the finally block. See dartbug.com/5517.
+
+class A {
+ int i;
+ A() : i = 42;
+
+ foo() {
+ bool executedFinally = false;
+ if (i == 42) {
+ try {
+ i = 12;
+ } finally {
+ Expect.equals(12, i);
+ executedFinally = true;
+ }
+ }
+ Expect.isTrue(executedFinally);
+ }
+}
+
+main() {
+ new A().foo();
+}
diff --git a/tests/language/exception/identity_test.dart b/tests/language/exception/identity_test.dart
new file mode 100644
index 0000000..2b16607
--- /dev/null
+++ b/tests/language/exception/identity_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2011, 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.
+
+import "package:expect/expect.dart";
+
+// Test that an object when thrown stays the same.
+
+class A {
+ A();
+}
+
+check(exception) {
+ try {
+ throw exception;
+ } catch (e) {
+ Expect.equals(exception, e);
+ }
+}
+
+main() {
+ check("str");
+ check(new A());
+ check(1);
+ check(1.2);
+}
diff --git a/tests/language/exception/in_increment_test.dart b/tests/language/exception/in_increment_test.dart
new file mode 100644
index 0000000..5e34a60
--- /dev/null
+++ b/tests/language/exception/in_increment_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, 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.
+// Test throws exception in the middle of the increment operation, the setter
+// part of the instance field increment never completes.
+// VMOptions=--optimization-counter-threshold=10
+
+main() {
+ var a = new A();
+ a.field = new A();
+ for (int i = 0; i < 20; i++) {
+ try {
+ a.foo(i);
+ } catch (e) {
+ // Ignore.
+ }
+ }
+}
+
+class A {
+ var field;
+ foo(i) {
+ field++; // throw exception
+ }
+}
diff --git a/tests/language/exception/on_catch_malformed_type_test.dart b/tests/language/exception/on_catch_malformed_type_test.dart
new file mode 100644
index 0000000..8b49027
--- /dev/null
+++ b/tests/language/exception/on_catch_malformed_type_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, 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.
+
+// Check that malformed types in on-catch are handled correctly, that is,
+// throws a type error in both production and checked mode.
+
+import 'package:expect/expect.dart';
+
+catchUnresolvedBefore() {
+ try {
+ throw "foo";
+ Expect.fail("This code shouldn't be executed");
+ } on String catch (oks) {
+ // This is tested before the catch block below.
+ } on Unavailable catch (ex) { /*@compile-error=unspecified*/
+ Expect.fail("This code shouldn't be executed");
+ }
+}
+
+catchUnresolvedAfter() {
+ Expect.throwsTypeError(() {
+ try {
+ throw "foo";
+ Expect.fail("This code shouldn't be executed");
+ } on Unavailable catch (ex) { /*@compile-error=unspecified*/
+ // This is tested before the catch block below.
+ // In both production and checked mode the test causes a type error.
+ } on String catch (oks) {
+ Expect.fail("This code shouldn't be executed");
+ }
+ });
+}
+
+main() {
+ catchUnresolvedBefore();
+ catchUnresolvedAfter();
+}
diff --git a/tests/language/exception/rethrow_test.dart b/tests/language/exception/rethrow_test.dart
new file mode 100644
index 0000000..0b0d3bc
--- /dev/null
+++ b/tests/language/exception/rethrow_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+ const MyException();
+}
+
+class OtherException {
+ const OtherException();
+}
+
+class RethrowTest {
+ late MyException currentException;
+
+ void throwException() {
+ currentException = new MyException();
+ throw currentException;
+ }
+
+ void testRethrowPastUncaught() {
+ try {
+ try {
+ try {
+ throwException();
+ Expect.fail("Should have thrown an exception");
+ } catch (e) {
+ Expect.equals(true, identical(e, currentException));
+ rethrow;
+ Expect.fail("Should have thrown an exception");
+ }
+ } on OtherException catch (e) {
+ Expect.fail("Should not have caught OtherException");
+ }
+ } catch (e) {
+ Expect.equals(true, identical(e, currentException));
+ }
+ }
+
+ void testRethrow() {
+ try {
+ try {
+ throwException();
+ Expect.fail("Should have thrown an exception");
+ } catch (e) {
+ Expect.equals(true, identical(e, currentException));
+ rethrow;
+ Expect.fail("Should have thrown an exception");
+ }
+ } catch (e) {
+ Expect.equals(true, identical(e, currentException));
+ }
+ }
+}
+
+main() {
+ RethrowTest t = new RethrowTest();
+ t.testRethrow();
+ t.testRethrowPastUncaught();
+}
diff --git a/tests/language/exception/throw1_test.dart b/tests/language/exception/throw1_test.dart
new file mode 100644
index 0000000..1ae121e
--- /dev/null
+++ b/tests/language/exception/throw1_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2012, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+ String getMessage();
+}
+
+class MyException implements TestException {
+ const MyException([String message = ""]) : message_ = message;
+ String getMessage() {
+ return message_;
+ }
+
+ final String message_;
+}
+
+class MyException2 implements TestException {
+ const MyException2([String message = ""]) : message_ = message;
+ String getMessage() {
+ return message_;
+ }
+
+ final String message_;
+}
+
+class MyException3 implements TestException {
+ const MyException3([String message = ""]) : message_ = message;
+ String getMessage() {
+ return message_;
+ }
+
+ final String message_;
+}
+
+class Helper {
+ static int f1(int i) {
+ try {
+ int j;
+ j = func();
+ if (j > 0) {
+ throw new MyException2("Test for exception being thrown");
+ }
+ } on MyException3 catch (exception) {
+ i = 100;
+ print(exception.getMessage());
+ } on TestException catch (exception) {
+ i = 50;
+ print(exception.getMessage());
+ } on MyException2 catch (exception) {
+ i = 150;
+ print(exception.getMessage());
+ } on MyException catch (exception) {
+ i = 200;
+ print(exception.getMessage());
+ } finally {
+ i = i + 800;
+ }
+ return i;
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+}
+
+class Throw1Test {
+ static testMain() {
+ Expect.equals(850, Helper.f1(1));
+ }
+}
+
+main() {
+ Throw1Test.testMain();
+}
diff --git a/tests/language/exception/throw2_test.dart b/tests/language/exception/throw2_test.dart
new file mode 100644
index 0000000..eaade24
--- /dev/null
+++ b/tests/language/exception/throw2_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2012, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+ String getMessage();
+}
+
+class MyException implements TestException {
+ const MyException([String message = ""]) : message_ = message;
+ String getMessage() {
+ return message_;
+ }
+
+ final String message_;
+}
+
+class MyException2 implements TestException {
+ const MyException2([String message = ""]) : message_ = message;
+ String getMessage() {
+ return message_;
+ }
+
+ final String message_;
+}
+
+class MyException3 implements TestException {
+ const MyException3([String message = ""]) : message_ = message;
+ String getMessage() {
+ return message_;
+ }
+
+ final String message_;
+}
+
+class Helper {
+ static int f1(int i) {
+ try {
+ int j;
+ j = func();
+ } on MyException3 catch (exception) {
+ i = 100;
+ print(exception.getMessage());
+ } on MyException2 catch (exception) {
+ try {
+ i = func2();
+ i = 200;
+ } on TestException catch (exception) {
+ i = 50;
+ }
+ print(exception.getMessage());
+ } on MyException catch (exception) {
+ i = func2();
+ print(exception.getMessage());
+ } finally {
+ i = i + 800;
+ }
+ return i;
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ if (i > 0) {
+ throw new MyException2("Test for exception being thrown");
+ }
+ return i;
+ }
+
+ static int func2() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ if (i > 0) {
+ throw new MyException2("Test for exception being thrown");
+ }
+ return i;
+ }
+}
+
+class Throw2Test {
+ static testMain() {
+ Expect.equals(850, Helper.f1(1));
+ }
+}
+
+main() {
+ Throw2Test.testMain();
+}
diff --git a/tests/language/exception/throw3_test.dart b/tests/language/exception/throw3_test.dart
new file mode 100644
index 0000000..1d72345
--- /dev/null
+++ b/tests/language/exception/throw3_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+ const MyException([String message = ""]) : message_ = message;
+ final String message_;
+}
+
+class Helper {
+ static int f1(int i) {
+ try {
+ int j;
+ i = 100;
+ i = func();
+ i = 200;
+ } on MyException catch (exception) {
+ i = 50;
+ print(exception.message_);
+ } finally {
+ i = i + 800;
+ }
+ return i;
+ }
+
+ static int func() {
+ try {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ if (i > 0) {
+ throw new MyException("Test for exception being thrown");
+ }
+ } on MyException catch (ex) {
+ print(ex.message_);
+ rethrow; // Rethrow the exception.
+ }
+ return 10;
+ }
+}
+
+class Throw3Test {
+ static testMain() {
+ Expect.equals(850, Helper.f1(1));
+ }
+}
+
+main() {
+ Throw3Test.testMain();
+}
diff --git a/tests/language/exception/throw4_test.dart b/tests/language/exception/throw4_test.dart
new file mode 100644
index 0000000..6dd2f74
--- /dev/null
+++ b/tests/language/exception/throw4_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+ const MyException1([String message = "1"]) : message_ = message;
+ final String message_;
+}
+
+class MyException2 {
+ const MyException2([String message = "2"]) : message_ = message;
+ final String message_;
+}
+
+class MyException3 {
+ const MyException3([String message = "3"]) : message_ = message;
+ final String message_;
+}
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1() {
+ int j = 0;
+ try {
+ j = func();
+ } on MyException3 catch (exception) {
+ i = i + 300;
+ print(exception.message_);
+ } on MyException2 catch (exception) {
+ i = i + 200;
+ print(exception.message_);
+ } on MyException1 catch (exception) {
+ i = i + 100;
+ print(exception.message_);
+ } finally {
+ i = i + 1000;
+ }
+ return i;
+ }
+
+ // No catch in the same function for the type of exception being thrown
+ // in the try block here. We expect the handler if checks to fall thru,
+ // the finally block to run and an implicit rethrow to happen.
+ int func() {
+ i = 0;
+ try {
+ while (i < 10) {
+ i++;
+ }
+ if (i > 0) {
+ throw new MyException1("Test for MyException1 being thrown");
+ }
+ } on MyException3 catch (exception) {
+ i = 300;
+ print(exception.message_);
+ } on MyException2 catch (exception) {
+ i = 200;
+ print(exception.message_);
+ } finally {
+ i = 800;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class Throw4Test {
+ static testMain() {
+ Expect.equals(1900, new Helper().f1());
+ }
+}
+
+main() {
+ Throw4Test.testMain();
+}
diff --git a/tests/language/exception/throw5_test.dart b/tests/language/exception/throw5_test.dart
new file mode 100644
index 0000000..349ade7
--- /dev/null
+++ b/tests/language/exception/throw5_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+ const MyException1([String message = "1"]) : message_ = message;
+ final String message_;
+}
+
+class MyException2 {
+ const MyException2([String message = "2"]) : message_ = message;
+ final String message_;
+}
+
+class MyException3 {
+ const MyException3([String message = "3"]) : message_ = message;
+ final String message_;
+}
+
+class Helper {
+ static int f1(int i) {
+ try {
+ int j;
+ j = func();
+ } on MyException3 catch (exception) {
+ i = 300;
+ print(exception.message_);
+ } on MyException2 catch (exception) {
+ i = 200;
+ print(exception.message_);
+ } on MyException1 catch (exception) {
+ i = 100;
+ print(exception.message_);
+ } finally {
+ i = i + 800;
+ }
+ return i;
+ }
+
+ // No catch in the same function for the type of exception being thrown
+ // in the try block here. We expect the handler if checks to fall thru and
+ // implicit rethrow to happen.
+ static int func() {
+ int i = 0;
+ try {
+ while (i < 10) {
+ i++;
+ }
+ if (i > 0) {
+ throw new MyException1("Test for MyException1 being thrown");
+ }
+ } on MyException3 catch (exception) {
+ i = 300;
+ print(exception.message_);
+ } on MyException2 catch (exception) {
+ i = 200;
+ print(exception.message_);
+ }
+ return i;
+ }
+}
+
+class Throw5Test {
+ static testMain() {
+ Expect.equals(900, Helper.f1(1));
+ }
+}
+
+main() {
+ Throw5Test.testMain();
+}
diff --git a/tests/language/exception/throw6_test.dart b/tests/language/exception/throw6_test.dart
new file mode 100644
index 0000000..1433467
--- /dev/null
+++ b/tests/language/exception/throw6_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+ const MyException1([String message = "1"]) : message_ = message;
+ final String message_;
+}
+
+class Helper {
+ Helper() : i = 0 {}
+
+ int f1() {
+ int j = 0;
+ try {
+ j = func();
+ } catch (exception) {
+ i = i + 100;
+ print(exception.message_);
+ } finally {
+ i = i + 1000;
+ }
+ return i;
+ }
+
+ // No catch in the same function for the type of exception being thrown
+ // in the try block here. We expect the handler if checks to fall thru,
+ // the finally block to run and an implicit rethrow to happen.
+ int func() {
+ i = 0;
+ try {
+ while (i < 10) {
+ i++;
+ }
+ if (i > 0) {
+ throw new MyException1("Test for MyException1 being thrown");
+ }
+ } finally {
+ i = 800;
+ }
+ return i;
+ }
+
+ int i;
+}
+
+class Throw6Test {
+ static testMain() {
+ Expect.equals(1900, new Helper().f1());
+ }
+}
+
+main() {
+ Throw6Test.testMain();
+}
diff --git a/tests/language/exception/throw8_test.dart b/tests/language/exception/throw8_test.dart
new file mode 100644
index 0000000..de84012
--- /dev/null
+++ b/tests/language/exception/throw8_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+var finallyExecutionCount = 0;
+bar() {
+ try {
+ try {
+ return 499;
+ } catch (e, st) {
+ rethrow;
+ }
+ } finally {
+ finallyExecutionCount++;
+ throw "quit finally with throw";
+ }
+}
+
+main() {
+ bool hasThrown = false;
+ try {
+ bar();
+ } catch (x) {
+ hasThrown = true;
+ Expect.equals(1, finallyExecutionCount);
+ }
+ Expect.isTrue(hasThrown);
+}
diff --git a/tests/language/exception/throw_expr_test.dart b/tests/language/exception/throw_expr_test.dart
new file mode 100644
index 0000000..c1f5044
--- /dev/null
+++ b/tests/language/exception/throw_expr_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2012, 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.
+
+import "package:expect/expect.dart";
+
+// Dart test program for testing throw expressions.
+
+void test1() {
+ var x = 6;
+ try {
+ throw x = 10;
+ x = 0;
+ } catch (e) {
+ Expect.equals(10, e);
+ Expect.equals(10, x);
+ x = 15;
+ }
+ Expect.equals(15, x);
+ x = 100;
+ try {
+ throw x++;
+ x = 0;
+ } catch (e) {
+ Expect.equals(100, e);
+ Expect.equals(101, x);
+ x = 150;
+ }
+ Expect.equals(150, x);
+}
+
+void test2() {
+ var x = 6;
+ try {
+ throw x + 4;
+ } catch (e) {
+ Expect.equals(10, e);
+ Expect.equals(6, x);
+ x = 15;
+ }
+ Expect.equals(15, x);
+}
+
+foo(x, y) => throw "foo" "$x";
+
+bar(x, y) => throw "foo" "${throw x}";
+
+class Q {
+ var qqq;
+ f(x) {
+ qqq = x;
+ }
+
+ Q get nono => throw "nono";
+}
+
+void test3() {
+ try {
+ throw throw throw "up";
+ } catch (e) {
+ Expect.equals("up", e);
+ }
+
+ dynamic x = 10;
+ try {
+ foo(x = 12, throw 7);
+ } catch (e) {
+ Expect.equals(7, e);
+ Expect.equals(12, x);
+ }
+
+ x = 10;
+ try {
+ foo(x++, 10);
+ } catch (e) {
+ Expect.equals("foo10", e);
+ Expect.equals(11, x);
+ }
+
+ x = 100;
+ try {
+ bar(++x, 10);
+ } catch (e) {
+ Expect.equals(101, e);
+ Expect.equals(101, x);
+ }
+
+ x = null;
+ try {
+ x = new Q();
+ x
+ ..f(11)
+ ..qqq = throw 77
+ ..f(22);
+ } catch (e) {
+ Expect.equals(77, e);
+ Expect.equals(11, x.qqq);
+ }
+}
+
+void test4() {
+ var q = new Q();
+ Expect.throws(() => q.nono, (e) => e == "nono");
+}
+
+main() {
+ test1();
+ test2();
+ test3();
+ test4();
+}
diff --git a/tests/language/exception/throw_test.dart b/tests/language/exception/throw_test.dart
new file mode 100644
index 0000000..0c864cc
--- /dev/null
+++ b/tests/language/exception/throw_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2011, 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.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+ const MyException(String this.message_);
+ final String message_;
+}
+
+class Helper {
+ static int f1(int i) {
+ try {
+ int j;
+ j = func();
+ if (j > 0) {
+ throw new MyException("Test for exception being thrown");
+ }
+ } on MyException catch (exception) {
+ i = 100;
+ print(exception.message_);
+ } finally {
+ i = i + 800;
+ }
+ return i;
+ }
+
+ static int func() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+}
+
+class ThrowTest {
+ static testMain() {
+ Expect.equals(900, Helper.f1(1));
+ }
+}
+
+main() {
+ ThrowTest.testMain();
+}
diff --git a/tests/language/exception/try_catch2_test.dart b/tests/language/exception/try_catch2_test.dart
new file mode 100644
index 0000000..8da606c
--- /dev/null
+++ b/tests/language/exception/try_catch2_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2012, 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.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown. (Nested try/catch blocks).
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+ String getMessage();
+}
+
+class MyException implements TestException {
+ const MyException([String message = ""]) : message_ = message;
+ String getMessage() {
+ return message_;
+ }
+
+ final String message_;
+}
+
+class StackTrace {
+ StackTrace() {}
+}
+
+class Helper {
+ static int f1(int i) {
+ try {
+ int j;
+ j = f2();
+ i = i + 1;
+ try {
+ j = f2() + f3() + j;
+ i = i + 1;
+ } on TestException catch (e, trace) {
+ j = 50;
+ }
+ j = f3() + j;
+ } on MyException catch (exception) {
+ i = 100;
+ } on TestException catch (e, trace) {
+ i = 200;
+ }
+ return i;
+ }
+
+ static int f2() {
+ return 2;
+ }
+
+ static int f3() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+}
+
+class TryCatch2Test {
+ static testMain() {
+ Expect.equals(3, Helper.f1(1));
+ }
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ TryCatch2Test.testMain();
+ }
+}
diff --git a/tests/language/exception/try_catch3_test.dart b/tests/language/exception/try_catch3_test.dart
new file mode 100644
index 0000000..6cff3f8
--- /dev/null
+++ b/tests/language/exception/try_catch3_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2012, 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.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+ String getMessage();
+}
+
+class MyException implements TestException {
+ const MyException([String message = ""]) : this._message = message;
+ String getMessage() {
+ return _message;
+ }
+
+ final String _message;
+}
+
+class MyParameterizedException<U, V> implements TestException {
+ const MyParameterizedException([String message = ""])
+ : this._message = message;
+ String getMessage() {
+ return _message;
+ }
+
+ final String _message;
+}
+
+class StackTrace {
+ StackTrace() {}
+ printStackTrace(TestException ex) {
+ print(ex);
+ }
+}
+
+class Helper {
+ static int test1(int i) {
+ try {
+ int j;
+ j = f2();
+ j = f3();
+ try {
+ int k = f2();
+ f3();
+ } on MyException catch (ex) {
+ int i = 10;
+ print(i);
+ } on TestException catch (ex) {
+ int k = 10;
+ print(k);
+ }
+ try {
+ j = j + 24;
+ } catch (e) {
+ i = 300;
+ print(e.getMessage());
+ }
+ try {
+ j += 20;
+ } catch (e) {
+ i = 400;
+ print(e.getMessage());
+ }
+ try {
+ j += 40;
+ } catch (e) {
+ i = 600;
+ print(e.getMessage());
+ }
+ try {
+ j += 60;
+ } catch (e, trace) {
+ i = 700;
+ print(trace.toString());
+ print(e.getMessage());
+ }
+ try {
+ j += 80;
+ } on MyException catch (e) {
+ i = 500;
+ print(e.getMessage());
+ }
+ } on MyParameterizedException<String, TestException> catch (e, trace) {
+ i = 800;
+ print(trace.toString());
+ rethrow;
+ } on MyException catch (exception) {
+ i = 100;
+ print(exception.getMessage());
+ } on TestException catch (e, trace) {
+ i = 200;
+ print(trace.toString());
+ } finally {
+ i = 900;
+ }
+ return i;
+ }
+
+ static int f2() {
+ return 2;
+ }
+
+ static int f3() {
+ int i = 0;
+ while (i < 10) {
+ i++;
+ }
+ return i;
+ }
+}
+
+class TryCatchTest {
+ static testMain() {
+ Expect.equals(900, Helper.test1(1));
+ }
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ TryCatchTest.testMain();
+ }
+}
diff --git a/tests/language/exception/try_catch4_test.dart b/tests/language/exception/try_catch4_test.dart
new file mode 100644
index 0000000..a6cbe03
--- /dev/null
+++ b/tests/language/exception/try_catch4_test.dart
@@ -0,0 +1,206 @@
+// Copyright (c) 2012, 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.
+// Check that our SSA graph does have the try body a predecessor of a
+// try/finally.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo1() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ a = 8;
+ return false;
+ } finally {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+doThrow() {
+ throw 2;
+}
+
+foo2() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ a = 8;
+ doThrow();
+ return false;
+ } catch (e) {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+foo3() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ doThrow();
+ } catch (e) {
+ a = 8;
+ entered = true;
+ return false;
+ } finally {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+foo4() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ a = 8;
+ break;
+ } finally {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+foo5() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ a = 8;
+ doThrow();
+ break;
+ } catch (e) {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+foo6() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ doThrow();
+ } catch (e) {
+ a = 8;
+ entered = true;
+ break;
+ } finally {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+foo7() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ a = 8;
+ continue;
+ } finally {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+foo8() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ a = 8;
+ doThrow();
+ continue;
+ } catch (e) {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+foo9() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ doThrow();
+ } catch (e) {
+ a = 8;
+ entered = true;
+ continue;
+ } finally {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ }
+}
+
+main_test() {
+ a = 0;
+ Expect.isTrue(foo1());
+ a = 0;
+ Expect.isTrue(foo2());
+ a = 0;
+ Expect.isTrue(foo3());
+ a = 0;
+ Expect.isTrue(foo4());
+ a = 0;
+ Expect.isTrue(foo5());
+ a = 0;
+ Expect.isTrue(foo6());
+ a = 0;
+ Expect.isTrue(foo7());
+ a = 0;
+ Expect.isTrue(foo8());
+ a = 0;
+ Expect.isTrue(foo9());
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ main_test();
+ }
+}
diff --git a/tests/language/exception/try_catch5_test.dart b/tests/language/exception/try_catch5_test.dart
new file mode 100644
index 0000000..6920b06
--- /dev/null
+++ b/tests/language/exception/try_catch5_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, 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.
+// Check that our SSA graph does have the try body a predecessor of a
+// try/finally.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo1() {
+ var b = false;
+ var entered = false;
+ while (true) {
+ if (entered) return b;
+ b = 8 == a; // This expression should not be GVN'ed.
+ try {
+ try {
+ a = 8;
+ return false;
+ } finally {
+ b = 8 == a;
+ entered = true;
+ continue;
+ }
+ } finally {
+ continue;
+ }
+ }
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ a = 0;
+ Expect.isTrue(foo1());
+ }
+}
diff --git a/tests/language/exception/try_catch_on_syntax_test.dart b/tests/language/exception/try_catch_on_syntax_test.dart
new file mode 100644
index 0000000..c19a94f
--- /dev/null
+++ b/tests/language/exception/try_catch_on_syntax_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2011, 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.
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+void test1() {
+ var foo = 0;
+ try {
+ throw new MyException1();
+ }
+ on on MyException2 catch (e) { } //# 02: syntax error
+ catch MyException2 catch (e) { } //# 03: syntax error
+ catch catch catch (e) { } //# 04: syntax error
+ on (e) { } //# 05: syntax error
+ catch MyException2 catch (e) { } //# 06: syntax error
+ on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ } on MyException catch (e) {
+ foo = 3;
+ }
+ on UndefinedClass //# 07: compile-time error
+ catch (e) {
+ foo = 4;
+ }
+ Expect.equals(2, foo);
+}
+
+testFinal() {
+ try {
+ throw "catch this!";
+ } catch (e, s) {
+ // Test that the error and stack trace variables are final.
+ e = null; // //# 10: compile-time error
+ s = null; // //# 11: compile-time error
+ }
+}
+
+main() {
+ test1();
+ testFinal();
+}
diff --git a/tests/language/exception/try_catch_optimized1_test.dart b/tests/language/exception/try_catch_optimized1_test.dart
new file mode 100644
index 0000000..c3b522a
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized1_test.dart
@@ -0,0 +1,290 @@
+// Copyright (c) 2013, 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+maythrow(x) {
+ if (x == null) throw 42;
+ return 99;
+}
+
+f1(x) {
+ var result = 123;
+ try {
+ result = maythrow(x);
+ if (result > 100) throw 42;
+ } catch (e) {
+ Expect.equals(result, 123);
+ Expect.equals(42, e);
+ result = 0;
+ }
+ return result;
+}
+
+class A {
+ maythrow(x) {
+ if (x == null) throw 42;
+ return 99;
+ }
+}
+
+f2(x) {
+ dynamic result = 123;
+ var a = new A();
+ try {
+ result++;
+ result = a.maythrow(x);
+ } catch (e) {
+ Expect.equals(124, result);
+ result = x;
+ }
+ return result;
+}
+
+f3(x, y) {
+ var result = 123;
+ var a = new A();
+ try {
+ result++;
+ result = a.maythrow(x);
+ } catch (e) {
+ result = y + 1; // Deopt on overflow
+ }
+ return result;
+}
+
+f4(x) {
+ try {
+ maythrow(x);
+ } catch (e) {
+ check_f4(e, "abc");
+ }
+}
+
+check_f4(e, s) {
+ if (e != 42) throw "ERROR";
+ if (s != "abc") throw "ERROR";
+}
+
+f5(x) {
+ try {
+ maythrow(x);
+ } catch (e) {
+ check_f5(e, "abc");
+ }
+
+ try {
+ maythrow(x);
+ } catch (e) {
+ check_f5(e, "abc");
+ }
+}
+
+check_f5(e, s) {
+ if (e != 42) throw "ERROR";
+ if (s != "abc") throw "ERROR";
+}
+
+f6(x, y) {
+ var a = x;
+ var b = y;
+ var c = 123;
+ check_f6(42, null, 1, 123, null, 1);
+ try {
+ maythrow(x);
+ } catch (e) {
+ check_f6(e, a, b, c, x, y);
+ }
+}
+
+check_f6(e, a, b, c, x, y) {
+ if (e != 42) throw "ERROR";
+ if (a != null) throw "ERROR";
+ if (b != 1) throw "ERROR";
+ if (c != 123) throw "ERROR";
+ if (x != null) throw "ERROR";
+ if (y != 1) throw "ERROR";
+}
+
+bool f7(String str) {
+ double d = double.parse(str);
+ var t = d;
+ try {
+ var a = d.toInt();
+ return false;
+ } on UnsupportedError catch (e) {
+ Expect.equals(true, identical(t, d));
+ return true;
+ }
+}
+
+f8(x, [a = 3, b = 4]) {
+ var c = 123;
+ var y = a;
+ try {
+ maythrow(x);
+ } catch (e, s) {
+ check_f8(e, s, a, b, c, x, y);
+ }
+}
+
+check_f8(e, s, a, b, c, x, y) {
+ if (e != 42) throw "ERROR";
+ if (s is! StackTrace) throw "ERROR";
+ if (a != 3) {
+ print(a);
+ throw "ERROR";
+ }
+ if (b != 4) throw "ERROR";
+ if (c != 123) throw "ERROR";
+ if (x != null) throw "ERROR";
+ if (y != a) throw "ERROR";
+}
+
+f9(x, [a = 3, b = 4]) {
+ var c = 123;
+ var y = a;
+ try {
+ if (x < a) maythrow(null);
+ maythrow(x);
+ } catch (e, s) {
+ check_f9(e, s, a, b, c, x, y);
+ }
+}
+
+check_f9(e, s, a, b, c, x, y) {
+ if (e != 42) throw "ERROR";
+ if (s is! StackTrace) throw "ERROR";
+ if (a != 3) {
+ print(a);
+ throw "ERROR";
+ }
+ if (b != 4) throw "ERROR";
+ if (c != 123) throw "ERROR";
+ if (x != null) throw "ERROR";
+ if (y != a) throw "ERROR";
+}
+
+f10(x, y) {
+ var result = 123;
+ try {
+ result = maythrow(x);
+ } catch (e) {
+ Expect.equals(123, result);
+ Expect.equals(0.5, y / 2.0);
+ result = 0;
+ }
+ return result;
+}
+
+f11(x) {
+ var result = 123;
+ var tmp = x;
+ try {
+ result = maythrow(x);
+ if (result > 100) throw 42;
+ } catch (e, s) {
+ Expect.equals(123, result);
+ Expect.equals(true, identical(tmp, x));
+ Expect.equals(true, s is StackTrace);
+ result = 0;
+ }
+ return result;
+}
+
+f12([x = null]) {
+ try {
+ maythrow(x);
+ } catch (e) {
+ check_f12(e, x);
+ }
+}
+
+check_f12(e, x) {
+ if (e != 42) throw "ERROR";
+ if (x != null) throw "ERROR";
+}
+
+f13(x) {
+ var result = 123;
+ try {
+ try {
+ result = maythrow(x);
+ if (result > 100) throw 42;
+ } catch (e) {
+ Expect.equals(123, result);
+ result = 0;
+ }
+ maythrow(x);
+ } catch (e) {
+ result++;
+ }
+ return result;
+}
+
+main() {
+ for (var i = 0; i < 20; i++) f1("abc");
+ Expect.equals(99, f1("abc"));
+ Expect.equals(0, f1(null));
+
+ for (var i = 0; i < 20; i++) f2("abc");
+ Expect.equals(99, f2("abc"));
+ Expect.equals(null, f2(null));
+
+ f3("123", 0);
+ for (var i = 0; i < 20; i++) f3(null, 0);
+ Expect.equals(99, f3("123", 0));
+ Expect.equals(0x40000000, f3(null, 0x3fffffff));
+
+ f4(null);
+ for (var i = 0; i < 20; i++) f4(123);
+ f4(null);
+
+ f5(null);
+ for (var i = 0; i < 20; i++) f5(123);
+ f5(null);
+
+ f6(null, 1);
+ for (var i = 0; i < 20; i++) f6(123, 1);
+ f6(null, 1);
+
+ f7("1.2");
+ f7("Infinity");
+ f7("-Infinity");
+ for (var i = 0; i < 20; i++) f7("1.2");
+ Expect.equals(false, f7("1.2"));
+ Expect.equals(true, f7("Infinity"));
+ Expect.equals(true, f7("-Infinity"));
+ Expect.equals(false, f7("123456789012345")); // Deopt.
+ for (var i = 0; i < 20; i++) f7("123456789012345");
+ Expect.equals(true, f7("Infinity"));
+ Expect.equals(true, f7("-Infinity"));
+
+ for (var i = 0; i < 20; i++) f8(null);
+ f8(null);
+
+ f9(5);
+ f9(5.0);
+ for (var i = 0; i < 20; i++) f9(3);
+ f9(3);
+
+ var y = 1.0;
+ Expect.equals(0, f10(null, y));
+ for (var i = 0; i < 20; i++) f10("abc", y);
+ Expect.equals(99, f10("abc", y));
+ Expect.equals(0, f10(null, y));
+
+ for (var i = 0; i < 20; i++) f11("abc");
+ Expect.equals(99, f11("abc"));
+ Expect.equals(0, f11(null));
+
+ for (var i = 0; i < 20; i++) f12(null);
+ f12(null);
+
+ f13(null);
+ for (var i = 0; i < 20; i++) f13("abc");
+ Expect.equals(99, f13("abc"));
+ Expect.equals(1, f13(null));
+}
diff --git a/tests/language/exception/try_catch_optimized2_test.dart b/tests/language/exception/try_catch_optimized2_test.dart
new file mode 100644
index 0000000..159a6e5
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized2_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test allocation sinking with optimized try-catch.
+
+bar() {
+ // Should not be inlined.
+ try {} finally {}
+}
+
+foo(List<int> a) {
+ var r = 0;
+ for (var i in a) {
+ r += i;
+ }
+ try {
+ bar();
+ } finally {}
+ return r;
+}
+
+main() {
+ var a = [1, 2, 3];
+ for (var i = 0; i < 20; i++) foo(a);
+ Expect.equals(6, foo(a));
+}
diff --git a/tests/language/exception/try_catch_optimized3_test.dart b/tests/language/exception/try_catch_optimized3_test.dart
new file mode 100644
index 0000000..a2b03fc
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized3_test.dart
@@ -0,0 +1,28 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test unboxed double operations inside try-catch.
+foo(bool b) {
+ if (b) throw 123;
+}
+
+test_double(double x, bool b) {
+ try {
+ x += 1.0;
+ foo(b);
+ } catch (e) {
+ var result = x - 1.0;
+ Expect.equals(1.0, result);
+ return result;
+ }
+}
+
+main() {
+ for (var i = 0; i < 100; i++) test_double(1.0, false);
+ test_double(1.0, false);
+ Expect.equals(1.0, test_double(1.0, true));
+}
diff --git a/tests/language/exception/try_catch_optimized4_test.dart b/tests/language/exception/try_catch_optimized4_test.dart
new file mode 100644
index 0000000..dc98f31
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized4_test.dart
@@ -0,0 +1,40 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test correct dead phi elimination with try catch.
+
+List<Object> a = [1, 2, 3, 4, 5];
+
+class MyError {}
+
+class M {
+ maythrow(i) {
+ try {
+ if (i <= 5) throw new MyError();
+ } catch (e) {
+ throw e;
+ }
+ }
+}
+
+loop_test() {
+ bool failed = false;
+ M m = new M();
+ for (Object i in a) {
+ try {
+ String res = m.maythrow(i);
+ failed = true;
+ } on MyError catch (e) {}
+ if (!identical(failed, false)) {
+ Expect.fail("");
+ }
+ }
+}
+
+main() {
+ for (var i = 0; i < 20; i++) loop_test();
+}
diff --git a/tests/language/exception/try_catch_optimized5_test.dart b/tests/language/exception/try_catch_optimized5_test.dart
new file mode 100644
index 0000000..a3b7b99
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized5_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2016, 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.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
+
+// Test optional parameters updated inside try-catch
+
+import "package:expect/expect.dart";
+
+@pragma('vm:never-inline')
+m1(int b) {
+ if (b == 1) throw 123;
+}
+
+@pragma('vm:never-inline')
+m2(int b) {
+ if (b == 2) throw 456;
+}
+
+@pragma('vm:never-inline')
+test1(int b, [int state = 0]) {
+ try {
+ state++;
+ m1(b);
+ state++;
+ m2(b);
+ state++;
+ } catch (e, s) {
+ if (b == 1 && state != 1) throw "fail1";
+ if (b == 2 && state != 2) throw "fail2";
+ if (b == 3 && state != 3) throw "fail3";
+ if (s is! StackTrace) throw "fail4";
+ return e;
+ }
+ return "no throw";
+}
+
+@pragma('vm:never-inline')
+test2(int b, [int state = -1]) {
+ state = 0;
+ try {
+ state++;
+ m1(b);
+ state++;
+ m2(b);
+ state++;
+ } catch (e, s) {
+ if (b == 1 && state != 1) throw "fail1";
+ if (b == 2 && state != 2) throw "fail2";
+ if (b == 3 && state != 3) throw "fail3";
+ if (s is! StackTrace) throw "fail4";
+ return e;
+ }
+ return "no throw";
+}
+
+main() {
+ for (var i = 0; i < 300; i++) {
+ Expect.equals("no throw", test1(0));
+ }
+ Expect.equals("no throw", test1(0));
+ Expect.equals(123, test1(1));
+ Expect.equals(456, test1(2));
+
+ for (var i = 0; i < 300; i++) {
+ Expect.equals("no throw", test2(0));
+ }
+ Expect.equals("no throw", test2(0));
+ Expect.equals(123, test2(1));
+ Expect.equals(456, test2(2));
+}
diff --git a/tests/language/exception/try_catch_osr_test.dart b/tests/language/exception/try_catch_osr_test.dart
new file mode 100644
index 0000000..345f764
--- /dev/null
+++ b/tests/language/exception/try_catch_osr_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2013, 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Test OSR in different places of a try-catch.
+
+import "package:expect/expect.dart";
+
+maythrow(x) {
+ try {
+ if (x == null) throw 42;
+ return 99;
+ } finally {}
+}
+
+f1() {
+ var s = 0, t = "abc";
+ for (var i = 0; i < 21; ++i) {
+ s += i;
+ }
+ try {
+ maythrow(null);
+ } catch (e) {
+ Expect.equals("abc", t);
+ Expect.equals(42, e);
+ s++;
+ }
+ return s;
+}
+
+f2([int x = 1]) {
+ var s = 0;
+ var t = "abc";
+ try {
+ try {
+ for (var i = 0; i < 20; ++i) {
+ if (i == 18) maythrow(null);
+ s += x;
+ }
+ } catch (e) {
+ Expect.equals(1, x);
+ Expect.equals("abc", t);
+ Expect.equals(42, e);
+ s++;
+ }
+ } catch (e) {}
+ return s;
+}
+
+f3() {
+ var s = 0, t = "abc";
+ try {
+ maythrow(null);
+ } catch (e) {
+ Expect.equals("abc", t);
+ for (var i = 0; i < 21; ++i) {
+ s += i;
+ }
+ Expect.equals("abc", t);
+ Expect.equals(42, e);
+ return s;
+ }
+}
+
+f4() {
+ var s = 0, t = "abc";
+ try {
+ for (var i = 0; i < 21; ++i) {
+ if (i == 18) maythrow(null);
+ s += i;
+ }
+ } catch (e) {
+ Expect.equals("abc", t);
+ Expect.equals(42, e);
+ s++;
+ }
+ return s;
+}
+
+f5() {
+ var s, t = "abc";
+ try {
+ maythrow(null);
+ } catch (e) {
+ Expect.equals("abc", t);
+ Expect.equals(42, e);
+ s = 0;
+ }
+ for (var i = 0; i < 21; ++i) {
+ s += i;
+ }
+ Expect.equals("abc", t);
+ return s;
+}
+
+main() {
+ Expect.equals(211, f1());
+ Expect.equals(19, f2());
+ Expect.equals(210, f3());
+ Expect.equals(9 * 17 + 1, f4());
+ Expect.equals(210, f5());
+}
diff --git a/tests/language/exception/try_catch_regress_27483_test.dart b/tests/language/exception/try_catch_regress_27483_test.dart
new file mode 100644
index 0000000..dde7246
--- /dev/null
+++ b/tests/language/exception/try_catch_regress_27483_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2016, 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.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
+
+// Test local variables updated inside try-catch.
+
+import "package:expect/expect.dart";
+
+@pragma('vm:never-inline')
+m1(int b) {
+ if (b == 1) throw 123;
+}
+
+@pragma('vm:never-inline')
+m2(int b) {
+ if (b == 2) throw 456;
+}
+
+@pragma('vm:never-inline')
+test(b) {
+ var state = 0;
+ try {
+ state++;
+ m1(b);
+ state++;
+ m2(b);
+ state++;
+ } catch (e, s) {
+ if (b == 1 && state != 1) throw "fail1";
+ if (b == 2 && state != 2) throw "fail2";
+ if (b == 3 && state != 3) throw "fail3";
+ return e;
+ }
+ return "no throw";
+}
+
+main() {
+ for (var i = 0; i < 300; i++) {
+ Expect.equals("no throw", test(0));
+ }
+ Expect.equals("no throw", test(0));
+ Expect.equals(123, test(1));
+ Expect.equals(456, test(2));
+}
diff --git a/tests/language/exception/try_catch_runtime_test.dart b/tests/language/exception/try_catch_runtime_test.dart
new file mode 100644
index 0000000..872f9d7
--- /dev/null
+++ b/tests/language/exception/try_catch_runtime_test.dart
@@ -0,0 +1,199 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, 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.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+class TryCatchTest {
+ static void test1() {
+ var foo = 0;
+ try {
+ throw new MyException1();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ } on MyException catch (e) {
+ foo = 3;
+ }
+ Expect.equals(2, foo);
+ }
+
+ static void test2() {
+ var foo = 0;
+ try {
+ throw new MyException1();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException catch (e) {
+ foo = 2;
+ } on MyException1 catch (e) {
+ foo = 3;
+ }
+ Expect.equals(2, foo);
+ }
+
+ static void test3() {
+ var foo = 0;
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ } on MyException catch (e) {
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test4() {
+ var foo = 0;
+ try {
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ }
+ } on MyException catch (e) {
+ Expect.equals(0, foo);
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test5() {
+ var foo = 0;
+ try {
+ throw new MyException1();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } catch (e) {
+ foo = 2;
+ }
+ Expect.equals(2, foo);
+ }
+
+ static void test6() {
+ var foo = 0;
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ } catch (e) {
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test7() {
+ var foo = 0;
+ try {
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ }
+ } catch (e) {
+ Expect.equals(0, foo);
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test8() {
+ var e = 3;
+ var caught = false;
+ try {
+ throw new MyException();
+ } catch (exc) {
+ caught = true;
+ }
+ Expect.equals(true, caught);
+ Expect.equals(3, e);
+ }
+
+ static void test9() {
+ dynamic e = 6;
+ try {
+ throw "up";
+ } on String {
+ e = "s";
+ } on int {
+ e = "i";
+ }
+ Expect.equals("s", e);
+ }
+
+ static void test10() {
+ try {
+ throw "up";
+ } on String catch (e) {
+ var e = 1; // ok, shadows exception variable.
+ Expect.equals(1, e);
+ }
+ }
+
+ static void test11() {
+ var e0 = 11;
+ try {
+ throw "up";
+ } on int catch (e0) {
+ Expect.fail("unreachable");
+ } on String catch (e1) {
+ // e0 from the other catch clause is not in scope.
+ Expect.equals(11, e0);
+ }
+ }
+
+ static void test12() {
+ const x = const [];
+ try {
+ throw "up";
+ } catch (e) {
+ Expect.equals("up", e);
+ } on String catch (e) {
+ // Compile-time constants in unreachable catch blocks are still
+ // compiled.
+
+ Expect.fail("unreachable");
+ }
+ }
+
+ static void testMain() {
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ test8();
+ test9();
+ test10();
+ test11();
+ test12();
+ }
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ TryCatchTest.testMain();
+ }
+}
diff --git a/tests/language/exception/try_catch_syntax_test.dart b/tests/language/exception/try_catch_syntax_test.dart
new file mode 100644
index 0000000..5a192d1
--- /dev/null
+++ b/tests/language/exception/try_catch_syntax_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2012, 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.
+
+main() {
+ testMissingCatch();
+ testMissingTry();
+ testDuplicateCatchVariable();
+ testIllegalFinally();
+ testIllegalCatch();
+ testIllegalRethrow();
+}
+
+testMissingCatch() {
+ try { } // //# 01: syntax error
+}
+
+testMissingTry() {
+ on Exception catch (e) { } // //# 02: syntax error
+ on Exception catch (e, trace) { } // //# 03: syntax error
+ finally { } // //# 04: syntax error
+}
+
+testDuplicateCatchVariable() {
+ try { } on Exception catch (e, e) { } //# 05: compile-time error
+}
+
+testIllegalFinally() {
+ try { } finally (e) { } //# 06: syntax error
+}
+
+testIllegalCatch() {
+ try { } catch () { } // //# 07: syntax error
+ try { } on MammaMia catch (e) { } //# 08: compile-time error
+ try { } catch (var e) { } // //# 09: syntax error
+ try { } catch (final e) { } // //# 10: syntax error
+ try { } catch (int e) { } // //# 11: syntax error
+ try { } catch (final int e) { } // //# 12: syntax error
+ try { } catch ([e, s]) { } // //# 13: syntax error
+ try { } catch (e, [s]) { } // //# 14: syntax error
+ try { } catch (e, [s0, s1]) { } // //# 15: syntax error
+}
+
+testIllegalRethrow() {
+ try { rethrow; } catch (e) { } // //# 16: compile-time error
+ try { } catch (e) { } finally { rethrow; } //# 17: compile-time error
+}
diff --git a/tests/language/exception/try_catch_test.dart b/tests/language/exception/try_catch_test.dart
new file mode 100644
index 0000000..2b8fee2
--- /dev/null
+++ b/tests/language/exception/try_catch_test.dart
@@ -0,0 +1,200 @@
+// Copyright (c) 2011, 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.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+class TryCatchTest {
+ static void test1() {
+ var foo = 0;
+ try {
+ throw new MyException1();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ } on MyException catch (e) {
+ foo = 3;
+ }
+ Expect.equals(2, foo);
+ }
+
+ static void test2() {
+ var foo = 0;
+ try {
+ throw new MyException1();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException catch (e) {
+ foo = 2;
+ } on MyException1 catch (e) {
+ foo = 3;
+ }
+ Expect.equals(2, foo);
+ }
+
+ static void test3() {
+ var foo = 0;
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ } on MyException catch (e) {
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test4() {
+ var foo = 0;
+ try {
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ }
+ } on MyException catch (e) {
+ Expect.equals(0, foo);
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test5() {
+ var foo = 0;
+ try {
+ throw new MyException1();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } catch (e) {
+ foo = 2;
+ }
+ Expect.equals(2, foo);
+ }
+
+ static void test6() {
+ var foo = 0;
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ } catch (e) {
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test7() {
+ var foo = 0;
+ try {
+ try {
+ throw new MyException();
+ } on MyException2 catch (e) {
+ foo = 1;
+ } on MyException1 catch (e) {
+ foo = 2;
+ }
+ } catch (e) {
+ Expect.equals(0, foo);
+ foo = 3;
+ }
+ Expect.equals(3, foo);
+ }
+
+ static void test8() {
+ var e = 3;
+ var caught = false;
+ try {
+ throw new MyException();
+ } catch (exc) {
+ caught = true;
+ }
+ Expect.equals(true, caught);
+ Expect.equals(3, e);
+ }
+
+ static void test9() {
+ dynamic e = 6;
+ try {
+ throw "up";
+ } on String {
+ e = "s";
+ } on int {
+ e = "i";
+ }
+ Expect.equals("s", e);
+ }
+
+ static void test10() {
+ try {
+ throw "up";
+ } on String catch (e) {
+ var e = 1; // ok, shadows exception variable.
+ Expect.equals(1, e);
+ }
+ }
+
+ static void test11() {
+ var e0 = 11;
+ try {
+ throw "up";
+ } on int catch (e0) {
+ Expect.fail("unreachable");
+ } on String catch (e1) {
+ // e0 from the other catch clause is not in scope.
+ Expect.equals(11, e0);
+ }
+ }
+
+ static void test12() {
+ const x = const [];
+ try {
+ throw "up";
+ } catch (e) {
+ Expect.equals("up", e);
+ } on String catch (e) {
+ // Compile-time constants in unreachable catch blocks are still
+ // compiled.
+ const y = x[0];
+ // ^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+ // ^
+ // [cfe] Constant evaluation error:
+ Expect.fail("unreachable");
+ }
+ }
+
+ static void testMain() {
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ test8();
+ test9();
+ test10();
+ test11();
+ test12();
+ }
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ TryCatchTest.testMain();
+ }
+}
diff --git a/tests/language/exception/try_finally_regress_25333_test.dart b/tests/language/exception/try_finally_regress_25333_test.dart
new file mode 100644
index 0000000..6318f7c
--- /dev/null
+++ b/tests/language/exception/try_finally_regress_25333_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, 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.
+
+// Test correct handling of try-catch inside try-finally.
+
+import "package:expect/expect.dart";
+
+void main() {
+ print("== test1 ==");
+ bool caught = false;
+ try {
+ test1();
+ print("Unexpected 1"); // should never go here
+ Expect.isTrue(false);
+ } catch (e) {
+ caught = true;
+ print("main catch 1: $e");
+ Expect.equals(e, "Ball");
+ }
+ Expect.isTrue(caught);
+ print("== test2 ==");
+ caught = false;
+ try {
+ test2();
+ print("Unexpected 2"); // should never go here
+ Expect.isTrue(false);
+ } catch (e) {
+ caught = true;
+ print("main catch 2: $e");
+ Expect.equals(e, "Ball");
+ }
+ Expect.isTrue(caught);
+}
+
+void test1() {
+ try {
+ throw "Ball";
+ } finally {
+ try {
+ throw "Frisbee";
+ } catch (e) {
+ print("test 1 catch: $e");
+ Expect.equals(e, "Frisbee");
+ }
+ }
+}
+
+void test2() {
+ try {
+ throwError(); // call a method that throws an error
+ } finally {
+ try {
+ throw "Frisbee";
+ } catch (e) {
+ print("test 2 catch: $e");
+ Expect.equals(e, "Frisbee");
+ }
+ }
+}
+
+void throwError() {
+ throw "Ball";
+}
diff --git a/tests/language/exception/try_finally_regress_25654_test.dart b/tests/language/exception/try_finally_regress_25654_test.dart
new file mode 100644
index 0000000..32a236f
--- /dev/null
+++ b/tests/language/exception/try_finally_regress_25654_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2016, 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.
+
+// Test break out of try-finally.
+
+import "package:expect/expect.dart";
+
+var count = 0;
+
+test() {
+ L:
+ while (true) {
+ try {
+ break L;
+ } finally {
+ count++;
+ }
+ }
+ throw "ex";
+}
+
+main() {
+ bool caught = false;
+ try {
+ test();
+ } catch (e) {
+ caught = true;
+ Expect.equals(e, "ex");
+ }
+ Expect.isTrue(caught);
+ Expect.equals(1, count);
+}