-
Notifications
You must be signed in to change notification settings - Fork 569
A lot of "unreachable code" warnings on Firefox #575
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
Comments
I'm seeing this issue occur again with latest playground, built with latest gopherjs. Reopning to track it. I'll try to add more details soon, but this is very easy to reproduce. I tested with Firefox Nightly. |
It happens on the same input as in the original issue report. |
Investing this a little further. To reproduce this with a simpler setup (a small Go package, and package main
import "strconv"
func main() {
u, err := strconv.ParseUint("42", 10, 64)
if err != nil {
panic(err)
}
if u != 42 {
panic("u != 42")
}
} The unreachable code only happens for certain packages/functions. For example, importing only The above program generates: The relevant line looks like this: |
Looking at the source of ...
n1 := n + uint64(v)
if n1 < n || n1 > maxVal {
// n+v overflows
n = maxUint64
err = ErrRange
goto Error
}
n = n1
}
return n, nil
Error:
return n, &NumError{"ParseUint", s, err}
} |
This is also affecting:
And possibly more. Those were just some that I found from some of my large codebase compiled with GopherJS. |
I don't know whether related, closure compiler reports "unreachable code" even for such a simple program as "Hello, world": package main
func main() {
println("Hello, world!")
}
2224: $pkg.$init = function() {};
2225: /* */ var $f, $c = false, $s = 0, $r; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0:
2226: init();
2227: /* */ } return; } if ($f === undefined) { $f = { $blk: $init }; } $f.$s = $s; $f.$r = $r; return $f; And when the compiler is started with java -jar ~/closure.jar --js main.js --js_output_file main.min.js --compilation_level ADVANCED_OPTIMIZATIONS |
With just
Serve on Darwin using firefox (macos) gives 3 "unreachable code after return statement" first is in internal/poll FD.ptr.prototype.WriteTo:
My eyeball-interpreter couldn't figure out where |
When GopherJS flattens a loop into a while-switch-case construct, it needs to generate an instruction to go back to the beginning of the loop after the last statement of the loop body. However, when the last statement is a control statement itself (return, continue, break, goto), this instruction becomes unnecessary and unreachable. Example Go code: ```go func foo() { for { // Do something break } } ``` This change prevents such an instruction from being generated. This has a marginal artifact size reduction (1632 bytes on todomvc), but also eliminates a warning Firefox prints in the console, which may be confusing to users (gopherjs#1069, gopherjs#575).
The improved check is able to detect cases when the return statement is wrapped in another statement, but is effectively the last executed statement in a list, for example: ```go func withGoto() (resultType, error) { // Do something. return result, nil Error: return nil, err // This is inside an *ast.LabeledStmt! } func withBlock() resultType { // Do something. { // Do more. return result // This is inside a *ast.BlockStmt! } } ``` Better detection prevents generation of unnecessary return statements at the end of a function (marginally smaller output size), as well as prevents "unreachable code" warnings in Firefox (gopherjs#575, gopherjs#1069).
The improved check is able to detect cases when the return statement is wrapped in another statement, but is effectively the last executed statement in a list, for example: ```go func withGoto() (resultType, error) { // Do something. return result, nil Error: return nil, err // This is inside an *ast.LabeledStmt! } func withBlock() resultType { // Do something. { // Do more. return result // This is inside a *ast.BlockStmt! } } ``` Better detection prevents generation of unnecessary return statements at the end of a function (marginally smaller output size), as well as prevents "unreachable code" warnings in Firefox (gopherjs#575, gopherjs#1069).
#1071 should eliminate "unreachable code" warnings in Firefox for both cases that this issue mentions. The Closure compiler warnings mentioned in #575 (comment) are of a different kind, based on a much more advanced analysis it does. AFAIK, GopherJS is not very friendly to Closure compiler in general. I have plans to do some work on reducing output size, so I'm going to punt on this problem until then. |
It seems like this occurs even in the playground itself, so it's hard to suggest a minimum code snippet with the playground.
http://www.gopherjs.org/playground/#/uo5azM3CaP
The text was updated successfully, but these errors were encountered: