From 7424b7c13940c36700db8cd19a6f16d75af07b50 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 21 Nov 2018 18:31:19 +0100 Subject: [PATCH] =?utf8?q?re=20PR=20ipa/87957=20(ICE=20tree=20check:=20exp?= =?utf8?q?ected=20tree=20that=20contains=20=E2=80=98decl=20minimal?= =?utf8?q?=E2=80=99=20structure,=20have=20=E2=80=98identifier=5Fnode?= =?utf8?q?=E2=80=99=20in=20warn=5Fodr,=20at=20ipa-devirt.c:1051=20since=20?= =?utf8?q?r265519)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit PR lto/87957 * tree.c (fld_decl_context): Break out from ... (free_lang_data_in_decl): ... here; free TREE_PUBLIC, TREE_PRIVATE DECL_ARTIFICIAL of TYPE_DECL; do not free TREE_TYPE of TYPE_DECL. (fld_incomplete_type_of): Build copy of TYP_DECL. * ipa-devirt.c (free_enum_values): Rename to ... (free_odr_warning_data): ... this one; free also duplicated TYPE_DECLs and TREE_TYPEs of TYPE_DECLs. (get_odr_type): Initialize odr_vtable_hash if needed. From-SVN: r266350 --- gcc/ChangeLog | 12 ++++++++ gcc/ipa-devirt.c | 46 +++++++++++++++++++--------- gcc/tree.c | 93 +++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 105 insertions(+), 46 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 88db1c1..82a1710 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2018-11-21 Jan Hubicka + + PR lto/87957 + * tree.c (fld_decl_context): Break out from ... + (free_lang_data_in_decl): ... here; free TREE_PUBLIC, TREE_PRIVATE + DECL_ARTIFICIAL of TYPE_DECL; do not free TREE_TYPE of TYPE_DECL. + (fld_incomplete_type_of): Build copy of TYP_DECL. + * ipa-devirt.c (free_enum_values): Rename to ... + (free_odr_warning_data): ... this one; free also duplicated TYPE_DECLs + and TREE_TYPEs of TYPE_DECLs. + (get_odr_type): Initialize odr_vtable_hash if needed. + 2018-11-21 Alexandre Oliva * final.c (compute_discriminator): Declare. Renamed from... diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index b72789c..8c375ff 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -2025,6 +2025,8 @@ get_odr_type (tree type, bool insert) if ((!slot || !*slot) && in_lto_p && can_be_vtable_hashed_p (type)) { hash = hash_odr_vtable (type); + if (!odr_vtable_hash) + odr_vtable_hash = new odr_vtable_hash_type (23); vtable_slot = odr_vtable_hash->find_slot_with_hash (type, hash, insert ? INSERT : NO_INSERT); } @@ -2289,27 +2291,43 @@ dump_type_inheritance_graph (FILE *f) "%i duplicates overall\n", num_all_types, num_types, num_duplicates); } -/* Save some WPA->ltrans streaming by freeing enum values. */ +/* Save some WPA->ltrans streaming by freeing stuff needed only for good + ODR warnings. + We free TYPE_VALUES of enums and also make TYPE_DECLs to not point back + to the type (which is needed to keep them in the same SCC and preserve + location information to output warnings) and subsequently we make all + TYPE_DECLS of same assembler name equivalent. */ static void -free_enum_values () +free_odr_warning_data () { - static bool enum_values_freed = false; - if (enum_values_freed || !flag_wpa || !odr_types_ptr) + static bool odr_data_freed = false; + + if (odr_data_freed || !flag_wpa || !odr_types_ptr) return; - enum_values_freed = true; - unsigned int i; - for (i = 0; i < odr_types.length (); i++) + + odr_data_freed = true; + + for (unsigned int i = 0; i < odr_types.length (); i++) if (odr_types[i]) { - if (TREE_CODE (odr_types[i]->type) == ENUMERAL_TYPE) - TYPE_VALUES (odr_types[i]->type) = NULL; + tree t = odr_types[i]->type; + + if (TREE_CODE (t) == ENUMERAL_TYPE) + TYPE_VALUES (t) = NULL; + TREE_TYPE (TYPE_NAME (t)) = void_type_node; + if (odr_types[i]->types) for (unsigned int j = 0; j < odr_types[i]->types->length (); j++) - if (TREE_CODE ((*odr_types[i]->types)[j]) == ENUMERAL_TYPE) - TYPE_VALUES ((*odr_types[i]->types)[j]) = NULL; + { + tree td = (*odr_types[i]->types)[j]; + + if (TREE_CODE (td) == ENUMERAL_TYPE) + TYPE_VALUES (td) = NULL; + TYPE_NAME (td) = TYPE_NAME (t); + } } - enum_values_freed = true; + odr_data_freed = true; } /* Initialize IPA devirt and build inheritance tree graph. */ @@ -2323,7 +2341,7 @@ build_type_inheritance_graph (void) if (odr_hash) { - free_enum_values (); + free_odr_warning_data (); return; } timevar_push (TV_IPA_INHERITANCE); @@ -2370,7 +2388,7 @@ build_type_inheritance_graph (void) dump_type_inheritance_graph (inheritance_dump_file); dump_end (TDI_inheritance, inheritance_dump_file); } - free_enum_values (); + free_odr_warning_data (); timevar_pop (TV_IPA_INHERITANCE); } diff --git a/gcc/tree.c b/gcc/tree.c index 50c4cd0..8264e9c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5206,6 +5206,24 @@ fld_process_array_type (tree t, tree t2, hash_map *map, return array; } +/* Return CTX after removal of contexts that are not relevant */ + +static tree +fld_decl_context (tree ctx) +{ + /* Variably modified types are needed for tree_is_indexable to decide + whether the type needs to go to local or global section. + This code is semi-broken but for now it is easiest to keep contexts + as expected. */ + if (ctx && TYPE_P (ctx) + && !variably_modified_type_p (ctx, NULL_TREE)) + { + while (ctx && TYPE_P (ctx)) + ctx = TYPE_CONTEXT (ctx); + } + return ctx; +} + /* For T being aggregate type try to turn it into a incomplete variant. Return T if no simplification is possible. */ @@ -5267,6 +5285,28 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld) } else TYPE_VALUES (copy) = NULL; + + /* Build copy of TYPE_DECL in TYPE_NAME if necessary. + This is needed for ODR violation warnings to come out right (we + want duplicate TYPE_DECLs whenever the type is duplicated because + of ODR violation. Because lang data in the TYPE_DECL may not + have been freed yet, rebuild it from scratch and copy relevant + fields. */ + TYPE_NAME (copy) = fld_simplified_type_name (copy); + tree name = TYPE_NAME (copy); + + if (name && TREE_CODE (name) == TYPE_DECL) + { + gcc_checking_assert (TREE_TYPE (name) == t); + tree name2 = build_decl (DECL_SOURCE_LOCATION (name), TYPE_DECL, + DECL_NAME (name), copy); + if (DECL_ASSEMBLER_NAME_SET_P (name)) + SET_DECL_ASSEMBLER_NAME (name2, DECL_ASSEMBLER_NAME (name)); + SET_DECL_ALIGN (name2, 0); + DECL_CONTEXT (name2) = fld_decl_context + (DECL_CONTEXT (name)); + TYPE_NAME (copy) = name2; + } } return copy; } @@ -5423,7 +5463,8 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld) if (TREE_CODE (type) == ENUMERAL_TYPE) { /* Type values are used only for C++ ODR checking. Drop them - for all type variants and non-ODR types. */ + for all type variants and non-ODR types. + For ODR types the data is freed in free_odr_warning_data. */ if (TYPE_MAIN_VARIANT (type) != type || !type_with_linkage_p (type)) TYPE_VALUES (type) = NULL; @@ -5455,11 +5496,7 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld) TYPE_CONTEXT (type) = ctx; } - /* Drop TYPE_DECLs in TYPE_NAME in favor of the identifier in the - TYPE_DECL if the type doesn't have linkage. - this must match fld_ */ - if (type != TYPE_MAIN_VARIANT (type) || ! type_with_linkage_p (type)) - TYPE_STUB_DECL (type) = NULL; + TYPE_STUB_DECL (type) = NULL; TYPE_NAME (type) = fld_simplified_type_name (type); } @@ -5486,16 +5523,19 @@ need_assembler_name_p (tree decl) e.g. -fno-signed-char/-fsigned-char mismatches to be handled well. See cp/mangle.c:write_builtin_type for details. */ - if (flag_lto_odr_type_mering - && TREE_CODE (decl) == TYPE_DECL - && DECL_NAME (decl) - && decl == TYPE_NAME (TREE_TYPE (decl)) - && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl) - && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) - && (type_with_linkage_p (TREE_TYPE (decl)) - || TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE) - && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) - return !DECL_ASSEMBLER_NAME_SET_P (decl); + if (TREE_CODE (decl) == TYPE_DECL) + { + if (flag_lto_odr_type_mering + && DECL_NAME (decl) + && decl == TYPE_NAME (TREE_TYPE (decl)) + && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl) + && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) + && (type_with_linkage_p (TREE_TYPE (decl)) + || TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE) + && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) + return !DECL_ASSEMBLER_NAME_SET_P (decl); + return false; + } /* Only FUNCTION_DECLs and VAR_DECLs are considered. */ if (!VAR_OR_FUNCTION_DECL_P (decl)) return false; @@ -5649,13 +5689,15 @@ free_lang_data_in_decl (tree decl, struct free_lang_data_d *fld) { DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; DECL_VISIBILITY_SPECIFIED (decl) = 0; - /* TREE_PUBLIC is used to tell if type is anonymous. */ + TREE_PUBLIC (decl) = 0; + TREE_PRIVATE (decl) = 0; + DECL_ARTIFICIAL (decl) = 0; TYPE_DECL_SUPPRESS_DEBUG (decl) = 0; DECL_INITIAL (decl) = NULL_TREE; DECL_ORIGINAL_TYPE (decl) = NULL_TREE; DECL_MODE (decl) = VOIDmode; - TREE_TYPE (decl) = void_type_node; SET_DECL_ALIGN (decl, 0); + /* TREE_TYPE is cleared at WPA time in free_odr_warning_data. */ } else if (TREE_CODE (decl) == FIELD_DECL) { @@ -5688,20 +5730,7 @@ free_lang_data_in_decl (tree decl, struct free_lang_data_d *fld) if (TREE_CODE (decl) != FIELD_DECL && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) || !DECL_VIRTUAL_P (decl))) - { - tree ctx = DECL_CONTEXT (decl); - /* Variably modified types are needed for tree_is_indexable to decide - whether the type needs to go to local or global section. - This code is semi-broken but for now it is easiest to keep contexts - as expected. */ - if (ctx && TYPE_P (ctx) - && !variably_modified_type_p (ctx, NULL_TREE)) - { - while (ctx && TYPE_P (ctx)) - ctx = TYPE_CONTEXT (ctx); - DECL_CONTEXT (decl) = ctx; - } - } + DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl)); } -- 2.7.4