]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: fix handling of defs_linux.go
authorMatthew Dempsky <mdempsky@google.com>
Wed, 6 Aug 2014 01:12:32 +0000 (18:12 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 6 Aug 2014 01:12:32 +0000 (18:12 -0700)
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

misc/cgo/testcdefs/cdefstest.c
misc/cgo/testcdefs/cdefstest.go
misc/cgo/testcdefs/main.c
src/cmd/cgo/gcc.go
src/cmd/cgo/out.go
src/pkg/runtime/defs_linux.go

index 10cdd66b6548dc3b6642d33ffeeac1f1edae57f4..ce670e729ec5a9932e6beae02c90fe052218f457 100644 (file)
@@ -6,3 +6,4 @@
 #include "cdefstest.h"
 
 struct CdefsTest test;
+struct PackedTest packed;
index e6305b77d7cafd6010b45cd30d7d23ea69de10f8..0804083a03e2cb178dd884b673ec8b8b23f86cdf 100644 (file)
@@ -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
index 2d3ee4dbea1f8d21341e424411a93b54962f36ee..c13a804306b24370a8ff44c6d8171963a2cedff3 100644 (file)
@@ -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
 }
index 13e83402919b46983c9963bbdeb08bc9cd17d94c..6b0ecd1099f974f36215bcb11d0de82c59a3a643 100644 (file)
@@ -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)
index c6c27c4dbff314de81f9d036ad0d69a2804e73e3..1ef78b757c21f0fb2617b97964caa73d64051533 100644 (file)
@@ -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_;
index 2f4e03a016ad3c2baec37966e8c7ab1751ae6030..8657dbb0ecf3db72674bc9b0672d7a197e81f9eb 100644 (file)
@@ -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"