archives

« Bugzilla Issues Index

#4375 — Treating !IsValidSimpleAssignmentTarget target as early ReferenceError for assignments/incops inconsistent with implementations


function f() { 'use strict'; eval = 5; }
function g() { 'use strict'; eval++; }

In all the implementations I can test, these are early SyntaxErrors. But the spec says that nodes that are not IsValidSimpleAssignmentTarget should be early ReferenceErrors.

I saw bug 3992 attempted to make this (or at least deliberately preserved it) for ES5 compatibility wrt things like

function h() { [3] = 5; }

which is kinda sorta fine, I guess. But with this wrinkle pointed out -- that this one case of not-a-valid-simple-assignment-target is uniformly implemented with other semantics in engines -- I'm not convinced uniform ReferenceError behavior is good.

Frankly, I suspect you can get away with making all these early SyntaxErrors, and I would try that first. But if not, you'll have to suss out arguments/eval for special behavior here.


deferred for Es7 consideration

I like them to all become syntax errors. There has been some discussion of this in the past but it has been held back by uncertainty about possible breakage.

(Seems unlikely, but somebody evaling code might be checking for the ReferenceError)


(In reply to Allen Wirfs-Brock from comment #1)
> I like them to all become syntax errors. There has been some discussion of
> this in the past but it has been held back by uncertainty about possible
> breakage.
>
> (Seems unlikely, but somebody evaling code might be checking for the
> ReferenceError)

I think there's a misunderstanding here. The example code in comment #0 throws a SyntaxError in ES5, but ES6 changed it to a ReferenceError. That means to avoid a possible breakage, ES6 needs to restore the SyntaxError for assignments to "eval" and "arguments" in strict mode code.

Here are the early error rules from ES5 and ES6 for the postfix increment operator, ES5 11.3.1 specifies to throw a SyntaxError, whereas ES6 12.4.1 specifies to throw a ReferenceError. Similar issues are present for the prefix increment operator and the assignment operator.

ES5:
---
11.3.1 Postfix Increment Operator

2. Throw a SyntaxError exception if the following conditions are all true:
- Type(lhs) is Reference is true
- IsStrictReference(lhs) is true
- Type(GetBase(lhs)) is Environment Record
- GetReferencedName(lhs) is either "eval" or " arguments"
---

ES6:
---
12.4 Postfix Expressions
12.4.1 Static Semantics: Early Errors
- It is an early Reference Error if IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.


12.1 Identifiers
12.1.3 Static Semantics: IsValidSimpleAssignmentTarget
IdentifierReference : Identifier
1. If this IdentifierReference is contained in strict mode code and StringValue of Identifier is "eval" or "arguments" , return false.
2. Return true.
---


The following test262 test files explicitly check for SyntaxError when assigning to eval/arguments.
---
test/language/arguments-object/10.5-1-s.js
test/language/arguments-object/10.5-1gs.js
test/language/arguments-object/10.5-7-b-1-s.js
test/language/directive-prologue/14.1-4gs.js
test/language/directive-prologue/14.1-5gs.js
test/language/expressions/assignment/11.13.1-4-30-s.js
test/language/expressions/assignment/11.13.1-4-31-s.js
test/language/expressions/compound-assignment/11.13.2-6-1-s.js
test/language/expressions/compound-assignment/11.13.2-6-1gs.js
test/language/expressions/compound-assignment/11.13.2-6-2-s.js
test/language/expressions/compound-assignment/11.13.2-6-3-s.js
test/language/expressions/compound-assignment/11.13.2-6-4-s.js
test/language/expressions/compound-assignment/11.13.2-6-5-s.js
test/language/expressions/compound-assignment/11.13.2-6-6-s.js
test/language/expressions/compound-assignment/11.13.2-6-7-s.js
test/language/expressions/compound-assignment/11.13.2-6-8-s.js
test/language/expressions/compound-assignment/11.13.2-6-9-s.js
test/language/expressions/compound-assignment/11.13.2-6-10-s.js
test/language/expressions/compound-assignment/11.13.2-6-11-s.js
test/language/expressions/compound-assignment/11.13.2-6-12-s.js
test/language/expressions/compound-assignment/11.13.2-6-13-s.js
test/language/expressions/compound-assignment/11.13.2-6-14-s.js
test/language/expressions/compound-assignment/11.13.2-6-15-s.js
test/language/expressions/compound-assignment/11.13.2-6-16-s.js
test/language/expressions/compound-assignment/11.13.2-6-17-s.js
test/language/expressions/compound-assignment/11.13.2-6-18-s.js
test/language/expressions/compound-assignment/11.13.2-6-19-s.js
test/language/expressions/compound-assignment/11.13.2-6-20-s.js
test/language/expressions/compound-assignment/11.13.2-6-21-s.js
test/language/expressions/compound-assignment/11.13.2-6-22-s.js
test/language/expressions/postfix-decrement/11.3.2-2-1-s.js
test/language/expressions/postfix-decrement/11.3.2-2-2-s.js
test/language/expressions/postfix-increment/11.3.1-2-1-s.js
test/language/expressions/postfix-increment/11.3.1-2-1gs.js
test/language/expressions/postfix-increment/11.3.1-2-2-s.js
test/language/expressions/prefix-decrement/11.4.5-2-1-s.js
test/language/expressions/prefix-decrement/11.4.5-2-2-s.js
test/language/expressions/prefix-decrement/11.4.5-2-2gs.js
test/language/expressions/prefix-increment/11.4.4-2-1-s.js
test/language/expressions/prefix-increment/11.4.4-2-2-s.js
test/language/statements/function/13.0-7-s.js
test/language/statements/function/13.0-8-s.js
test/language/statements/function/13.0-9-s.js
test/language/statements/function/13.0-10-s.js
test/language/statements/function/13.0-11-s.js
test/language/statements/function/13.0-13-s.js
test/language/statements/function/13.0-14-s.js
test/language/statements/function/13.0-15-s.js
test/language/statements/function/13.0-16-s.js
test/language/statements/function/13.0_4-5gs.js
test/language/statements/variable/12.2.1-2-s.js
test/language/statements/variable/12.2.1-4-s.js
test/language/statements/variable/12.2.1-8-s.js
test/language/statements/variable/12.2.1-13-s.js
test/language/statements/variable/12.2.1-15-s.js
test/language/statements/variable/12.2.1-19-s.js
---