diff options
author | Ian Lance Taylor <iant@golang.org> | 2016-02-23 16:11:46 -0800 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2016-04-14 05:23:27 +0000 |
commit | 2d22b845d92212071d698264f2445e957ff1106f (patch) | |
tree | 7fed8eff9e05442ce3a2a5d4cea250f4d685bbcf | |
parent | e44998bcd25af29785354c8a5bcfb6348121f3b8 (diff) | |
download | go-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.go | 10 | ||||
-rw-r--r-- | src/cmd/cgo/gcc.go | 11 |
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 { |