mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
e32ac7978d
commit
a16954b8a7
6 changed files with 121 additions and 94 deletions
|
|
@ -1379,14 +1379,14 @@ func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
|
|||
func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr)
|
||||
|
||||
//go:linkname _cgoCheckPointer runtime.cgoCheckPointer
|
||||
func _cgoCheckPointer(interface{}, ...interface{}) interface{}
|
||||
func _cgoCheckPointer(interface{}, ...interface{})
|
||||
|
||||
//go:linkname _cgoCheckResult runtime.cgoCheckResult
|
||||
func _cgoCheckResult(interface{})
|
||||
`
|
||||
|
||||
const gccgoGoProlog = `
|
||||
func _cgoCheckPointer(interface{}, ...interface{}) interface{}
|
||||
func _cgoCheckPointer(interface{}, ...interface{})
|
||||
|
||||
func _cgoCheckResult(interface{})
|
||||
`
|
||||
|
|
@ -1566,18 +1566,17 @@ typedef struct __go_empty_interface {
|
|||
void *__object;
|
||||
} Eface;
|
||||
|
||||
extern Eface runtimeCgoCheckPointer(Eface, Slice)
|
||||
extern void runtimeCgoCheckPointer(Eface, Slice)
|
||||
__asm__("runtime.cgoCheckPointer")
|
||||
__attribute__((weak));
|
||||
|
||||
extern Eface localCgoCheckPointer(Eface, Slice)
|
||||
extern void localCgoCheckPointer(Eface, Slice)
|
||||
__asm__("GCCGOSYMBOLPREF._cgoCheckPointer");
|
||||
|
||||
Eface localCgoCheckPointer(Eface ptr, Slice args) {
|
||||
void localCgoCheckPointer(Eface ptr, Slice args) {
|
||||
if(runtimeCgoCheckPointer) {
|
||||
return runtimeCgoCheckPointer(ptr, args);
|
||||
runtimeCgoCheckPointer(ptr, args);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
extern void runtimeCgoCheckResult(Eface)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue