From 012b51cf21538e0695cbcc6b725f1140655c86b7 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 20 Nov 2018 19:06:03 +0100 Subject: [PATCH] ipa-devirt.c (add_type_duplicate): Do not ICE on incomplete enums. * ipa-devirt.c (add_type_duplicate): Do not ICE on incomplete enums. * tree.c (build_array_type_1): Forward declare. (fld_type_variant_equal_p): Add INNER_TYPE parameter. (fld_type_variant): Likewise. (fld_simplified_types): New hash. (fld_process_array_type): New function. (fld_incomplete_type_of): Handle array and enumeration types. (fld_simplified_type): Handle simplification of arrays. (free_lang_data): Allocate and free simplified types hash. From-SVN: r266325 --- gcc/ChangeLog | 12 ++++++++ gcc/ipa-devirt.c | 3 +- gcc/tree.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 83 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d0849d6..116e4b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 2018-11-20 Jan Hubicka + * ipa-devirt.c (add_type_duplicate): Do not ICE on incomplete enums. + * tree.c (build_array_type_1): Forward declare. + (fld_type_variant_equal_p): Add INNER_TYPE parameter. + (fld_type_variant): Likewise. + (fld_simplified_types): New hash. + (fld_process_array_type): New function. + (fld_incomplete_type_of): Handle array and enumeration types. + (fld_simplified_type): Handle simplification of arrays. + (free_lang_data): Allocate and free simplified types hash. + +2018-11-20 Jan Hubicka + PR lto/87957 * ipa-devirt.c (odr_subtypes_equivalent_p): Report ODR violation when sybtype already violates ODR. diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index cbc0eec..229eebc 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1720,7 +1720,8 @@ add_type_duplicate (odr_type val, tree type) else if (!COMPLETE_TYPE_P (val->type) && COMPLETE_TYPE_P (type)) { prevail = true; - build_bases = TYPE_BINFO (type); + if (TREE_CODE (type) == RECORD_TYPE) + build_bases = TYPE_BINFO (type); } else if (COMPLETE_TYPE_P (val->type) && !COMPLETE_TYPE_P (type)) ; diff --git a/gcc/tree.c b/gcc/tree.c index a9720e5..50c4cd0 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -265,6 +265,8 @@ static void print_type_hash_statistics (void); static void print_debug_expr_statistics (void); static void print_value_expr_statistics (void); +static tree build_array_type_1 (tree, tree, bool, bool); + tree global_trees[TI_MAX]; tree integer_types[itk_none]; @@ -5109,10 +5111,11 @@ fld_simplified_type_name (tree type) /* Do same comparsion as check_qualified_type skipping lang part of type and be more permissive about type names: we only care that names are - same (for diagnostics) and that ODR names are the same. */ + same (for diagnostics) and that ODR names are the same. + If INNER_TYPE is non-NULL, be sure that TREE_TYPE match it. */ static bool -fld_type_variant_equal_p (tree t, tree v) +fld_type_variant_equal_p (tree t, tree v, tree inner_type) { if (TYPE_QUALS (t) != TYPE_QUALS (v) /* We want to match incomplete variants with complete types. @@ -5122,21 +5125,24 @@ fld_type_variant_equal_p (tree t, tree v) || TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (v))) || fld_simplified_type_name (t) != fld_simplified_type_name (v) || !attribute_list_equal (TYPE_ATTRIBUTES (t), - TYPE_ATTRIBUTES (v))) + TYPE_ATTRIBUTES (v)) + || (inner_type && TREE_TYPE (v) != inner_type)) return false; - + return true; } -/* Find variant of FIRST that match T and create new one if necessary. */ +/* Find variant of FIRST that match T and create new one if necessary. + Set TREE_TYPE to INNER_TYPE if non-NULL. */ static tree -fld_type_variant (tree first, tree t, struct free_lang_data_d *fld) +fld_type_variant (tree first, tree t, struct free_lang_data_d *fld, + tree inner_type = NULL) { if (first == TYPE_MAIN_VARIANT (t)) return t; for (tree v = first; v; v = TYPE_NEXT_VARIANT (v)) - if (fld_type_variant_equal_p (t, v)) + if (fld_type_variant_equal_p (t, v, inner_type)) return v; tree v = build_variant_type_copy (first); TYPE_READONLY (v) = TYPE_READONLY (t); @@ -5154,7 +5160,9 @@ fld_type_variant (tree first, tree t, struct free_lang_data_d *fld) SET_TYPE_ALIGN (v, TYPE_ALIGN (t)); TYPE_USER_ALIGN (v) = TYPE_USER_ALIGN (t); } - gcc_checking_assert (fld_type_variant_equal_p (t,v)); + if (inner_type) + TREE_TYPE (v) = inner_type; + gcc_checking_assert (fld_type_variant_equal_p (t,v, inner_type)); add_tree_to_fld_list (v, fld); return v; } @@ -5163,6 +5171,41 @@ fld_type_variant (tree first, tree t, struct free_lang_data_d *fld) static hash_map *fld_incomplete_types; +/* Map types to simplified types. */ + +static hash_map *fld_simplified_types; + +/* Produce variant of T whose TREE_TYPE is T2. If it is main variant, + use MAP to prevent duplicates. */ + +static tree +fld_process_array_type (tree t, tree t2, hash_map *map, + struct free_lang_data_d *fld) +{ + if (TREE_TYPE (t) == t2) + return t; + + if (TYPE_MAIN_VARIANT (t) != t) + { + return fld_type_variant + (fld_process_array_type (TYPE_MAIN_VARIANT (t), + TYPE_MAIN_VARIANT (t2), map, fld), + t, fld, t2); + } + + bool existed; + tree &array + = map->get_or_insert (t, &existed); + if (!existed) + { + array = build_array_type_1 (t2, TYPE_DOMAIN (t), + TYPE_TYPELESS_STORAGE (t), false); + TYPE_CANONICAL (array) = TYPE_CANONICAL (t); + add_tree_to_fld_list (array, fld); + } + return array; +} + /* For T being aggregate type try to turn it into a incomplete variant. Return T if no simplification is possible. */ @@ -5190,7 +5233,12 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld) } return t; } - if (!RECORD_OR_UNION_TYPE_P (t) || !COMPLETE_TYPE_P (t)) + if (TREE_CODE (t) == ARRAY_TYPE) + return fld_process_array_type (t, + fld_incomplete_type_of (TREE_TYPE (t), fld), + fld_incomplete_types, fld); + if ((!RECORD_OR_UNION_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE) + || !COMPLETE_TYPE_P (t)) return t; if (TYPE_MAIN_VARIANT (t) == t) { @@ -5202,18 +5250,18 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld) { copy = build_distinct_type_copy (t); - /* It is possible type was not seen by free_lang_data yet. */ + /* It is possible that type was not seen by free_lang_data yet. */ add_tree_to_fld_list (copy, fld); TYPE_SIZE (copy) = NULL; - SET_TYPE_MODE (copy, VOIDmode); - SET_TYPE_ALIGN (copy, BITS_PER_UNIT); TYPE_USER_ALIGN (copy) = 0; TYPE_SIZE_UNIT (copy) = NULL; TYPE_CANONICAL (copy) = TYPE_CANONICAL (t); - TYPE_TYPELESS_STORAGE (copy) = 0; TREE_ADDRESSABLE (copy) = 0; if (AGGREGATE_TYPE_P (t)) { + SET_TYPE_MODE (copy, VOIDmode); + SET_TYPE_ALIGN (copy, BITS_PER_UNIT); + TYPE_TYPELESS_STORAGE (copy) = 0; TYPE_FIELDS (copy) = NULL; TYPE_BINFO (copy) = NULL; } @@ -5232,8 +5280,13 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld) static tree fld_simplified_type (tree t, struct free_lang_data_d *fld) { - if (t && POINTER_TYPE_P (t)) + if (!t) + return t; + if (POINTER_TYPE_P (t)) return fld_incomplete_type_of (t, fld); + if (TREE_CODE (t) == ARRAY_TYPE) + return fld_process_array_type (t, fld_simplified_type (TREE_TYPE (t), fld), + fld_simplified_types, fld); return t; } @@ -6070,6 +6123,7 @@ free_lang_data (void) return 0; fld_incomplete_types = new hash_map; + fld_simplified_types = new hash_map; /* Provide a dummy TRANSLATION_UNIT_DECL if the FE failed to provide one. */ if (vec_safe_is_empty (all_translation_units)) @@ -6126,6 +6180,7 @@ free_lang_data (void) rebuild_type_inheritance_graph (); delete fld_incomplete_types; + delete fld_simplified_types; return 0; } -- 2.7.4