Commit 6c2cbdb1 authored by Rob Pike's avatar Rob Pike

cmd/vet: fix printf test for unsafe Pointer

And fix test. Pointer to unsafe.Pointer tests nothing important...
Also identify the incorrect type: go/types.Type is a Stringer.

Also fix a couple of incorrect format verbs found by new printf checker,
now that we can run it on more files.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7385051
parent bd92dd6a
......@@ -276,6 +276,9 @@ func (f *File) checkPrintfArg(call *ast.CallExpr, verb rune, flags []byte, argNu
return
}
}
if f.pkg == nil { // Nothing more to do.
return
}
// Verb is good. If nargs>1, we have something like %.*s and all but the final
// arg must be integer.
for i := 0; i < nargs-1; i++ {
......@@ -285,8 +288,13 @@ func (f *File) checkPrintfArg(call *ast.CallExpr, verb rune, flags []byte, argNu
}
for _, v := range printVerbs {
if v.verb == verb {
if !f.matchArgType(v.typ, call.Args[argNum+nargs-1]) {
f.Badf(call.Pos(), "arg for printf verb %%%c of wrong type", verb)
arg := call.Args[argNum+nargs-1]
if !f.matchArgType(v.typ, arg) {
typeString := ""
if typ := f.pkg.types[arg]; typ != nil {
typeString = typ.String()
}
f.Badf(call.Pos(), "arg for printf verb %%%c of wrong type: %s", verb, typeString)
}
break
}
......@@ -298,9 +306,6 @@ func (f *File) checkPrintfArg(call *ast.CallExpr, verb rune, flags []byte, argNu
}
func (f *File) matchArgType(t printfArgType, arg ast.Expr) bool {
if f.pkg == nil {
return true // Don't know; assume OK.
}
// TODO: for now, we can only test builtin types and untyped constants.
typ := f.pkg.types[arg]
if typ == nil {
......@@ -322,7 +327,7 @@ func (f *File) matchArgType(t printfArgType, arg ast.Expr) bool {
case types.String:
return t&argString != 0
case types.UnsafePointer:
return t&argPointer != 0
return t&(argPointer|argInt) != 0
case types.UntypedBool:
return t&argBool != 0
case types.UntypedComplex:
......
......@@ -14,8 +14,8 @@ import (
)
func UnsafePointerPrintfTest() {
var up *unsafe.Pointer
fmt.Printf("%p", up)
var up unsafe.Pointer
fmt.Printf("%p, %x %X", up, up, up)
}
// Error methods that do not satisfy the Error interface and should be checked.
......
......@@ -1119,7 +1119,7 @@ func TestStoreLoadRelAcq32(t *testing.T) {
d1 := X.data1
d2 := X.data2
if d1 != i || d2 != float32(i) {
t.Fatalf("incorrect data: %d/%d (%d)", d1, d2, i)
t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i)
}
}
}
......@@ -1167,7 +1167,7 @@ func TestStoreLoadRelAcq64(t *testing.T) {
d1 := X.data1
d2 := X.data2
if d1 != i || d2 != float64(i) {
t.Fatalf("incorrect data: %d/%d (%d)", d1, d2, i)
t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i)
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment