Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New option to throw error on obvious runtime errors #1500

Closed
alexlamsl opened this issue Feb 23, 2017 · 10 comments
Closed

New option to throw error on obvious runtime errors #1500

alexlamsl opened this issue Feb 23, 2017 · 10 comments

Comments

@alexlamsl
Copy link
Collaborator

From #1497 (comment)

@alexlamsl
Copy link
Collaborator Author

$ node
> try{console.log(function(){var a;const a=2;return a}())}catch(e){console.log("E!",e)}
try{console.log(function(){var a;const a=2;return a}())}catch(e){console.log("E!",e)}
                                         ^
SyntaxError: Identifier 'a' has already been declared

> try{console.log(function(){a = 1;const a=2;return a}())}catch(e){console.log("E!",e)}
E! ReferenceError: a is not defined
    at repl:1:30

@alexlamsl
Copy link
Collaborator Author

$ node
> "use strict";try{"abc".in=1}catch(e){console.error("E", e)}
E TypeError: Cannot create property 'in' on string 'abc'
    at repl:1:26
    at ContextifyScript.Script.runInThisContext (vm.js:23:33)

@alexlamsl
Copy link
Collaborator Author

After #1910 the const-related portion of this would go onto harmony only.

If we were to introduce say options.parse.captain_obvious, and throw errors for cases listed above, we are in theory preventing code that could otherwise run properly from being optimised.

I guess we should have that flag off by default, and serve as some form of extra sanity checks?

@kzc
Copy link
Contributor

kzc commented May 11, 2017

The original motivation for this issue was that an optimization was ignoring the const-ness of const variables and uglify issued a warning rather than error. It should have disallowed the optimization outright so that the original incorrect code could be preserved in the final output. Has this been resolved? I think const variable modification is no longer allowed.

@alexlamsl
Copy link
Collaborator Author

The new collapse_vars still does the wrong thing per se:

$ echo 'function f(){const a=1;a=2;return a}' | bin/uglifyjs -c reduce_vars=0
function f(){return 2}

reduce_vars knows to avoid const on current master, and with #1910 that logic is removed because the parser will just throw upon encountering const.

@kzc
Copy link
Contributor

kzc commented May 11, 2017

I consider that a regression in 2.x. It did not use to behave like that:

$ uglifyjs -V
uglify-js 2.7.5

$ echo 'function f(){const a=1;a=2;return a}' | uglifyjs -c collapse_vars
function f(){const a=1;return a=2}

$ echo 'function f(){const a=1;a=2;return a}' | uglifyjs -c collapse_vars,reduce_vars
function f(){const a=1;return a=2}

The code emitted above, although transformed, would preserve the error of the assignment to const.

@alexlamsl
Copy link
Collaborator Author

Indeed that's odd - 2.8.23 is using the older version of collapse_vars yet it collapsed the assignment somehow:

$ bin/uglifyjs -V
uglify-js 2.8.23

$ echo 'function f(){const a=1;a=2;return a}' | bin/uglifyjs -c reduce_vars=0,evaluate=0
function f(){return 2}

I'll try and figure this out in a bit when I'm done with #1910 & #1916

@alexlamsl
Copy link
Collaborator Author

alexlamsl commented May 11, 2017

Ah, looking in the wrong place for v2.x - nothing to do with collapse_vars:

  • sequences: a=2; return a; ➡️ return a=2, a;
  • cascade: return a=2, a; ➡️ return a=2;
  • unused: const a=1; return a=2; ➡️ return 2;

So I think if I add the extra checks for assign_as_unused to make sure it doesn't act on const, that should fix that regression.

@kzc
Copy link
Contributor

kzc commented May 12, 2017

@alexlamsl I think this issue can be closed now that you've addressed the const problem in various ways in various branches.

@alexlamsl
Copy link
Collaborator Author

Cool 😎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants