v8/test/mjsunit/call-lhs-web-compat-early-errors.js
Marja Hölttä 5d5b728b8a [logical assignment] Disallow foo() &&= 1 etc
Having the web compatibility hack (allowing foo() = 1) enabled for
logical assignment was unintentional.

Browser compatibility data:
https://docs.google.com/document/d/1cGorRZ73KvQqu57tT4ahCjSLncibFMUwlkaL-XIstzI/edit?usp=sharing

Bug: v8:10372, v8:10950
Change-Id: I87f6348b75ce72ee5bd5db143f789ceeee596070
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2423721
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70105}
2020-09-24 08:17:17 +00:00

70 lines
2.2 KiB
JavaScript

// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Will be used in the tests
function foo() {}
function wrapInLazyFunction(s) {
// Use an async function, since some tests use the await keyword.
return "async function test() { " + s + "}";
}
function wrapInEagerFunction(s) {
// Use an async function, since some tests use the await keyword. Await the
// result, so that we get the error right away.
return "await (async function test() { " + s + "})();";
}
function assertEarlyError(s) {
assertThrows(wrapInLazyFunction(s), SyntaxError);
}
function assertLateError(s) {
assertDoesNotThrow(wrapInLazyFunction(s));
assertThrows(wrapInEagerFunction(s), ReferenceError);
}
// Web compatibility:
assertLateError("foo() = 0;");
assertLateError("foo()++;");
assertLateError("foo()--;");
assertLateError("++foo();");
assertLateError("--foo();");
assertLateError("foo() = 1;");
assertLateError("foo() += 1;");
assertLateError("foo() -= 1;");
assertLateError("foo() *= 1;");
assertLateError("foo() /= 1;");
assertLateError("for (foo() = 0; ; ) {}");
assertLateError("for ( ; ; foo() = 0) {}");
assertLateError("for (foo() of []) {}");
assertLateError("for (foo() in {}) {}");
assertLateError("for await (foo() of []) {}");
// These are early errors though:
assertEarlyError("for (let foo() = 0; ;) {}");
assertEarlyError("for (const foo() = 0; ;) {}");
assertEarlyError("for (var foo() = 0; ;) {}");
// Modern language features:
// Tagged templates
assertEarlyError("foo() `foo` ++;");
assertEarlyError("foo() `foo` --;");
assertEarlyError("++ foo() `foo`;");
assertEarlyError("-- foo() `foo`;");
assertEarlyError("foo() `foo` = 1;");
assertEarlyError("foo() `foo` += 1;");
assertEarlyError("foo() `foo` -= 1;");
assertEarlyError("foo() `foo` *= 1;");
assertEarlyError("foo() `foo` /= 1;");
assertEarlyError("for (foo() `foo` = 0; ; ) {}");
assertEarlyError("for (; ; foo() `foo` = 0) {}");
// Logical assignment
assertEarlyError("foo() &&= 1;");
assertEarlyError("foo() ||= 1;");
assertEarlyError("foo() ??= 1;");
assertEarlyError("for (foo() &&= 0; ;) {}");
assertEarlyError("for ( ; ; foo() &&= 0) {}");