Skip to content

Commit f946a15

Browse files
AGMETEORodeke-em
authored andcommitted
passes/sigchanyzer: allow valid inlined unbuffered signal channel
Permit signal.Notify(make(chan os.Signal)) which is valid code, given that the channel isn't read elsewhere, the fact that signals can be lost is unimportant. Updates golang/go#45043 Change-Id: Ie984dfeedbb4e1e33a29391c3abb1fc83299fed3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/311729 Reviewed-by: Cuong Manh Le <[email protected]> Reviewed-by: Emmanuel Odeke <[email protected]> Trust: Cuong Manh Le <[email protected]> Run-TryBot: Cuong Manh Le <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent 4934781 commit f946a15

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

go/analysis/passes/sigchanyzer/sigchanyzer.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ func run(pass *analysis.Pass) (interface{}, error) {
4949
chanDecl = decl
5050
}
5151
case *ast.CallExpr:
52+
// Only signal.Notify(make(chan os.Signal), os.Interrupt) is safe,
53+
// conservatively treate others as not safe, see golang/go#45043
54+
if isBuiltinMake(pass.TypesInfo, arg) {
55+
return
56+
}
5257
chanDecl = arg
5358
}
5459
if chanDecl == nil || len(chanDecl.Args) != 1 {
@@ -127,3 +132,16 @@ func findDecl(arg *ast.Ident) ast.Node {
127132
}
128133
return nil
129134
}
135+
136+
func isBuiltinMake(info *types.Info, call *ast.CallExpr) bool {
137+
typVal := info.Types[call.Fun]
138+
if !typVal.IsBuiltin() {
139+
return false
140+
}
141+
switch fun := call.Fun.(type) {
142+
case *ast.Ident:
143+
return info.ObjectOf(fun).Name() == "make"
144+
default:
145+
return false
146+
}
147+
}

go/analysis/passes/sigchanyzer/testdata/src/a/a.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,19 @@ func j() {
3636
f := signal.Notify
3737
f(c, os.Interrupt) // want "misuse of unbuffered os.Signal channel as argument to signal.Notify"
3838
}
39+
40+
func k() {
41+
signal.Notify(make(chan os.Signal), os.Interrupt) // ok
42+
}
43+
44+
func l() {
45+
signal.Notify(make(chan os.Signal, 1), os.Interrupt) // ok
46+
}
47+
48+
func m() {
49+
signal.Notify(make(chan ao.Signal, 1), os.Interrupt) // ok
50+
}
51+
52+
func n() {
53+
signal.Notify(make(chan ao.Signal), os.Interrupt) // ok
54+
}

go/analysis/passes/sigchanyzer/testdata/src/a/a.go.golden

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,19 @@ func j() {
3636
f := signal.Notify
3737
f(c, os.Interrupt) // want "misuse of unbuffered os.Signal channel as argument to signal.Notify"
3838
}
39+
40+
func k() {
41+
signal.Notify(make(chan os.Signal), os.Interrupt) // ok
42+
}
43+
44+
func l() {
45+
signal.Notify(make(chan os.Signal, 1), os.Interrupt) // ok
46+
}
47+
48+
func m() {
49+
signal.Notify(make(chan ao.Signal, 1), os.Interrupt) // ok
50+
}
51+
52+
func n() {
53+
signal.Notify(make(chan ao.Signal), os.Interrupt) // ok
54+
}

0 commit comments

Comments
 (0)