1
0
mirror of https://github.com/golang/go synced 2024-11-12 05:40:22 -07:00

cmd/cgo: use intgo, not int, for string and slice structures

Fixes #5548.

R=golang-dev, minux.ma
CC=golang-dev
https://golang.org/cl/9643044
This commit is contained in:
Ian Lance Taylor 2013-05-23 22:51:07 -07:00
parent 9bdb7e1967
commit 8f7863d638
4 changed files with 71 additions and 11 deletions

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

View File

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

View File

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

View 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;
`