From 1d757b0950831ee9e223b3159e9d44461b6dbdd2 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sat, 15 Feb 2020 00:11:04 +0100 Subject: [PATCH] Fix duplicates for anonymous structures with -fdump-ada-spec This fixes a weakness in the way -fdump-ada-spec builds names for anonymous structures in the C/C++ code, resulting in duplicate identifiers under specific circumstances. c-family/ * c-ada-spec.c: Include bitmap.h. (dump_ada_double_name): Rename into... (dump_anonymous_type_name): ...this. Always use the TYPE_UID. (dump_ada_array_type): Adjust to above renaming. Robustify. (dump_nested_types_1): New function copied from... Add dumped_types parameter and pass it down to dump_nested_type. (dump_nested_types): ...this. Remove parent parameter. Just call dump_nested_types_1 on an automatic bitmap. (dump_nested_type): Add dumped_types parameter. : Do not dump it if already present in dumped_types. Adjust recursive calls and adjust to above renaming. (dump_ada_declaration): Adjust call to dump_nested_types. Tidy up and adjust to above renaming. (dump_ada_specs): Initialize and release bitmap obstack. --- gcc/c-family/ChangeLog | 17 +++++ gcc/c-family/c-ada-spec.c | 138 ++++++++++++++++++++------------------ 2 files changed, 88 insertions(+), 67 deletions(-) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index cabf850a921..e4250724e84 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,20 @@ +2020-02-14 Eric Botcazou + + * c-ada-spec.c: Include bitmap.h. + (dump_ada_double_name): Rename into... + (dump_anonymous_type_name): ...this. Always use the TYPE_UID. + (dump_ada_array_type): Adjust to above renaming. Robustify. + (dump_nested_types_1): New function copied from... Add dumped_types + parameter and pass it down to dump_nested_type. + (dump_nested_types): ...this. Remove parent parameter. Just call + dump_nested_types_1 on an automatic bitmap. + (dump_nested_type): Add dumped_types parameter. + : Do not dump it if already present in dumped_types. + Adjust recursive calls and adjust to above renaming. + (dump_ada_declaration): Adjust call to dump_nested_types. + Tidy up and adjust to above renaming. + (dump_ada_specs): Initialize and release bitmap obstack. + 2020-02-10 Martin Sebor PR c/93640 diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c index e0c18c883da..6d9192f2a26 100644 --- a/gcc/c-family/c-ada-spec.c +++ b/gcc/c-family/c-ada-spec.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "stringpool.h" #include "attribs.h" +#include "bitmap.h" /* Local functions, macros and variables. */ static int dump_ada_node (pretty_printer *, tree, tree, int, bool, bool); @@ -1475,30 +1476,21 @@ dump_ada_decl_name (pretty_printer *buffer, tree decl, bool limited_access) } } -/* Dump in BUFFER a name based on both T1 and T2 followed by a suffix. */ +/* Dump in BUFFER a name for the type T, which is a _TYPE without TYPE_NAME. + PARENT is the parent node of T. */ static void -dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2) +dump_anonymous_type_name (pretty_printer *buffer, tree t, tree parent) { - if (DECL_NAME (t1)) - pp_ada_tree_identifier (buffer, DECL_NAME (t1), t1, false); + if (DECL_NAME (parent)) + pp_ada_tree_identifier (buffer, DECL_NAME (parent), parent, false); else { pp_string (buffer, "anon"); - pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1))); + pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (parent))); } - pp_underscore (buffer); - - if (DECL_NAME (t2)) - pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, false); - else - { - pp_string (buffer, "anon"); - pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t2))); - } - - switch (TREE_CODE (TREE_TYPE (t2))) + switch (TREE_CODE (t)) { case ARRAY_TYPE: pp_string (buffer, "_array"); @@ -1516,6 +1508,8 @@ dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2) pp_string (buffer, "_unknown"); break; } + + pp_scalar (buffer, "%d", TYPE_UID (t)); } /* Dump in BUFFER aspect Import on a given node T. SPC is the current @@ -1816,10 +1810,9 @@ dump_ada_array_type (pretty_printer *buffer, tree node, tree type, int spc) /* Print the dimensions. */ dump_ada_array_domains (buffer, node, spc); - /* Print array's type. */ + /* Print the component type. */ if (!char_array) { - /* Retrieve the element type. */ tree tmp = node; while (TREE_CODE (tmp) == ARRAY_TYPE) tmp = TREE_TYPE (tmp); @@ -1829,10 +1822,12 @@ dump_ada_array_type (pretty_printer *buffer, tree node, tree type, int spc) if (TREE_CODE (tmp) != POINTER_TYPE) pp_string (buffer, "aliased "); - if (TYPE_NAME (tmp) || !RECORD_OR_UNION_TYPE_P (tmp)) + if (TYPE_NAME (tmp) + || (!RECORD_OR_UNION_TYPE_P (tmp) + && TREE_CODE (tmp) != ENUMERAL_TYPE)) dump_ada_node (buffer, tmp, node, spc, false, true); - else - dump_ada_double_name (buffer, type, get_underlying_decl (tmp)); + else if (type) + dump_anonymous_type_name (buffer, tmp, type); } } @@ -2469,10 +2464,11 @@ dump_forward_type (pretty_printer *buffer, tree type, tree t, int spc) TREE_VISITED (decl) = 1; } -static void dump_nested_type (pretty_printer *, tree, tree, tree, int); +static void dump_nested_type (pretty_printer *, tree, tree, tree, bitmap, int); -/* Dump in BUFFER anonymous types nested inside T's definition. - PARENT is the parent node of T. SPC is the indentation level. +/* Dump in BUFFER anonymous types nested inside T's definition. PARENT is the + parent node of T. DUMPED_TYPES is the bitmap of already dumped types. SPC + is the indentation level. In C anonymous nested tagged types have no name whereas in C++ they have one. In C their TYPE_DECL is at top level whereas in C++ it is nested. @@ -2484,13 +2480,14 @@ static void dump_nested_type (pretty_printer *, tree, tree, tree, int); pass on the nested TYPE_DECLs and a second pass on the unnamed types. */ static void -dump_nested_types (pretty_printer *buffer, tree t, tree parent, int spc) +dump_nested_types_1 (pretty_printer *buffer, tree t, tree parent, + bitmap dumped_types, int spc) { tree type, field; /* Find possible anonymous pointers/arrays/structs/unions recursively. */ type = TREE_TYPE (t); - if (type == NULL_TREE) + if (!type) return; for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) @@ -2498,19 +2495,31 @@ dump_nested_types (pretty_printer *buffer, tree t, tree parent, int spc) && DECL_NAME (field) != DECL_NAME (t) && !DECL_ORIGINAL_TYPE (field) && TYPE_NAME (TREE_TYPE (field)) != TYPE_NAME (type)) - dump_nested_type (buffer, field, t, parent, spc); + dump_nested_type (buffer, field, t, parent, dumped_types, spc); for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && !TYPE_NAME (TREE_TYPE (field))) - dump_nested_type (buffer, field, t, parent, spc); + dump_nested_type (buffer, field, t, parent, dumped_types, spc); } -/* Dump in BUFFER the anonymous type of FIELD inside T. - PARENT is the parent node of T. SPC is the indentation level. */ +/* Likewise, but to be invoked only at top level. We dump each anonymous type + nested inside T's definition exactly once, even if it is referenced several + times in it (typically an array type), with a name prefixed by that of T. */ + +static void +dump_nested_types (pretty_printer *buffer, tree t, int spc) +{ + auto_bitmap dumped_types; + dump_nested_types_1 (buffer, t, t, dumped_types, spc); +} + +/* Dump in BUFFER the anonymous type of FIELD inside T. PARENT is the parent + node of T. DUMPED_TYPES is the bitmap of already dumped types. SPC is the + indentation level. */ static void dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, - int spc) + bitmap dumped_types, int spc) { tree field_type = TREE_TYPE (field); tree decl, tmp; @@ -2523,6 +2532,11 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, break; case ARRAY_TYPE: + /* Anonymous array types are shared. */ + if (!bitmap_set_bit (dumped_types, TYPE_UID (field_type))) + return; + + /* Recurse on the element type if need be. */ tmp = TREE_TYPE (field_type); while (TREE_CODE (tmp) == ARRAY_TYPE) tmp = TREE_TYPE (tmp); @@ -2533,7 +2547,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, && !TREE_VISITED (decl)) { /* Generate full declaration. */ - dump_nested_type (buffer, decl, t, parent, spc); + dump_nested_type (buffer, decl, t, parent, dumped_types, spc); TREE_VISITED (decl) = 1; } else if (!decl && TREE_CODE (tmp) == POINTER_TYPE) @@ -2545,7 +2559,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, else pp_string (buffer, "type "); - dump_ada_double_name (buffer, parent, field); + dump_anonymous_type_name (buffer, field_type, parent); pp_string (buffer, " is "); dump_ada_array_type (buffer, field_type, parent, spc); pp_semicolon (buffer); @@ -2561,7 +2575,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, if (TYPE_NAME (field_type)) dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true); else - dump_ada_double_name (buffer, parent, field); + dump_anonymous_type_name (buffer, field_type, parent); pp_string (buffer, " is "); dump_ada_enum_type (buffer, field_type, spc); pp_semicolon (buffer); @@ -2570,14 +2584,14 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent, case RECORD_TYPE: case UNION_TYPE: - dump_nested_types (buffer, field, t, spc); + dump_nested_types_1 (buffer, field, parent, dumped_types, spc); pp_string (buffer, "type "); if (TYPE_NAME (field_type)) dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true); else - dump_ada_double_name (buffer, parent, field); + dump_anonymous_type_name (buffer, field_type, parent); if (TREE_CODE (field_type) == UNION_TYPE) pp_string (buffer, " (discr : unsigned := 0)"); @@ -2843,7 +2857,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) pp_string (buffer, "subtype "); else { - dump_nested_types (buffer, t, t, spc); + dump_nested_types (buffer, t, spc); if (separate_class_package (t)) { @@ -2920,8 +2934,6 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) } else { - tree tmp = TYPE_NAME (TREE_TYPE (t)); - if (spc == INDENT_INCR || TREE_STATIC (t)) is_var = true; @@ -2930,10 +2942,10 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) if (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != POINTER_TYPE) pp_string (buffer, "aliased "); - if (tmp) - dump_ada_node (buffer, tmp, type, spc, false, true); + if (TYPE_NAME (TREE_TYPE (t))) + dump_ada_node (buffer, TREE_TYPE (t), type, spc, false, true); else if (type) - dump_ada_double_name (buffer, type, t); + dump_anonymous_type_name (buffer, TREE_TYPE (t), type); else dump_ada_array_type (buffer, TREE_TYPE (t), type, spc); } @@ -3152,33 +3164,21 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) pp_string (buffer, " : "); - if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)) - || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE) - { - if (TYPE_NAME (TREE_TYPE (t)) - || TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE) - pp_string (buffer, "aliased "); - - if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL) - pp_string (buffer, "constant "); - - if (TYPE_NAME (TREE_TYPE (t))) - dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true); - else if (type) - dump_ada_double_name (buffer, type, t); - } - else - { - if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE - && (TYPE_NAME (TREE_TYPE (t)) - || TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE)) - pp_string (buffer, "aliased "); + if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE + && (TYPE_NAME (TREE_TYPE (t)) + || (TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE + && TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE))) + pp_string (buffer, "aliased "); - if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL) - pp_string (buffer, "constant "); + if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL) + pp_string (buffer, "constant "); - dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true); - } + if (TYPE_NAME (TREE_TYPE (t)) + || (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)) + && TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE)) + dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true); + else if (type) + dump_anonymous_type_name (buffer, TREE_TYPE (t), type); } } @@ -3474,6 +3474,8 @@ void dump_ada_specs (void (*collect_all_refs)(const char *), int (*check)(tree, cpp_operation)) { + bitmap_obstack_initialize (NULL); + /* Iterate over the list of files to dump specs for. */ for (int i = 0; i < source_refs_used; i++) dump_ads (source_refs[i], collect_all_refs, check); @@ -3481,4 +3483,6 @@ dump_ada_specs (void (*collect_all_refs)(const char *), /* Free various tables. */ free (source_refs); delete overloaded_names; + + bitmap_obstack_release (NULL); } -- 2.30.2