1
0
mirror of https://github.com/golang/go synced 2024-11-12 08:50:22 -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:
Ian Lance Taylor 2016-10-21 07:54:46 -07:00
parent a73d68e75e
commit b7c7949817
3 changed files with 39 additions and 8 deletions

View File

@ -73,5 +73,6 @@ func Test14838(t *testing.T) { test14838(t) }
func Test8756(t *testing.T) { test8756(t) }
func Test17065(t *testing.T) { test17065(t) }
func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
func TestCheckConst(t *testing.T) { testCheckConst(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }

View 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)
}

View File

@ -651,19 +651,19 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
// deferred.
needsUnsafe := false
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
for i, param := range name.FuncType.Params {
// params is going to become the parameters of the
// function literal.
// args is going to become the list of arguments to the
// function literal.
// nargs is going to become the list of arguments made
// by the call within the function literal.
// nparam is the parameter of the function literal that
// corresponds to param.
origArg := call.Call.Args[i]
args[i] = origArg
nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i))
nargs[i] = nparam
// The Go version of the C type might use unsafe.Pointer,
// but the file might not import unsafe.
@ -678,8 +678,6 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
Type: ptype,
}
call.Call.Args[i] = nparam
if !p.needsPointerCheck(f, param.Go, origArg) {
continue
}
@ -707,7 +705,7 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
fcall := &ast.CallExpr{
Fun: call.Call.Fun,
Args: call.Call.Args,
Args: nargs,
}
ftype := &ast.FuncType{
Params: &ast.FieldList{
@ -741,7 +739,6 @@ func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
List: append(stmts, fbody),
},
}
call.Call.Args = args
call.Call.Lparen = token.NoPos
call.Call.Rparen = token.NoPos