Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix(minifier): reference read has side effect (#6851)
  • Loading branch information
Boshen committed Oct 24, 2024
commit 686727fc96fbe903f496174944948c7e57f167de
16 changes: 0 additions & 16 deletions crates/oxc_ecmascript/src/constant_evaluation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,22 +430,6 @@ pub trait ConstantEvaluation<'a> {
left_string.cmp(&right_string) == Ordering::Less,
));
}

// Special case: `typeof a < typeof a` is always false.
if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) =
(left_expr, right_expr)
{
if (left.operator, right.operator) == (UnaryOperator::Typeof, UnaryOperator::Typeof)
{
if let (Expression::Identifier(left), Expression::Identifier(right)) =
(&left.argument, &right.argument)
{
if left.name == right.name {
return Some(ConstantValue::Boolean(false));
}
}
}
}
}

// TODO: bigint is handled very differently in the spec
Expand Down
10 changes: 5 additions & 5 deletions crates/oxc_ecmascript/src/side_effects/check_for_state_change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ impl<'a, 'b> CheckForStateChange<'a, 'b> for Expression<'a> {
.expressions
.iter()
.any(|expr| expr.check_for_state_change(check_for_new_objects)),
Self::Identifier(_ident) =>
/* TODO: ident.reference_flags == ReferenceFlags::Write */
{
false
}
Self::Identifier(ident) => match ident.name.as_str() {
"undefined" | "NaN" | "Infinity" => false,
// Reference read can have a side effect.
_ => true,
},
Self::UnaryExpression(unary_expr) => {
unary_expr.check_for_state_change(check_for_new_objects)
}
Expand Down
47 changes: 15 additions & 32 deletions crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use oxc_ecmascript::{
use oxc_span::{GetSpan, SPAN};
use oxc_syntax::{
number::{NumberBase, ToJsString},
operator::{BinaryOperator, LogicalOperator, UnaryOperator},
operator::{BinaryOperator, LogicalOperator},
};
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};

Expand Down Expand Up @@ -411,23 +411,6 @@ impl<'a, 'b> PeepholeFoldConstants {
return Tri::from(left_string == right_string);
}

if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) =
(left_expr, right_expr)
{
if (left.operator, right.operator)
== (UnaryOperator::Typeof, UnaryOperator::Typeof)
{
if let (Expression::Identifier(left), Expression::Identifier(right)) =
(&left.argument, &right.argument)
{
if left.name == right.name {
// Special case, typeof a == typeof a is always true.
return Tri::True;
}
}
}
}

Tri::Unknown
}
ValueType::Undefined | ValueType::Null => Tri::True,
Expand Down Expand Up @@ -713,28 +696,28 @@ mod test {
fn test_boolean_number_comparison() {
test_same("!x==+y");
test_same("!x<=+y");
test("!x !== +y", "true");
test_same("!x !== +y");
}

#[test]
fn test_number_boolean_comparison() {
test_same("+x==!y");
test_same("+x<=!y");
test("+x === !y", "false");
test_same("+x === !y");
}

#[test]
fn test_boolean_string_comparison() {
test_same("!x==''+y");
test_same("!x<=''+y");
test("!x !== '' + y", "true");
test_same("!x !== '' + y");
}

#[test]
fn test_string_boolean_comparison() {
test_same("''+x==!y");
test_same("''+x<=!y");
test("'' + x === !y", "false");
test_same("'' + x === !y");
}

#[test]
Expand All @@ -746,8 +729,8 @@ mod test {
test("+'a' < +'b'", "false");
test_same("typeof a < 'a'");
test_same("'a' >= typeof a");
test("typeof a < typeof a", "false");
test("typeof a >= typeof a", "true");
test_same("typeof a < typeof a");
test_same("typeof a >= typeof a");
test("typeof 3 > typeof 4", "false");
test("typeof function() {} < typeof function() {}", "false");
test("'a' == 'a'", "true");
Expand All @@ -756,11 +739,11 @@ mod test {
test_same("typeof a != 'number'");
test_same("'undefined' == typeof a");
test_same("'undefined' == typeof a");
test("typeof a == typeof a", "true");
test_same("typeof a == typeof a");
test("'a' === 'a'", "true");
test("'b' !== 'a'", "true");
test("typeof a === typeof a", "true");
test("typeof a !== typeof a", "false");
test_same("typeof a === typeof a");
test_same("typeof a !== typeof a");
test_same("'' + x <= '' + y");
test_same("'' + x != '' + y");
test_same("'' + x === '' + y");
Expand All @@ -783,7 +766,7 @@ mod test {
test("1 !== '1'", "true");
test_same("+x>''+y");
test_same("+x==''+y");
test("+x !== '' + y", "true");
test_same("+x !== '' + y");
}

#[test]
Expand All @@ -799,7 +782,7 @@ mod test {
test("'1' !== 1", "true");
test_same("''+x<+y");
test_same("''+x==+y");
test("'' + x === +y", "false");
test_same("'' + x === +y");
}

#[test]
Expand Down Expand Up @@ -901,8 +884,8 @@ mod test {
test_same("x>=NaN");
test_same("NaN==x");
test_same("x!=NaN");
test("NaN === x", "false");
test("x !== NaN", "true");
test_same("NaN === x");
test_same("x !== NaN");
test_same("NaN==foo()");
}

Expand Down Expand Up @@ -1109,7 +1092,7 @@ mod test {
fn test_fold_void() {
test_same("void 0");
test("void 1", "void 0");
test("void x", "void 0");
test_same("void x");
test_same("void x()");
}

Expand Down
14 changes: 1 addition & 13 deletions tasks/coverage/snapshots/runtime.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ commit: 06454619

runtime Summary:
AST Parsed : 18444/18444 (100.00%)
Positive Passed: 18269/18444 (99.05%)
Positive Passed: 18273/18444 (99.07%)
tasks/coverage/test262/test/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js
minify error: Test262Error: Expected SameValue(«function f(){}», «undefined») to be true

Expand Down Expand Up @@ -420,15 +420,6 @@ minify error: Test262Error: #3.2: -0 - 0 === - 0. Actual: +0
tasks/coverage/test262/test/language/expressions/super/call-spread-obj-getter-init.js
transform error: Test262Error: Expected SameValue(«true», «false») to be true

tasks/coverage/test262/test/language/expressions/template-literal/literal-expr-tostr-error.js
minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all

tasks/coverage/test262/test/language/expressions/template-literal/middle-list-many-expr-tostr-error.js
minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all

tasks/coverage/test262/test/language/expressions/template-literal/middle-list-one-expr-tostr-error.js
minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all

tasks/coverage/test262/test/language/expressions/unary-plus/S11.4.6_A3_T3.js
minify error: Test262Error: #4: +"INFINITY" === Not-a-Number. Actual: Infinity

Expand All @@ -438,9 +429,6 @@ minify error: Test262Error: #3.2: +(-0) === -0. Actual: +0
tasks/coverage/test262/test/language/expressions/unary-plus/bigint-throws.js
minify error: Test262Error: +0n throws TypeError Expected a TypeError to be thrown but no exception was thrown at all

tasks/coverage/test262/test/language/expressions/void/S11.4.2_A2_T2.js
minify error: Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all

tasks/coverage/test262/test/language/global-code/decl-func.js
codegen error: Test262Error: descriptor should not be configurable

Expand Down