-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: inconsistent behaviour in multiple assignment #23017
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
The order of evaluation rules for the language do not specify precisely when a pointer indirection occurs. I think that either behavior is permitted by the language. CC @griesemer |
From the spec:
That sounds like program 1, we should set |
[edited: The conclusion below is wrong, see next comment] @randall77 I think this example in the spec is wrong. The prose before says:
That is, we shouldn't get to the assignment if there's a nil-pointer exception. I'd conclude the behavior for program 1 is correct. Secondly, I don't see anything in the spec stating when panics due to assignments to nil maps should happen in multiple assignments; I'd conclude that the behavior for program 2 is at least not incorrect. We should a) fix the spec example, and b) decide if we want to say anything more about map assignments. |
Never mind; I misread. The operands are evaluated, but not the entire expression. So the spec example is correct, and program 1 should assign to m. |
My understanding of the spec is that
That is, program 1 should print 1. |
Related discussion: #15620. |
Program 1 is miscompiled by cmd/compile because order.go rewrites
into
|
gccgo prints 1 and 5 for programs 1 and 2, respectively. |
Right, the spec says:
So I take that to mean that in the first phase, we evaluate the right hand side, plus any arguments of See #22881 also. |
OP's program 1 fails for all of go1.3-tip. Go 1.2 gets it right! |
Punting again, too late for 1.13. |
How about:
Must I expected it does, but current test case indicate it is not modified. |
Ah ok, it should not modify map, because we evaluate RHS first, but RHS panics. |
Change https://golang.org/cl/198679 mentions this issue: |
Change https://golang.org/cl/200580 mentions this issue: |
Passes toolstash-check. Updates #23017 Change-Id: I0ae82e28a6e9e732ba2a6aa98f9b35551efcea10 Reviewed-on: https://go-review.googlesource.com/c/go/+/200580 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Change https://golang.org/cl/261677 mentions this issue: |
"aliased" is the function responsible for detecting whether we can turn "a, b = x, y" into just "a = x; b = y", or we need to pre-compute y and save it in a temporary variable because it might depend on a. It currently has two issues: 1. It suboptimally treats assignments to blank as writes to heap memory. Users generally won't write "_, b = x, y" directly, but it comes up a lot in generated code within the compiler. This CL changes it to ignore blank assignments. 2. When deciding whether the assigned variable might be referenced by pointers, it mistakenly checks Class() and Name.Addrtaken() on "n" (the *value* expression being assigned) rather than "a" (the destination expression). It doesn't appear to result in correctness issues (i.e., incorrectly reporting no aliasing when there is potential aliasing), due to all the (overly conservative) rewrite passes before code reaches here. But it generates unnecessary code and could have correctness issues if we improve those other passes to be more aggressive. This CL fixes the misuse of "n" for "a" by renaming the variables to "r" and "l", respectively, to make their meaning clearer. Improving these two cases shaves 4.6kB of text from cmd/go, and 93kB from k8s.io/kubernetes/cmd/kubelet: text data bss dec hex filename 9732136 290072 231552 10253760 9c75c0 go.before 9727542 290072 231552 10249166 9c63ce go.after 97977637 1007051 301344 99286032 5eafc10 kubelet.before 97884549 1007051 301344 99192944 5e99070 kubelet.after While here, this CL also collapses "memwrite" and "varwrite" into a single variable. Logically, they're detecting the same thing: are we assigning to a memory location that a pointer might alias. There's no need for two variables. Updates #6853. Updates #23017. Change-Id: I5a307b8e20bcd2196e85c55eb025d3f01e303008 Reviewed-on: https://go-review.googlesource.com/c/go/+/261677 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Change https://golang.org/cl/281172 mentions this issue: |
What version of Go are you using (
go version
)?go version go1.9.2 linux/amd64
Does this issue reproduce with the latest release?
yes
What did you do?
Two programs:
program 1:
program 2:
What did you expect to see?
The behaviors of the two programs should be consistent.
What did you see instead?
The behaviors of the two programs are not consistent.
program 1 finishes zero assignments.
but program 2 finishes one assignment.
The text was updated successfully, but these errors were encountered: