summaryrefslogtreecommitdiff
path: root/misc/cgo
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-11-07 15:24:51 -0500
committerRuss Cox <rsc@golang.org>2013-11-07 15:24:51 -0500
commitb8365ed0bf1e36a60b0e69805c1b49da77010607 (patch)
tree79ddd69917dbb676e21a2a9e2f2cfbfbca565cad /misc/cgo
parentaf665d035591a9a1e3be311d8f483c62582b27b6 (diff)
downloadgo-b8365ed0bf1e36a60b0e69805c1b49da77010607.tar.gz
cmd/cgo: fix handling of array of pointers when using clang
Clang does not record the "size" field for pointer types, so we must insert the size ourselves. We were already doing this, but only for the case of pointer types. For an array of pointer types, the setting of the size for the nested pointer type was happening after the computation of the size of the array type, meaning that the array type was always computed as 0 bytes. Delay the size computation. This bug happens on all Clang systems, not just FreeBSD. Our test checked that cgo wrote something, not that it was correct. FreeBSD's default clang rejects array[0] as a C struct field, so it noticed the incorrect sizes. But the sizes were incorrect everywhere. Update testcdefs to check the output has the right semantics. Fixes issue 6292. R=golang-dev, iant CC=golang-dev https://codereview.appspot.com/22840043
Diffstat (limited to 'misc/cgo')
-rw-r--r--misc/cgo/testcdefs/main.c48
-rw-r--r--misc/cgo/testcdefs/main.go11
-rwxr-xr-xmisc/cgo/testcdefs/test.bash2
3 files changed, 57 insertions, 4 deletions
diff --git a/misc/cgo/testcdefs/main.c b/misc/cgo/testcdefs/main.c
new file mode 100644
index 000000000..2d3ee4dbe
--- /dev/null
+++ b/misc/cgo/testcdefs/main.c
@@ -0,0 +1,48 @@
+// 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"
+
+void runtime·printf(int8*, ...);
+
+// From cdefstest.go.
+typedef struct CdefsOrig CdefsOrig;
+struct CdefsOrig {
+ int8 array1[20];
+ int8 array2[20][20];
+ int8 *array3[20];
+ int8 *array4[20][20];
+ int8 **array5[20][20];
+};
+
+void
+main·test(int32 ret)
+{
+ CdefsOrig o;
+ CdefsTest t;
+
+ ret = 0;
+ if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
+ runtime·printf("array1: size, offset = %d, %d, want %d, %d\n", sizeof(t.array1), offsetof(CdefsTest, array1[0]), sizeof(o.array1), offsetof(CdefsOrig, array1[0]));
+ ret = 1;
+ }
+ if(sizeof(t.array2) != sizeof(o.array2) || offsetof(CdefsTest, array2[0][0]) != offsetof(CdefsOrig, array2[0][0])) {
+ runtime·printf("array2: size, offset = %d, %d, want %d, %d\n", sizeof(t.array2), offsetof(CdefsTest, array2[0][0]), sizeof(o.array2), offsetof(CdefsOrig, array2[0][0]));
+ ret = 1;
+ }
+ if(sizeof(t.array3) != sizeof(o.array3) || offsetof(CdefsTest, array3[0]) != offsetof(CdefsOrig, array3[0])) {
+ runtime·printf("array3: size, offset = %d, %d, want %d, %d\n", sizeof(t.array3), offsetof(CdefsTest, array3[0]), sizeof(o.array3), offsetof(CdefsOrig, array3[0]));
+ ret = 1;
+ }
+ if(sizeof(t.array4) != sizeof(o.array4) || offsetof(CdefsTest, array4[0][0]) != offsetof(CdefsOrig, array4[0][0])) {
+ runtime·printf("array4: size, offset = %d, %d, want %d, %d\n", sizeof(t.array4), offsetof(CdefsTest, array4[0][0]), sizeof(o.array4), offsetof(CdefsOrig, array4[0][0]));
+ ret = 1;
+ }
+ if(sizeof(t.array5) != sizeof(o.array5) || offsetof(CdefsTest, array5[0][0]) != offsetof(CdefsOrig, array5[0][0])) {
+ runtime·printf("array5: size, offset = %d, %d, want %d, %d\n", sizeof(t.array5), offsetof(CdefsTest, array5[0][0]), sizeof(o.array5), offsetof(CdefsOrig, array5[0][0]));
+ ret = 1;
+ }
+ FLUSH(&ret); // flush return value
+}
diff --git a/misc/cgo/testcdefs/main.go b/misc/cgo/testcdefs/main.go
index 864b4b2a7..9231741ad 100644
--- a/misc/cgo/testcdefs/main.go
+++ b/misc/cgo/testcdefs/main.go
@@ -2,7 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package cgotest
+package main
-// This file only exists so we can run 'go build' and build our .c files
-func test() {}
+import "os"
+
+func test() int32 // in main.c
+
+func main() {
+ os.Exit(int(test()))
+}
diff --git a/misc/cgo/testcdefs/test.bash b/misc/cgo/testcdefs/test.bash
index cbfa9b27d..1a14ad35c 100755
--- a/misc/cgo/testcdefs/test.bash
+++ b/misc/cgo/testcdefs/test.bash
@@ -10,7 +10,7 @@ do
go tool cgo -cdefs ${FP}.go > ${FP}.h
done
-go build .
+go build . && ./testcdefs
EXIT=$?
rm -rf _obj main *.h
exit $EXIT