There is a bug in gengtype's handling of types marked with GTY((user)) which can lead to gtype-desc.c containing broken test-and-mark functions that fail to call the user-provided traversal functions, leading to segfaults.
If the type is first encountered as an incomplete type declaration: struct foo; find_structure records the name of the type, setting its kind to TYPE_STRUCT (not TYPE_USER_STRUCT). Later, when the complete type is seen (with its GTY((user)) marking): struct GTY((user)) foo { }; create_user_defined_type calls: type_p ty = find_structure (type_name, TYPE_USER_STRUCT); but the name is already found, erroneously of kind TYPE_STRUCT. Since the parser treats it as a user struct, no attempt is made to parse the fields. Later, when write_func_for_structure writes out the marking function for the type, this conditional: if (orig_s->kind != TYPE_USER_STRUCT) fails to treat the type as a "user" type, instead walking an empty list of fields. Hence it write out bogus marking functions into gtype-desc.c (with analogous effects on PCH): void gt_ggc_mx_foo (void *x_p) { struct foo * const x = (struct foo *)x_p; if (ggc_test_and_set_mark (x)) { } } This code compiles and runs - until GC (or PCH) happens, when it erroneously collects any objects that are only referenced by affected types. Note the erroneously empty body - the above should have read: void gt_ggc_mx_foo (void *x_p) { struct foo * const x = (struct foo *)x_p; if (ggc_test_and_set_mark (x)) { gt_ggc_mx (x); } } i.e. with a call to the user-provided gt_ggc_mx function, otherwise none of the references to affected GTY((user)) types are followed, and only a subset of the reference graph is walked. This patch fixes the "kind" of the type handled within create_user_defined_type to ensure it is treated as a "user" type, fixing the generated gtype-desc.c code. Successfully bootstrapped and regrtested on x86_64-unknown-linux-gnu. * gengtype.c (create_user_defined_type): Ensure that the kind is set to TYPE_USER_STRUCT, fixing a bug seen when an incomplete declaration is seen before the GTY((user)) marking. --- gcc/gengtype.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 2085496..9c12752 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -559,6 +559,12 @@ type_p create_user_defined_type (const char *type_name, struct fileloc *pos) { type_p ty = find_structure (type_name, TYPE_USER_STRUCT); + + /* We might have already seen an incomplete decl of the given type, + in which case we won't have yet seen a GTY((user)), and the type will + only have kind "TYPE_STRUCT". Mark it as a user struct. */ + ty->kind = TYPE_USER_STRUCT; + ty->u.s.line = *pos; ty->u.s.bitmap = get_lang_bitmap (pos->file); do_typedef (type_name, ty, pos); -- 1.7.11.7