mirror of
https://github.com/golang/go
synced 2024-11-18 20:14:43 -07:00
1a3e968b1f
In CL 253457, we did the same fix for direct function calls. But for method calls, the receiver argument also need to be passed through the wrapper function, which we are not doing so the compiler crashes with the code in #44415. As we already rewrite t.M(...) into T.M(t, ...) during walkCall1, to fix this, we can do the same trick in wrapCall, so the receiver argument will be treated as others. Fixes #44415 Change-Id: I396182983c85d9c5e4494657da79d25636e8a079 Reviewed-on: https://go-review.googlesource.com/c/go/+/294849 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org>
96 lines
1.8 KiB
Go
96 lines
1.8 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()))
|
|
}
|
|
|
|
type S struct{}
|
|
|
|
//go:noinline
|
|
//go:uintptrescapes
|
|
func (S) 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
|
|
}
|
|
|
|
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
|
|
|
|
func() {
|
|
s := &S{}
|
|
defer s.test("method call", uintptr(setup()), uintptr(setup()))
|
|
}()
|
|
<-done
|
|
|
|
f()
|
|
<-done
|
|
}
|