Files
tinygo/transform/testdata/allocs2.go
T
Jake Bailey 335b085fd2 transform: add allocation alias regression cases
Add allocation diagnostics coverage for pointer-returning helpers, aggregate
slice returns, and conditional pointer returns before changing the allocation
optimizer.

The golden files record the current heap-allocation behavior so later commits
show exactly which diagnostics each optimizer improvement removes.
2026-06-19 11:05:56 +02:00

177 lines
3.0 KiB
Go

package main
import (
"runtime/volatile"
"unsafe"
)
func main() {
n1 := 5
derefInt(&n1)
n2 := 6
returnIntPtr(&n2)
s1 := make([]int, 3)
readIntSlice(s1)
s2 := [3]int{}
readIntSlice(s2[:])
s3 := make([]int, 3)
returnIntSlice(s3)
useSlice(make([]int, getUnknownNumber()))
s4 := make([]byte, 300)
readByteSlice(s4)
s5 := make([]int, 4)
_ = append(s5, 5)
s6 := make([]int, 3)
s7 := []int{1, 2, 3}
copySlice(s6, s7)
c1 := getComplex128()
useInterface(c1)
n3 := 5
func() int {
return n3
}()
callVariadic(3, 5, 8)
s8 := []int{3, 5, 8}
callVariadic(s8...)
n4 := 3
n5 := 7
func() {
n4 = n5
}()
println(n4, n5)
// This shouldn't escape.
var buf [32]byte
s := string(buf[:])
println(len(s))
var rbuf [5]rune
s = string(rbuf[:])
println(s)
// Unsafe usage of DMA buffers: the compiler thinks this buffer won't be
// used anymore after the volatile store.
var dmaBuf1 [4]byte
pseudoVolatile.Set(uint32(unsafeNoEscape(unsafe.Pointer(&dmaBuf1[0]))))
// Safe usage of DMA buffers: keep the buffer alive until it is no longer
// needed, but don't mark it as needing to be heap allocated. The compiler
// will keep the buffer stack allocated if possible.
var dmaBuf2 [4]byte
pseudoVolatile.Set(uint32(unsafeNoEscape(unsafe.Pointer(&dmaBuf2[0]))))
// ...use the buffer in the DMA peripheral
keepAliveNoEscape(unsafe.Pointer(&dmaBuf2[0]))
}
type vector3 [3]float32
func scaleVector3(vec *vector3, f float32) *vector3 {
vec[0] *= f
vec[1] *= f
vec[2] *= f
return vec
}
func crossVector3(a, b *vector3) vector3 {
return vector3{
a[1]*b[2] - a[2]*b[1],
a[2]*b[0] - a[0]*b[2],
a[0]*b[1] - a[1]*b[0],
}
}
func nonEscapingReturnedPointer() vector3 {
a := vector3{1, 2, 3}
b := vector3{4, 5, 6}
c := scaleVector3(&b, 0.5)
return crossVector3(&a, c)
}
var escapedSlice []int
func escapingReturnedSlice() {
s := make([]int, 3)
escapedSlice = returnIntSlice(s)
}
var escapedVector3 *vector3
func escapingReturnedPointer() {
b := vector3{4, 5, 6}
c := scaleVector3(&b, 0.5)
escapedVector3 = c
}
func recursiveScaleVector3(vec *vector3, n int) *vector3 {
if n == 0 {
return vec
}
return recursiveScaleVector3(vec, n-1)
}
func recursiveReturnedPointer() vector3 {
b := vector3{4, 5, 6}
c := recursiveScaleVector3(&b, 1)
return *c
}
func derefInt(x *int) int {
return *x
}
func returnIntPtr(x *int) *int {
return x
}
func readIntSlice(s []int) int {
return s[1]
}
func readByteSlice(s []byte) byte {
return s[1]
}
func returnIntSlice(s []int) []int {
return s
}
func getUnknownNumber() int
func copySlice(out, in []int) {
copy(out, in)
}
func getComplex128() complex128
func useInterface(interface{})
func callVariadic(...int)
func useSlice([]int)
// See the function with the same name in the machine package.
//
//go:linkname unsafeNoEscape machine.unsafeNoEscape
func unsafeNoEscape(ptr unsafe.Pointer) uintptr
//go:linkname keepAliveNoEscape machine.keepAliveNoEscape
func keepAliveNoEscape(ptr unsafe.Pointer)
var pseudoVolatile volatile.Register32