Sloppy mode webcompat: allow conflicting function declarations in blocks
The web appears to depend on being able to redeclare functions-in-blocks in sloppy mode (examples seen so far tend to redeclare identical functions, most likely accidentally). This patch opens a minimal hole: two same-named function declarations in the same scope are allowed, only in sloppy mode. BUG=v8:4693, chromium:579395 LOG=y Review URL: https://codereview.chromium.org/1622723003 Cr-Commit-Position: refs/heads/master@{#33478}
This commit is contained in:
parent
677e54e244
commit
8aeb6080e1
@ -1926,6 +1926,7 @@ Variable* Parser::Declare(Declaration* declaration,
|
||||
DCHECK(proxy->raw_name() != NULL);
|
||||
const AstRawString* name = proxy->raw_name();
|
||||
VariableMode mode = declaration->mode();
|
||||
bool is_function_declaration = declaration->IsFunctionDeclaration();
|
||||
if (scope == nullptr) scope = scope_;
|
||||
Scope* declaration_scope =
|
||||
IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope();
|
||||
@ -1952,7 +1953,7 @@ Variable* Parser::Declare(Declaration* declaration,
|
||||
// Declare the name.
|
||||
Variable::Kind kind = Variable::NORMAL;
|
||||
int declaration_group_start = -1;
|
||||
if (declaration->IsFunctionDeclaration()) {
|
||||
if (is_function_declaration) {
|
||||
kind = Variable::FUNCTION;
|
||||
} else if (declaration->IsVariableDeclaration() &&
|
||||
declaration->AsVariableDeclaration()->is_class_declaration()) {
|
||||
@ -1963,8 +1964,11 @@ Variable* Parser::Declare(Declaration* declaration,
|
||||
var = declaration_scope->DeclareLocal(
|
||||
name, mode, declaration->initialization(), kind, kNotAssigned,
|
||||
declaration_group_start);
|
||||
} else if (IsLexicalVariableMode(mode) ||
|
||||
IsLexicalVariableMode(var->mode()) ||
|
||||
} else if (((IsLexicalVariableMode(mode) ||
|
||||
IsLexicalVariableMode(var->mode())) &&
|
||||
// Allow duplicate function decls for web compat, see bug 4693.
|
||||
(is_strict(language_mode()) || !is_function_declaration ||
|
||||
!var->is_function())) ||
|
||||
((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
|
||||
!declaration_scope->is_script_scope())) {
|
||||
// The name was declared in this scope before; check for conflicting
|
||||
|
29
test/mjsunit/regress/regress-4693.js
Normal file
29
test/mjsunit/regress/regress-4693.js
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2016 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.
|
||||
//
|
||||
// Flags: --harmony-sloppy-function
|
||||
|
||||
// In sloppy mode we allow function redeclarations within blocks for webcompat.
|
||||
(function() {
|
||||
assertEquals(undefined, f); // Annex B
|
||||
if (true) {
|
||||
assertEquals(2, f());
|
||||
function f() { return 1 }
|
||||
assertEquals(2, f());
|
||||
function f() { return 2 }
|
||||
assertEquals(2, f());
|
||||
}
|
||||
assertEquals(2, f()); // Annex B
|
||||
})();
|
||||
|
||||
// Should still fail in strict mode
|
||||
assertThrows(`
|
||||
(function() {
|
||||
"use strict";
|
||||
if (true) {
|
||||
function f() { return 1 }
|
||||
function f() { return 2 }
|
||||
}
|
||||
})();
|
||||
`, SyntaxError);
|
@ -448,6 +448,9 @@
|
||||
'language/types/number/S8.5_A2.1': [PASS, FAIL_OK],
|
||||
'language/types/number/S8.5_A2.2': [PASS, FAIL_OK],
|
||||
|
||||
# https://code.google.com/p/v8/issues/detail?id=4693
|
||||
'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-function-declaration': [PASS, FAIL_SLOPPY],
|
||||
|
||||
############################ INVALID TESTS #############################
|
||||
|
||||
# The reference value calculated by Test262 is incorrect if you run these
|
||||
|
Loading…
Reference in New Issue
Block a user