Fix RELEASE_ASSERT_NOT_REACHED on CoverInitializedName used as a value

A CoverInitializedName such as `{ a = 0 }` (object shorthand with default) is
only valid when the enclosing object literal is refined into a destructuring
pattern. When such an object literal is instead consumed as a real value -- the
base of a member access, call, computed access, or tagged template, e.g.
`( {... { a = 0 }. b = 1 } )` -- the pending CoverInitializedName error was
discarded by a later assignment, so no SyntaxError was raised and the
AssignmentPattern property value reached bytecode generation, hitting
RELEASE_ASSERT_NOT_REACHED in Node::generateExpressionByteCode.

Report the pending CoverInitializedName as an early SyntaxError in the two
LeftHandSideExpression member-access loops the moment the base is consumed as a
value, since it can no longer be refined into a pattern.

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2026-06-18 17:36:31 +09:00 committed by MuHong Byun
commit bab3a57975
2 changed files with 21 additions and 1 deletions

View file

@ -2574,6 +2574,16 @@ public:
bool hasOptional = false;
while (true) {
// If the just-parsed base carries a pending CoverInitializedName (e.g. `{ a = 0 }`)
// and we are about to apply a member access / call / computed access / tagged
// template, the base is being used as a real value and can no longer be refined
// into a destructuring pattern. This is an early error (e.g. `({ a = 0 }.b = 1)`).
if (UNLIKELY(static_cast<bool>(this->context->firstCoverInitializedNameError))) {
if (this->match(GuessDot) || this->match(LeftParenthesis) || this->match(LeftSquareBracket) || this->match(Period)
|| (this->lookahead.type == Token::TemplateToken && this->lookahead.valueTemplate->head)) {
this->throwUnexpectedToken(this->context->firstCoverInitializedNameError);
}
}
bool optional = false;
if (this->match(GuessDot)) {
Marker startMarker = this->startMarker;
@ -2746,6 +2756,16 @@ public:
this->throwUnexpectedToken(this->lookahead);
}
// A pending CoverInitializedName (e.g. `{ a = 0 }`) cannot be the base of a
// member access / computed access / tagged template: the base is used as a
// real value, so the CoverInitializedName is an early error here.
if (UNLIKELY(static_cast<bool>(this->context->firstCoverInitializedNameError))) {
if (this->match(LeftSquareBracket) || this->match(Period)
|| (this->lookahead.type == Token::TemplateToken && this->lookahead.valueTemplate->head)) {
this->throwUnexpectedToken(this->context->firstCoverInitializedNameError);
}
}
if (this->match(LeftSquareBracket)) {
this->context->isBindingElement = false;
this->context->isAssignmentTarget = false;

@ -1 +1 @@
Subproject commit 6a5e25ea0a0fa51f56e14217dcfb277ebad3d876
Subproject commit 4c69299c40e92812107cc5c81fe2571c46479138