]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vet: skip printf check for non-constant format string during failed import
authorAliaksandr Valialkin <valyala@gmail.com>
Sat, 10 Sep 2016 14:04:41 +0000 (17:04 +0300)
committerRob Pike <r@golang.org>
Wed, 5 Oct 2016 14:25:46 +0000 (14:25 +0000)
Fixes #17006

Change-Id: I3c2060ca5384a4b9782a7d804305d2cf4388dd5a
Reviewed-on: https://go-review.googlesource.com/29014
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
src/cmd/vet/print.go
src/cmd/vet/testdata/print.go

index b5037e6ec7232bedb5fd717a302eef367cf6013c..df8e57e259b817133659fea23e4ddbe24ce206a7 100644 (file)
@@ -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
        }
index 75a79ff9c71e8c4d1f5411c4b1ba621b374b7844..4221e9017fedb879aeb5085a6f3233acc0200352 100644 (file)
@@ -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{}