Mercurial > hg > CbC > CbC_gcc
diff gcc/ipa-devirt.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/ipa-devirt.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/ipa-devirt.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,6 +1,6 @@ /* Basic IPA utilities for type inheritance graph construction and devirtualization. - Copyright (C) 2013-2017 Free Software Foundation, Inc. + Copyright (C) 2013-2018 Free Software Foundation, Inc. Contributed by Jan Hubicka This file is part of GCC. @@ -656,7 +656,7 @@ gcc_assert (!TYPE_BINFO (type)); } -/* Compare T2 and T2 based on name or structure. */ +/* Compare T1 and T2 based on name or structure. */ static bool odr_subtypes_equivalent_p (tree t1, tree t2, @@ -678,14 +678,14 @@ return false; /* For ODR types be sure to compare their names. - To support -wno-odr-type-merging we allow one type to be non-ODR + To support -Wno-odr-type-merging we allow one type to be non-ODR and other ODR even though it is a violation. */ if (types_odr_comparable (t1, t2, true)) { if (!types_same_for_odr (t1, t2, true)) return false; /* Limit recursion: If subtypes are ODR types and we know - that they are same, be happy. */ + that they are same, be happy. */ if (!odr_type_p (t1) || !get_odr_type (t1, true)->odr_violated) return true; } @@ -749,6 +749,7 @@ prevailing = vtable; vtable = tmp; } + auto_diagnostic_group d; if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))), OPT_Wodr, @@ -790,22 +791,25 @@ && TREE_CODE (ref1->referred->decl) == FUNCTION_DECL)) && TREE_CODE (ref2->referred->decl) != FUNCTION_DECL) { - if (!class_type->rtti_broken - && warning_at (DECL_SOURCE_LOCATION - (TYPE_NAME (DECL_CONTEXT (vtable->decl))), - OPT_Wodr, - "virtual table of type %qD contains RTTI " - "information", - DECL_CONTEXT (vtable->decl))) + if (!class_type->rtti_broken) { - inform (DECL_SOURCE_LOCATION - (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), - "but is prevailed by one without from other translation " - "unit"); - inform (DECL_SOURCE_LOCATION - (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), - "RTTI will not work on this type"); - class_type->rtti_broken = true; + auto_diagnostic_group d; + if (warning_at (DECL_SOURCE_LOCATION + (TYPE_NAME (DECL_CONTEXT (vtable->decl))), + OPT_Wodr, + "virtual table of type %qD contains RTTI " + "information", + DECL_CONTEXT (vtable->decl))) + { + inform (DECL_SOURCE_LOCATION + (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), + "but is prevailed by one without from other" + " translation unit"); + inform (DECL_SOURCE_LOCATION + (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), + "RTTI will not work on this type"); + class_type->rtti_broken = true; + } } n2++; end2 = !vtable->iterate_reference (n2, ref2); @@ -831,6 +835,7 @@ if (DECL_SIZE (prevailing->decl) != DECL_SIZE (vtable->decl)) { class_type->odr_violated = true; + auto_diagnostic_group d; if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))), OPT_Wodr, @@ -859,6 +864,7 @@ if (TREE_CODE (ref1->referred->decl) != FUNCTION_DECL && TREE_CODE (ref2->referred->decl) != FUNCTION_DECL) { + auto_diagnostic_group d; if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))), OPT_Wodr, @@ -900,6 +906,7 @@ vtable = tmp; ref1 = ref2; } + auto_diagnostic_group d; if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))), OPT_Wodr, @@ -931,6 +938,7 @@ /* And in the last case we have either mistmatch in between two virtual methods or two virtual table pointers. */ + auto_diagnostic_group d; if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (vtable->decl))), OPT_Wodr, "virtual table of type %qD violates " @@ -986,6 +994,7 @@ if (lto_location_cache::current_cache) lto_location_cache::current_cache->apply_location_cache (); + auto_diagnostic_group d; if (!warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (t1)), OPT_Wodr, "type %qT violates the C++ One Definition Rule", t1)) @@ -1580,8 +1589,15 @@ "in another translation unit")); return false; } - gcc_assert (DECL_NONADDRESSABLE_P (f1) - == DECL_NONADDRESSABLE_P (f2)); + if (DECL_BIT_FIELD (f1) != DECL_BIT_FIELD (f2)) + { + warn_odr (t1, t2, f1, f2, warn, warned, + G_("one field is bitfield while other is not")); + return false; + } + else + gcc_assert (DECL_NONADDRESSABLE_P (f1) + == DECL_NONADDRESSABLE_P (f2)); } /* If one aggregate has more fields than the other, they @@ -1844,7 +1860,12 @@ } } - /* Next compare memory layout. */ + /* Next compare memory layout. + The DECL_SOURCE_LOCATIONs in this invocation came from LTO streaming. + We must apply the location cache to ensure that they are valid + before we can pass them to odr_types_equivalent_p (PR lto/83121). */ + if (lto_location_cache::current_cache) + lto_location_cache::current_cache->apply_location_cache (); if (!odr_types_equivalent_p (val->type, type, !flag_ltrans && !val->odr_violated && !warned, &warned, &visited, @@ -2690,6 +2711,24 @@ } } +/* Force rebuilding type inheritance graph from scratch. + This is use to make sure that we do not keep references to types + which was not visible to free_lang_data. */ + +void +rebuild_type_inheritance_graph () +{ + if (!odr_hash) + return; + delete odr_hash; + if (in_lto_p) + delete odr_vtable_hash; + odr_hash = NULL; + odr_vtable_hash = NULL; + odr_types_ptr = NULL; + free_polymorphic_call_targets_hash (); +} + /* When virtual function is removed, we may need to flush the cache. */ static void @@ -2901,10 +2940,27 @@ struct final_warning_record { + /* If needed grow type_warnings vector and initialize new decl_warn_count + to have dyn_count set to profile_count::zero (). */ + void grow_type_warnings (unsigned newlen); + profile_count dyn_count; auto_vec<odr_type_warn_count> type_warnings; hash_map<tree, decl_warn_count> decl_warnings; }; + +void +final_warning_record::grow_type_warnings (unsigned newlen) +{ + unsigned len = type_warnings.length (); + if (newlen > len) + { + type_warnings.safe_grow_cleared (newlen); + for (unsigned i = len; i < newlen; i++) + type_warnings[i].dyn_count = profile_count::zero (); + } +} + struct final_warning_record *final_warning_records; /* Return vector containing possible targets of polymorphic call of type @@ -3176,9 +3232,8 @@ && warn_suggest_final_types && !outer_type->derived_types.length ()) { - if (outer_type->id >= (int)final_warning_records->type_warnings.length ()) - final_warning_records->type_warnings.safe_grow_cleared - (odr_types.length ()); + final_warning_records->grow_type_warnings + (outer_type->id); final_warning_records->type_warnings[outer_type->id].count++; if (!final_warning_records->type_warnings [outer_type->id].dyn_count.initialized_p ()) @@ -3545,8 +3600,7 @@ { final_warning_records = new (final_warning_record); final_warning_records->dyn_count = profile_count::zero (); - final_warning_records->type_warnings.safe_grow_cleared - (odr_types.length ()); + final_warning_records->grow_type_warnings (odr_types.length ()); free_polymorphic_call_targets_hash (); } @@ -3566,7 +3620,7 @@ bool final; if (final_warning_records) - final_warning_records->dyn_count = e->count; + final_warning_records->dyn_count = e->count.ipa (); vec <cgraph_node *>targets = possible_polymorphic_call_targets @@ -3710,8 +3764,7 @@ { if (dump_enabled_p ()) { - location_t locus = gimple_location_safe (e->call_stmt); - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus, + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt, "speculatively devirtualizing call " "in %s to %s\n", n->dump_name (), @@ -3727,8 +3780,7 @@ nconverted++; update = true; e->make_speculative - (likely_target, e->count.apply_scale (8, 10), - e->frequency * 8 / 10); + (likely_target, e->count.apply_scale (8, 10)); } } if (update)