-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
gollvm/gofrontend: when evaluates x twice in "x op= y", which was detectable if evaluating y affects x. #52811
gollvm/gofrontend: when evaluates x twice in "x op= y", which was detectable if evaluating y affects x. #52811
Comments
when evaluates x twice in "x op= y", which was detectable if evaluating y affects x. We should identify such cases and evaluate y first. fix golang/go#52811 (golang/go#52811)
When evaluates x twice in "x op= y", which was detectable if evaluating y affects x. We should identify such cases and evaluate y first. For reference see this bug in the go git repository: Fix golang/go#52811
Change https://go.dev/cl/405394 mentions this issue: |
cc @thanm |
I don't think that the language spec provides any guarantees about the order of evaluation of this statement. If you think that it does guarantee the order, can you explain your reasoning? Thanks. |
I think the issue is valid. Clearer repro:
This program should print |
Rationale: the Printing |
I would agree with that. Per the spec
So the operand |
OK, thanks. |
Change https://go.dev/cl/405616 mentions this issue: |
Change https://go.dev/cl/405617 mentions this issue: |
We found this issue by testing GoLLVM using the test case: |
@huanglanzhiguan Thanks. That would have been a helpful detail to mention in the original issue report. |
I've written a patch for the gofrontend to attempt to fix this problem (https://go.dev/cl/405617). When I run the initial program in this issue with the gc compiler, it prints 3501. When I run it with the patched gofrontend, I get 2388. This hinges on how we execute x[0] += func() int {
x = two
return 1113
}() I'm currently executing it as t1 := x
t2 := 0
t3 := func() int { x = two; return 1113 }()
t1[t2] = t3 When I do that, the program prints 2388. The only way to get 3501 is for the function to be executed before loading Does anybody think that the gofrontend is incorrect in printing 2388? Does anybody think that gc is incorrect in printing 3501? Thanks. |
It's correct for the reported, obfuscated test case to print either 2388 or 3501 (2388+1113). It's just incorrect to print other values, including 2412 (1299+1113). The original issue21687.go test case was written specifically to be flexible about order-of-evaluation variations in compilers. The new gofrontend behavior sounds correct to me. |
Fixes golang/go#52811 Change-Id: I369415d1188a483cba81257fdfbb0e5c1a7df1c4 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/405617 Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
What version of Go are you using (
go version
)?gollvm
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputDebian
Intel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz (Cascade Lake)
What did you do?
error case:
What did you expect to see?
3501
What did you see instead?
2412
cmd/compile: "x[i] op= y" evaluates x[i] more than once can also be referenced.
Error & Solution
An output of
2412
indicates that x[0] was evaluated twice as follows: once indexing into the old map to read the value 1299, and then once into the new to store the value1299 + 1113
.gofrontend doesn't consider such case: when evaluates x twice in "x op= y", evaluating y may affect x. In such case, y on the right should be evaluated first and x on the left should be read latter.
The text was updated successfully, but these errors were encountered: