-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
cmd/compile: max/min builtin broken when used with string(byte) conversions #64565
Comments
Simpler reproducer: func main() {
num := "765"
maxSymbol := ""
for i := 0; i < len(num); i++ {
newMax := max(string(num[i]), maxSymbol)
fmt.Printf("max(%q, %q)=%q\n", string(num[i]), maxSymbol, newMax)
maxSymbol = newMax
}
} $ go run main.go
max("7", "")="7"
max("6", "6")="6"
max("5", "5")="5" Making a func main() {
num := "765"
maxSymbol := ""
for i := 0; i < len(num); i++ {
tmp := string(num[i])
newMax := max(tmp, maxSymbol)
fmt.Printf("max(%q, %q)=%q\n", tmp, maxSymbol, newMax)
maxSymbol = newMax
}
} $ go run main.go
max("7", "")="7"
max("6", "7")="7"
max("5", "7")="7" EDIT: The same thing happens with |
CC @golang/compiler |
Note that the commit title is not accurate. |
This appears to be an escape analysis issue. @gopherbot Please backport to Go 1.21. This is a silent miscompilation / memory corruption issue. |
Backport issue(s) opened: #64567 (for 1.21). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases. |
I find it weird that in this reproducer:
If you stop a debugger in the newMax assignment line where |
Change https://go.dev/cl/547715 mentions this issue: |
Thanks all for the report. FWIW, since there's some interest in the issue, here's an explanation of what's going on. Starting from this reproducer:
The compiler transforms this into basically:
where intstring and strmax are provided by the runtime. However, the compiler was not correctly taking into consideration that strmax returns one of its arguments. That is, it didn't realize
|
Thank you for taking the time to provide such a detailed explanation, much appreciated! |
Change https://go.dev/cl/547757 mentions this issue: |
…n/max When I was plumbing min/max support through the compiler, I was thinking mostly about numeric argument types. As a result, I forgot that escape analysis would need to be aware that min/max can operate on string values, which contain pointers. Updates #64565. Fixes #64567. Change-Id: I36127ce5a2da942401910fa0f9de922726c9f94d Reviewed-on: https://go-review.googlesource.com/c/go/+/547715 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> (cherry picked from commit 34416d7) Reviewed-on: https://go-review.googlesource.com/c/go/+/547757 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
When I was plumbing min/max support through the compiler, I was thinking mostly about numeric argument types. As a result, I forgot that escape analysis would need to be aware that min/max can operate on string values, which contain pointers. Fixes golang#64565. Change-Id: I36127ce5a2da942401910fa0f9de922726c9f94d Reviewed-on: https://go-review.googlesource.com/c/go/+/547715 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Go version
go1.21.0 linux/amd64
What operating system and processor architecture are you using (
go env
)?What did you do?
Here is a proof https://go.dev/play/p/Dr26MV2mvGW from https://www.reddit.com/r/golang/comments/18be9xl/max_and_assign_issue/
Credit to /u/ar1819 and /u/YamadaAnna
What did you expect to see?
max() and slices.Max() should have the same results. 7 is the bigger number.
What did you see instead?
max() output numbers lower than 7 as maxes.
The text was updated successfully, but these errors were encountered: