diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-02-09 21:34:18 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-02-09 20:34:18 +0000 |
commit | 7d8adcba74fab09f7aec6f75fe038db834b646d9 (patch) | |
tree | a1aa06183cb5b8d8a0c83a3b176e3b7213ea6272 /gcc | |
parent | 62c7e4b7485d26f3bbc3cf648ea86346955ac4c7 (diff) | |
download | gcc-7d8adcba74fab09f7aec6f75fe038db834b646d9.zip gcc-7d8adcba74fab09f7aec6f75fe038db834b646d9.tar.gz gcc-7d8adcba74fab09f7aec6f75fe038db834b646d9.tar.bz2 |
ipa-devirt.c (odr_types_equivalent_p): Fix formating.
* ipa-devirt.c (odr_types_equivalent_p): Fix formating.
(add_type_duplicate): Fix comparison of BINFOs.
From-SVN: r220546
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/ipa-devirt.c | 116 |
2 files changed, 101 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e661a9d..445e9a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2015-02-08 Jan Hubicka <hubicka@ucw.cz> + * ipa-devirt.c (odr_types_equivalent_p): Fix formating. + (add_type_duplicate): Fix comparison of BINFOs. + +2015-02-08 Jan Hubicka <hubicka@ucw.cz> + * ipa-polymorphic-call.c (ipa_polymorphic_call_context): Avoid ICE on getting VOID pointer. diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index aaffa3c..790e483 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -807,7 +807,8 @@ warn_types_mismatch (tree t1, tree t2) gimple_canonical_types_compatible_p. */ static bool -odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, hash_set<type_pair,pair_traits> *visited) +odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, + hash_set<type_pair,pair_traits> *visited) { /* Check first for the obvious case of pointer identity. */ if (t1 == t2) @@ -1206,8 +1207,8 @@ add_type_duplicate (odr_type val, tree type) val->types_set = new hash_set<tree>; /* Always prefer complete type to be the leader. */ - if (!COMPLETE_TYPE_P (val->type) - && COMPLETE_TYPE_P (type)) + if ((!COMPLETE_TYPE_P (val->type) || !TYPE_BINFO (val->type)) + && (COMPLETE_TYPE_P (type) && TYPE_BINFO (val->type))) { tree tmp = type; @@ -1229,7 +1230,8 @@ add_type_duplicate (odr_type val, tree type) vec_safe_push (val->types, type); /* First we compare memory layout. */ - if (!odr_types_equivalent_p (val->type, type, !flag_ltrans && !val->odr_violated, + if (!odr_types_equivalent_p (val->type, type, + !flag_ltrans && !val->odr_violated, &warned, &visited)) { merge = false; @@ -1253,31 +1255,105 @@ add_type_duplicate (odr_type val, tree type) && TREE_CODE (type) == RECORD_TYPE && TYPE_BINFO (val->type) && TYPE_BINFO (type)) { - for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) - if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (TYPE_BINFO (type), i))) + if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) + != BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))) + { + if (!warned && !val->odr_violated) + { + tree extra_base; + warn_odr (type, val->type, NULL, NULL, !warned, &warned, + "a type with the same name but different " + "number of polymorphic bases is " + "defined in another translation unit"); + if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) + > BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))) + extra_base = BINFO_BASE_BINFO + (TYPE_BINFO (type), + BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))); + else + extra_base = BINFO_BASE_BINFO + (TYPE_BINFO (val->type), + BINFO_N_BASE_BINFOS (TYPE_BINFO (type))); + inform (DECL_SOURCE_LOCATION + (TYPE_NAME (DECL_CONTEXT (extra_base))), + "the extra base is defined here "); + } + base_mismatch = true; + } + else + for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) { - odr_type base = get_odr_type - (BINFO_TYPE - (BINFO_BASE_BINFO (TYPE_BINFO (type), - i)), - true); - if (val->bases.length () <= j || val->bases[j] != base) - base_mismatch = true; - j++; + tree base1 = BINFO_BASE_BINFO (TYPE_BINFO (type), i); + tree base2 = BINFO_BASE_BINFO (TYPE_BINFO (val->type), i); + tree type1 = BINFO_TYPE (base1); + tree type2 = BINFO_TYPE (base2); + + if (types_odr_comparable (type1, type2)) + { + if (!types_same_for_odr (type1, type2)) + base_mismatch = true; + } + else + { + hash_set<type_pair,pair_traits> visited; + if (!odr_types_equivalent_p (type1, type2, false, NULL, + &visited)) + base_mismatch = true; + } + if (base_mismatch) + { + if (!warned && !val->odr_violated) + warn_odr (type, val->type, NULL, NULL, + !warned, &warned, + "a type with the same name but different base " + "type is defined in another translation unit"); + warn_types_mismatch (type1, type2); + break; + } + if (BINFO_OFFSET (base1) != BINFO_OFFSET (base2)) + { + base_mismatch = true; + if (!warned && !val->odr_violated) + warn_odr (type, val->type, NULL, NULL, + !warned, &warned, + "a type with the same name but different base " + "layout is defined in another translation unit"); + break; + } } + /* Sanity check that all bases will be build same way again. */ + if (!base_mismatch && val->bases.length ()) + { + unsigned int num_poly_bases = 0; + + for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) + if (polymorphic_type_binfo_p (BINFO_BASE_BINFO + (TYPE_BINFO (type), i))) + num_poly_bases++; + gcc_assert (num_poly_bases == val->bases.length ()); + for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); + i++) + if (polymorphic_type_binfo_p (BINFO_BASE_BINFO + (TYPE_BINFO (type), i))) + { + odr_type base = get_odr_type + (BINFO_TYPE + (BINFO_BASE_BINFO (TYPE_BINFO (type), + i)), + true); + gcc_assert (val->bases[j] == base); + j++; + } + } if (base_mismatch) { merge = false; odr_violation_reported = true; - - if (!warned && !val->odr_violated) - warn_odr (type, val->type, NULL, NULL, !warned, &warned, - "a type with the same name but different bases is " - "defined in another translation unit"); val->odr_violated = true; + if (symtab->dump_file) { - fprintf (symtab->dump_file, "ODR bse violation or merging bug?\n"); + fprintf (symtab->dump_file, "ODR base violation\n"); print_node (symtab->dump_file, "", val->type, 0); putc ('\n',symtab->dump_file); |