]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: access errno from void C function
authorShenghou Ma <minux.ma@gmail.com>
Mon, 17 Dec 2012 16:26:08 +0000 (00:26 +0800)
committerShenghou Ma <minux.ma@gmail.com>
Mon, 17 Dec 2012 16:26:08 +0000 (00:26 +0800)
Fixes #3729.

R=rsc
CC=golang-dev
https://golang.org/cl/6938052

misc/cgo/test/cgo_test.go
misc/cgo/test/issue3729.go [new file with mode: 0644]
misc/cgo/test/issue3729w.go [new file with mode: 0644]
misc/cgo/test/issue4417.go
src/cmd/cgo/gcc.go

index 4634b851c2754fbb0398953b057eacf3e81b6583..cfb6d0ee833e91bb67273933c32fe5148788a7db 100644 (file)
@@ -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 (file)
index 0000000..1bea38b
--- /dev/null
@@ -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 <errno.h>
+
+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 (file)
index 0000000..702115b
--- /dev/null
@@ -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")
+}
index 99a9f57a0edbe4ee13d9d0c0b3f3251f3ee758a5..0b48071d4d6551fd088b83ff3d50ec38a8ed467b 100644 (file)
@@ -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.
index a974475b8aca515a004398abcc7f599e2edf4533..3266abe6187ea5179c0a4bb1a4c6c7766f7ab6fc 100644 (file)
@@ -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}}
        }