mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00: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:
parent
432f18221f
commit
1b18a6072e
5 changed files with 71 additions and 7 deletions
|
|
@ -33,5 +33,6 @@ func Test1635(t *testing.T) { test1635(t) }
|
||||||
func TestPrintf(t *testing.T) { testPrintf(t) }
|
func TestPrintf(t *testing.T) { testPrintf(t) }
|
||||||
func Test4029(t *testing.T) { test4029(t) }
|
func Test4029(t *testing.T) { test4029(t) }
|
||||||
func TestBoolAlign(t *testing.T) { testBoolAlign(t) }
|
func TestBoolAlign(t *testing.T) { testBoolAlign(t) }
|
||||||
|
func Test3729(t *testing.T) { test3729(t) }
|
||||||
|
|
||||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||||
|
|
|
||||||
47
misc/cgo/test/issue3729.go
Normal file
47
misc/cgo/test/issue3729.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
16
misc/cgo/test/issue3729w.go
Normal file
16
misc/cgo/test/issue3729w.go
Normal 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")
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
// run
|
|
||||||
|
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
|
||||||
|
|
@ -676,9 +676,6 @@ func (p *Package) rewriteRef(f *File) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if r.Context == "call2" {
|
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.
|
// Invent new Name for the two-result function.
|
||||||
n := f.Name["2"+r.Name.Go]
|
n := f.Name["2"+r.Name.Go]
|
||||||
if n == nil {
|
if n == nil {
|
||||||
|
|
@ -933,6 +930,7 @@ type typeConv struct {
|
||||||
void ast.Expr
|
void ast.Expr
|
||||||
unsafePointer ast.Expr
|
unsafePointer ast.Expr
|
||||||
string ast.Expr
|
string ast.Expr
|
||||||
|
goVoid ast.Expr // _Ctype_void, denotes C's void
|
||||||
|
|
||||||
ptrSize int64
|
ptrSize int64
|
||||||
intSize int64
|
intSize int64
|
||||||
|
|
@ -964,6 +962,7 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
|
||||||
c.unsafePointer = c.Ident("unsafe.Pointer")
|
c.unsafePointer = c.Ident("unsafe.Pointer")
|
||||||
c.void = c.Ident("void")
|
c.void = c.Ident("void")
|
||||||
c.string = c.Ident("string")
|
c.string = c.Ident("string")
|
||||||
|
c.goVoid = c.Ident("_Ctype_void")
|
||||||
}
|
}
|
||||||
|
|
||||||
// base strips away qualifiers and typedefs to get the underlying type
|
// 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:
|
case *dwarf.VoidType:
|
||||||
t.Go = c.void
|
t.Go = c.goVoid
|
||||||
t.C.Set("void")
|
t.C.Set("void")
|
||||||
|
t.Align = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
switch dtype.(type) {
|
switch dtype.(type) {
|
||||||
|
|
@ -1381,7 +1381,9 @@ func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
|
||||||
}
|
}
|
||||||
var r *Type
|
var r *Type
|
||||||
var gr []*ast.Field
|
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)
|
r = c.Type(dtype.ReturnType, pos)
|
||||||
gr = []*ast.Field{{Type: r.Go}}
|
gr = []*ast.Field{{Type: r.Go}}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue