]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vet: do not check print-like functions with unknown type
authorAliaksandr Valialkin <valyala@gmail.com>
Tue, 24 May 2016 10:53:44 +0000 (13:53 +0300)
committerRob Pike <r@golang.org>
Tue, 24 May 2016 16:13:44 +0000 (16:13 +0000)
Fixes #15787

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

index 07499e6ae6bc6ab6f30ffd528e95ec8ca1dcc582..f4b985cfbdc4611b5d2c2206b439c42fd560348f 100644 (file)
@@ -587,22 +587,24 @@ func (f *File) argCanBeChecked(call *ast.CallExpr, formatArg int, isStar bool, s
 func (f *File) checkPrint(call *ast.CallExpr, name string) {
        firstArg := 0
        typ := f.pkg.types[call.Fun].Type
-       if typ != nil {
-               if sig, ok := typ.(*types.Signature); ok {
-                       if !sig.Variadic() {
-                               // Skip checking non-variadic functions.
-                               return
-                       }
-                       params := sig.Params()
-                       firstArg = params.Len() - 1
-
-                       typ := params.At(firstArg).Type()
-                       typ = typ.(*types.Slice).Elem()
-                       it, ok := typ.(*types.Interface)
-                       if !ok || !it.Empty() {
-                               // Skip variadic functions accepting non-interface{} args.
-                               return
-                       }
+       if typ == nil {
+               // Skip checking functions with unknown type.
+               return
+       }
+       if sig, ok := typ.(*types.Signature); ok {
+               if !sig.Variadic() {
+                       // Skip checking non-variadic functions.
+                       return
+               }
+               params := sig.Params()
+               firstArg = params.Len() - 1
+
+               typ := params.At(firstArg).Type()
+               typ = typ.(*types.Slice).Elem()
+               it, ok := typ.(*types.Interface)
+               if !ok || !it.Empty() {
+                       // Skip variadic functions accepting non-interface{} args.
+                       return
                }
        }
        args := call.Args
index 261ee788c7b0d025e5ea6d8c312a555f4bc63c62..ab97256c0882986253ff27e5271aae7496d1280a 100644 (file)
@@ -8,6 +8,7 @@ package testdata
 
 import (
        "fmt"
+       "io"
        "math"
        "os"
        "unsafe" // just for test case printing unsafe.Pointer
@@ -272,11 +273,21 @@ func Printf(format string, args ...interface{}) {
        panic("don't call - testing only")
 }
 
+// Println is used by the test so we must declare it.
+func Println(args ...interface{}) {
+       panic("don't call - testing only")
+}
+
 // Logf is used by the test so we must declare it.
 func Logf(format string, args ...interface{}) {
        panic("don't call - testing only")
 }
 
+// Log is used by the test so we must declare it.
+func Log(args ...interface{}) {
+       panic("don't call - testing only")
+}
+
 // printf is used by the test so we must declare it.
 func printf(format string, args ...interface{}) {
        panic("don't call - testing only")
@@ -415,3 +426,10 @@ var recursiveStruct1V = &RecursiveStruct1{}
 func (int) String() {
        return ""
 }
+
+func (s *unknownStruct) Fprintln(w io.Writer, s string) {}
+
+func UnknownStructFprintln() {
+       s := unknownStruct{}
+       s.Fprintln(os.Stdout, "hello, world!") // OK
+}