mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/cgo: fix handling of defs_linux.go
Instead of including <sys/types.h> to get size_t, instead include the ISO C standard <stddef.h> header, which defines fewer additional types at risk of colliding with the user code. In particular, this prevents collisions between <sys/types.h>'s userspace definitions with the kernel definitions needed by defs_linux.go. Also, -cdefs mode uses #pragma pack, so we can keep misaligned fields. Fixes #8477. LGTM=iant R=golang-codereviews, iant CC=golang-codereviews https://golang.org/cl/120610043
This commit is contained in:
parent
48e7533783
commit
f7a8adbd51
6 changed files with 48 additions and 9 deletions
|
|
@ -6,3 +6,4 @@
|
||||||
#include "cdefstest.h"
|
#include "cdefstest.h"
|
||||||
|
|
||||||
struct CdefsTest test;
|
struct CdefsTest test;
|
||||||
|
struct PackedTest packed;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,25 @@ struct cdefsTest {
|
||||||
// Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
|
// Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
|
||||||
char **array5[20][20];
|
char **array5[20][20];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Test that packed structures can be translated to C correctly too.
|
||||||
|
// See issue 8477.
|
||||||
|
|
||||||
|
struct packedTest {
|
||||||
|
char first;
|
||||||
|
int second;
|
||||||
|
long long third;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
// Test that conflicting type definitions don't cause problems with cgo.
|
||||||
|
// See issue 8477.
|
||||||
|
|
||||||
|
typedef struct timespec {
|
||||||
|
double bogus;
|
||||||
|
} pid_t;
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type CdefsTest C.struct_cdefsTest
|
type CdefsTest C.struct_cdefsTest
|
||||||
|
type PackedTest C.struct_packedTest
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,22 @@ struct CdefsOrig {
|
||||||
int8 **array5[20][20];
|
int8 **array5[20][20];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct PackedOrig PackedOrig;
|
||||||
|
#pragma pack on
|
||||||
|
struct PackedOrig {
|
||||||
|
int8 first;
|
||||||
|
int32 second;
|
||||||
|
int64 third;
|
||||||
|
};
|
||||||
|
#pragma pack off
|
||||||
|
|
||||||
void
|
void
|
||||||
main·test(int32 ret)
|
main·test(int32 ret)
|
||||||
{
|
{
|
||||||
CdefsOrig o;
|
CdefsOrig o;
|
||||||
CdefsTest t;
|
CdefsTest t;
|
||||||
|
PackedOrig po;
|
||||||
|
PackedTest pt;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
|
if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
|
||||||
|
|
@ -44,5 +55,17 @@ main·test(int32 ret)
|
||||||
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]));
|
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;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
if(sizeof(pt.first) != sizeof(po.first) || offsetof(PackedTest, first) != offsetof(PackedOrig, first)) {
|
||||||
|
runtime·printf("first: size, offset = %d, %d, want %d, %d\n", sizeof(pt.first), offsetof(PackedTest, first), sizeof(po.first), offsetof(PackedOrig, first));
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
if(sizeof(pt.second) != sizeof(po.second) || offsetof(PackedTest, second) != offsetof(PackedOrig, second)) {
|
||||||
|
runtime·printf("second: size, offset = %d, %d, want %d, %d\n", sizeof(pt.second), offsetof(PackedTest, second), sizeof(po.second), offsetof(PackedOrig, second));
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
if(sizeof(pt.third) != sizeof(po.third) || offsetof(PackedTest, third) != offsetof(PackedOrig, third)) {
|
||||||
|
runtime·printf("third: size, offset = %d, %d, want %d, %d\n", sizeof(pt.third), offsetof(PackedTest, third), sizeof(po.third), offsetof(PackedOrig, third));
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
FLUSH(&ret); // flush return value
|
FLUSH(&ret); // flush return value
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1587,12 +1587,14 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
||||||
talign = size
|
talign = size
|
||||||
}
|
}
|
||||||
|
|
||||||
if talign > 0 && f.ByteOffset%talign != 0 {
|
if talign > 0 && f.ByteOffset%talign != 0 && !*cdefs {
|
||||||
// Drop misaligned fields, the same way we drop integer bit fields.
|
// Drop misaligned fields, the same way we drop integer bit fields.
|
||||||
// The goal is to make available what can be made available.
|
// The goal is to make available what can be made available.
|
||||||
// Otherwise one bad and unneeded field in an otherwise okay struct
|
// Otherwise one bad and unneeded field in an otherwise okay struct
|
||||||
// makes the whole program not compile. Much of the time these
|
// makes the whole program not compile. Much of the time these
|
||||||
// structs are in system headers that cannot be corrected.
|
// structs are in system headers that cannot be corrected.
|
||||||
|
// Exception: In -cdefs mode, we use #pragma pack, so misaligned
|
||||||
|
// fields should still work.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
n := len(fld)
|
n := len(fld)
|
||||||
|
|
|
||||||
|
|
@ -1148,16 +1148,10 @@ __cgo_size_assert(double, 8)
|
||||||
`
|
`
|
||||||
|
|
||||||
const builtinProlog = `
|
const builtinProlog = `
|
||||||
#include <sys/types.h> /* for size_t below */
|
#include <stddef.h> /* for ptrdiff_t and size_t below */
|
||||||
|
|
||||||
/* Define intgo when compiling with GCC. */
|
/* Define intgo when compiling with GCC. */
|
||||||
#ifdef __PTRDIFF_TYPE__
|
typedef ptrdiff_t intgo;
|
||||||
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; } _GoString_;
|
||||||
typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
|
typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ package runtime
|
||||||
#include <asm-generic/errno.h>
|
#include <asm-generic/errno.h>
|
||||||
#include <asm-generic/poll.h>
|
#include <asm-generic/poll.h>
|
||||||
#include <linux/eventpoll.h>
|
#include <linux/eventpoll.h>
|
||||||
|
#undef size_t
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue