From ee8ec42929541055a9e063b50f9ffd5ee9404517 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Sat, 10 Sep 2016 17:04:41 +0300 Subject: [PATCH] cmd/vet: skip printf check for non-constant format string during failed import Fixes #17006 Change-Id: I3c2060ca5384a4b9782a7d804305d2cf4388dd5a Reviewed-on: https://go-review.googlesource.com/29014 Run-TryBot: Rob Pike TryBot-Result: Gobot Gobot Reviewed-by: Rob Pike --- src/cmd/vet/print.go | 24 +++++++++++++++--------- src/cmd/vet/testdata/print.go | 3 +++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/cmd/vet/print.go b/src/cmd/vet/print.go index b5037e6ec7..df8e57e259 100644 --- a/src/cmd/vet/print.go +++ b/src/cmd/vet/print.go @@ -94,7 +94,7 @@ func formatString(f *File, call *ast.CallExpr) (string, int) { if typ != nil { if sig, ok := typ.(*types.Signature); ok { if !sig.Variadic() { - // Skip checking non-variadic functions + // Skip checking non-variadic functions. return "", -1 } idx := sig.Params().Len() - 2 @@ -103,30 +103,36 @@ func formatString(f *File, call *ast.CallExpr) (string, int) { // fixed arguments. return "", -1 } - s, ok := stringLiteralArg(f, call, idx) + s, ok := stringConstantArg(f, call, idx) if !ok { - // The last argument before variadic args isn't a string + // The last argument before variadic args isn't a string. return "", -1 } return s, idx } } - // Cannot determine call's signature. Fallback to scanning for the first - // string argument in the call + // Cannot determine call's signature. Fall back to scanning for the first + // string constant in the call. for idx := range call.Args { - if s, ok := stringLiteralArg(f, call, idx); ok { + if s, ok := stringConstantArg(f, call, idx); ok { return s, idx } + if f.pkg.types[call.Args[idx]].Type == types.Typ[types.String] { + // Skip checking a call with a non-constant format + // string argument, since its contents are unavailable + // for validation. + return "", -1 + } } return "", -1 } -// stringLiteralArg returns call's string constant argument at the index idx. +// stringConstantArg returns call's string constant argument at the index idx. // // ("", false) is returned if call's argument at the index idx isn't a string -// literal. -func stringLiteralArg(f *File, call *ast.CallExpr, idx int) (string, bool) { +// constant. +func stringConstantArg(f *File, call *ast.CallExpr, idx int) (string, bool) { if idx >= len(call.Args) { return "", false } diff --git a/src/cmd/vet/testdata/print.go b/src/cmd/vet/testdata/print.go index 75a79ff9c7..4221e9017f 100644 --- a/src/cmd/vet/testdata/print.go +++ b/src/cmd/vet/testdata/print.go @@ -238,6 +238,9 @@ func PrintfTests() { externalprintf.Logf(level, "%d", 42) // OK externalprintf.Errorf(level, level, "foo %q bar", "foobar") // OK externalprintf.Logf(level, "%d") // ERROR "format reads arg 1, have only 0 args" + var formatStr = "%s %s" + externalprintf.Sprintf(formatStr, "a", "b") // OK + externalprintf.Logf(level, formatStr, "a", "b") // OK // user-defined Println-like functions ss := &someStruct{} -- 2.48.1