From: Shenghou Ma Date: Mon, 17 Dec 2012 16:26:08 +0000 (+0800) Subject: cmd/cgo: access errno from void C function X-Git-Tag: go1.1rc2~1605 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1b18a6072e3af427b92e26e7f472fd6d0c6efc09;p=gostls13.git cmd/cgo: access errno from void C function Fixes #3729. R=rsc CC=golang-dev https://golang.org/cl/6938052 --- diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go index 4634b851c2..cfb6d0ee83 100644 --- a/misc/cgo/test/cgo_test.go +++ b/misc/cgo/test/cgo_test.go @@ -33,5 +33,6 @@ func Test1635(t *testing.T) { test1635(t) } func TestPrintf(t *testing.T) { testPrintf(t) } func Test4029(t *testing.T) { test4029(t) } func TestBoolAlign(t *testing.T) { testBoolAlign(t) } +func Test3729(t *testing.T) { test3729(t) } func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } diff --git a/misc/cgo/test/issue3729.go b/misc/cgo/test/issue3729.go new file mode 100644 index 0000000000..1bea38b6e8 --- /dev/null +++ b/misc/cgo/test/issue3729.go @@ -0,0 +1,47 @@ +// Copyright 2012 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. + +// Issue 3729: cmd/cgo: access errno from void C function +// void f(void) returns [0]byte, error in Go world. + +// +build !windows + +package cgotest + +/* +#include + +void g(void) { + errno = E2BIG; +} + +// try to pass some non-trivial arguments to function g2 +const char _expA = 0x42; +const float _expB = 3.14159; +const short _expC = 0x55aa; +const int _expD = 0xdeadbeef; +void g2(int x, char a, float b, short c, int d) { + if (a == _expA && b == _expB && c == _expC && d == _expD) + errno = x; + else + errno = -1; +} +*/ +import "C" + +import ( + "syscall" + "testing" +) + +func test3729(t *testing.T) { + _, e := C.g() + if e != syscall.E2BIG { + t.Errorf("got %q, expect %q", e, syscall.E2BIG) + } + _, e = C.g2(C.EINVAL, C._expA, C._expB, C._expC, C._expD) + if e != syscall.EINVAL { + t.Errorf("got %q, expect %q", e, syscall.EINVAL) + } +} diff --git a/misc/cgo/test/issue3729w.go b/misc/cgo/test/issue3729w.go new file mode 100644 index 0000000000..702115b811 --- /dev/null +++ b/misc/cgo/test/issue3729w.go @@ -0,0 +1,16 @@ +// Copyright 2012 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. + +// Issue 3729: cmd/cgo: access errno from void C function +// void f(void) returns [0]byte, error in Go world. + +// +build windows + +package cgotest + +import "testing" + +func test3729(t *testing.T) { + t.Log("skip errno test on Windows") +} diff --git a/misc/cgo/test/issue4417.go b/misc/cgo/test/issue4417.go index 99a9f57a0e..0b48071d4d 100644 --- a/misc/cgo/test/issue4417.go +++ b/misc/cgo/test/issue4417.go @@ -1,5 +1,3 @@ -// run - // Copyright 2012 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. diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go index a974475b8a..3266abe618 100644 --- a/src/cmd/cgo/gcc.go +++ b/src/cmd/cgo/gcc.go @@ -676,9 +676,6 @@ func (p *Package) rewriteRef(f *File) { break } if r.Context == "call2" { - if r.Name.FuncType.Result == nil { - error_(r.Pos(), "assignment count mismatch: 2 = 0") - } // Invent new Name for the two-result function. n := f.Name["2"+r.Name.Go] if n == nil { @@ -933,6 +930,7 @@ type typeConv struct { void ast.Expr unsafePointer ast.Expr string ast.Expr + goVoid ast.Expr // _Ctype_void, denotes C's void ptrSize int64 intSize int64 @@ -964,6 +962,7 @@ func (c *typeConv) Init(ptrSize, intSize int64) { c.unsafePointer = c.Ident("unsafe.Pointer") c.void = c.Ident("void") c.string = c.Ident("string") + c.goVoid = c.Ident("_Ctype_void") } // base strips away qualifiers and typedefs to get the underlying type @@ -1292,8 +1291,9 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { } case *dwarf.VoidType: - t.Go = c.void + t.Go = c.goVoid t.C.Set("void") + t.Align = 1 } switch dtype.(type) { @@ -1381,7 +1381,9 @@ func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { } var r *Type var gr []*ast.Field - if _, ok := dtype.ReturnType.(*dwarf.VoidType); !ok && dtype.ReturnType != nil { + if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok { + gr = []*ast.Field{{Type: c.goVoid}} + } else if dtype.ReturnType != nil { r = c.Type(dtype.ReturnType, pos) gr = []*ast.Field{{Type: r.Go}} }