mirror of
https://github.com/golang/go
synced 2024-11-12 02:00:23 -07:00
cmd/cgo: Fix issue with cgo cdefs
The problem is that the cdecl() function in cmd/cgo/godefs.go isn't properly translating the Go array type to a C array type when an asterisk follows the [] in the array type declaration (it is perfectly legal to put the asterisk on either side of the [] in go syntax, depending on how you set up your pointers). That said, the cdefs tool is only designed to translate from Go types generated using the cgo *godefs* tool -- where the godefs tool is designed to translate gcc-style C types into Go types. In essence, the cdefs tool translates from gcc-style C types to Go types (via the godefs tool), then back to kenc-style C types. Because of this, cdefs does not need to know how to translate arbitraty Go types into C, just the ones produced by godefs. The problem is that during this translation process, the logic is slightly wrong when going from (e.g.): char *array[10]; to: array [10]*int8; back to: int8 *array[10]; In the current implementation of cdecl(), the translation from the Go type declaration back to the kenc-style declaration looks for Go types of the form: name *[]type; rather than the actual generated Go type declaration of: name []*type; Both are valid Go syntax, with slightly different semantics, but the latter is the only one that can ever be generated by the godefs tools. (The semantics of the former are not directly expressible in a single C statement -- you would have to have to first typedef the array type, then declare a pointer to that typedef'd type in a separate statement). This commit changes the logic of cdecl() to look properly for, and translate, Go type declarations of the form: name []*type; Additionally, the original implementation only allowed for a single asterisk and a single sized aray (i.e. only a single level of pointer indirection, and only one set of []) on the type, whereas the patched version allows for an arbitrary number of both. Tests are included in misc/cgo/testcdefs and the all.bash script has been updated to account for these. R=golang-dev, bradfitz, dave, iant CC=golang-dev https://golang.org/cl/11377043
This commit is contained in:
parent
188ddaa487
commit
f7dfeea90f
8
misc/cgo/testcdefs/cdefstest.c
Normal file
8
misc/cgo/testcdefs/cdefstest.c
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
#include "runtime.h"
|
||||
#include "cdefstest.h"
|
||||
|
||||
struct CdefsTest test;
|
41
misc/cgo/testcdefs/cdefstest.go
Normal file
41
misc/cgo/testcdefs/cdefstest.go
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2013 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.
|
||||
//
|
||||
// +build ignore
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
// This file tests a bug found in the cgo -cdefs tool that incorrectly
|
||||
// translated Go pointer arrays generated by the cgo godefs tool back into C
|
||||
// pointer arrays.
|
||||
//
|
||||
// The comments below show how the type is translated from gcc-style C into Go
|
||||
// and back into C for both the buggy version and the correct version
|
||||
|
||||
struct cdefsTest {
|
||||
// This was already being handled correctly
|
||||
// Correct: -> Array [20]int8 -> int8 array[20]
|
||||
char array1[20];
|
||||
|
||||
// Buggy: -> Array [20][20]int8 -> [20]int8 array[20]
|
||||
// Correct: -> Array [20][20]int8 -> int8 array[20][20]
|
||||
char array2[20][20];
|
||||
|
||||
// Buggy: -> Array [20]*int8 -> *int8 array[20]
|
||||
// Correct: -> Array [20]*int8 -> int8 *array[20]
|
||||
char *array3[20];
|
||||
|
||||
// Buggy: -> Array [20][20]*int8 -> [20]*int8 array[20]
|
||||
// Correct: -> Array [20]**int8 -> int8 *array[20][20]
|
||||
char *array4[20][20];
|
||||
|
||||
// Buggy: -> Array [20][20]**int8 -> [20]**int8 array[20]
|
||||
// Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
|
||||
char **array5[20][20];
|
||||
};
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type CdefsTest C.struct_cdefsTest
|
8
misc/cgo/testcdefs/main.go
Normal file
8
misc/cgo/testcdefs/main.go
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
package cgotest
|
||||
|
||||
// This file only exists so we can run 'go build' and build our .c files
|
||||
func test() {}
|
16
misc/cgo/testcdefs/test.bash
Executable file
16
misc/cgo/testcdefs/test.bash
Executable file
@ -0,0 +1,16 @@
|
||||
# Copyright 2013 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.
|
||||
|
||||
# Just add issue file prefixes to this list if more issues come up
|
||||
FILE_PREFIXES="cdefstest"
|
||||
|
||||
for FP in $FILE_PREFIXES
|
||||
do
|
||||
go tool cgo -cdefs ${FP}.go > ${FP}.h
|
||||
done
|
||||
|
||||
go build .
|
||||
EXIT=$?
|
||||
rm -rf _obj main *.h
|
||||
exit $EXIT
|
@ -261,17 +261,17 @@ func cdecl(name, typ string) string {
|
||||
if strings.HasPrefix(typ, "*[0]") {
|
||||
typ = "*void"
|
||||
}
|
||||
// X *byte -> *X byte
|
||||
if strings.HasPrefix(typ, "*") {
|
||||
name = "*" + name
|
||||
typ = typ[1:]
|
||||
}
|
||||
// X [4]byte -> X[4] byte
|
||||
if strings.HasPrefix(typ, "[") {
|
||||
for strings.HasPrefix(typ, "[") {
|
||||
i := strings.Index(typ, "]") + 1
|
||||
name = name + typ[:i]
|
||||
typ = typ[i:]
|
||||
}
|
||||
// X *byte -> *X byte
|
||||
for strings.HasPrefix(typ, "*") {
|
||||
name = "*" + name
|
||||
typ = typ[1:]
|
||||
}
|
||||
// X T -> T X
|
||||
// Handle the special case: 'unsafe.Pointer' is 'void *'
|
||||
if typ == "unsafe.Pointer" {
|
||||
|
@ -124,6 +124,11 @@ freebsd-386 | freebsd-amd64 | linux-386 | linux-amd64 | netbsd-386 | netbsd-amd6
|
||||
esac
|
||||
) || exit $?
|
||||
|
||||
[ "$CGO_ENABLED" != 1 ] ||
|
||||
(xcd ../misc/cgo/testcdefs
|
||||
./test.bash || exit 1
|
||||
) || exit $?
|
||||
|
||||
[ "$CGO_ENABLED" != 1 ] ||
|
||||
[ "$GOHOSTOS" == windows ] ||
|
||||
(xcd ../misc/cgo/testso
|
||||
|
Loading…
Reference in New Issue
Block a user