1
0
mirror of https://github.com/golang/go synced 2024-11-22 03:24:41 -07:00

cmd/cgo: access errno from void C function

Fixes #3729.

R=rsc
CC=golang-dev
https://golang.org/cl/6938052
This commit is contained in:
Shenghou Ma 2012-12-18 00:26:08 +08:00
parent 432f18221f
commit 1b18a6072e
5 changed files with 71 additions and 7 deletions

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

View File

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

View File

@ -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")
}

View 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.

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