aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/cgocall.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/cgocall.go')
-rw-r--r--src/runtime/cgocall.go22
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)
}