From c5e18d561cdea18973e49f70186767272993c51b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Bargull?= <andre.bargull@gmail.com>
Date: Sat, 9 May 2015 12:33:04 +0200
Subject: [PATCH] Assignment with left-hand side property accessor

The assignment operator evaluates its operands from left to right. When
the left-hand side expression is a property accessor, RequireObjectCoercible
and ToPropertyKey are called on the property accessor before the right-hand
side expression is evaluated.
---
 .../expressions/assignment/S11.13.1_A7_T1.js  | 38 ++++++++++++++++++
 .../expressions/assignment/S11.13.1_A7_T2.js  | 38 ++++++++++++++++++
 .../expressions/assignment/S11.13.1_A7_T3.js  | 26 +++++++++++++
 .../expressions/assignment/S11.13.1_A7_T4.js  | 25 ++++++++++++
 .../compound-assignment/S11.13.2_A7.10_T1.js  | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.10_T2.js  | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.10_T3.js  | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.10_T4.js  | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.11_T1.js  | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.11_T2.js  | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.11_T3.js  | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.11_T4.js  | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.1_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.1_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.1_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.1_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.2_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.2_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.2_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.2_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.3_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.3_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.3_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.3_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.4_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.4_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.4_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.4_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.5_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.5_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.5_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.5_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.6_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.6_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.6_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.6_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.7_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.7_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.7_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.7_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.8_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.8_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.8_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.8_T4.js   | 26 +++++++++++++
 .../compound-assignment/S11.13.2_A7.9_T1.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.9_T2.js   | 39 +++++++++++++++++++
 .../compound-assignment/S11.13.2_A7.9_T3.js   | 27 +++++++++++++
 .../compound-assignment/S11.13.2_A7.9_T4.js   | 26 +++++++++++++
 48 files changed, 1568 insertions(+)
 create mode 100755 test/language/expressions/assignment/S11.13.1_A7_T1.js
 create mode 100755 test/language/expressions/assignment/S11.13.1_A7_T2.js
 create mode 100755 test/language/expressions/assignment/S11.13.1_A7_T3.js
 create mode 100755 test/language/expressions/assignment/S11.13.1_A7_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.10_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.10_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.10_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.10_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.11_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.11_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.11_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.11_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.1_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.1_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.1_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.1_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.2_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.2_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.2_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.2_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.3_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.3_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.3_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.3_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.4_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.4_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.4_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.4_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.5_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.5_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.5_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.5_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.6_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.6_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.6_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.6_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.7_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.7_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.7_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.7_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.8_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.8_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.8_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.8_T4.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.9_T1.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.9_T2.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.9_T3.js
 create mode 100755 test/language/expressions/compound-assignment/S11.13.2_A7.9_T4.js

diff --git a/test/language/expressions/assignment/S11.13.1_A7_T1.js b/test/language/expressions/assignment/S11.13.1_A7_T1.js
new file mode 100755
index 0000000000..74a655ead5
--- /dev/null
+++ b/test/language/expressions/assignment/S11.13.1_A7_T1.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] = expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] = expr();
+});
diff --git a/test/language/expressions/assignment/S11.13.1_A7_T2.js b/test/language/expressions/assignment/S11.13.1_A7_T2.js
new file mode 100755
index 0000000000..173f3e6b08
--- /dev/null
+++ b/test/language/expressions/assignment/S11.13.1_A7_T2.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] = expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] = expr();
+});
diff --git a/test/language/expressions/assignment/S11.13.1_A7_T3.js b/test/language/expressions/assignment/S11.13.1_A7_T3.js
new file mode 100755
index 0000000000..5bbc35d603
--- /dev/null
+++ b/test/language/expressions/assignment/S11.13.1_A7_T3.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] = expr();
+});
diff --git a/test/language/expressions/assignment/S11.13.1_A7_T4.js b/test/language/expressions/assignment/S11.13.1_A7_T4.js
new file mode 100755
index 0000000000..33111b0b9d
--- /dev/null
+++ b/test/language/expressions/assignment/S11.13.1_A7_T4.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] = expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.10_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T1.js
new file mode 100755
index 0000000000..13fdc3563c
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x ^= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] ^= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] ^= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.10_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T2.js
new file mode 100755
index 0000000000..cb0da6b889
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x ^= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] ^= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] ^= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.10_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T3.js
new file mode 100755
index 0000000000..ff238d1d7d
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x ^= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] ^= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.10_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T4.js
new file mode 100755
index 0000000000..4aadbb01a4
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.10_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x ^= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] ^= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.11_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T1.js
new file mode 100755
index 0000000000..c90e4b3be9
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x |= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] |= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] |= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.11_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T2.js
new file mode 100755
index 0000000000..54b6ac33cc
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x |= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] |= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] |= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.11_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T3.js
new file mode 100755
index 0000000000..98d6714bd3
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x |= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] |= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.11_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T4.js
new file mode 100755
index 0000000000..310f3ba9bd
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.11_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x |= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] |= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.1_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T1.js
new file mode 100755
index 0000000000..ef60588bcb
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x *= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] *= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] *= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.1_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T2.js
new file mode 100755
index 0000000000..5d679b239f
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x *= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] *= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] *= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.1_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T3.js
new file mode 100755
index 0000000000..3d8082f1d9
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x *= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] *= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.1_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T4.js
new file mode 100755
index 0000000000..3f49ca96e0
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.1_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x *= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] *= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.2_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T1.js
new file mode 100755
index 0000000000..bdef8f389b
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x /= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] /= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] /= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.2_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T2.js
new file mode 100755
index 0000000000..66bf3c3698
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x /= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] /= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] /= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.2_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T3.js
new file mode 100755
index 0000000000..f1b12354be
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x /= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] /= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.2_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T4.js
new file mode 100755
index 0000000000..c7963d97ea
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.2_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x /= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] /= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.3_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T1.js
new file mode 100755
index 0000000000..bd5856afd1
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x %= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] %= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] %= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.3_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T2.js
new file mode 100755
index 0000000000..0361333a2f
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x %= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] %= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] %= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.3_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T3.js
new file mode 100755
index 0000000000..ab16d1c928
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x %= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] %= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.3_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T4.js
new file mode 100755
index 0000000000..c7f0f54171
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.3_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x %= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] %= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.4_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T1.js
new file mode 100755
index 0000000000..164c2202e4
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x += y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] += expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] += expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.4_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T2.js
new file mode 100755
index 0000000000..f3391e7688
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x += y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] += expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] += expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.4_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T3.js
new file mode 100755
index 0000000000..4580299c13
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x += y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] += expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.4_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T4.js
new file mode 100755
index 0000000000..b149e25281
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.4_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x += y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] += expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.5_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T1.js
new file mode 100755
index 0000000000..654dcfa67a
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x -= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] -= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] -= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.5_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T2.js
new file mode 100755
index 0000000000..bfb79e0dc2
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x -= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] -= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] -= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.5_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T3.js
new file mode 100755
index 0000000000..a4df835b2f
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x -= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] -= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.5_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T4.js
new file mode 100755
index 0000000000..dd0515e5d2
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.5_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x -= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] -= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.6_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T1.js
new file mode 100755
index 0000000000..e0213c0c3a
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x <<= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] <<= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] <<= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.6_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T2.js
new file mode 100755
index 0000000000..73efcb61fa
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x <<= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] <<= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] <<= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.6_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T3.js
new file mode 100755
index 0000000000..d57eb8296f
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x <<= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] <<= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.6_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T4.js
new file mode 100755
index 0000000000..df88da9e31
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.6_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x <<= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] <<= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.7_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T1.js
new file mode 100755
index 0000000000..03c494c496
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x >>= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] >>= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] >>= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.7_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T2.js
new file mode 100755
index 0000000000..94e2e39a32
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x >>= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] >>= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] >>= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.7_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T3.js
new file mode 100755
index 0000000000..b60a358ff3
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x >>= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] >>= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.7_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T4.js
new file mode 100755
index 0000000000..43d18298bd
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.7_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x >>= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] >>= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.8_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T1.js
new file mode 100755
index 0000000000..4c4d65ad63
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x >>>= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] >>>= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] >>>= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.8_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T2.js
new file mode 100755
index 0000000000..c3fcfa1028
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x >>>= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] >>>= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] >>>= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.8_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T3.js
new file mode 100755
index 0000000000..7a50332651
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x >>>= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] >>>= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.8_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T4.js
new file mode 100755
index 0000000000..844282d17c
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.8_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x >>>= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] >>>= expr();
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.9_T1.js b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T1.js
new file mode 100755
index 0000000000..7f69c9d344
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T1.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    null value.
+    Check operator is "x &= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = null;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] &= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = null;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] &= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.9_T2.js b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T2.js
new file mode 100755
index 0000000000..d149d5bb10
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T2.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. base is the
+    undefined value.
+    Check operator is "x &= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = undefined;
+  var prop = function() {
+    throw new DummyError();
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop()] &= expr();
+});
+
+assert.throws(TypeError, function() {
+  var base = undefined;
+  var prop = {
+    toString: function() {
+      $ERROR("property key evaluated");
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] &= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.9_T3.js b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T3.js
new file mode 100755
index 0000000000..da724914e6
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T3.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. Evaluating
+    ToPropertyKey(prop) throws an error.
+    Check operator is "x &= y".
+---*/
+
+function DummyError() { }
+
+assert.throws(DummyError, function() {
+  var base = {};
+  var prop = {
+    toString: function() {
+      throw new DummyError();
+    }
+  };
+  var expr = function() {
+    $ERROR("right-hand side expression evaluated");
+  };
+
+  base[prop] &= expr();
+});
diff --git a/test/language/expressions/compound-assignment/S11.13.2_A7.9_T4.js b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T4.js
new file mode 100755
index 0000000000..709f65a5f6
--- /dev/null
+++ b/test/language/expressions/compound-assignment/S11.13.2_A7.9_T4.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: Compound Assignment Operator evaluates its operands from left to right.
+description: >
+    The left-hand side expression is evaluated before the right-hand side.
+    Left-hand side expression is MemberExpression: base[prop]. ToPropertyKey(prop)
+    is only called once.
+    Check operator is "x &= y".
+---*/
+
+var propKeyEvaluated = false;
+var base = {};
+var prop = {
+  toString: function() {
+    assert(!propKeyEvaluated);
+    propKeyEvaluated = true;
+    return "";
+  }
+};
+var expr = function() {
+  return 0;
+};
+
+base[prop] &= expr();
-- 
GitLab