mirror of
https://github.com/golang/go
synced 2024-11-08 11:16:19 -07:00
76a615b20a
Before generating wrapper function, turn any f(a, b, []T{c, d, e}...) calls back into f(a, b, c, d, e). This allows the existing code for recognizing and specially handling unsafe.Pointer->uintptr conversions to correctly handle variadic arguments too. Fixes #41460. Change-Id: I0a1255abdd1bd5dafd3e89547aedd4aec878394c Reviewed-on: https://go-review.googlesource.com/c/go/+/263297 Trust: Matthew Dempsky <mdempsky@google.com> Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
66 lines
1.3 KiB
Go
66 lines
1.3 KiB
Go
// run
|
|
|
|
// Copyright 2020 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.
|
|
|
|
// This test makes sure unsafe-uintptr arguments are handled correctly.
|
|
|
|
package main
|
|
|
|
import (
|
|
"runtime"
|
|
"unsafe"
|
|
)
|
|
|
|
var done = make(chan bool, 1)
|
|
|
|
func setup() unsafe.Pointer {
|
|
s := "ok"
|
|
runtime.SetFinalizer(&s, func(p *string) { *p = "FAIL" })
|
|
return unsafe.Pointer(&s)
|
|
}
|
|
|
|
//go:noinline
|
|
//go:uintptrescapes
|
|
func test(s string, p, q uintptr, rest ...uintptr) int {
|
|
runtime.GC()
|
|
runtime.GC()
|
|
|
|
if *(*string)(unsafe.Pointer(p)) != "ok" {
|
|
panic(s + ": p failed")
|
|
}
|
|
if *(*string)(unsafe.Pointer(q)) != "ok" {
|
|
panic(s + ": q failed")
|
|
}
|
|
for _, r := range rest {
|
|
if *(*string)(unsafe.Pointer(r)) != "ok" {
|
|
panic(s + ": r[i] failed")
|
|
}
|
|
}
|
|
|
|
done <- true
|
|
return 0
|
|
}
|
|
|
|
//go:noinline
|
|
func f() int {
|
|
return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
|
}
|
|
|
|
func main() {
|
|
test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
|
<-done
|
|
|
|
go test("go", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
|
<-done
|
|
|
|
func() {
|
|
defer test("defer", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
|
}()
|
|
<-done
|
|
|
|
f()
|
|
<-done
|
|
}
|