diff options
Diffstat (limited to 'src/runtime/cgocall.go')
| -rw-r--r-- | src/runtime/cgocall.go | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go index a881ae1489..5f8ff8139a 100644 --- a/src/runtime/cgocall.go +++ b/src/runtime/cgocall.go @@ -406,24 +406,24 @@ var racecgosync uint64 // represents possible synchronization in C code // cgoCheckPointer checks if the argument contains a Go pointer that // points to a Go pointer, and panics if it does. -func cgoCheckPointer(ptr interface{}, args ...interface{}) { +func cgoCheckPointer(ptr interface{}, arg interface{}) { if debug.cgocheck == 0 { return } - ep := (*eface)(unsafe.Pointer(&ptr)) + ep := efaceOf(&ptr) t := ep._type top := true - if len(args) > 0 && (t.kind&kindMask == kindPtr || t.kind&kindMask == kindUnsafePointer) { + if arg != nil && (t.kind&kindMask == kindPtr || t.kind&kindMask == kindUnsafePointer) { p := ep.data if t.kind&kindDirectIface == 0 { p = *(*unsafe.Pointer)(p) } - if !cgoIsGoPointer(p) { + if p == nil || !cgoIsGoPointer(p) { return } - aep := (*eface)(unsafe.Pointer(&args[0])) + aep := efaceOf(&arg) switch aep._type.kind & kindMask { case kindBool: if t.kind&kindMask == kindUnsafePointer { @@ -460,7 +460,7 @@ const cgoResultFail = "cgo result has Go pointer" // depending on indir. The top parameter is whether we are at the top // level, where Go pointers are allowed. func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) { - if t.ptrdata == 0 { + if t.ptrdata == 0 || p == nil { // If the type has no pointers there is nothing to do. return } @@ -517,7 +517,7 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) { st := (*slicetype)(unsafe.Pointer(t)) s := (*slice)(p) p = s.array - if !cgoIsGoPointer(p) { + if p == nil || !cgoIsGoPointer(p) { return } if !top { @@ -548,11 +548,17 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) { return } for _, f := range st.fields { + if f.typ.ptrdata == 0 { + continue + } cgoCheckArg(f.typ, add(p, f.offset()), true, top, msg) } case kindPtr, kindUnsafePointer: if indir { p = *(*unsafe.Pointer)(p) + if p == nil { + return + } } if !cgoIsGoPointer(p) { @@ -644,7 +650,7 @@ func cgoCheckResult(val interface{}) { return } - ep := (*eface)(unsafe.Pointer(&val)) + ep := efaceOf(&val) t := ep._type cgoCheckArg(t, ep.data, t.kind&kindDirectIface == 0, false, cgoResultFail) } |
