diff options
Diffstat (limited to 'src/cmd/fix/cftype.go')
| -rw-r--r-- | src/cmd/fix/cftype.go | 130 |
1 files changed, 4 insertions, 126 deletions
diff --git a/src/cmd/fix/cftype.go b/src/cmd/fix/cftype.go index 04ece9fe5b..3e9f4c5a35 100644 --- a/src/cmd/fix/cftype.go +++ b/src/cmd/fix/cftype.go @@ -6,9 +6,6 @@ package main import ( "go/ast" - "go/token" - "reflect" - "strings" ) func init() { @@ -18,130 +15,11 @@ func init() { var cftypeFix = fix{ name: "cftype", date: "2017-09-27", - f: cftypefix, - desc: `Fixes initializers and casts of C.*Ref and JNI types`, + f: noop, + desc: `Fixes initializers and casts of C.*Ref and JNI types (removed)`, disabled: false, } -// Old state: -// -// type CFTypeRef unsafe.Pointer -// -// New state: -// -// type CFTypeRef uintptr -// -// and similar for other *Ref types. -// This fix finds nils initializing these types and replaces the nils with 0s. -func cftypefix(f *ast.File) bool { - return typefix(f, func(s string) bool { - return strings.HasPrefix(s, "C.") && strings.HasSuffix(s, "Ref") && s != "C.CFAllocatorRef" - }) -} - -// typefix replaces nil with 0 for all nils whose type, when passed to badType, returns true. -func typefix(f *ast.File, badType func(string) bool) bool { - if !imports(f, "C") { - return false - } - typeof, _ := typecheck(&TypeConfig{}, f) - changed := false - - // step 1: Find all the nils with the offending types. - // Compute their replacement. - badNils := map[any]ast.Expr{} - walk(f, func(n any) { - if i, ok := n.(*ast.Ident); ok && i.Name == "nil" && badType(typeof[n]) { - badNils[n] = &ast.BasicLit{ValuePos: i.NamePos, Kind: token.INT, Value: "0"} - } - }) - - // step 2: find all uses of the bad nils, replace them with 0. - // There's no easy way to map from an ast.Expr to all the places that use them, so - // we use reflect to find all such references. - if len(badNils) > 0 { - exprType := reflect.TypeFor[ast.Expr]() - exprSliceType := reflect.TypeFor[[]ast.Expr]() - walk(f, func(n any) { - if n == nil { - return - } - v := reflect.ValueOf(n) - if v.Kind() != reflect.Pointer { - return - } - if v.IsNil() { - return - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return - } - for i := 0; i < v.NumField(); i++ { - f := v.Field(i) - if f.Type() == exprType { - if r := badNils[f.Interface()]; r != nil { - f.Set(reflect.ValueOf(r)) - changed = true - } - } - if f.Type() == exprSliceType { - for j := 0; j < f.Len(); j++ { - e := f.Index(j) - if r := badNils[e.Interface()]; r != nil { - e.Set(reflect.ValueOf(r)) - changed = true - } - } - } - } - }) - } - - // step 3: fix up invalid casts. - // It used to be ok to cast between *unsafe.Pointer and *C.CFTypeRef in a single step. - // Now we need unsafe.Pointer as an intermediate cast. - // (*unsafe.Pointer)(x) where x is type *bad -> (*unsafe.Pointer)(unsafe.Pointer(x)) - // (*bad.type)(x) where x is type *unsafe.Pointer -> (*bad.type)(unsafe.Pointer(x)) - walk(f, func(n any) { - if n == nil { - return - } - // Find pattern like (*a.b)(x) - c, ok := n.(*ast.CallExpr) - if !ok { - return - } - if len(c.Args) != 1 { - return - } - p, ok := c.Fun.(*ast.ParenExpr) - if !ok { - return - } - s, ok := p.X.(*ast.StarExpr) - if !ok { - return - } - t, ok := s.X.(*ast.SelectorExpr) - if !ok { - return - } - pkg, ok := t.X.(*ast.Ident) - if !ok { - return - } - dst := pkg.Name + "." + t.Sel.Name - src := typeof[c.Args[0]] - if badType(dst) && src == "*unsafe.Pointer" || - dst == "unsafe.Pointer" && strings.HasPrefix(src, "*") && badType(src[1:]) { - c.Args[0] = &ast.CallExpr{ - Fun: &ast.SelectorExpr{X: &ast.Ident{Name: "unsafe"}, Sel: &ast.Ident{Name: "Pointer"}}, - Args: []ast.Expr{c.Args[0]}, - } - changed = true - } - }) - - return changed +func noop(f *ast.File) bool { + return false } |
