mirror of
https://github.com/golang/go
synced 2024-11-14 08:40:27 -07:00
cmd/cgo: preserve original call arguments when pointer checking
With the old code rewriting refs would rewrite the inner arguments rather than the outer ones, leaving a reference to C.val in the outer arguments. Change-Id: I9b91cb4179eccd08500d14c6591bb15acf8673eb Reviewed-on: https://go-review.googlesource.com/31672 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
a73d68e75e
commit
b7c7949817
@ -73,5 +73,6 @@ func Test14838(t *testing.T) { test14838(t) }
|
|||||||
func Test8756(t *testing.T) { test8756(t) }
|
func Test8756(t *testing.T) { test8756(t) }
|
||||||
func Test17065(t *testing.T) { test17065(t) }
|
func Test17065(t *testing.T) { test17065(t) }
|
||||||
func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
|
func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
|
||||||
|
func TestCheckConst(t *testing.T) { testCheckConst(t) }
|
||||||
|
|
||||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||||
|
33
misc/cgo/test/checkconst.go
Normal file
33
misc/cgo/test/checkconst.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Test a constant in conjunction with pointer checking.
|
||||||
|
|
||||||
|
package cgotest
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define CheckConstVal 0
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int *p;
|
||||||
|
} CheckConstStruct;
|
||||||
|
|
||||||
|
static void CheckConstFunc(CheckConstStruct *p, int e) {
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testCheckConst(t *testing.T) {
|
||||||
|
// The test is that this compiles successfully.
|
||||||
|
p := C.malloc(C.size_t(unsafe.Sizeof(C.int(0))))
|
||||||
|
defer C.free(p)
|
||||||
|
C.CheckConstFunc(&C.CheckConstStruct{(*C.int)(p)}, C.CheckConstVal)
|
||||||
|
}
|
@ -651,19 +651,19 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
|
|||||||
// deferred.
|
// deferred.
|
||||||
needsUnsafe := false
|
needsUnsafe := false
|
||||||
params := make([]*ast.Field, len(name.FuncType.Params))
|
params := make([]*ast.Field, len(name.FuncType.Params))
|
||||||
args := make([]ast.Expr, len(name.FuncType.Params))
|
nargs := make([]ast.Expr, len(name.FuncType.Params))
|
||||||
var stmts []ast.Stmt
|
var stmts []ast.Stmt
|
||||||
for i, param := range name.FuncType.Params {
|
for i, param := range name.FuncType.Params {
|
||||||
// params is going to become the parameters of the
|
// params is going to become the parameters of the
|
||||||
// function literal.
|
// function literal.
|
||||||
// args is going to become the list of arguments to the
|
// nargs is going to become the list of arguments made
|
||||||
// function literal.
|
// by the call within the function literal.
|
||||||
// nparam is the parameter of the function literal that
|
// nparam is the parameter of the function literal that
|
||||||
// corresponds to param.
|
// corresponds to param.
|
||||||
|
|
||||||
origArg := call.Call.Args[i]
|
origArg := call.Call.Args[i]
|
||||||
args[i] = origArg
|
|
||||||
nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i))
|
nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i))
|
||||||
|
nargs[i] = nparam
|
||||||
|
|
||||||
// The Go version of the C type might use unsafe.Pointer,
|
// The Go version of the C type might use unsafe.Pointer,
|
||||||
// but the file might not import unsafe.
|
// but the file might not import unsafe.
|
||||||
@ -678,8 +678,6 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
|
|||||||
Type: ptype,
|
Type: ptype,
|
||||||
}
|
}
|
||||||
|
|
||||||
call.Call.Args[i] = nparam
|
|
||||||
|
|
||||||
if !p.needsPointerCheck(f, param.Go, origArg) {
|
if !p.needsPointerCheck(f, param.Go, origArg) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -707,7 +705,7 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
|
|||||||
|
|
||||||
fcall := &ast.CallExpr{
|
fcall := &ast.CallExpr{
|
||||||
Fun: call.Call.Fun,
|
Fun: call.Call.Fun,
|
||||||
Args: call.Call.Args,
|
Args: nargs,
|
||||||
}
|
}
|
||||||
ftype := &ast.FuncType{
|
ftype := &ast.FuncType{
|
||||||
Params: &ast.FieldList{
|
Params: &ast.FieldList{
|
||||||
@ -741,7 +739,6 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
|
|||||||
List: append(stmts, fbody),
|
List: append(stmts, fbody),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
call.Call.Args = args
|
|
||||||
call.Call.Lparen = token.NoPos
|
call.Call.Lparen = token.NoPos
|
||||||
call.Call.Rparen = token.NoPos
|
call.Call.Rparen = token.NoPos
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user