aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/cgocall.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-10-14 14:53:59 -0700
committerIan Lance Taylor <iant@golang.org>2016-10-19 21:20:50 +0000
commita16954b8a7d66169760fb60dd7f3d4e400a5e98c (patch)
tree3cf55b6ab53091088fbd49dd70645711cf78476e /src/runtime/cgocall.go
parente32ac7978df02fae0cbbd92bb65d0d50ea4d2df5 (diff)
downloadgo-a16954b8a7d66169760fb60dd7f3d4e400a5e98c.tar.gz
go-a16954b8a7d66169760fb60dd7f3d4e400a5e98c.zip
cmd/cgo: always use a function literal for pointer checking
The pointer checking code needs to know the exact type of the parameter expected by the C function, so that it can use a type assertion to convert the empty interface returned by cgoCheckPointer to the correct type. Previously this was done by using a type conversion, but that meant that the code accepted arguments that were convertible to the parameter type, rather than arguments that were assignable as in a normal function call. In other words, some code that should not have passed type checking was accepted. This CL changes cgo to always use a function literal for pointer checking. Now the argument is passed to the function literal, which has the correct argument type, so type checking is performed just as for a function call as it should be. Since we now always use a function literal, simplify the checking code to run as a statement by itself. It now no longer needs to return a value, and we no longer need a type assertion. This does have the cost of introducing another function call into any call to a C function that requires pointer checking, but the cost of the additional call should be minimal compared to the cost of pointer checking. Fixes #16591. Change-Id: I220165564cf69db9fd5f746532d7f977a5b2c989 Reviewed-on: https://go-review.googlesource.com/31233 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/runtime/cgocall.go')
-rw-r--r--src/runtime/cgocall.go11
1 files changed, 5 insertions, 6 deletions
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 7d358b3346..4542cb7b09 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -370,10 +370,10 @@ var racecgosync uint64 // represents possible synchronization in C code
// pointers.)
// cgoCheckPointer checks if the argument contains a Go pointer that
-// points to a Go pointer, and panics if it does. It returns the pointer.
-func cgoCheckPointer(ptr interface{}, args ...interface{}) interface{} {
+// points to a Go pointer, and panics if it does.
+func cgoCheckPointer(ptr interface{}, args ...interface{}) {
if debug.cgocheck == 0 {
- return ptr
+ return
}
ep := (*eface)(unsafe.Pointer(&ptr))
@@ -386,7 +386,7 @@ func cgoCheckPointer(ptr interface{}, args ...interface{}) interface{} {
p = *(*unsafe.Pointer)(p)
}
if !cgoIsGoPointer(p) {
- return ptr
+ return
}
aep := (*eface)(unsafe.Pointer(&args[0]))
switch aep._type.kind & kindMask {
@@ -397,7 +397,7 @@ func cgoCheckPointer(ptr interface{}, args ...interface{}) interface{} {
}
pt := (*ptrtype)(unsafe.Pointer(t))
cgoCheckArg(pt.elem, p, true, false, cgoCheckPointerFail)
- return ptr
+ return
case kindSlice:
// Check the slice rather than the pointer.
ep = aep
@@ -415,7 +415,6 @@ func cgoCheckPointer(ptr interface{}, args ...interface{}) interface{} {
}
cgoCheckArg(t, ep.data, t.kind&kindDirectIface == 0, top, cgoCheckPointerFail)
- return ptr
}
const cgoCheckPointerFail = "cgo argument has Go pointer to Go pointer"