go/test/uintptrescapes.dir/main.go
Ian Lance Taylor bbe5da4260 cmd/compile, syscall: add //go:uintptrescapes comment, and use it
This new comment can be used to declare that the uintptr arguments to a
function may be converted from pointers, and that those pointers should
be considered to escape. This is used for the Call methods in
dll_windows.go that take uintptr arguments, because they call Syscall.

We can't treat these functions as we do syscall.Syscall, because unlike
Syscall they may cause the stack to grow. For Syscall we can assume that
stack arguments can remain on the stack, but for these functions we need
them to escape.

Fixes #16035.

Change-Id: Ia0e5b4068c04f8d303d95ab9ea394939f1f57454
Reviewed-on: https://go-review.googlesource.com/24551
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-07-06 20:48:41 +00:00

92 lines
1.3 KiB
Go

// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"os"
"sync"
"unsafe"
"./a"
)
func F1() int {
var buf [1024]int
a.F1(uintptr(unsafe.Pointer(&buf[0])))
return buf[0]
}
func F2() int {
var buf [1024]int
a.F2(uintptr(unsafe.Pointer(&buf[0])))
return buf[0]
}
var t = a.GetT()
func M1() int {
var buf [1024]int
t.M1(uintptr(unsafe.Pointer(&buf[0])))
return buf[0]
}
func M2() int {
var buf [1024]int
t.M2(uintptr(unsafe.Pointer(&buf[0])))
return buf[0]
}
func main() {
// Use different goroutines to force stack growth.
var wg sync.WaitGroup
wg.Add(4)
c := make(chan bool, 4)
go func() {
defer wg.Done()
b := F1()
if b != 42 {
fmt.Printf("F1: got %d, expected 42\n", b)
c <- false
}
}()
go func() {
defer wg.Done()
b := F2()
if b != 42 {
fmt.Printf("F2: got %d, expected 42\n", b)
c <- false
}
}()
go func() {
defer wg.Done()
b := M1()
if b != 42 {
fmt.Printf("M1: got %d, expected 42\n", b)
c <- false
}
}()
go func() {
defer wg.Done()
b := M2()
if b != 42 {
fmt.Printf("M2: got %d, expected 42\n", b)
c <- false
}
}()
wg.Wait()
select {
case <-c:
os.Exit(1)
default:
}
}