aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-02-23 16:11:46 -0800
committerAndrew Gerrand <adg@golang.org>2016-04-14 05:23:27 +0000
commit2d22b845d92212071d698264f2445e957ff1106f (patch)
tree7fed8eff9e05442ce3a2a5d4cea250f4d685bbcf
parente44998bcd25af29785354c8a5bcfb6348121f3b8 (diff)
downloadgo-2d22b845d92212071d698264f2445e957ff1106f.tar.gz
go-2d22b845d92212071d698264f2445e957ff1106f.zip
cmd/cgo: recognize known C typedefs as types
Fixes #14483. Change-Id: I0cddfe27fd8d00ba85659d0b618410e39ebf45cb Reviewed-on: https://go-review.googlesource.com/19860 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-on: https://go-review.googlesource.com/22041 Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r--misc/cgo/errors/ptr.go10
-rw-r--r--src/cmd/cgo/gcc.go11
2 files changed, 17 insertions, 4 deletions
diff --git a/misc/cgo/errors/ptr.go b/misc/cgo/errors/ptr.go
index 834cde9199..bbcaaabecb 100644
--- a/misc/cgo/errors/ptr.go
+++ b/misc/cgo/errors/ptr.go
@@ -123,6 +123,16 @@ var ptrTests = []ptrTest{
fail: false,
},
{
+ // Passing the address of a slice of an array that is
+ // an element in a struct, with a type conversion.
+ name: "slice-ok-4",
+ c: `typedef void* PV; void f(PV p) {}`,
+ imports: []string{"unsafe"},
+ support: `type S struct { p *int; a [4]byte }`,
+ body: `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`,
+ fail: false,
+ },
+ {
// Passing the address of a static variable with no
// pointers doesn't matter.
name: "varok",
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index fb5049c1a1..e1456cb284 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -819,14 +819,17 @@ func (p *Package) hasSideEffects(f *File, x ast.Expr) bool {
func (p *Package) isType(t ast.Expr) bool {
switch t := t.(type) {
case *ast.SelectorExpr:
- if t.Sel.Name != "Pointer" {
- return false
- }
id, ok := t.X.(*ast.Ident)
if !ok {
return false
}
- return id.Name == "unsafe"
+ if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
+ return true
+ }
+ if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
+ return true
+ }
+ return false
case *ast.Ident:
// TODO: This ignores shadowing.
switch t.Name {