From patchwork Fri Feb 14 23:13:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 1238387 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-519574-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=vsP6a1cr; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48K8Mb2yPMz9sPK for ; Sat, 15 Feb 2020 10:14:01 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=tM7xW+VsxN2CrEhv MLwjCrT4z8JTHTWQP+/4ihJIgU3oMdbZKXNTTQNuVmwLo3YsZFsr6+IWcGCTmxkz OOMvGXbc3aq8xdK1Sj9ocNFrn/8LTtLtU2c7W7qZdtZRrUUolCbcrLmpmSub7tKD WqP4L34OOSenqiq17eiwlya1hGQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=CMs6rPokm064rRRbsLgIRg AJZhs=; b=vsP6a1crtjaDH6Au8v3or1cOULsLB6VuMRpdHagtqFxovzzm5A2v2v Ep6rcgSKQSVUjSfXMK6oGZFSZiFMNSxCP6tRQhnO0QqLUGNDqe7HDIGL19RFKWjj 6l9KguzG9UBBlzV8bYlyWlReucB48OhB7Qg2OPM+QOuz8uq/ShvSY= Received: (qmail 57287 invoked by alias); 14 Feb 2020 23:13:52 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 57279 invoked by uid 89); 14 Feb 2020 23:13:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=t's, anon X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 14 Feb 2020 23:13:50 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 8205981386 for ; Sat, 15 Feb 2020 00:13:47 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0DfgNSD_SGEf for ; Sat, 15 Feb 2020 00:13:47 +0100 (CET) Received: from polaris.localnet (unknown [IPv6:2a01:e0a:41b:9230:1a03:73ff:fe45:373a]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 4BCFF8137F for ; Sat, 15 Feb 2020 00:13:47 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [c-family] Fix duplicates for anonymous structures with -fdump-ada-spec Date: Sat, 15 Feb 2020 00:13:45 +0100 Message-ID: <2783037.rgQo4liRtm@polaris> MIME-Version: 1.0 This fixes a weakness in the way -fdump-ada-spec builds names for anonymous structures in C/C++ code, resulting in duplicate identifiers under specific circumstances. Probably worth fixing in GCC 10 instead of waiting longer. Bootstrapped/regtested on x86_64-suse-linux, applied on the mainline. 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. 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); }