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
gccgo: "range x" evaluates x even when it shouldn't #22313
Comments
|
Just curious: why did we add that caveat to the spec in the first place? It's annoyingly inconsistent with the general “range expression is evaluated once” rule... |
@bcmills I think so that
is equivalent to
|
I was going to say that they're already not equivalent, but now I don't even know. The current phrasing of the spec suggests that this program should not evaluate the call to func panicArray() [3]int {
panic("nope")
}
func main() {
for i := range panicArray() {
fmt.Println(i)
}
} |
|
That's my point: according to the current phrasing, it seems like “if the range expression is an array or a pointer to an array and at most one iteration variable is present, only the range expression's length is evaluated” is not conditioned upon whether the expression is a constant. I suppose that depends on fairly subtle details about what it means to “evaluate” the length of an array of constant size returned by a function call. (Contrast |
That's why the new phrasing, suggested via #22258 ( https://go-review.googlesource.com/c/go/+/71431/3/doc/go_spec.html ) makes this clearer. The range expression Note that |
Oh, I just noticed there's even this example in the spec, which demonstrates the same bug:
|
Change https://golang.org/cl/91555 mentions this issue: |
The language spec says that in `for i = range x`, in which there is no second iteration variable, if len(x) is constant, then x is not evaluated. This only matters when x is an expression that panics but whose type is an array type; in such a case, we should not evaluate x, since len of any array type is a constant. Fixes golang/go#22313 Reviewed-on: https://go-review.googlesource.com/91555 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@257330 138bc75d-0d04-0410-961f-82ee72b054a4
Change https://golang.org/cl/91715 mentions this issue: |
The last change was incomplete, in that it did not evaluate the array argument in some cases where it had to be evaluated. This reuses the existing code for checking whether len/cap is constant. Also clean up the use of _ as the second variable in a for/range, which was previously inconsistent depending on whether the statement used = or :=. Updates golang/go#22313 Change-Id: I8fe09a64026aa9f8833197df2454a8581e98f60b Reviewed-on: https://go-review.googlesource.com/91715 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
The last change was incomplete, in that it did not evaluate the array argument in some cases where it had to be evaluated. This reuses the existing code for checking whether len/cap is constant. Also clean up the use of _ as the second variable in a for/range, which was previously inconsistent depending on whether the statement used = or :=. Updates golang/go#22313 Reviewed-on: https://go-review.googlesource.com/91715 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@257377 138bc75d-0d04-0410-961f-82ee72b054a4
The language spec says that in `for i = range x`, in which there is no second iteration variable, if len(x) is constant, then x is not evaluated. This only matters when x is an expression that panics but whose type is an array type; in such a case, we should not evaluate x, since len of any array type is a constant. Fixes golang/go#22313 Reviewed-on: https://go-review.googlesource.com/91555 From-SVN: r257330
The Go spec says (though see also #22258):
In the program below
*p
has a constant length (and evenlen(*p)
is constant) and there's at most one iteration variable present, so*p
should not be evaluated:When compiled with cmd/compile, this program runs and exits normally. (Seemingly according to spec.)
When compiled with gccgo, this program panics because of a nil pointer dereference. (Seemingly contrary to the spec.)
/cc @ianlancetaylor @griesemer
The text was updated successfully, but these errors were encountered: