Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix two classes of "unreachable code" warnings in Firefox. #1071

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

Merged
merged 2 commits into from
Oct 4, 2021

Conversation

nevkontakte
Copy link
Member

This PR prevents GopherJS compiler from emitting unnecessary control statements in two cases:

  1. A redundant return at the end of a function, which already has a return statement at the end, but this statement is wrapped into another AST element.
  2. A redundant instruction to go to the beginning of a flattened loop, in case the last statement of the loop is a return or unconditional branching statement (break, continue, goto).

The change is mostly cosmetic and prevents Firefox from spamming "unreachable code" warnings, which can be confusing to GopherJS users. It also marginally reduces the size of the generated code, but the effect is so small that it doesn't really matter.

Fixed #575, #1069.

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).
@nevkontakte nevkontakte merged commit 6b77bd3 into gopherjs:master Oct 4, 2021
@nevkontakte nevkontakte deleted the issue-575 branch October 4, 2021 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A lot of "unreachable code" warnings on Firefox
2 participants