mirror of git://gcc.gnu.org/git/gcc.git
re PR ipa/87957 (ICE tree check: expected tree that contains ‘decl minimal’ structure, have ‘identifier_node’ in warn_odr, at ipa-devirt.c:1051 since r265519)
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
This commit is contained in:
parent
6bdb055ea8
commit
7424b7c139
|
|
@ -1,3 +1,15 @@
|
||||||
|
2018-11-21 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
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 <oliva@adacore.com>
|
2018-11-21 Alexandre Oliva <oliva@adacore.com>
|
||||||
|
|
||||||
* final.c (compute_discriminator): Declare. Renamed from...
|
* final.c (compute_discriminator): Declare. Renamed from...
|
||||||
|
|
|
||||||
|
|
@ -2025,6 +2025,8 @@ get_odr_type (tree type, bool insert)
|
||||||
if ((!slot || !*slot) && in_lto_p && can_be_vtable_hashed_p (type))
|
if ((!slot || !*slot) && in_lto_p && can_be_vtable_hashed_p (type))
|
||||||
{
|
{
|
||||||
hash = hash_odr_vtable (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,
|
vtable_slot = odr_vtable_hash->find_slot_with_hash (type, hash,
|
||||||
insert ? INSERT : NO_INSERT);
|
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);
|
"%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
|
static void
|
||||||
free_enum_values ()
|
free_odr_warning_data ()
|
||||||
{
|
{
|
||||||
static bool enum_values_freed = false;
|
static bool odr_data_freed = false;
|
||||||
if (enum_values_freed || !flag_wpa || !odr_types_ptr)
|
|
||||||
|
if (odr_data_freed || !flag_wpa || !odr_types_ptr)
|
||||||
return;
|
return;
|
||||||
enum_values_freed = true;
|
|
||||||
unsigned int i;
|
odr_data_freed = true;
|
||||||
for (i = 0; i < odr_types.length (); i++)
|
|
||||||
|
for (unsigned int i = 0; i < odr_types.length (); i++)
|
||||||
if (odr_types[i])
|
if (odr_types[i])
|
||||||
{
|
{
|
||||||
if (TREE_CODE (odr_types[i]->type) == ENUMERAL_TYPE)
|
tree t = odr_types[i]->type;
|
||||||
TYPE_VALUES (odr_types[i]->type) = NULL;
|
|
||||||
|
if (TREE_CODE (t) == ENUMERAL_TYPE)
|
||||||
|
TYPE_VALUES (t) = NULL;
|
||||||
|
TREE_TYPE (TYPE_NAME (t)) = void_type_node;
|
||||||
|
|
||||||
if (odr_types[i]->types)
|
if (odr_types[i]->types)
|
||||||
for (unsigned int j = 0; j < odr_types[i]->types->length (); j++)
|
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. */
|
/* Initialize IPA devirt and build inheritance tree graph. */
|
||||||
|
|
@ -2323,7 +2341,7 @@ build_type_inheritance_graph (void)
|
||||||
|
|
||||||
if (odr_hash)
|
if (odr_hash)
|
||||||
{
|
{
|
||||||
free_enum_values ();
|
free_odr_warning_data ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timevar_push (TV_IPA_INHERITANCE);
|
timevar_push (TV_IPA_INHERITANCE);
|
||||||
|
|
@ -2370,7 +2388,7 @@ build_type_inheritance_graph (void)
|
||||||
dump_type_inheritance_graph (inheritance_dump_file);
|
dump_type_inheritance_graph (inheritance_dump_file);
|
||||||
dump_end (TDI_inheritance, inheritance_dump_file);
|
dump_end (TDI_inheritance, inheritance_dump_file);
|
||||||
}
|
}
|
||||||
free_enum_values ();
|
free_odr_warning_data ();
|
||||||
timevar_pop (TV_IPA_INHERITANCE);
|
timevar_pop (TV_IPA_INHERITANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
93
gcc/tree.c
93
gcc/tree.c
|
|
@ -5206,6 +5206,24 @@ fld_process_array_type (tree t, tree t2, hash_map<tree, tree> *map,
|
||||||
return array;
|
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.
|
/* For T being aggregate type try to turn it into a incomplete variant.
|
||||||
Return T if no simplification is possible. */
|
Return T if no simplification is possible. */
|
||||||
|
|
||||||
|
|
@ -5267,6 +5285,28 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TYPE_VALUES (copy) = NULL;
|
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;
|
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)
|
if (TREE_CODE (type) == ENUMERAL_TYPE)
|
||||||
{
|
{
|
||||||
/* Type values are used only for C++ ODR checking. Drop them
|
/* 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
|
if (TYPE_MAIN_VARIANT (type) != type
|
||||||
|| !type_with_linkage_p (type))
|
|| !type_with_linkage_p (type))
|
||||||
TYPE_VALUES (type) = NULL;
|
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;
|
TYPE_CONTEXT (type) = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drop TYPE_DECLs in TYPE_NAME in favor of the identifier in the
|
TYPE_STUB_DECL (type) = NULL;
|
||||||
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_NAME (type) = fld_simplified_type_name (type);
|
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.
|
e.g. -fno-signed-char/-fsigned-char mismatches to be handled well.
|
||||||
See cp/mangle.c:write_builtin_type for details. */
|
See cp/mangle.c:write_builtin_type for details. */
|
||||||
|
|
||||||
if (flag_lto_odr_type_mering
|
if (TREE_CODE (decl) == TYPE_DECL)
|
||||||
&& TREE_CODE (decl) == TYPE_DECL
|
{
|
||||||
&& DECL_NAME (decl)
|
if (flag_lto_odr_type_mering
|
||||||
&& decl == TYPE_NAME (TREE_TYPE (decl))
|
&& DECL_NAME (decl)
|
||||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl)
|
&& decl == TYPE_NAME (TREE_TYPE (decl))
|
||||||
&& !TYPE_ARTIFICIAL (TREE_TYPE (decl))
|
&& TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl)
|
||||||
&& (type_with_linkage_p (TREE_TYPE (decl))
|
&& !TYPE_ARTIFICIAL (TREE_TYPE (decl))
|
||||||
|| TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE)
|
&& (type_with_linkage_p (TREE_TYPE (decl))
|
||||||
&& !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
|
|| TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE)
|
||||||
return !DECL_ASSEMBLER_NAME_SET_P (decl);
|
&& !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. */
|
/* Only FUNCTION_DECLs and VAR_DECLs are considered. */
|
||||||
if (!VAR_OR_FUNCTION_DECL_P (decl))
|
if (!VAR_OR_FUNCTION_DECL_P (decl))
|
||||||
return false;
|
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 (decl) = VISIBILITY_DEFAULT;
|
||||||
DECL_VISIBILITY_SPECIFIED (decl) = 0;
|
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;
|
TYPE_DECL_SUPPRESS_DEBUG (decl) = 0;
|
||||||
DECL_INITIAL (decl) = NULL_TREE;
|
DECL_INITIAL (decl) = NULL_TREE;
|
||||||
DECL_ORIGINAL_TYPE (decl) = NULL_TREE;
|
DECL_ORIGINAL_TYPE (decl) = NULL_TREE;
|
||||||
DECL_MODE (decl) = VOIDmode;
|
DECL_MODE (decl) = VOIDmode;
|
||||||
TREE_TYPE (decl) = void_type_node;
|
|
||||||
SET_DECL_ALIGN (decl, 0);
|
SET_DECL_ALIGN (decl, 0);
|
||||||
|
/* TREE_TYPE is cleared at WPA time in free_odr_warning_data. */
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (decl) == FIELD_DECL)
|
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
|
if (TREE_CODE (decl) != FIELD_DECL
|
||||||
&& ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
|
&& ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
|
||||||
|| !DECL_VIRTUAL_P (decl)))
|
|| !DECL_VIRTUAL_P (decl)))
|
||||||
{
|
DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue