]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: use intgo, not int, for string and slice structures
authorIan Lance Taylor <iant@golang.org>
Fri, 24 May 2013 05:51:07 +0000 (22:51 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 24 May 2013 05:51:07 +0000 (22:51 -0700)
Fixes #5548.

R=golang-dev, minux.ma
CC=golang-dev
https://golang.org/cl/9643044

misc/cgo/test/cgo_test.go
misc/cgo/test/issue5548.go [new file with mode: 0644]
misc/cgo/test/issue5548_c.c [new file with mode: 0644]
src/cmd/cgo/out.go

index 14e1224e9ac300929ed43dfc4c3d9026904baa6a..66c454f8e37f3c4a3fdb400063c5b14484c59dd6 100644 (file)
@@ -40,5 +40,6 @@ func TestCallbackCallers(t *testing.T)     { testCallbackCallers(t) }
 func Test5227(t *testing.T)                { test5227(t) }
 func TestCflags(t *testing.T)              { testCflags(t) }
 func Test5337(t *testing.T)                { test5337(t) }
+func Test5548(t *testing.T)                { test5548(t) }
 
 func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/issue5548.go b/misc/cgo/test/issue5548.go
new file mode 100644 (file)
index 0000000..b41f465
--- /dev/null
@@ -0,0 +1,26 @@
+// 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
+
+import "testing"
+
+/*
+extern int issue5548_in_c(void);
+*/
+import "C"
+
+//export issue5548FromC
+func issue5548FromC(s string, i int) int {
+       if len(s) == 4 && s == "test" && i == 42 {
+               return 1
+       }
+       return 0
+}
+
+func test5548(t *testing.T) {
+       if C.issue5548_in_c() == 0 {
+               t.Fail()
+       }
+}
diff --git a/misc/cgo/test/issue5548_c.c b/misc/cgo/test/issue5548_c.c
new file mode 100644 (file)
index 0000000..ee9c459
--- /dev/null
@@ -0,0 +1,24 @@
+// 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 "_cgo_export.h"
+
+static void clobber_stack() {
+       volatile char a[1024];
+       int i;
+       for(i = 0; i < sizeof a; i++)
+               a[i] = 0xff;
+}
+
+static int call_go() {
+       GoString s;
+       s.p = "test";
+       s.n = 4;
+       return issue5548FromC(s, 42);
+}
+
+int issue5548_in_c() {
+       clobber_stack();
+       return call_go();
+}
index ee1d89142e9007453050550311cac55297ca664d..810b57d6921100d1dc17a63603f71cab249618c1 100644 (file)
@@ -937,7 +937,8 @@ func (p *Package) cgoType(e ast.Expr) *Type {
                return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("%s*", x.C)}
        case *ast.ArrayType:
                if t.Len == nil {
-                       return &Type{Size: p.PtrSize + 8, Align: p.PtrSize, C: c("GoSlice")}
+                       // Slice: pointer, len, cap.
+                       return &Type{Size: p.PtrSize * 3, Align: p.PtrSize, C: c("GoSlice")}
                }
        case *ast.StructType:
                // TODO
@@ -974,8 +975,7 @@ func (p *Package) cgoType(e ast.Expr) *Type {
                        return &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("GoUintptr")}
                }
                if t.Name == "string" {
-                       // The string data is 1 pointer + 1 int, but this always
-                       // rounds to 2 pointers due to alignment.
+                       // The string data is 1 pointer + 1 (pointer-sized) int.
                        return &Type{Size: 2 * p.PtrSize, Align: p.PtrSize, C: c("GoString")}
                }
                if t.Name == "error" {
@@ -1028,11 +1028,20 @@ __cgo_size_assert(double, 8)
 `
 
 const builtinProlog = `
-typedef struct { char *p; int n; } _GoString_;
-typedef struct { char *p; int n; int c; } _GoBytes_;
+/* Define intgo when compiling with GCC.  */
+#ifdef __PTRDIFF_TYPE__
+typedef __PTRDIFF_TYPE__ intgo;
+#elif defined(_LP64)
+typedef long long intgo;
+#else
+typedef int intgo;
+#endif
+
+typedef struct { char *p; intgo n; } _GoString_;
+typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
 _GoString_ GoString(char *p);
-_GoString_ GoStringN(char *p, int l);
-_GoBytes_ GoBytes(void *p, int n);
+_GoString_ GoStringN(char *p, intgo l);
+_GoBytes_ GoBytes(void *p, intgo n);
 char *CString(_GoString_);
 `
 
@@ -1050,14 +1059,14 @@ void
 }
 
 void
-·_Cfunc_GoStringN(int8 *p, int32 l, String s)
+·_Cfunc_GoStringN(int8 *p, intgo l, String s)
 {
        s = runtime·gostringn((byte*)p, l);
        FLUSH(&s);
 }
 
 void
-·_Cfunc_GoBytes(int8 *p, int32 l, Slice s)
+·_Cfunc_GoBytes(int8 *p, intgo l, Slice s)
 {
        s = runtime·gobytes((byte*)p, l);
        FLUSH(&s);
@@ -1134,9 +1143,9 @@ typedef double GoFloat64;
 typedef __complex float GoComplex64;
 typedef __complex double GoComplex128;
 
-typedef struct { char *p; int n; } GoString;
+typedef struct { char *p; GoInt n; } GoString;
 typedef void *GoMap;
 typedef void *GoChan;
 typedef struct { void *t; void *v; } GoInterface;
-typedef struct { void *data; int len; int cap; } GoSlice;
+typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
 `