Skip to content
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

builtin: appending a two max-len []struct{} results in a slice with negative len #7550

Closed
UserAB1236872 opened this issue Mar 15, 2014 · 5 comments
Milestone

Comments

@UserAB1236872
Copy link

What does 'go version' print?

go version 1.2.1 windows/amd64

What steps reproduce the problem?
Run this minimal program:

package main

import "fmt"

func main() {
    length := (1 << 63) - 1
    a := make([]struct{}, length/(1<<32))
    b := make([]struct{}, length/(1<<32))
    a = append(a, b...)
    fmt.Println(len(a), cap(a))
}

Note that this *cannot* be reproduced on the Playground. Even if you substitute the
value of length with the 32-bit MaxInt (since the Playground seems to use a size of 4
instead of 8 for ints), you'll correctly get a panic from this operation.

What happened?

It will print -2 7638104968020361214 (that is, the slice has len -2 and cap
7638104968020361214).

What should have happened instead?

Probably a panic of some sort.

Please provide any additional information below.

This seems to only happen with slices of type struct{}. I tried to reproduce the error
with a []int, and it always panicked in some way. One other odd node, if instead of doing

a = append(a,b...)

you do

a = append(a,struct{}{})

It will correctly panic with the error:

panic: runtime error:  runtime: allocation size out of range

One confusing thing is that the panic the Playground gives for these operations is:

panic: runtime error: growslice: cap out of range

So that may be an additional bug, or may be expected.
@UserAB1236872
Copy link
Author

Comment 1:

Oops, sorry, I copied a modification of the program, the lines should be
length := (1 << 63) - 1
a := make([]struct{}, length)
b := make([]struct{}, length)
a = append(a, b...)
fmt.Println(len(a), cap(a))
The division was when I was trying to check it with a []int

@ianlancetaylor
Copy link
Contributor

Comment 2:

For clarity, for this program:
package main
import "fmt"
func main() {
        length := (1 << 63) - 1
        a := make([]struct{}, length)
        b := make([]struct{}, length)
        a = append(a, b...)
        fmt.Println(len(a), cap(a))
}
"go run" prints "-2 -2".  When built with gccgo, it crashes with a "append: slice
overflow" panic.

Labels changed: added repo-main, release-go1.3.

@davecheney
Copy link
Contributor

Comment 3:

FWIW, 32bit platforms print the expected error message.

@davecheney
Copy link
Contributor

Comment 4:

https://golang.org/cl/83520043 is a start of a fix, it needs tightening up

Owner changed to @davecheney.

Status changed to Started.

@davecheney
Copy link
Contributor

Comment 5:

This issue was closed by revision 9121e7e.

Status changed to Fixed.

@rsc rsc added this to the Go1.3 milestone Apr 14, 2015
@rsc rsc removed the release-go1.3 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants