From 6931e393f8f6d81fc88146d8a57339e2a0a2f7ee Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Thu, 14 Oct 2021 12:48:49 +0100 Subject: [PATCH] fprintf: Fix nested struct printing wrt attributes This code: struct X { struct { } __attribute__((foo)) x __attribute__((bar)); } Was wrongly printed as: struct X { struct { } x __attribute__((foo)) __attribute__((bar)); } This unfortunately matters a lot, since "bar" is suppose to apply to "x", but "foo" to typeof(x). In the wrong form, both apply to "x", leading to e.g. incorrect layout for __aligned__ attribute. Signed-off-by: Douglas Raillard Signed-off-by: Arnaldo Carvalho de Melo --- dwarves_fprintf.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index c35868a..1c1d949 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -787,7 +787,7 @@ print_default: (type->tag == DW_TAG_class_type && !tconf.classes_as_structs) ? "class" : "struct", tconf.type_spacing - 7, - type__name(ctype), name); + type__name(ctype), name ?: ""); } else { struct class *cclass = tag__class(type); @@ -802,7 +802,7 @@ print_default: ctype = tag__type(type); if (type__name(ctype) != NULL && !expand_types) { - printed += fprintf(fp, "union %-*s %s", tconf.type_spacing - 6, type__name(ctype), name); + printed += fprintf(fp, "union %-*s %s", tconf.type_spacing - 6, type__name(ctype), name ?: ""); } else { tconf.type_spacing -= 8; printed += union__fprintf(ctype, cu, &tconf, fp); @@ -812,7 +812,7 @@ print_default: ctype = tag__type(type); if (type__name(ctype) != NULL) - printed += fprintf(fp, "enum %-*s %s", tconf.type_spacing - 5, type__name(ctype), name); + printed += fprintf(fp, "enum %-*s %s", tconf.type_spacing - 5, type__name(ctype), name ?: ""); else printed += enumeration__fprintf(type, &tconf, fp); break; @@ -863,7 +863,21 @@ static size_t class_member__fprintf(struct class_member *member, bool union_memb if (member->is_static) printed += fprintf(fp, "static "); - printed += type__fprintf(type, cu, name, &sconf, fp); + /* For struct-like constructs, the name of the member cannot be + * conflated with the name of its type, otherwise __attribute__ are + * printed in the wrong order. + */ + if (tag__is_union(type) || tag__is_struct(type) || + tag__is_enumeration(type)) { + printed += type__fprintf(type, cu, NULL, &sconf, fp); + if (name) { + if (!type__name(tag__type(type))) + printed += fprintf(fp, " "); + printed += fprintf(fp, "%s", name); + } + } else { + printed += type__fprintf(type, cu, name, &sconf, fp); + } if (member->is_static) { if (member->const_value != 0)