aboutsummaryrefslogtreecommitdiff
path: root/test/uintptrescapes2.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2019-10-01 11:22:07 -0700
committerMatthew Dempsky <mdempsky@google.com>2019-11-05 00:26:30 +0000
commitb3bd7ab3d76c694bd87dfa31f9e7ccef15ed90a7 (patch)
tree907bad812817534aacf6622f9134d95f4df08d02 /test/uintptrescapes2.go
parent6cbd737c8e4a5aa5a8e85895c5ee6ff53a358622 (diff)
downloadgo-b3bd7ab3d76c694bd87dfa31f9e7ccef15ed90a7.tar.gz
go-b3bd7ab3d76c694bd87dfa31f9e7ccef15ed90a7.zip
cmd/compile: fix //go:uintptrescapes for basic method calls
The logic for keeping arguments alive for calls to //go:uintptrescapes functions was only applying to direct function calls. This CL changes it to also apply to direct method calls, which should address most uses of Proc.Call and LazyProc.Call. It's still an open question (#34684) whether other call forms (e.g., method expressions, or indirect calls via function values, method values, or interfaces). Fixes #34474. Change-Id: I874f97145972b0e237a4c9e8926156298f4d6ce0 Reviewed-on: https://go-review.googlesource.com/c/go/+/198043 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'test/uintptrescapes2.go')
-rw-r--r--test/uintptrescapes2.go40
1 files changed, 31 insertions, 9 deletions
diff --git a/test/uintptrescapes2.go b/test/uintptrescapes2.go
index 866efd94d8..3ff1d94042 100644
--- a/test/uintptrescapes2.go
+++ b/test/uintptrescapes2.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -m -live
+// errorcheck -0 -l -m -live
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -13,31 +13,53 @@ import (
)
//go:uintptrescapes
-//go:noinline
func F1(a uintptr) {} // ERROR "escaping uintptr"
//go:uintptrescapes
-//go:noinline
func F2(a ...uintptr) {} // ERROR "escaping ...uintptr"
//go:uintptrescapes
-//go:noinline
func F3(uintptr) {} // ERROR "escaping uintptr"
//go:uintptrescapes
-//go:noinline
func F4(...uintptr) {} // ERROR "escaping ...uintptr"
-func G() {
+type T struct{}
+
+//go:uintptrescapes
+func (T) M1(a uintptr) {} // ERROR "escaping uintptr"
+
+//go:uintptrescapes
+func (T) M2(a ...uintptr) {} // ERROR "escaping ...uintptr" "leaking param: a"
+
+func TestF1() {
var t int // ERROR "moved to heap"
F1(uintptr(unsafe.Pointer(&t))) // ERROR "live at call to F1: .?autotmp" "stack object .autotmp_[0-9]+ unsafe.Pointer$"
+}
+
+func TestF3() {
var t2 int // ERROR "moved to heap"
- F3(uintptr(unsafe.Pointer(&t2))) // ERROR "live at call to F3: .?autotmp"
+ F3(uintptr(unsafe.Pointer(&t2))) // ERROR "live at call to F3: .?autotmp" "stack object .autotmp_[0-9]+ unsafe.Pointer$"
}
-func H() {
+func TestM1() {
+ var t T
+ var v int // ERROR "moved to heap"
+ t.M1(uintptr(unsafe.Pointer(&v))) // ERROR "live at call to T.M1: .?autotmp" "stack object .autotmp_[0-9]+ unsafe.Pointer$"
+}
+
+func TestF2() {
var v int // ERROR "moved to heap"
F2(0, 1, uintptr(unsafe.Pointer(&v)), 2) // ERROR "live at call to newobject: .?autotmp" "live at call to F2: .?autotmp" "escapes to heap" "stack object .autotmp_[0-9]+ unsafe.Pointer$"
+}
+
+func TestF4() {
var v2 int // ERROR "moved to heap"
- F4(0, 1, uintptr(unsafe.Pointer(&v2)), 2) // ERROR "live at call to newobject: .?autotmp" "live at call to F4: .?autotmp" "escapes to heap"
+ F4(0, 1, uintptr(unsafe.Pointer(&v2)), 2) // ERROR "live at call to newobject: .?autotmp" "live at call to F4: .?autotmp" "escapes to heap" "stack object .autotmp_[0-9]+ unsafe.Pointer$"
+}
+
+func TestM2() {
+ var t T
+ var v int // ERROR "moved to heap"
+ t.M2(0, 1, uintptr(unsafe.Pointer(&v)), 2) // ERROR "live at call to newobject: .?autotmp" "live at call to T.M2: .?autotmp" "escapes to heap" "stack object .autotmp_[0-9]+ unsafe.Pointer$"
}