Skip to content

Commit c3544e2

Browse files
committed
go/analysis/passes/httpresponse: fix ReceiverNamed usage
Fixes a bug where ReceiverNamed returns a nil *types.Named if the type is not a Named type. Updates related documentation in httpmux. Fixes golang/go#66259 Change-Id: I512feeb11473f2278edf4d9ef3312319d9dd1edf Reviewed-on: https://go-review.googlesource.com/c/tools/+/571057 Run-TryBot: Tim King <taking@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Jonathan Amsterdam <jba@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent d0f7dce commit c3544e2

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

go/analysis/passes/httpmux/httpmux.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -84,26 +84,29 @@ func isServeMuxRegisterCall(pass *analysis.Pass, call *ast.CallExpr) bool {
8484
if !isMethodNamed(fn, "net/http", "Handle", "HandleFunc") {
8585
return false
8686
}
87-
isPtr, named := typesinternal.ReceiverNamed(fn.Type().(*types.Signature).Recv())
87+
recv := fn.Type().(*types.Signature).Recv() // isMethodNamed() -> non-nil
88+
isPtr, named := typesinternal.ReceiverNamed(recv)
8889
return isPtr && analysisutil.IsNamedType(named, "net/http", "ServeMux")
8990
}
9091

92+
// isMethodNamed reports when a function f is a method,
93+
// in a package with the path pkgPath and the name of f is in names.
9194
func isMethodNamed(f *types.Func, pkgPath string, names ...string) bool {
9295
if f == nil {
9396
return false
9497
}
9598
if f.Pkg() == nil || f.Pkg().Path() != pkgPath {
96-
return false
99+
return false // not at pkgPath
97100
}
98101
if f.Type().(*types.Signature).Recv() == nil {
99-
return false
102+
return false // not a method
100103
}
101104
for _, n := range names {
102105
if f.Name() == n {
103106
return true
104107
}
105108
}
106-
return false
109+
return false // not in names
107110
}
108111

109112
// stringConstantExpr returns expression's string constant value.

go/analysis/passes/httpresponse/httpresponse.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func isHTTPFuncOrMethodOnClient(info *types.Info, expr *ast.CallExpr) bool {
119119
return false // the function called does not return two values.
120120
}
121121
isPtr, named := typesinternal.ReceiverNamed(res.At(0))
122-
if !isPtr || !analysisutil.IsNamedType(named, "net/http", "Response") {
122+
if !isPtr || named == nil || !analysisutil.IsNamedType(named, "net/http", "Response") {
123123
return false // the first return type is not *http.Response.
124124
}
125125

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

+9
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,12 @@ func badUnwrapResp() {
110110
log.Fatal(err)
111111
}
112112
}
113+
114+
type i66259 struct{}
115+
116+
func (_ *i66259) Foo() (*int, int) { return nil, 1 }
117+
118+
func issue66259() {
119+
var f *i66259
120+
f.Foo()
121+
}

0 commit comments

Comments
 (0)