Resolved an issue where an earlier error was not reported first in certain cases

Previously, once after an error was reported, following errors were ignored
even if they had occured in prior lines. Strict octal error and conflicting
variable declarations error could be missed under this implementation.
This patch solves this problem by making an error replaceable.

Bug: v8:13187
Change-Id: I8295baf0db757a5c1b504920cb274cdee78f5055
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4019398
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84212}
This commit is contained in:
Kotaro Ohsugi 2022-11-11 21:36:14 +09:00 committed by V8 LUCI CQ
parent 6fe5bd32ef
commit 9b07049cd8
14 changed files with 90 additions and 8 deletions

View File

@ -285,3 +285,4 @@ Zheng Liu <i6122f@gmail.com>
Zhongping Wang <kewpie.w.zp@gmail.com>
柳荣一 <admin@web-tinker.com>
Yang Xiang <xiangyangemail@gmail.com>
Kotaro Ohsugi <dec4m4rk@gmail.com>

View File

@ -1270,8 +1270,9 @@ Declaration* DeclarationScope::CheckConflictingVarDeclarations(
if (decl->IsVariableDeclaration() &&
decl->AsVariableDeclaration()->AsNested() != nullptr) {
Scope* current = decl->AsVariableDeclaration()->AsNested()->scope();
DCHECK(decl->var()->mode() == VariableMode::kVar ||
decl->var()->mode() == VariableMode::kDynamic);
if (decl->var()->mode() != VariableMode::kVar &&
decl->var()->mode() != VariableMode::kDynamic)
continue;
// Iterate through all scopes until the declaration scope.
do {
// There is a conflict if there exists a non-VAR binding.

View File

@ -1286,7 +1286,6 @@ class ParserBase {
// a scope where the name has also been let bound or the var declaration is
// hoisted over such a scope.
void CheckConflictingVarDeclarations(DeclarationScope* scope) {
if (has_error()) return;
bool allowed_catch_binding_var_redeclaration = false;
Declaration* decl = scope->CheckConflictingVarDeclarations(
&allowed_catch_binding_var_redeclaration);

View File

@ -81,7 +81,8 @@ void PendingCompilationErrorHandler::ReportMessageAt(int start_position,
int end_position,
MessageTemplate message,
const char* arg) {
if (has_pending_error_) return;
if (has_pending_error_ && end_position >= error_details_.start_pos()) return;
has_pending_error_ = true;
error_details_ = MessageDetails(start_position, end_position, message, arg);
@ -91,7 +92,8 @@ void PendingCompilationErrorHandler::ReportMessageAt(int start_position,
int end_position,
MessageTemplate message,
const AstRawString* arg) {
if (has_pending_error_) return;
if (has_pending_error_ && end_position >= error_details_.start_pos()) return;
has_pending_error_ = true;
error_details_ = MessageDetails(start_position, end_position, message, arg);
@ -102,7 +104,8 @@ void PendingCompilationErrorHandler::ReportMessageAt(int start_position,
MessageTemplate message,
const AstRawString* arg0,
const char* arg1) {
if (has_pending_error_) return;
if (has_pending_error_ && end_position >= error_details_.start_pos()) return;
has_pending_error_ = true;
error_details_ =
MessageDetails(start_position, end_position, message, arg0, arg1);

View File

@ -127,6 +127,8 @@ class PendingCompilationErrorHandler {
}
MessageLocation GetLocation(Handle<Script> script) const;
int start_pos() const { return start_position_; }
int end_pos() const { return end_position_; }
MessageTemplate message() const { return message_; }
template <typename IsolateT>

View File

@ -44,7 +44,9 @@ class Utf16CharacterStream {
virtual ~Utf16CharacterStream() = default;
V8_INLINE void set_parser_error() {
buffer_cursor_ = buffer_end_;
// source_pos() returns one previous position of the cursor.
// Offset 1 cancels this out and makes it return exactly buffer_end_.
buffer_cursor_ = buffer_end_ + 1;
has_parser_error_ = true;
}
V8_INLINE void reset_parser_error_flag() { has_parser_error_ = false; }
@ -245,7 +247,9 @@ class V8_EXPORT_PRIVATE Scanner {
if (!has_parser_error()) {
c0_ = kEndOfInput;
source_->set_parser_error();
for (TokenDesc& desc : token_storage_) desc.token = Token::ILLEGAL;
for (TokenDesc& desc : token_storage_) {
if (desc.token != Token::UNINITIALIZED) desc.token = Token::ILLEGAL;
}
}
}
V8_INLINE void reset_parser_error_flag() {

View File

@ -0,0 +1,9 @@
// Copyright 2022 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.
function foo() {
"\123";
"use strict";
abc 1;
}

View File

@ -0,0 +1,9 @@
# Copyright 2022 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.
*%(basename)s:6: SyntaxError: Octal escape sequences are not allowed in strict mode.
"\123";
^^
SyntaxError: Octal escape sequences are not allowed in strict mode.

View File

@ -0,0 +1,9 @@
// Copyright 2022 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.
function foo() {
"use strict";
"\123";
abc 1;
}

View File

@ -0,0 +1,9 @@
# Copyright 2022 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.
*%(basename)s:7: SyntaxError: Octal escape sequences are not allowed in strict mode.
"\123";
^^
SyntaxError: Octal escape sequences are not allowed in strict mode.

View File

@ -0,0 +1,9 @@
// Copyright 2022 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.
function foo() {
"use strict";
01;
abc 1;
}

View File

@ -0,0 +1,9 @@
# Copyright 2022 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.
*%(basename)s:7: SyntaxError: Octal literals are not allowed in strict mode.
01;
^^
SyntaxError: Octal literals are not allowed in strict mode.

View File

@ -0,0 +1,9 @@
// Copyright 2022 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.
{
let a;
var a;
abc 1;
}

View File

@ -0,0 +1,9 @@
# Copyright 2022 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.
*%(basename)s:7: SyntaxError: Identifier 'a' has already been declared
var a;
^
SyntaxError: Identifier 'a' has already been declared