Skip to content

Commit 28ba991

Browse files
adonovangopherbot
authored andcommitted
go/analysis/passes/printf: add missing Unalias call
The maybePrintfWrapper function checks to see that a function has the form of a printf wrapper, but it wrongly assumed that the representation of the type of the "args ...any" parameter is exactly interface{}, not a named alias. This will not work with gotypesalias=1. Unfortunately our CL system failed to report this (or indeed any gotypesalias=1 coverage at all) because of a bug in the Go bootstrapping process that, in the absence of a go.work file (which sets the language version to go1.23), the default values of the GODEBUG table were based on an older version of Go. (The problem was only noticed when running a test of unitchecker locally in the context of issue 68796.) Also, the problem wasn't caught by our existing tests of the printf checker because they all pre-date "any", and so spelled it "interface{}". This CL will need to be vendored into the go1.23 release. Updates golang/go#68744 Updates golang/go#68796 Change-Id: I834ea20c2a684ffcd7ce9494d3700371ae6ab3c1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/603938 Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Findley <rfindley@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent 3057be8 commit 28ba991

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

go/analysis/passes/printf/printf.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ func maybePrintfWrapper(info *types.Info, decl ast.Decl) *printfWrapper {
159159
params := sig.Params()
160160
nparams := params.Len() // variadic => nonzero
161161

162+
// Check final parameter is "args ...interface{}".
162163
args := params.At(nparams - 1)
163-
iface, ok := args.Type().(*types.Slice).Elem().(*types.Interface)
164+
iface, ok := aliases.Unalias(args.Type().(*types.Slice).Elem()).(*types.Interface)
164165
if !ok || !iface.Empty() {
165-
return nil // final (args) param is not ...interface{}
166+
return nil
166167
}
167168

168169
// Is second last param 'format string'?

go/analysis/passes/printf/printf_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ func Test(t *testing.T) {
1515
testdata := analysistest.TestData()
1616
printf.Analyzer.Flags.Set("funcs", "Warn,Warnf")
1717

18-
analysistest.Run(t, testdata, printf.Analyzer, "a", "b", "nofmt", "typeparams")
18+
analysistest.Run(t, testdata, printf.Analyzer,
19+
"a", "b", "nofmt", "typeparams", "issue68744")
1920
analysistest.RunWithSuggestedFixes(t, testdata, printf.Analyzer, "fix")
2021
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package issue68744
2+
3+
import "fmt"
4+
5+
// The use of "any" here is crucial to exercise the bug.
6+
// (None of our earlier tests covered this vital detail!)
7+
func wrapf(format string, args ...any) { // want wrapf:"printfWrapper"
8+
fmt.Printf(format, args...)
9+
}
10+
11+
func _() {
12+
wrapf("%s", 123) // want `issue68744.wrapf format %s has arg 123 of wrong type int`
13+
}

0 commit comments

Comments
 (0)