Open
Description
$ tinygo version
tinygo version 0.31.2 linux/amd64 (using go version go1.22.0 and LLVM version 17.0.1)
Kinda a corner case but reporting anyway since I saw it.
Trying to compile the the following program:
package main
import "unsafe"
var p = unsafe.SliceData([]int{})
var v = *p
func main() {}
crashes tinygo:
$ tinygo build crash.go
panic: interp: load out of bounds
goroutine 37 [running]:
github.com/tinygo-org/tinygo/interp.(*memoryView).load(0xc000c4a8a0, {0x0?}, 0x8)
/__w/tinygo/tinygo/interp/memory.go:315 +0x1e5
github.com/tinygo-org/tinygo/interp.(*runner).run(0xc001b9e140, 0xc00154c0a0, {0x0, 0x0, 0x54ec79?}, 0x0, {0x5fba2cf, 0x4})
/__w/tinygo/tinygo/interp/interpreter.go:582 +0x19db
github.com/tinygo-org/tinygo/interp.RunFunc({0xc000320780?}, 0x29e8d60800, 0x0)
/__w/tinygo/tinygo/interp/interp.go:237 +0x3a6
github.com/tinygo-org/tinygo/builder.Build.func3(0xc0015c3080)
/__w/tinygo/tinygo/builder/build.go:450 +0xc8f
github.com/tinygo-org/tinygo/builder.runJob(0xc0015c3080, 0xc00200b4a0)
/__w/tinygo/tinygo/builder/jobs.go:222 +0x4d
created by github.com/tinygo-org/tinygo/builder.runJobs in goroutine 1
/__w/tinygo/tinygo/builder/jobs.go:123 +0x5bd
Strictly speaking, the program is valid (and the main Go toolchain compiles it). From the unsafe.SliceData
doc:
The function SliceData returns a pointer to the underlying array of the slice argument. If the slice's capacity cap(slice) is not zero, that pointer is &slice[:1][0]. If slice is nil, the result is nil. Otherwise it is a non-nil pointer to an unspecified memory address.
Since cap([]int{}) = 0
, p
is a non-nil pointer and thus it should be allowed to dereference it in the assignment to v
.