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:
adamk 2016-01-22 16:40:15 -08:00 committed by Commit bot
parent 677e54e244
commit 8aeb6080e1
3 changed files with 39 additions and 3 deletions

View File

@ -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

View 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);

View File

@ -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