This patch to GCC fixes the -fdump-go-spec output for enums. Previously GCC always printed "int", which is often incorrect as the Go type "int" is 64 bits on a 64-bit hosts, while enums are typically 32 bits. This was mostly harmless but caused the representation of the ffi_cif type from libffi to be wrong, as the first type in that field is an enum. This caused the other fields to be misaligned from the point of view of Go, which caused the garbage collector to not see some pointers stored by the code in libgo/go/runtime/ffi.go. These pointers could then be collected early, causing a crash. This patch fixes the problem by simply treating enums as integers. Bootstrapped and ran Go and godump tests on x86_64-pc-linux-gnu. Committed to mainline.
Ian gcc/ChangeLog: 2017-01-03 Ian Lance Taylor <i...@google.com> * godump.c (go_format_type): Treat ENUMERAL_TYPE like INTEGER_TYPE. gcc/testsuite/ChangeLog: 2017-01-03 Ian Lance Taylor <i...@google.com> * gcc.misc-tests/godump-1.c: Update for accurate representation of enums.
Index: gcc/godump.c =================================================================== --- gcc/godump.c (revision 244040) +++ gcc/godump.c (working copy) @@ -722,10 +722,6 @@ go_format_type (struct godump_container switch (TREE_CODE (type)) { - case ENUMERAL_TYPE: - obstack_grow (ob, "int", 3); - break; - case TYPE_DECL: { void **slot; @@ -741,6 +737,7 @@ go_format_type (struct godump_container } break; + case ENUMERAL_TYPE: case INTEGER_TYPE: { const char *s; Index: gcc/testsuite/gcc.misc-tests/godump-1.c =================================================================== --- gcc/testsuite/gcc.misc-tests/godump-1.c (revision 244040) +++ gcc/testsuite/gcc.misc-tests/godump-1.c (working copy) @@ -373,7 +373,7 @@ enum { E11 }; /* { dg-final { scan-file godump-1.out "(?n)^const _E11 = 0$" } } */ enum { EV11 } e1_v1; -/* { dg-final { scan-file godump-1.out "(?n)^var _e1_v1 int$" } } */ +/* { dg-final { scan-file godump-1.out "(?n)^var _e1_v1 u?int\[0-9\]*$" } } */ /* { dg-final { scan-file godump-1.out "(?n)^const _EV11 = 0$" } } */ enum { E21, E22 }; @@ -381,7 +381,7 @@ enum { E21, E22 }; /* { dg-final { scan-file godump-1.out "(?n)^const _E22 = 1$" } } */ enum { EV21, EV22 } e2_v1; -/* { dg-final { scan-file godump-1.out "(?n)^var _e2_v1 int$" } } */ +/* { dg-final { scan-file godump-1.out "(?n)^var _e2_v1 u?int\[0-9\]*$" } } */ /* { dg-final { scan-file godump-1.out "(?n)^const _EV21 = 0$" } } */ /* { dg-final { scan-file godump-1.out "(?n)^const _EV22 = 1$" } } */ @@ -392,12 +392,12 @@ enum { EN1 = 3, EN2 = 77, EN3 = -1, EN4 /* { dg-final { scan-file godump-1.out "(?n)^const _EN4 = 0$" } } */ typedef enum { ET1, ET2 } et_t; -/* { dg-final { scan-file godump-1.out "(?n)^type _et_t int$" } } */ +/* { dg-final { scan-file godump-1.out "(?n)^type _et_t u?int\[0-9\]*$" } } */ /* { dg-final { scan-file godump-1.out "(?n)^const _ET1 = 0$" } } */ /* { dg-final { scan-file godump-1.out "(?n)^const _ET2 = 1$" } } */ enum { ETV1, ETV2 } et_v1; -/* { dg-final { scan-file godump-1.out "(?n)^var _et_v1 int$" } } */ +/* { dg-final { scan-file godump-1.out "(?n)^var _et_v1 u?int\[0-9\]*$" } } */ /* { dg-final { scan-file godump-1.out "(?n)^const _ETV1 = 0$" } } */ /* { dg-final { scan-file godump-1.out "(?n)^const _ETV2 = 1$" } } */