mirror of
https://github.com/golang/go
synced 2024-10-14 03:43:28 +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,3 +6,4 @@
|
|||
#include "cdefstest.h"
|
||||
|
||||
struct CdefsTest test;
|
||||
struct PackedTest packed;
|
||||
|
|
|
@ -35,7 +35,25 @@ struct cdefsTest {
|
|||
// Correct: -> Array [20][20]**int8 -> int8 **array[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"
|
||||
|
||||
type CdefsTest C.struct_cdefsTest
|
||||
type PackedTest C.struct_packedTest
|
||||
|
|
|
@ -17,11 +17,22 @@ struct CdefsOrig {
|
|||
int8 **array5[20][20];
|
||||
};
|
||||
|
||||
typedef struct PackedOrig PackedOrig;
|
||||
#pragma pack on
|
||||
struct PackedOrig {
|
||||
int8 first;
|
||||
int32 second;
|
||||
int64 third;
|
||||
};
|
||||
#pragma pack off
|
||||
|
||||
void
|
||||
main·test(int32 ret)
|
||||
{
|
||||
CdefsOrig o;
|
||||
CdefsTest t;
|
||||
PackedOrig po;
|
||||
PackedTest pt;
|
||||
|
||||
ret = 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]));
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1587,12 +1587,14 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
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.
|
||||
// The goal is to make available what can be made available.
|
||||
// Otherwise one bad and unneeded field in an otherwise okay struct
|
||||
// makes the whole program not compile. Much of the time these
|
||||
// structs are in system headers that cannot be corrected.
|
||||
// Exception: In -cdefs mode, we use #pragma pack, so misaligned
|
||||
// fields should still work.
|
||||
continue
|
||||
}
|
||||
n := len(fld)
|
||||
|
|
|
@ -1148,16 +1148,10 @@ __cgo_size_assert(double, 8)
|
|||
`
|
||||
|
||||
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. */
|
||||
#ifdef __PTRDIFF_TYPE__
|
||||
typedef __PTRDIFF_TYPE__ intgo;
|
||||
#elif defined(_LP64)
|
||||
typedef long long intgo;
|
||||
#else
|
||||
typedef int intgo;
|
||||
#endif
|
||||
typedef ptrdiff_t intgo;
|
||||
|
||||
typedef struct { char *p; intgo n; } _GoString_;
|
||||
typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
|
||||
|
|
|
@ -28,6 +28,7 @@ package runtime
|
|||
#include <asm-generic/errno.h>
|
||||
#include <asm-generic/poll.h>
|
||||
#include <linux/eventpoll.h>
|
||||
#undef size_t
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
|
Loading…
Reference in a new issue