mirror of
https://github.com/golang/go
synced 2024-11-22 20:40:03 -07:00
[dev.typeparams] cmd/compile: skip escape analysis diagnostics for wrappers
This CL changes escape analysis to skip reporting diagnostics (at least for parameter tagging) for generated wrappers. We're inconsistent about when/where wrappers are generated, which made errorcheck tests of escape analysis unnecessarily brittle to changes in wrapper generation. This CL addresses this making errorcheck tests only care about tagging of the actual functions themselves, not the wrappers too. Change-Id: Ia1a0b9dabee4d4162b05647f871db03b032c945a Reviewed-on: https://go-review.googlesource.com/c/go/+/330689 Trust: Matthew Dempsky <mdempsky@google.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>
This commit is contained in:
parent
b55cc6687d
commit
df00abc61b
@ -365,6 +365,11 @@ func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
|
|||||||
return fmt.Sprintf("arg#%d", narg)
|
return fmt.Sprintf("arg#%d", narg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only report diagnostics for user code;
|
||||||
|
// not for wrappers generated around them.
|
||||||
|
// TODO(mdempsky): Generalize this.
|
||||||
|
diagnose := base.Flag.LowerM != 0 && !(fn.Wrapper() || fn.Dupok())
|
||||||
|
|
||||||
if len(fn.Body) == 0 {
|
if len(fn.Body) == 0 {
|
||||||
// Assume that uintptr arguments must be held live across the call.
|
// Assume that uintptr arguments must be held live across the call.
|
||||||
// This is most important for syscall.Syscall.
|
// This is most important for syscall.Syscall.
|
||||||
@ -375,7 +380,7 @@ func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
|
|||||||
fn.Pragma |= ir.UintptrKeepAlive
|
fn.Pragma |= ir.UintptrKeepAlive
|
||||||
|
|
||||||
if f.Type.IsUintptr() {
|
if f.Type.IsUintptr() {
|
||||||
if base.Flag.LowerM != 0 {
|
if diagnose {
|
||||||
base.WarnfAt(f.Pos, "assuming %v is unsafe uintptr", name())
|
base.WarnfAt(f.Pos, "assuming %v is unsafe uintptr", name())
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
@ -390,11 +395,11 @@ func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
|
|||||||
// External functions are assumed unsafe, unless
|
// External functions are assumed unsafe, unless
|
||||||
// //go:noescape is given before the declaration.
|
// //go:noescape is given before the declaration.
|
||||||
if fn.Pragma&ir.Noescape != 0 {
|
if fn.Pragma&ir.Noescape != 0 {
|
||||||
if base.Flag.LowerM != 0 && f.Sym != nil {
|
if diagnose && f.Sym != nil {
|
||||||
base.WarnfAt(f.Pos, "%v does not escape", name())
|
base.WarnfAt(f.Pos, "%v does not escape", name())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if base.Flag.LowerM != 0 && f.Sym != nil {
|
if diagnose && f.Sym != nil {
|
||||||
base.WarnfAt(f.Pos, "leaking param: %v", name())
|
base.WarnfAt(f.Pos, "leaking param: %v", name())
|
||||||
}
|
}
|
||||||
esc.AddHeap(0)
|
esc.AddHeap(0)
|
||||||
@ -407,14 +412,14 @@ func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
|
|||||||
fn.Pragma |= ir.UintptrKeepAlive
|
fn.Pragma |= ir.UintptrKeepAlive
|
||||||
|
|
||||||
if f.Type.IsUintptr() {
|
if f.Type.IsUintptr() {
|
||||||
if base.Flag.LowerM != 0 {
|
if diagnose {
|
||||||
base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name())
|
base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name())
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if f.IsDDD() && f.Type.Elem().IsUintptr() {
|
if f.IsDDD() && f.Type.Elem().IsUintptr() {
|
||||||
// final argument is ...uintptr.
|
// final argument is ...uintptr.
|
||||||
if base.Flag.LowerM != 0 {
|
if diagnose {
|
||||||
base.WarnfAt(f.Pos, "marking %v as escaping ...uintptr", name())
|
base.WarnfAt(f.Pos, "marking %v as escaping ...uintptr", name())
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
@ -436,7 +441,7 @@ func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
|
|||||||
esc := loc.paramEsc
|
esc := loc.paramEsc
|
||||||
esc.Optimize()
|
esc.Optimize()
|
||||||
|
|
||||||
if base.Flag.LowerM != 0 && !loc.escapes {
|
if diagnose && !loc.escapes {
|
||||||
if esc.Empty() {
|
if esc.Empty() {
|
||||||
base.WarnfAt(f.Pos, "%v does not escape", name())
|
base.WarnfAt(f.Pos, "%v does not escape", name())
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ type T struct{}
|
|||||||
func (T) M1(a uintptr) {} // ERROR "escaping uintptr"
|
func (T) M1(a uintptr) {} // ERROR "escaping uintptr"
|
||||||
|
|
||||||
//go:uintptrescapes
|
//go:uintptrescapes
|
||||||
func (T) M2(a ...uintptr) {} // ERROR "escaping ...uintptr" "leaking param: a"
|
func (T) M2(a ...uintptr) {} // ERROR "escaping ...uintptr"
|
||||||
|
|
||||||
func TestF1() {
|
func TestF1() {
|
||||||
var t int // ERROR "moved to heap"
|
var t int // ERROR "moved to heap"
|
||||||
|
Loading…
Reference in New Issue
Block a user