From 098f9ca3de5043c376e0cb68c14acf535ad8d66e Mon Sep 17 00:00:00 2001
From: Caitlin Potter <caitp@igalia.com>
Date: Thu, 2 Feb 2017 12:42:12 -0500
Subject: [PATCH] Add tests for try/finally in async functions

---
 .../try-reject-finally-reject.js              | 27 +++++++++++++++++++
 .../try-reject-finally-return.js              | 25 +++++++++++++++++
 .../try-reject-finally-throw.js               | 25 +++++++++++++++++
 .../try-return-finally-reject.js              | 25 +++++++++++++++++
 .../try-return-finally-return.js              | 25 +++++++++++++++++
 .../try-return-finally-throw.js               | 23 ++++++++++++++++
 .../try-throw-finally-reject.js               | 25 +++++++++++++++++
 .../try-throw-finally-return.js               | 25 +++++++++++++++++
 .../try-throw-finally-throw.js                | 23 ++++++++++++++++
 .../try-reject-finally-reject.js              | 27 +++++++++++++++++++
 .../try-reject-finally-return.js              | 25 +++++++++++++++++
 .../try-reject-finally-throw.js               | 25 +++++++++++++++++
 .../try-return-finally-reject.js              | 25 +++++++++++++++++
 .../try-return-finally-return.js              | 25 +++++++++++++++++
 .../try-return-finally-throw.js               | 23 ++++++++++++++++
 .../try-throw-finally-reject.js               | 25 +++++++++++++++++
 .../try-throw-finally-return.js               | 25 +++++++++++++++++
 .../async-function/try-throw-finally-throw.js | 23 ++++++++++++++++
 .../try-reject-finally-reject.js              | 27 +++++++++++++++++++
 .../try-reject-finally-return.js              | 25 +++++++++++++++++
 .../try-reject-finally-throw.js               | 25 +++++++++++++++++
 .../try-return-finally-reject.js              | 25 +++++++++++++++++
 .../try-return-finally-return.js              | 25 +++++++++++++++++
 .../try-return-finally-throw.js               | 23 ++++++++++++++++
 .../try-throw-finally-reject.js               | 25 +++++++++++++++++
 .../try-throw-finally-return.js               | 25 +++++++++++++++++
 .../async-function/try-throw-finally-throw.js | 23 ++++++++++++++++
 27 files changed, 669 insertions(+)
 create mode 100644 test/language/expressions/async-arrow-function/try-reject-finally-reject.js
 create mode 100644 test/language/expressions/async-arrow-function/try-reject-finally-return.js
 create mode 100644 test/language/expressions/async-arrow-function/try-reject-finally-throw.js
 create mode 100644 test/language/expressions/async-arrow-function/try-return-finally-reject.js
 create mode 100644 test/language/expressions/async-arrow-function/try-return-finally-return.js
 create mode 100644 test/language/expressions/async-arrow-function/try-return-finally-throw.js
 create mode 100644 test/language/expressions/async-arrow-function/try-throw-finally-reject.js
 create mode 100644 test/language/expressions/async-arrow-function/try-throw-finally-return.js
 create mode 100644 test/language/expressions/async-arrow-function/try-throw-finally-throw.js
 create mode 100644 test/language/expressions/async-function/try-reject-finally-reject.js
 create mode 100644 test/language/expressions/async-function/try-reject-finally-return.js
 create mode 100644 test/language/expressions/async-function/try-reject-finally-throw.js
 create mode 100644 test/language/expressions/async-function/try-return-finally-reject.js
 create mode 100644 test/language/expressions/async-function/try-return-finally-return.js
 create mode 100644 test/language/expressions/async-function/try-return-finally-throw.js
 create mode 100644 test/language/expressions/async-function/try-throw-finally-reject.js
 create mode 100644 test/language/expressions/async-function/try-throw-finally-return.js
 create mode 100644 test/language/expressions/async-function/try-throw-finally-throw.js
 create mode 100644 test/language/statements/async-function/try-reject-finally-reject.js
 create mode 100644 test/language/statements/async-function/try-reject-finally-return.js
 create mode 100644 test/language/statements/async-function/try-reject-finally-throw.js
 create mode 100644 test/language/statements/async-function/try-return-finally-reject.js
 create mode 100644 test/language/statements/async-function/try-return-finally-return.js
 create mode 100644 test/language/statements/async-function/try-return-finally-throw.js
 create mode 100644 test/language/statements/async-function/try-throw-finally-reject.js
 create mode 100644 test/language/statements/async-function/try-throw-finally-return.js
 create mode 100644 test/language/statements/async-function/try-throw-finally-throw.js

diff --git a/test/language/expressions/async-arrow-function/try-reject-finally-reject.js b/test/language/expressions/async-arrow-function/try-reject-finally-reject.js
new file mode 100644
index 0000000000..6c9531e66c
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-reject-finally-reject.js
@@ -0,0 +1,27 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-reject-finally-return.js b/test/language/expressions/async-arrow-function/try-reject-finally-return.js
new file mode 100644
index 0000000000..71e4e1410f
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-reject-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    return "override";
+  }
+};
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-reject-finally-throw.js b/test/language/expressions/async-arrow-function/try-reject-finally-throw.js
new file mode 100644
index 0000000000..a058272f2c
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-reject-finally-throw.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    throw "override";
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-return-finally-reject.js b/test/language/expressions/async-arrow-function/try-return-finally-reject.js
new file mode 100644
index 0000000000..115e231001
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-return-finally-reject.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    return "early-return";
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-return-finally-return.js b/test/language/expressions/async-arrow-function/try-return-finally-return.js
new file mode 100644
index 0000000000..4b0798f9b7
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-return-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    return "early-return";
+  } finally {
+    return await new Promise(function(resolve, reject) {
+      resolve("override");
+    });
+  }
+};
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-return-finally-throw.js b/test/language/expressions/async-arrow-function/try-return-finally-throw.js
new file mode 100644
index 0000000000..ab6d6a8c44
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-return-finally-throw.js
@@ -0,0 +1,23 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    return "early-return";
+  } finally {
+    throw "override";
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-throw-finally-reject.js b/test/language/expressions/async-arrow-function/try-throw-finally-reject.js
new file mode 100644
index 0000000000..7c5e2f32ab
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-throw-finally-reject.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    throw "early-throw";
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-throw-finally-return.js b/test/language/expressions/async-arrow-function/try-throw-finally-return.js
new file mode 100644
index 0000000000..a34cb3d194
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-throw-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    throw "early-throw";
+  } finally {
+    return await new Promise(function(resolve, reject) {
+      resolve("override");
+    });
+  }
+};
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-arrow-function/try-throw-finally-throw.js b/test/language/expressions/async-arrow-function/try-throw-finally-throw.js
new file mode 100644
index 0000000000..59b8bfd73b
--- /dev/null
+++ b/test/language/expressions/async-arrow-function/try-throw-finally-throw.js
@@ -0,0 +1,23 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async() => {
+  try {
+    throw "early-throw";
+  } finally {
+    throw "override";
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-reject-finally-reject.js b/test/language/expressions/async-function/try-reject-finally-reject.js
new file mode 100644
index 0000000000..7e15c23b78
--- /dev/null
+++ b/test/language/expressions/async-function/try-reject-finally-reject.js
@@ -0,0 +1,27 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-reject-finally-return.js b/test/language/expressions/async-function/try-reject-finally-return.js
new file mode 100644
index 0000000000..21f96918ae
--- /dev/null
+++ b/test/language/expressions/async-function/try-reject-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    return "override";
+  }
+};
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-reject-finally-throw.js b/test/language/expressions/async-function/try-reject-finally-throw.js
new file mode 100644
index 0000000000..d5ed694908
--- /dev/null
+++ b/test/language/expressions/async-function/try-reject-finally-throw.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    throw "override";
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-return-finally-reject.js b/test/language/expressions/async-function/try-return-finally-reject.js
new file mode 100644
index 0000000000..e7a1df90fa
--- /dev/null
+++ b/test/language/expressions/async-function/try-return-finally-reject.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    return "early-return";
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-return-finally-return.js b/test/language/expressions/async-function/try-return-finally-return.js
new file mode 100644
index 0000000000..3727e4b94b
--- /dev/null
+++ b/test/language/expressions/async-function/try-return-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    return "early-return";
+  } finally {
+    return await new Promise(function(resolve, reject) {
+      resolve("override");
+    });
+  }
+};
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-return-finally-throw.js b/test/language/expressions/async-function/try-return-finally-throw.js
new file mode 100644
index 0000000000..e41fc34358
--- /dev/null
+++ b/test/language/expressions/async-function/try-return-finally-throw.js
@@ -0,0 +1,23 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    return "early-return";
+  } finally {
+    throw "override";
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-throw-finally-reject.js b/test/language/expressions/async-function/try-throw-finally-reject.js
new file mode 100644
index 0000000000..3ff3c5eb72
--- /dev/null
+++ b/test/language/expressions/async-function/try-throw-finally-reject.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    throw "early-throw";
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-throw-finally-return.js b/test/language/expressions/async-function/try-throw-finally-return.js
new file mode 100644
index 0000000000..dc28e980a6
--- /dev/null
+++ b/test/language/expressions/async-function/try-throw-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    throw "early-throw";
+  } finally {
+    return await new Promise(function(resolve, reject) {
+      resolve("override");
+    });
+  }
+};
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/expressions/async-function/try-throw-finally-throw.js b/test/language/expressions/async-function/try-throw-finally-throw.js
new file mode 100644
index 0000000000..5ffcc04827
--- /dev/null
+++ b/test/language/expressions/async-function/try-throw-finally-throw.js
@@ -0,0 +1,23 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+var f = async function() {
+  try {
+    throw "early-throw";
+  } finally {
+    throw "override";
+  }
+};
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-reject-finally-reject.js b/test/language/statements/async-function/try-reject-finally-reject.js
new file mode 100644
index 0000000000..f8c4f79c48
--- /dev/null
+++ b/test/language/statements/async-function/try-reject-finally-reject.js
@@ -0,0 +1,27 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+}
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-reject-finally-return.js b/test/language/statements/async-function/try-reject-finally-return.js
new file mode 100644
index 0000000000..bf522673bf
--- /dev/null
+++ b/test/language/statements/async-function/try-reject-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    return "override";
+  }
+}
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-reject-finally-throw.js b/test/language/statements/async-function/try-reject-finally-throw.js
new file mode 100644
index 0000000000..4211cf29d7
--- /dev/null
+++ b/test/language/statements/async-function/try-reject-finally-throw.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    await new Promise(function(resolve, reject) {
+      reject("early-reject");
+    });
+  } finally {
+    throw "override";
+  }
+}
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-return-finally-reject.js b/test/language/statements/async-function/try-return-finally-reject.js
new file mode 100644
index 0000000000..b477407a51
--- /dev/null
+++ b/test/language/statements/async-function/try-return-finally-reject.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    return "early-return";
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+}
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-return-finally-return.js b/test/language/statements/async-function/try-return-finally-return.js
new file mode 100644
index 0000000000..60c0e73cd6
--- /dev/null
+++ b/test/language/statements/async-function/try-return-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    return "early-return";
+  } finally {
+    return await new Promise(function(resolve, reject) {
+      resolve("override");
+    });
+  }
+}
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-return-finally-throw.js b/test/language/statements/async-function/try-return-finally-throw.js
new file mode 100644
index 0000000000..8e03895cd3
--- /dev/null
+++ b/test/language/statements/async-function/try-return-finally-throw.js
@@ -0,0 +1,23 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer resolving an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    return "early-return";
+  } finally {
+    throw "override";
+  }
+}
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-throw-finally-reject.js b/test/language/statements/async-function/try-throw-finally-reject.js
new file mode 100644
index 0000000000..590b392927
--- /dev/null
+++ b/test/language/statements/async-function/try-throw-finally-reject.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    throw "early-throw";
+  } finally {
+    await new Promise(function(resolve, reject) {
+      reject("override");
+    });
+  }
+}
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Awaited rejection in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-throw-finally-return.js b/test/language/statements/async-function/try-throw-finally-return.js
new file mode 100644
index 0000000000..73f4da6a88
--- /dev/null
+++ b/test/language/statements/async-function/try-throw-finally-return.js
@@ -0,0 +1,25 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    throw "early-throw";
+  } finally {
+    return await new Promise(function(resolve, reject) {
+      resolve("override");
+    });
+  }
+}
+
+f().then(function(value) {
+  assert.sameValue(value, "override", "Return in finally block");
+}).then($DONE, $DONE);
diff --git a/test/language/statements/async-function/try-throw-finally-throw.js b/test/language/statements/async-function/try-throw-finally-throw.js
new file mode 100644
index 0000000000..9d560a14fc
--- /dev/null
+++ b/test/language/statements/async-function/try-throw-finally-throw.js
@@ -0,0 +1,23 @@
+// Copyright 2017 Caitlin Potter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Caitlin Potter <caitp@igalia.com>
+esid: pending
+description: >
+  Implementations must defer rejecting an async function's Promise until after
+  all finally blocks have been evaluated.
+flags: [async]
+---*/
+
+async function f() {
+  try {
+    throw "early-throw";
+  } finally {
+    throw "override";
+  }
+}
+
+f().then($DONE, function(value) {
+  assert.sameValue(value, "override", "Exception thrown in finally block");
+}).then($DONE, $DONE);
-- 
GitLab