11debfc3dSmrg /* Basic IPA utilities for type inheritance graph construction and 21debfc3dSmrg devirtualization. 3*8feb0f0bSmrg Copyright (C) 2013-2020 Free Software Foundation, Inc. 41debfc3dSmrg Contributed by Jan Hubicka 51debfc3dSmrg 61debfc3dSmrg This file is part of GCC. 71debfc3dSmrg 81debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under 91debfc3dSmrg the terms of the GNU General Public License as published by the Free 101debfc3dSmrg Software Foundation; either version 3, or (at your option) any later 111debfc3dSmrg version. 121debfc3dSmrg 131debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 141debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 151debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 161debfc3dSmrg for more details. 171debfc3dSmrg 181debfc3dSmrg You should have received a copy of the GNU General Public License 191debfc3dSmrg along with GCC; see the file COPYING3. If not see 201debfc3dSmrg <http://www.gnu.org/licenses/>. */ 211debfc3dSmrg 221debfc3dSmrg /* Brief vocabulary: 231debfc3dSmrg ODR = One Definition Rule 241debfc3dSmrg In short, the ODR states that: 251debfc3dSmrg 1 In any translation unit, a template, type, function, or object can 261debfc3dSmrg have no more than one definition. Some of these can have any number 271debfc3dSmrg of declarations. A definition provides an instance. 281debfc3dSmrg 2 In the entire program, an object or non-inline function cannot have 291debfc3dSmrg more than one definition; if an object or function is used, it must 301debfc3dSmrg have exactly one definition. You can declare an object or function 311debfc3dSmrg that is never used, in which case you don't have to provide 321debfc3dSmrg a definition. In no event can there be more than one definition. 331debfc3dSmrg 3 Some things, like types, templates, and extern inline functions, can 341debfc3dSmrg be defined in more than one translation unit. For a given entity, 351debfc3dSmrg each definition must be the same. Non-extern objects and functions 361debfc3dSmrg in different translation units are different entities, even if their 371debfc3dSmrg names and types are the same. 381debfc3dSmrg 391debfc3dSmrg OTR = OBJ_TYPE_REF 401debfc3dSmrg This is the Gimple representation of type information of a polymorphic call. 411debfc3dSmrg It contains two parameters: 421debfc3dSmrg otr_type is a type of class whose method is called. 431debfc3dSmrg otr_token is the index into virtual table where address is taken. 441debfc3dSmrg 451debfc3dSmrg BINFO 461debfc3dSmrg This is the type inheritance information attached to each tree 471debfc3dSmrg RECORD_TYPE by the C++ frontend. It provides information about base 481debfc3dSmrg types and virtual tables. 491debfc3dSmrg 501debfc3dSmrg BINFO is linked to the RECORD_TYPE by TYPE_BINFO. 511debfc3dSmrg BINFO also links to its type by BINFO_TYPE and to the virtual table by 521debfc3dSmrg BINFO_VTABLE. 531debfc3dSmrg 541debfc3dSmrg Base types of a given type are enumerated by BINFO_BASE_BINFO 551debfc3dSmrg vector. Members of this vectors are not BINFOs associated 561debfc3dSmrg with a base type. Rather they are new copies of BINFOs 571debfc3dSmrg (base BINFOs). Their virtual tables may differ from 581debfc3dSmrg virtual table of the base type. Also BINFO_OFFSET specifies 591debfc3dSmrg offset of the base within the type. 601debfc3dSmrg 611debfc3dSmrg In the case of single inheritance, the virtual table is shared 621debfc3dSmrg and BINFO_VTABLE of base BINFO is NULL. In the case of multiple 631debfc3dSmrg inheritance the individual virtual tables are pointer to by 641debfc3dSmrg BINFO_VTABLE of base binfos (that differs of BINFO_VTABLE of 651debfc3dSmrg binfo associated to the base type). 661debfc3dSmrg 671debfc3dSmrg BINFO lookup for a given base type and offset can be done by 681debfc3dSmrg get_binfo_at_offset. It returns proper BINFO whose virtual table 691debfc3dSmrg can be used for lookup of virtual methods associated with the 701debfc3dSmrg base type. 711debfc3dSmrg 721debfc3dSmrg token 731debfc3dSmrg This is an index of virtual method in virtual table associated 741debfc3dSmrg to the type defining it. Token can be looked up from OBJ_TYPE_REF 751debfc3dSmrg or from DECL_VINDEX of a given virtual table. 761debfc3dSmrg 771debfc3dSmrg polymorphic (indirect) call 781debfc3dSmrg This is callgraph representation of virtual method call. Every 791debfc3dSmrg polymorphic call contains otr_type and otr_token taken from 801debfc3dSmrg original OBJ_TYPE_REF at callgraph construction time. 811debfc3dSmrg 821debfc3dSmrg What we do here: 831debfc3dSmrg 841debfc3dSmrg build_type_inheritance_graph triggers a construction of the type inheritance 851debfc3dSmrg graph. 861debfc3dSmrg 871debfc3dSmrg We reconstruct it based on types of methods we see in the unit. 881debfc3dSmrg This means that the graph is not complete. Types with no methods are not 891debfc3dSmrg inserted into the graph. Also types without virtual methods are not 901debfc3dSmrg represented at all, though it may be easy to add this. 911debfc3dSmrg 921debfc3dSmrg The inheritance graph is represented as follows: 931debfc3dSmrg 941debfc3dSmrg Vertices are structures odr_type. Every odr_type may correspond 951debfc3dSmrg to one or more tree type nodes that are equivalent by ODR rule. 961debfc3dSmrg (the multiple type nodes appear only with linktime optimization) 971debfc3dSmrg 981debfc3dSmrg Edges are represented by odr_type->base and odr_type->derived_types. 991debfc3dSmrg At the moment we do not track offsets of types for multiple inheritance. 1001debfc3dSmrg Adding this is easy. 1011debfc3dSmrg 1021debfc3dSmrg possible_polymorphic_call_targets returns, given an parameters found in 1031debfc3dSmrg indirect polymorphic edge all possible polymorphic call targets of the call. 1041debfc3dSmrg 1051debfc3dSmrg pass_ipa_devirt performs simple speculative devirtualization. 1061debfc3dSmrg */ 1071debfc3dSmrg 1081debfc3dSmrg #include "config.h" 1091debfc3dSmrg #include "system.h" 1101debfc3dSmrg #include "coretypes.h" 1111debfc3dSmrg #include "backend.h" 1121debfc3dSmrg #include "rtl.h" 1131debfc3dSmrg #include "tree.h" 1141debfc3dSmrg #include "gimple.h" 1151debfc3dSmrg #include "alloc-pool.h" 1161debfc3dSmrg #include "tree-pass.h" 1171debfc3dSmrg #include "cgraph.h" 1181debfc3dSmrg #include "lto-streamer.h" 1191debfc3dSmrg #include "fold-const.h" 1201debfc3dSmrg #include "print-tree.h" 1211debfc3dSmrg #include "calls.h" 1221debfc3dSmrg #include "ipa-utils.h" 1231debfc3dSmrg #include "gimple-fold.h" 1241debfc3dSmrg #include "symbol-summary.h" 1251debfc3dSmrg #include "tree-vrp.h" 1261debfc3dSmrg #include "ipa-prop.h" 127a2dc1f3fSmrg #include "ipa-fnsummary.h" 1281debfc3dSmrg #include "demangle.h" 1291debfc3dSmrg #include "dbgcnt.h" 1301debfc3dSmrg #include "gimple-pretty-print.h" 1311debfc3dSmrg #include "intl.h" 132a2dc1f3fSmrg #include "stringpool.h" 133a2dc1f3fSmrg #include "attribs.h" 134*8feb0f0bSmrg #include "data-streamer.h" 135*8feb0f0bSmrg #include "lto-streamer.h" 136*8feb0f0bSmrg #include "streamer-hooks.h" 1371debfc3dSmrg 1381debfc3dSmrg /* Hash based set of pairs of types. */ 1391debfc3dSmrg struct type_pair 1401debfc3dSmrg { 1411debfc3dSmrg tree first; 1421debfc3dSmrg tree second; 1431debfc3dSmrg }; 1441debfc3dSmrg 1451debfc3dSmrg template <> 146a2dc1f3fSmrg struct default_hash_traits <type_pair> 147a2dc1f3fSmrg : typed_noop_remove <type_pair> 1481debfc3dSmrg { 149a2dc1f3fSmrg GTY((skip)) typedef type_pair value_type; 150a2dc1f3fSmrg GTY((skip)) typedef type_pair compare_type; 1511debfc3dSmrg static hashval_t 1521debfc3dSmrg hash (type_pair p) 1531debfc3dSmrg { 1541debfc3dSmrg return TYPE_UID (p.first) ^ TYPE_UID (p.second); 1551debfc3dSmrg } 156*8feb0f0bSmrg static const bool empty_zero_p = true; 1571debfc3dSmrg static bool 1581debfc3dSmrg is_empty (type_pair p) 1591debfc3dSmrg { 1601debfc3dSmrg return p.first == NULL; 1611debfc3dSmrg } 1621debfc3dSmrg static bool 1631debfc3dSmrg is_deleted (type_pair p ATTRIBUTE_UNUSED) 1641debfc3dSmrg { 1651debfc3dSmrg return false; 1661debfc3dSmrg } 1671debfc3dSmrg static bool 1681debfc3dSmrg equal (const type_pair &a, const type_pair &b) 1691debfc3dSmrg { 1701debfc3dSmrg return a.first==b.first && a.second == b.second; 1711debfc3dSmrg } 1721debfc3dSmrg static void 1731debfc3dSmrg mark_empty (type_pair &e) 1741debfc3dSmrg { 1751debfc3dSmrg e.first = NULL; 1761debfc3dSmrg } 1771debfc3dSmrg }; 1781debfc3dSmrg 179*8feb0f0bSmrg /* HACK alert: this is used to communicate with ipa-inline-transform that 180*8feb0f0bSmrg thunk is being expanded and there is no need to clear the polymorphic 181*8feb0f0bSmrg call target cache. */ 182*8feb0f0bSmrg bool thunk_expansion; 183*8feb0f0bSmrg 1841debfc3dSmrg static bool odr_types_equivalent_p (tree, tree, bool, bool *, 1851debfc3dSmrg hash_set<type_pair> *, 1861debfc3dSmrg location_t, location_t); 187c0a68be4Smrg static void warn_odr (tree t1, tree t2, tree st1, tree st2, 188c0a68be4Smrg bool warn, bool *warned, const char *reason); 1891debfc3dSmrg 1901debfc3dSmrg static bool odr_violation_reported = false; 1911debfc3dSmrg 1921debfc3dSmrg 1931debfc3dSmrg /* Pointer set of all call targets appearing in the cache. */ 1941debfc3dSmrg static hash_set<cgraph_node *> *cached_polymorphic_call_targets; 1951debfc3dSmrg 1961debfc3dSmrg /* The node of type inheritance graph. For each type unique in 1971debfc3dSmrg One Definition Rule (ODR) sense, we produce one node linking all 1981debfc3dSmrg main variants of types equivalent to it, bases and derived types. */ 1991debfc3dSmrg 2001debfc3dSmrg struct GTY(()) odr_type_d 2011debfc3dSmrg { 2021debfc3dSmrg /* leader type. */ 2031debfc3dSmrg tree type; 2041debfc3dSmrg /* All bases; built only for main variants of types. */ 2051debfc3dSmrg vec<odr_type> GTY((skip)) bases; 2061debfc3dSmrg /* All derived types with virtual methods seen in unit; 2071debfc3dSmrg built only for main variants of types. */ 2081debfc3dSmrg vec<odr_type> GTY((skip)) derived_types; 2091debfc3dSmrg 2101debfc3dSmrg /* All equivalent types, if more than one. */ 2111debfc3dSmrg vec<tree, va_gc> *types; 2121debfc3dSmrg /* Set of all equivalent types, if NON-NULL. */ 2131debfc3dSmrg hash_set<tree> * GTY((skip)) types_set; 2141debfc3dSmrg 2151debfc3dSmrg /* Unique ID indexing the type in odr_types array. */ 2161debfc3dSmrg int id; 2171debfc3dSmrg /* Is it in anonymous namespace? */ 2181debfc3dSmrg bool anonymous_namespace; 2191debfc3dSmrg /* Do we know about all derivations of given type? */ 2201debfc3dSmrg bool all_derivations_known; 2211debfc3dSmrg /* Did we report ODR violation here? */ 2221debfc3dSmrg bool odr_violated; 223*8feb0f0bSmrg /* Set when virtual table without RTTI prevailed table with. */ 2241debfc3dSmrg bool rtti_broken; 225*8feb0f0bSmrg /* Set when the canonical type is determined using the type name. */ 226*8feb0f0bSmrg bool tbaa_enabled; 2271debfc3dSmrg }; 2281debfc3dSmrg 2291debfc3dSmrg /* Return TRUE if all derived types of T are known and thus 2301debfc3dSmrg we may consider the walk of derived type complete. 2311debfc3dSmrg 2321debfc3dSmrg This is typically true only for final anonymous namespace types and types 2331debfc3dSmrg defined within functions (that may be COMDAT and thus shared across units, 2341debfc3dSmrg but with the same set of derived types). */ 2351debfc3dSmrg 2361debfc3dSmrg bool 2371debfc3dSmrg type_all_derivations_known_p (const_tree t) 2381debfc3dSmrg { 2391debfc3dSmrg if (TYPE_FINAL_P (t)) 2401debfc3dSmrg return true; 2411debfc3dSmrg if (flag_ltrans) 2421debfc3dSmrg return false; 2431debfc3dSmrg /* Non-C++ types may have IDENTIFIER_NODE here, do not crash. */ 2441debfc3dSmrg if (!TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL) 2451debfc3dSmrg return true; 2461debfc3dSmrg if (type_in_anonymous_namespace_p (t)) 2471debfc3dSmrg return true; 2481debfc3dSmrg return (decl_function_context (TYPE_NAME (t)) != NULL); 2491debfc3dSmrg } 2501debfc3dSmrg 2511debfc3dSmrg /* Return TRUE if type's constructors are all visible. */ 2521debfc3dSmrg 2531debfc3dSmrg static bool 2541debfc3dSmrg type_all_ctors_visible_p (tree t) 2551debfc3dSmrg { 2561debfc3dSmrg return !flag_ltrans 2571debfc3dSmrg && symtab->state >= CONSTRUCTION 2581debfc3dSmrg /* We cannot always use type_all_derivations_known_p. 2591debfc3dSmrg For function local types we must assume case where 2601debfc3dSmrg the function is COMDAT and shared in between units. 2611debfc3dSmrg 2621debfc3dSmrg TODO: These cases are quite easy to get, but we need 2631debfc3dSmrg to keep track of C++ privatizing via -Wno-weak 2641debfc3dSmrg as well as the IPA privatizing. */ 2651debfc3dSmrg && type_in_anonymous_namespace_p (t); 2661debfc3dSmrg } 2671debfc3dSmrg 2681debfc3dSmrg /* Return TRUE if type may have instance. */ 2691debfc3dSmrg 2701debfc3dSmrg static bool 2711debfc3dSmrg type_possibly_instantiated_p (tree t) 2721debfc3dSmrg { 2731debfc3dSmrg tree vtable; 2741debfc3dSmrg varpool_node *vnode; 2751debfc3dSmrg 2761debfc3dSmrg /* TODO: Add abstract types here. */ 2771debfc3dSmrg if (!type_all_ctors_visible_p (t)) 2781debfc3dSmrg return true; 2791debfc3dSmrg 2801debfc3dSmrg vtable = BINFO_VTABLE (TYPE_BINFO (t)); 2811debfc3dSmrg if (TREE_CODE (vtable) == POINTER_PLUS_EXPR) 2821debfc3dSmrg vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0); 2831debfc3dSmrg vnode = varpool_node::get (vtable); 2841debfc3dSmrg return vnode && vnode->definition; 2851debfc3dSmrg } 2861debfc3dSmrg 2871debfc3dSmrg /* Hash used to unify ODR types based on their mangled name and for anonymous 2881debfc3dSmrg namespace types. */ 2891debfc3dSmrg 2901debfc3dSmrg struct odr_name_hasher : pointer_hash <odr_type_d> 2911debfc3dSmrg { 2921debfc3dSmrg typedef union tree_node *compare_type; 2931debfc3dSmrg static inline hashval_t hash (const odr_type_d *); 2941debfc3dSmrg static inline bool equal (const odr_type_d *, const tree_node *); 2951debfc3dSmrg static inline void remove (odr_type_d *); 2961debfc3dSmrg }; 2971debfc3dSmrg 2981debfc3dSmrg static bool 2991debfc3dSmrg can_be_name_hashed_p (tree t) 3001debfc3dSmrg { 3011debfc3dSmrg return (!in_lto_p || odr_type_p (t)); 3021debfc3dSmrg } 3031debfc3dSmrg 3041debfc3dSmrg /* Hash type by its ODR name. */ 3051debfc3dSmrg 3061debfc3dSmrg static hashval_t 3071debfc3dSmrg hash_odr_name (const_tree t) 3081debfc3dSmrg { 309c0a68be4Smrg gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t); 3101debfc3dSmrg 3111debfc3dSmrg /* If not in LTO, all main variants are unique, so we can do 3121debfc3dSmrg pointer hash. */ 3131debfc3dSmrg if (!in_lto_p) 3141debfc3dSmrg return htab_hash_pointer (t); 3151debfc3dSmrg 3161debfc3dSmrg /* Anonymous types are unique. */ 3171debfc3dSmrg if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t)) 3181debfc3dSmrg return htab_hash_pointer (t); 3191debfc3dSmrg 3201debfc3dSmrg gcc_checking_assert (TYPE_NAME (t) 3211debfc3dSmrg && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))); 3221debfc3dSmrg return IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (TYPE_NAME (t))); 3231debfc3dSmrg } 3241debfc3dSmrg 3251debfc3dSmrg /* Return the computed hashcode for ODR_TYPE. */ 3261debfc3dSmrg 3271debfc3dSmrg inline hashval_t 3281debfc3dSmrg odr_name_hasher::hash (const odr_type_d *odr_type) 3291debfc3dSmrg { 3301debfc3dSmrg return hash_odr_name (odr_type->type); 3311debfc3dSmrg } 3321debfc3dSmrg 3331debfc3dSmrg /* For languages with One Definition Rule, work out if 3341debfc3dSmrg types are the same based on their name. 3351debfc3dSmrg 3361debfc3dSmrg This is non-trivial for LTO where minor differences in 3371debfc3dSmrg the type representation may have prevented type merging 3381debfc3dSmrg to merge two copies of otherwise equivalent type. 3391debfc3dSmrg 3401debfc3dSmrg Until we start streaming mangled type names, this function works 3411debfc3dSmrg only for polymorphic types. 3421debfc3dSmrg */ 3431debfc3dSmrg 3441debfc3dSmrg bool 345c0a68be4Smrg types_same_for_odr (const_tree type1, const_tree type2) 3461debfc3dSmrg { 3471debfc3dSmrg gcc_checking_assert (TYPE_P (type1) && TYPE_P (type2)); 3481debfc3dSmrg 3491debfc3dSmrg type1 = TYPE_MAIN_VARIANT (type1); 3501debfc3dSmrg type2 = TYPE_MAIN_VARIANT (type2); 3511debfc3dSmrg 3521debfc3dSmrg if (type1 == type2) 3531debfc3dSmrg return true; 3541debfc3dSmrg 3551debfc3dSmrg if (!in_lto_p) 3561debfc3dSmrg return false; 3571debfc3dSmrg 358c0a68be4Smrg /* Anonymous namespace types are never duplicated. */ 3591debfc3dSmrg if ((type_with_linkage_p (type1) && type_in_anonymous_namespace_p (type1)) 3601debfc3dSmrg || (type_with_linkage_p (type2) && type_in_anonymous_namespace_p (type2))) 3611debfc3dSmrg return false; 3621debfc3dSmrg 363*8feb0f0bSmrg /* If both type has mangled defined check if they are same. 364*8feb0f0bSmrg Watch for anonymous types which are all mangled as "<anon">. */ 365*8feb0f0bSmrg if (!type_with_linkage_p (type1) || !type_with_linkage_p (type2)) 3661debfc3dSmrg return false; 367*8feb0f0bSmrg if (type_in_anonymous_namespace_p (type1) 368*8feb0f0bSmrg || type_in_anonymous_namespace_p (type2)) 3691debfc3dSmrg return false; 3701debfc3dSmrg return (DECL_ASSEMBLER_NAME (TYPE_NAME (type1)) 3711debfc3dSmrg == DECL_ASSEMBLER_NAME (TYPE_NAME (type2))); 3721debfc3dSmrg } 3731debfc3dSmrg 3741debfc3dSmrg /* Return true if we can decide on ODR equivalency. 3751debfc3dSmrg 3761debfc3dSmrg In non-LTO it is always decide, in LTO however it depends in the type has 377c0a68be4Smrg ODR info attached. */ 3781debfc3dSmrg 3791debfc3dSmrg bool 380c0a68be4Smrg types_odr_comparable (tree t1, tree t2) 3811debfc3dSmrg { 3821debfc3dSmrg return (!in_lto_p 383c0a68be4Smrg || TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2) 384c0a68be4Smrg || (odr_type_p (TYPE_MAIN_VARIANT (t1)) 385*8feb0f0bSmrg && odr_type_p (TYPE_MAIN_VARIANT (t2)))); 3861debfc3dSmrg } 3871debfc3dSmrg 3881debfc3dSmrg /* Return true if T1 and T2 are ODR equivalent. If ODR equivalency is not 3891debfc3dSmrg known, be conservative and return false. */ 3901debfc3dSmrg 3911debfc3dSmrg bool 3921debfc3dSmrg types_must_be_same_for_odr (tree t1, tree t2) 3931debfc3dSmrg { 3941debfc3dSmrg if (types_odr_comparable (t1, t2)) 3951debfc3dSmrg return types_same_for_odr (t1, t2); 3961debfc3dSmrg else 3971debfc3dSmrg return TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2); 3981debfc3dSmrg } 3991debfc3dSmrg 4001debfc3dSmrg /* If T is compound type, return type it is based on. */ 4011debfc3dSmrg 4021debfc3dSmrg static tree 4031debfc3dSmrg compound_type_base (const_tree t) 4041debfc3dSmrg { 4051debfc3dSmrg if (TREE_CODE (t) == ARRAY_TYPE 4061debfc3dSmrg || POINTER_TYPE_P (t) 4071debfc3dSmrg || TREE_CODE (t) == COMPLEX_TYPE 4081debfc3dSmrg || VECTOR_TYPE_P (t)) 4091debfc3dSmrg return TREE_TYPE (t); 4101debfc3dSmrg if (TREE_CODE (t) == METHOD_TYPE) 4111debfc3dSmrg return TYPE_METHOD_BASETYPE (t); 4121debfc3dSmrg if (TREE_CODE (t) == OFFSET_TYPE) 4131debfc3dSmrg return TYPE_OFFSET_BASETYPE (t); 4141debfc3dSmrg return NULL_TREE; 4151debfc3dSmrg } 4161debfc3dSmrg 4171debfc3dSmrg /* Return true if T is either ODR type or compound type based from it. 4181debfc3dSmrg If the function return true, we know that T is a type originating from C++ 4191debfc3dSmrg source even at link-time. */ 4201debfc3dSmrg 4211debfc3dSmrg bool 4221debfc3dSmrg odr_or_derived_type_p (const_tree t) 4231debfc3dSmrg { 4241debfc3dSmrg do 4251debfc3dSmrg { 426c0a68be4Smrg if (odr_type_p (TYPE_MAIN_VARIANT (t))) 4271debfc3dSmrg return true; 4281debfc3dSmrg /* Function type is a tricky one. Basically we can consider it 4291debfc3dSmrg ODR derived if return type or any of the parameters is. 4301debfc3dSmrg We need to check all parameters because LTO streaming merges 4311debfc3dSmrg common types (such as void) and they are not considered ODR then. */ 4321debfc3dSmrg if (TREE_CODE (t) == FUNCTION_TYPE) 4331debfc3dSmrg { 4341debfc3dSmrg if (TYPE_METHOD_BASETYPE (t)) 4351debfc3dSmrg t = TYPE_METHOD_BASETYPE (t); 4361debfc3dSmrg else 4371debfc3dSmrg { 4381debfc3dSmrg if (TREE_TYPE (t) && odr_or_derived_type_p (TREE_TYPE (t))) 4391debfc3dSmrg return true; 4401debfc3dSmrg for (t = TYPE_ARG_TYPES (t); t; t = TREE_CHAIN (t)) 441c0a68be4Smrg if (odr_or_derived_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (t)))) 4421debfc3dSmrg return true; 4431debfc3dSmrg return false; 4441debfc3dSmrg } 4451debfc3dSmrg } 4461debfc3dSmrg else 4471debfc3dSmrg t = compound_type_base (t); 4481debfc3dSmrg } 4491debfc3dSmrg while (t); 4501debfc3dSmrg return t; 4511debfc3dSmrg } 4521debfc3dSmrg 4531debfc3dSmrg /* Compare types T1 and T2 and return true if they are 4541debfc3dSmrg equivalent. */ 4551debfc3dSmrg 4561debfc3dSmrg inline bool 4571debfc3dSmrg odr_name_hasher::equal (const odr_type_d *o1, const tree_node *t2) 4581debfc3dSmrg { 4591debfc3dSmrg tree t1 = o1->type; 4601debfc3dSmrg 461c0a68be4Smrg gcc_checking_assert (TYPE_MAIN_VARIANT (t2) == t2); 462c0a68be4Smrg gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == t1); 4631debfc3dSmrg if (t1 == t2) 4641debfc3dSmrg return true; 4651debfc3dSmrg if (!in_lto_p) 4661debfc3dSmrg return false; 467c0a68be4Smrg /* Check for anonymous namespaces. */ 4681debfc3dSmrg if ((type_with_linkage_p (t1) && type_in_anonymous_namespace_p (t1)) 4691debfc3dSmrg || (type_with_linkage_p (t2) && type_in_anonymous_namespace_p (t2))) 4701debfc3dSmrg return false; 4711debfc3dSmrg gcc_checking_assert (DECL_ASSEMBLER_NAME (TYPE_NAME (t1))); 4721debfc3dSmrg gcc_checking_assert (DECL_ASSEMBLER_NAME (TYPE_NAME (t2))); 4731debfc3dSmrg return (DECL_ASSEMBLER_NAME (TYPE_NAME (t1)) 4741debfc3dSmrg == DECL_ASSEMBLER_NAME (TYPE_NAME (t2))); 4751debfc3dSmrg } 4761debfc3dSmrg 4771debfc3dSmrg /* Free ODR type V. */ 4781debfc3dSmrg 4791debfc3dSmrg inline void 4801debfc3dSmrg odr_name_hasher::remove (odr_type_d *v) 4811debfc3dSmrg { 4821debfc3dSmrg v->bases.release (); 4831debfc3dSmrg v->derived_types.release (); 4841debfc3dSmrg if (v->types_set) 4851debfc3dSmrg delete v->types_set; 4861debfc3dSmrg ggc_free (v); 4871debfc3dSmrg } 4881debfc3dSmrg 4891debfc3dSmrg /* ODR type hash used to look up ODR type based on tree type node. */ 4901debfc3dSmrg 4911debfc3dSmrg typedef hash_table<odr_name_hasher> odr_hash_type; 4921debfc3dSmrg static odr_hash_type *odr_hash; 4931debfc3dSmrg 4941debfc3dSmrg /* ODR types are also stored into ODR_TYPE vector to allow consistent 4951debfc3dSmrg walking. Bases appear before derived types. Vector is garbage collected 4961debfc3dSmrg so we won't end up visiting empty types. */ 4971debfc3dSmrg 4981debfc3dSmrg static GTY(()) vec <odr_type, va_gc> *odr_types_ptr; 4991debfc3dSmrg #define odr_types (*odr_types_ptr) 5001debfc3dSmrg 501*8feb0f0bSmrg /* All enums defined and accessible for the unit. */ 502*8feb0f0bSmrg static GTY(()) vec <tree, va_gc> *odr_enums; 503*8feb0f0bSmrg 504*8feb0f0bSmrg /* Information we hold about value defined by an enum type. */ 505*8feb0f0bSmrg struct odr_enum_val 506*8feb0f0bSmrg { 507*8feb0f0bSmrg const char *name; 508*8feb0f0bSmrg wide_int val; 509*8feb0f0bSmrg location_t locus; 510*8feb0f0bSmrg }; 511*8feb0f0bSmrg 512*8feb0f0bSmrg /* Information about enum values. */ 513*8feb0f0bSmrg struct odr_enum 514*8feb0f0bSmrg { 515*8feb0f0bSmrg location_t locus; 516*8feb0f0bSmrg auto_vec<odr_enum_val, 0> vals; 517*8feb0f0bSmrg bool warned; 518*8feb0f0bSmrg }; 519*8feb0f0bSmrg 520*8feb0f0bSmrg /* A table of all ODR enum definitions. */ 521*8feb0f0bSmrg static hash_map <nofree_string_hash, odr_enum> *odr_enum_map = NULL; 522*8feb0f0bSmrg static struct obstack odr_enum_obstack; 523*8feb0f0bSmrg 5241debfc3dSmrg /* Set TYPE_BINFO of TYPE and its variants to BINFO. */ 5251debfc3dSmrg void 5261debfc3dSmrg set_type_binfo (tree type, tree binfo) 5271debfc3dSmrg { 5281debfc3dSmrg for (; type; type = TYPE_NEXT_VARIANT (type)) 5291debfc3dSmrg if (COMPLETE_TYPE_P (type)) 5301debfc3dSmrg TYPE_BINFO (type) = binfo; 5311debfc3dSmrg else 5321debfc3dSmrg gcc_assert (!TYPE_BINFO (type)); 5331debfc3dSmrg } 5341debfc3dSmrg 535c0a68be4Smrg /* Return true if type variants match. 536c0a68be4Smrg This assumes that we already verified that T1 and T2 are variants of the 537c0a68be4Smrg same type. */ 538c0a68be4Smrg 539c0a68be4Smrg static bool 540c0a68be4Smrg type_variants_equivalent_p (tree t1, tree t2) 541c0a68be4Smrg { 542c0a68be4Smrg if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) 543c0a68be4Smrg return false; 544c0a68be4Smrg 545c0a68be4Smrg if (comp_type_attributes (t1, t2) != 1) 546c0a68be4Smrg return false; 547c0a68be4Smrg 548c0a68be4Smrg if (COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2) 549c0a68be4Smrg && TYPE_ALIGN (t1) != TYPE_ALIGN (t2)) 550c0a68be4Smrg return false; 551c0a68be4Smrg 552c0a68be4Smrg return true; 553c0a68be4Smrg } 554c0a68be4Smrg 555a2dc1f3fSmrg /* Compare T1 and T2 based on name or structure. */ 5561debfc3dSmrg 5571debfc3dSmrg static bool 5581debfc3dSmrg odr_subtypes_equivalent_p (tree t1, tree t2, 5591debfc3dSmrg hash_set<type_pair> *visited, 5601debfc3dSmrg location_t loc1, location_t loc2) 5611debfc3dSmrg { 5621debfc3dSmrg 5631debfc3dSmrg /* This can happen in incomplete types that should be handled earlier. */ 5641debfc3dSmrg gcc_assert (t1 && t2); 5651debfc3dSmrg 5661debfc3dSmrg if (t1 == t2) 5671debfc3dSmrg return true; 5681debfc3dSmrg 5691debfc3dSmrg /* Anonymous namespace types must match exactly. */ 570c0a68be4Smrg if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1)) 571c0a68be4Smrg && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1))) 572c0a68be4Smrg || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2)) 573c0a68be4Smrg && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2)))) 5741debfc3dSmrg return false; 5751debfc3dSmrg 5761debfc3dSmrg /* For ODR types be sure to compare their names. 577a2dc1f3fSmrg To support -Wno-odr-type-merging we allow one type to be non-ODR 5781debfc3dSmrg and other ODR even though it is a violation. */ 579c0a68be4Smrg if (types_odr_comparable (t1, t2)) 5801debfc3dSmrg { 581c0a68be4Smrg if (t1 != t2 582c0a68be4Smrg && odr_type_p (TYPE_MAIN_VARIANT (t1)) 583c0a68be4Smrg && get_odr_type (TYPE_MAIN_VARIANT (t1), true)->odr_violated) 584c0a68be4Smrg return false; 585c0a68be4Smrg if (!types_same_for_odr (t1, t2)) 586c0a68be4Smrg return false; 587c0a68be4Smrg if (!type_variants_equivalent_p (t1, t2)) 5881debfc3dSmrg return false; 5891debfc3dSmrg /* Limit recursion: If subtypes are ODR types and we know 5901debfc3dSmrg that they are same, be happy. */ 591c0a68be4Smrg if (odr_type_p (TYPE_MAIN_VARIANT (t1))) 5921debfc3dSmrg return true; 5931debfc3dSmrg } 5941debfc3dSmrg 5951debfc3dSmrg /* Component types, builtins and possibly violating ODR types 5961debfc3dSmrg have to be compared structurally. */ 5971debfc3dSmrg if (TREE_CODE (t1) != TREE_CODE (t2)) 5981debfc3dSmrg return false; 5991debfc3dSmrg if (AGGREGATE_TYPE_P (t1) 6001debfc3dSmrg && (TYPE_NAME (t1) == NULL_TREE) != (TYPE_NAME (t2) == NULL_TREE)) 6011debfc3dSmrg return false; 6021debfc3dSmrg 603c0a68be4Smrg type_pair pair={TYPE_MAIN_VARIANT (t1), TYPE_MAIN_VARIANT (t2)}; 604c0a68be4Smrg if (TYPE_UID (TYPE_MAIN_VARIANT (t1)) > TYPE_UID (TYPE_MAIN_VARIANT (t2))) 6051debfc3dSmrg { 606c0a68be4Smrg pair.first = TYPE_MAIN_VARIANT (t2); 607c0a68be4Smrg pair.second = TYPE_MAIN_VARIANT (t1); 6081debfc3dSmrg } 6091debfc3dSmrg if (visited->add (pair)) 6101debfc3dSmrg return true; 611c0a68be4Smrg if (!odr_types_equivalent_p (TYPE_MAIN_VARIANT (t1), TYPE_MAIN_VARIANT (t2), 612c0a68be4Smrg false, NULL, visited, loc1, loc2)) 613c0a68be4Smrg return false; 614c0a68be4Smrg if (!type_variants_equivalent_p (t1, t2)) 615c0a68be4Smrg return false; 616c0a68be4Smrg return true; 6171debfc3dSmrg } 6181debfc3dSmrg 6191debfc3dSmrg /* Return true if DECL1 and DECL2 are identical methods. Consider 6201debfc3dSmrg name equivalent to name.localalias.xyz. */ 6211debfc3dSmrg 6221debfc3dSmrg static bool 6231debfc3dSmrg methods_equal_p (tree decl1, tree decl2) 6241debfc3dSmrg { 6251debfc3dSmrg if (DECL_ASSEMBLER_NAME (decl1) == DECL_ASSEMBLER_NAME (decl2)) 6261debfc3dSmrg return true; 6271debfc3dSmrg const char sep = symbol_table::symbol_suffix_separator (); 6281debfc3dSmrg 6291debfc3dSmrg const char *name1 = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl1)); 6301debfc3dSmrg const char *ptr1 = strchr (name1, sep); 6311debfc3dSmrg int len1 = ptr1 ? ptr1 - name1 : strlen (name1); 6321debfc3dSmrg 6331debfc3dSmrg const char *name2 = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl2)); 6341debfc3dSmrg const char *ptr2 = strchr (name2, sep); 6351debfc3dSmrg int len2 = ptr2 ? ptr2 - name2 : strlen (name2); 6361debfc3dSmrg 6371debfc3dSmrg if (len1 != len2) 6381debfc3dSmrg return false; 6391debfc3dSmrg return !strncmp (name1, name2, len1); 6401debfc3dSmrg } 6411debfc3dSmrg 6421debfc3dSmrg /* Compare two virtual tables, PREVAILING and VTABLE and output ODR 6431debfc3dSmrg violation warnings. */ 6441debfc3dSmrg 6451debfc3dSmrg void 6461debfc3dSmrg compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) 6471debfc3dSmrg { 6481debfc3dSmrg int n1, n2; 6491debfc3dSmrg 6501debfc3dSmrg if (DECL_VIRTUAL_P (prevailing->decl) != DECL_VIRTUAL_P (vtable->decl)) 6511debfc3dSmrg { 6521debfc3dSmrg odr_violation_reported = true; 6531debfc3dSmrg if (DECL_VIRTUAL_P (prevailing->decl)) 6541debfc3dSmrg { 6551debfc3dSmrg varpool_node *tmp = prevailing; 6561debfc3dSmrg prevailing = vtable; 6571debfc3dSmrg vtable = tmp; 6581debfc3dSmrg } 659c0a68be4Smrg auto_diagnostic_group d; 6601debfc3dSmrg if (warning_at (DECL_SOURCE_LOCATION 6611debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 6621debfc3dSmrg OPT_Wodr, 6631debfc3dSmrg "virtual table of type %qD violates one definition rule", 6641debfc3dSmrg DECL_CONTEXT (vtable->decl))) 6651debfc3dSmrg inform (DECL_SOURCE_LOCATION (prevailing->decl), 6661debfc3dSmrg "variable of same assembler name as the virtual table is " 6671debfc3dSmrg "defined in another translation unit"); 6681debfc3dSmrg return; 6691debfc3dSmrg } 6701debfc3dSmrg if (!prevailing->definition || !vtable->definition) 6711debfc3dSmrg return; 6721debfc3dSmrg 6731debfc3dSmrg /* If we do not stream ODR type info, do not bother to do useful compare. */ 6741debfc3dSmrg if (!TYPE_BINFO (DECL_CONTEXT (vtable->decl)) 6751debfc3dSmrg || !polymorphic_type_binfo_p (TYPE_BINFO (DECL_CONTEXT (vtable->decl)))) 6761debfc3dSmrg return; 6771debfc3dSmrg 6781debfc3dSmrg odr_type class_type = get_odr_type (DECL_CONTEXT (vtable->decl), true); 6791debfc3dSmrg 6801debfc3dSmrg if (class_type->odr_violated) 6811debfc3dSmrg return; 6821debfc3dSmrg 6831debfc3dSmrg for (n1 = 0, n2 = 0; true; n1++, n2++) 6841debfc3dSmrg { 6851debfc3dSmrg struct ipa_ref *ref1, *ref2; 6861debfc3dSmrg bool end1, end2; 6871debfc3dSmrg 6881debfc3dSmrg end1 = !prevailing->iterate_reference (n1, ref1); 6891debfc3dSmrg end2 = !vtable->iterate_reference (n2, ref2); 6901debfc3dSmrg 6911debfc3dSmrg /* !DECL_VIRTUAL_P means RTTI entry; 692*8feb0f0bSmrg We warn when RTTI is lost because non-RTTI prevails; we silently 6931debfc3dSmrg accept the other case. */ 6941debfc3dSmrg while (!end2 6951debfc3dSmrg && (end1 6961debfc3dSmrg || (methods_equal_p (ref1->referred->decl, 6971debfc3dSmrg ref2->referred->decl) 6981debfc3dSmrg && TREE_CODE (ref1->referred->decl) == FUNCTION_DECL)) 6991debfc3dSmrg && TREE_CODE (ref2->referred->decl) != FUNCTION_DECL) 7001debfc3dSmrg { 701c0a68be4Smrg if (!class_type->rtti_broken) 702c0a68be4Smrg { 703c0a68be4Smrg auto_diagnostic_group d; 704c0a68be4Smrg if (warning_at (DECL_SOURCE_LOCATION 7051debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 7061debfc3dSmrg OPT_Wodr, 7071debfc3dSmrg "virtual table of type %qD contains RTTI " 7081debfc3dSmrg "information", 7091debfc3dSmrg DECL_CONTEXT (vtable->decl))) 7101debfc3dSmrg { 7111debfc3dSmrg inform (DECL_SOURCE_LOCATION 7121debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), 713c0a68be4Smrg "but is prevailed by one without from other" 714c0a68be4Smrg " translation unit"); 7151debfc3dSmrg inform (DECL_SOURCE_LOCATION 7161debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), 7171debfc3dSmrg "RTTI will not work on this type"); 7181debfc3dSmrg class_type->rtti_broken = true; 7191debfc3dSmrg } 720c0a68be4Smrg } 7211debfc3dSmrg n2++; 7221debfc3dSmrg end2 = !vtable->iterate_reference (n2, ref2); 7231debfc3dSmrg } 7241debfc3dSmrg while (!end1 7251debfc3dSmrg && (end2 7261debfc3dSmrg || (methods_equal_p (ref2->referred->decl, ref1->referred->decl) 7271debfc3dSmrg && TREE_CODE (ref2->referred->decl) == FUNCTION_DECL)) 7281debfc3dSmrg && TREE_CODE (ref1->referred->decl) != FUNCTION_DECL) 7291debfc3dSmrg { 7301debfc3dSmrg n1++; 7311debfc3dSmrg end1 = !prevailing->iterate_reference (n1, ref1); 7321debfc3dSmrg } 7331debfc3dSmrg 7341debfc3dSmrg /* Finished? */ 7351debfc3dSmrg if (end1 && end2) 7361debfc3dSmrg { 7371debfc3dSmrg /* Extra paranoia; compare the sizes. We do not have information 7381debfc3dSmrg about virtual inheritance offsets, so just be sure that these 7391debfc3dSmrg match. 7401debfc3dSmrg Do this as very last check so the not very informative error 7411debfc3dSmrg is not output too often. */ 7421debfc3dSmrg if (DECL_SIZE (prevailing->decl) != DECL_SIZE (vtable->decl)) 7431debfc3dSmrg { 7441debfc3dSmrg class_type->odr_violated = true; 745c0a68be4Smrg auto_diagnostic_group d; 746c0a68be4Smrg tree ctx = TYPE_NAME (DECL_CONTEXT (vtable->decl)); 747c0a68be4Smrg if (warning_at (DECL_SOURCE_LOCATION (ctx), OPT_Wodr, 7481debfc3dSmrg "virtual table of type %qD violates " 7491debfc3dSmrg "one definition rule", 7501debfc3dSmrg DECL_CONTEXT (vtable->decl))) 7511debfc3dSmrg { 752c0a68be4Smrg ctx = TYPE_NAME (DECL_CONTEXT (prevailing->decl)); 753c0a68be4Smrg inform (DECL_SOURCE_LOCATION (ctx), 7541debfc3dSmrg "the conflicting type defined in another translation" 7551debfc3dSmrg " unit has virtual table of different size"); 7561debfc3dSmrg } 7571debfc3dSmrg } 7581debfc3dSmrg return; 7591debfc3dSmrg } 7601debfc3dSmrg 7611debfc3dSmrg if (!end1 && !end2) 7621debfc3dSmrg { 7631debfc3dSmrg if (methods_equal_p (ref1->referred->decl, ref2->referred->decl)) 7641debfc3dSmrg continue; 7651debfc3dSmrg 7661debfc3dSmrg class_type->odr_violated = true; 7671debfc3dSmrg 7681debfc3dSmrg /* If the loops above stopped on non-virtual pointer, we have 7691debfc3dSmrg mismatch in RTTI information mangling. */ 7701debfc3dSmrg if (TREE_CODE (ref1->referred->decl) != FUNCTION_DECL 7711debfc3dSmrg && TREE_CODE (ref2->referred->decl) != FUNCTION_DECL) 7721debfc3dSmrg { 773c0a68be4Smrg auto_diagnostic_group d; 7741debfc3dSmrg if (warning_at (DECL_SOURCE_LOCATION 7751debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 7761debfc3dSmrg OPT_Wodr, 7771debfc3dSmrg "virtual table of type %qD violates " 7781debfc3dSmrg "one definition rule", 7791debfc3dSmrg DECL_CONTEXT (vtable->decl))) 7801debfc3dSmrg { 7811debfc3dSmrg inform (DECL_SOURCE_LOCATION 7821debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), 7831debfc3dSmrg "the conflicting type defined in another translation " 7841debfc3dSmrg "unit with different RTTI information"); 7851debfc3dSmrg } 7861debfc3dSmrg return; 7871debfc3dSmrg } 7881debfc3dSmrg /* At this point both REF1 and REF2 points either to virtual table 7891debfc3dSmrg or virtual method. If one points to virtual table and other to 7901debfc3dSmrg method we can complain the same way as if one table was shorter 7911debfc3dSmrg than other pointing out the extra method. */ 7921debfc3dSmrg if (TREE_CODE (ref1->referred->decl) 7931debfc3dSmrg != TREE_CODE (ref2->referred->decl)) 7941debfc3dSmrg { 7951debfc3dSmrg if (VAR_P (ref1->referred->decl)) 7961debfc3dSmrg end1 = true; 7971debfc3dSmrg else if (VAR_P (ref2->referred->decl)) 7981debfc3dSmrg end2 = true; 7991debfc3dSmrg } 8001debfc3dSmrg } 8011debfc3dSmrg 8021debfc3dSmrg class_type->odr_violated = true; 8031debfc3dSmrg 804*8feb0f0bSmrg /* Complain about size mismatch. Either we have too many virtual 8051debfc3dSmrg functions or too many virtual table pointers. */ 8061debfc3dSmrg if (end1 || end2) 8071debfc3dSmrg { 8081debfc3dSmrg if (end1) 8091debfc3dSmrg { 8101debfc3dSmrg varpool_node *tmp = prevailing; 8111debfc3dSmrg prevailing = vtable; 8121debfc3dSmrg vtable = tmp; 8131debfc3dSmrg ref1 = ref2; 8141debfc3dSmrg } 815c0a68be4Smrg auto_diagnostic_group d; 8161debfc3dSmrg if (warning_at (DECL_SOURCE_LOCATION 8171debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (vtable->decl))), 8181debfc3dSmrg OPT_Wodr, 8191debfc3dSmrg "virtual table of type %qD violates " 8201debfc3dSmrg "one definition rule", 8211debfc3dSmrg DECL_CONTEXT (vtable->decl))) 8221debfc3dSmrg { 8231debfc3dSmrg if (TREE_CODE (ref1->referring->decl) == FUNCTION_DECL) 8241debfc3dSmrg { 8251debfc3dSmrg inform (DECL_SOURCE_LOCATION 8261debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), 8271debfc3dSmrg "the conflicting type defined in another translation " 8281debfc3dSmrg "unit"); 8291debfc3dSmrg inform (DECL_SOURCE_LOCATION 8301debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (ref1->referring->decl))), 8311debfc3dSmrg "contains additional virtual method %qD", 8321debfc3dSmrg ref1->referred->decl); 8331debfc3dSmrg } 8341debfc3dSmrg else 8351debfc3dSmrg { 8361debfc3dSmrg inform (DECL_SOURCE_LOCATION 8371debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), 8381debfc3dSmrg "the conflicting type defined in another translation " 8391debfc3dSmrg "unit has virtual table with more entries"); 8401debfc3dSmrg } 8411debfc3dSmrg } 8421debfc3dSmrg return; 8431debfc3dSmrg } 8441debfc3dSmrg 845*8feb0f0bSmrg /* And in the last case we have either mismatch in between two virtual 8461debfc3dSmrg methods or two virtual table pointers. */ 847c0a68be4Smrg auto_diagnostic_group d; 8481debfc3dSmrg if (warning_at (DECL_SOURCE_LOCATION 8491debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (vtable->decl))), OPT_Wodr, 8501debfc3dSmrg "virtual table of type %qD violates " 8511debfc3dSmrg "one definition rule", 8521debfc3dSmrg DECL_CONTEXT (vtable->decl))) 8531debfc3dSmrg { 8541debfc3dSmrg if (TREE_CODE (ref1->referred->decl) == FUNCTION_DECL) 8551debfc3dSmrg { 8561debfc3dSmrg inform (DECL_SOURCE_LOCATION 8571debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), 8581debfc3dSmrg "the conflicting type defined in another translation " 8591debfc3dSmrg "unit"); 8601debfc3dSmrg gcc_assert (TREE_CODE (ref2->referred->decl) 8611debfc3dSmrg == FUNCTION_DECL); 8621debfc3dSmrg inform (DECL_SOURCE_LOCATION 8631debfc3dSmrg (ref1->referred->ultimate_alias_target ()->decl), 8641debfc3dSmrg "virtual method %qD", 8651debfc3dSmrg ref1->referred->ultimate_alias_target ()->decl); 8661debfc3dSmrg inform (DECL_SOURCE_LOCATION 8671debfc3dSmrg (ref2->referred->ultimate_alias_target ()->decl), 8681debfc3dSmrg "ought to match virtual method %qD but does not", 8691debfc3dSmrg ref2->referred->ultimate_alias_target ()->decl); 8701debfc3dSmrg } 8711debfc3dSmrg else 8721debfc3dSmrg inform (DECL_SOURCE_LOCATION 8731debfc3dSmrg (TYPE_NAME (DECL_CONTEXT (prevailing->decl))), 8741debfc3dSmrg "the conflicting type defined in another translation " 8751debfc3dSmrg "unit has virtual table with different contents"); 8761debfc3dSmrg return; 8771debfc3dSmrg } 8781debfc3dSmrg } 8791debfc3dSmrg } 8801debfc3dSmrg 8811debfc3dSmrg /* Output ODR violation warning about T1 and T2 with REASON. 8821debfc3dSmrg Display location of ST1 and ST2 if REASON speaks about field or 8831debfc3dSmrg method of the type. 8841debfc3dSmrg If WARN is false, do nothing. Set WARNED if warning was indeed 8851debfc3dSmrg output. */ 8861debfc3dSmrg 887c0a68be4Smrg static void 8881debfc3dSmrg warn_odr (tree t1, tree t2, tree st1, tree st2, 8891debfc3dSmrg bool warn, bool *warned, const char *reason) 8901debfc3dSmrg { 891c0a68be4Smrg tree decl2 = TYPE_NAME (TYPE_MAIN_VARIANT (t2)); 8921debfc3dSmrg if (warned) 8931debfc3dSmrg *warned = false; 8941debfc3dSmrg 895c0a68be4Smrg if (!warn || !TYPE_NAME(TYPE_MAIN_VARIANT (t1))) 8961debfc3dSmrg return; 8971debfc3dSmrg 898*8feb0f0bSmrg /* ODR warnings are output during LTO streaming; we must apply location 8991debfc3dSmrg cache for potential warnings to be output correctly. */ 9001debfc3dSmrg if (lto_location_cache::current_cache) 9011debfc3dSmrg lto_location_cache::current_cache->apply_location_cache (); 9021debfc3dSmrg 903c0a68be4Smrg auto_diagnostic_group d; 904c0a68be4Smrg if (t1 != TYPE_MAIN_VARIANT (t1) 905c0a68be4Smrg && TYPE_NAME (t1) != TYPE_NAME (TYPE_MAIN_VARIANT (t1))) 906c0a68be4Smrg { 907c0a68be4Smrg if (!warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (TYPE_MAIN_VARIANT (t1))), 908c0a68be4Smrg OPT_Wodr, "type %qT (typedef of %qT) violates the " 909c0a68be4Smrg "C++ One Definition Rule", 910c0a68be4Smrg t1, TYPE_MAIN_VARIANT (t1))) 911c0a68be4Smrg return; 912c0a68be4Smrg } 913c0a68be4Smrg else 914c0a68be4Smrg { 915c0a68be4Smrg if (!warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (TYPE_MAIN_VARIANT (t1))), 916c0a68be4Smrg OPT_Wodr, "type %qT violates the C++ One Definition Rule", 9171debfc3dSmrg t1)) 9181debfc3dSmrg return; 919c0a68be4Smrg } 9201debfc3dSmrg if (!st1 && !st2) 9211debfc3dSmrg ; 9221debfc3dSmrg /* For FIELD_DECL support also case where one of fields is 9231debfc3dSmrg NULL - this is used when the structures have mismatching number of 9241debfc3dSmrg elements. */ 9251debfc3dSmrg else if (!st1 || TREE_CODE (st1) == FIELD_DECL) 9261debfc3dSmrg { 9271debfc3dSmrg inform (DECL_SOURCE_LOCATION (decl2), 9281debfc3dSmrg "a different type is defined in another translation unit"); 9291debfc3dSmrg if (!st1) 9301debfc3dSmrg { 9311debfc3dSmrg st1 = st2; 9321debfc3dSmrg st2 = NULL; 9331debfc3dSmrg } 9341debfc3dSmrg inform (DECL_SOURCE_LOCATION (st1), 9351debfc3dSmrg "the first difference of corresponding definitions is field %qD", 9361debfc3dSmrg st1); 9371debfc3dSmrg if (st2) 9381debfc3dSmrg decl2 = st2; 9391debfc3dSmrg } 9401debfc3dSmrg else if (TREE_CODE (st1) == FUNCTION_DECL) 9411debfc3dSmrg { 9421debfc3dSmrg inform (DECL_SOURCE_LOCATION (decl2), 9431debfc3dSmrg "a different type is defined in another translation unit"); 9441debfc3dSmrg inform (DECL_SOURCE_LOCATION (st1), 9451debfc3dSmrg "the first difference of corresponding definitions is method %qD", 9461debfc3dSmrg st1); 9471debfc3dSmrg decl2 = st2; 9481debfc3dSmrg } 9491debfc3dSmrg else 9501debfc3dSmrg return; 9511debfc3dSmrg inform (DECL_SOURCE_LOCATION (decl2), reason); 9521debfc3dSmrg 9531debfc3dSmrg if (warned) 9541debfc3dSmrg *warned = true; 9551debfc3dSmrg } 9561debfc3dSmrg 957*8feb0f0bSmrg /* Return true if T1 and T2 are incompatible and we want to recursively 9581debfc3dSmrg dive into them from warn_type_mismatch to give sensible answer. */ 9591debfc3dSmrg 9601debfc3dSmrg static bool 9611debfc3dSmrg type_mismatch_p (tree t1, tree t2) 9621debfc3dSmrg { 9631debfc3dSmrg if (odr_or_derived_type_p (t1) && odr_or_derived_type_p (t2) 9641debfc3dSmrg && !odr_types_equivalent_p (t1, t2)) 9651debfc3dSmrg return true; 9661debfc3dSmrg return !types_compatible_p (t1, t2); 9671debfc3dSmrg } 9681debfc3dSmrg 9691debfc3dSmrg 9701debfc3dSmrg /* Types T1 and T2 was found to be incompatible in a context they can't 9711debfc3dSmrg (either used to declare a symbol of same assembler name or unified by 9721debfc3dSmrg ODR rule). We already output warning about this, but if possible, output 9731debfc3dSmrg extra information on how the types mismatch. 9741debfc3dSmrg 9751debfc3dSmrg This is hard to do in general. We basically handle the common cases. 9761debfc3dSmrg 9771debfc3dSmrg If LOC1 and LOC2 are meaningful locations, use it in the case the types 9781debfc3dSmrg themselves do not have one. */ 9791debfc3dSmrg 9801debfc3dSmrg void 9811debfc3dSmrg warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2) 9821debfc3dSmrg { 9831debfc3dSmrg /* Location of type is known only if it has TYPE_NAME and the name is 9841debfc3dSmrg TYPE_DECL. */ 9851debfc3dSmrg location_t loc_t1 = TYPE_NAME (t1) && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL 9861debfc3dSmrg ? DECL_SOURCE_LOCATION (TYPE_NAME (t1)) 9871debfc3dSmrg : UNKNOWN_LOCATION; 9881debfc3dSmrg location_t loc_t2 = TYPE_NAME (t2) && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL 9891debfc3dSmrg ? DECL_SOURCE_LOCATION (TYPE_NAME (t2)) 9901debfc3dSmrg : UNKNOWN_LOCATION; 9911debfc3dSmrg bool loc_t2_useful = false; 9921debfc3dSmrg 9931debfc3dSmrg /* With LTO it is a common case that the location of both types match. 9941debfc3dSmrg See if T2 has a location that is different from T1. If so, we will 9951debfc3dSmrg inform user about the location. 9961debfc3dSmrg Do not consider the location passed to us in LOC1/LOC2 as those are 9971debfc3dSmrg already output. */ 9981debfc3dSmrg if (loc_t2 > BUILTINS_LOCATION && loc_t2 != loc_t1) 9991debfc3dSmrg { 10001debfc3dSmrg if (loc_t1 <= BUILTINS_LOCATION) 10011debfc3dSmrg loc_t2_useful = true; 10021debfc3dSmrg else 10031debfc3dSmrg { 10041debfc3dSmrg expanded_location xloc1 = expand_location (loc_t1); 10051debfc3dSmrg expanded_location xloc2 = expand_location (loc_t2); 10061debfc3dSmrg 10071debfc3dSmrg if (strcmp (xloc1.file, xloc2.file) 10081debfc3dSmrg || xloc1.line != xloc2.line 10091debfc3dSmrg || xloc1.column != xloc2.column) 10101debfc3dSmrg loc_t2_useful = true; 10111debfc3dSmrg } 10121debfc3dSmrg } 10131debfc3dSmrg 10141debfc3dSmrg if (loc_t1 <= BUILTINS_LOCATION) 10151debfc3dSmrg loc_t1 = loc1; 10161debfc3dSmrg if (loc_t2 <= BUILTINS_LOCATION) 10171debfc3dSmrg loc_t2 = loc2; 10181debfc3dSmrg 10191debfc3dSmrg location_t loc = loc_t1 <= BUILTINS_LOCATION ? loc_t2 : loc_t1; 10201debfc3dSmrg 10211debfc3dSmrg /* It is a quite common bug to reference anonymous namespace type in 10221debfc3dSmrg non-anonymous namespace class. */ 1023*8feb0f0bSmrg tree mt1 = TYPE_MAIN_VARIANT (t1); 1024*8feb0f0bSmrg tree mt2 = TYPE_MAIN_VARIANT (t2); 1025*8feb0f0bSmrg if ((type_with_linkage_p (mt1) 1026*8feb0f0bSmrg && type_in_anonymous_namespace_p (mt1)) 1027*8feb0f0bSmrg || (type_with_linkage_p (mt2) 1028*8feb0f0bSmrg && type_in_anonymous_namespace_p (mt2))) 10291debfc3dSmrg { 1030*8feb0f0bSmrg if (!type_with_linkage_p (mt1) 1031*8feb0f0bSmrg || !type_in_anonymous_namespace_p (mt1)) 10321debfc3dSmrg { 10331debfc3dSmrg std::swap (t1, t2); 1034*8feb0f0bSmrg std::swap (mt1, mt2); 10351debfc3dSmrg std::swap (loc_t1, loc_t2); 10361debfc3dSmrg } 1037*8feb0f0bSmrg gcc_assert (TYPE_NAME (mt1) 1038*8feb0f0bSmrg && TREE_CODE (TYPE_NAME (mt1)) == TYPE_DECL); 1039*8feb0f0bSmrg tree n1 = TYPE_NAME (mt1); 1040*8feb0f0bSmrg tree n2 = TYPE_NAME (mt2) ? TYPE_NAME (mt2) : NULL; 1041*8feb0f0bSmrg 1042c0a68be4Smrg if (TREE_CODE (n1) == TYPE_DECL) 1043c0a68be4Smrg n1 = DECL_NAME (n1); 1044*8feb0f0bSmrg if (n2 && TREE_CODE (n2) == TYPE_DECL) 1045c0a68be4Smrg n2 = DECL_NAME (n2); 1046*8feb0f0bSmrg /* Most of the time, the type names will match, do not be unnecessarily 10471debfc3dSmrg verbose. */ 1048*8feb0f0bSmrg if (n1 != n2) 10491debfc3dSmrg inform (loc_t1, 10501debfc3dSmrg "type %qT defined in anonymous namespace cannot match " 10511debfc3dSmrg "type %qT across the translation unit boundary", 10521debfc3dSmrg t1, t2); 10531debfc3dSmrg else 10541debfc3dSmrg inform (loc_t1, 10551debfc3dSmrg "type %qT defined in anonymous namespace cannot match " 10561debfc3dSmrg "across the translation unit boundary", 10571debfc3dSmrg t1); 10581debfc3dSmrg if (loc_t2_useful) 10591debfc3dSmrg inform (loc_t2, 10601debfc3dSmrg "the incompatible type defined in another translation unit"); 10611debfc3dSmrg return; 10621debfc3dSmrg } 10631debfc3dSmrg /* If types have mangled ODR names and they are different, it is most 10641debfc3dSmrg informative to output those. 10651debfc3dSmrg This also covers types defined in different namespaces. */ 1066*8feb0f0bSmrg const char *odr1 = get_odr_name_for_type (mt1); 1067*8feb0f0bSmrg const char *odr2 = get_odr_name_for_type (mt2); 1068*8feb0f0bSmrg if (odr1 != NULL && odr2 != NULL && odr1 != odr2) 10691debfc3dSmrg { 1070*8feb0f0bSmrg const int opts = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; 1071*8feb0f0bSmrg char *name1 = xstrdup (cplus_demangle (odr1, opts)); 1072*8feb0f0bSmrg char *name2 = cplus_demangle (odr2, opts); 10731debfc3dSmrg if (name1 && name2 && strcmp (name1, name2)) 10741debfc3dSmrg { 10751debfc3dSmrg inform (loc_t1, 10761debfc3dSmrg "type name %qs should match type name %qs", 10771debfc3dSmrg name1, name2); 10781debfc3dSmrg if (loc_t2_useful) 10791debfc3dSmrg inform (loc_t2, 10801debfc3dSmrg "the incompatible type is defined here"); 10811debfc3dSmrg free (name1); 10821debfc3dSmrg return; 10831debfc3dSmrg } 10841debfc3dSmrg free (name1); 10851debfc3dSmrg } 10861debfc3dSmrg /* A tricky case are compound types. Often they appear the same in source 10871debfc3dSmrg code and the mismatch is dragged in by type they are build from. 10881debfc3dSmrg Look for those differences in subtypes and try to be informative. In other 10891debfc3dSmrg cases just output nothing because the source code is probably different 10901debfc3dSmrg and in this case we already output a all necessary info. */ 10911debfc3dSmrg if (!TYPE_NAME (t1) || !TYPE_NAME (t2)) 10921debfc3dSmrg { 10931debfc3dSmrg if (TREE_CODE (t1) == TREE_CODE (t2)) 10941debfc3dSmrg { 10951debfc3dSmrg if (TREE_CODE (t1) == ARRAY_TYPE 10961debfc3dSmrg && COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2)) 10971debfc3dSmrg { 10981debfc3dSmrg tree i1 = TYPE_DOMAIN (t1); 10991debfc3dSmrg tree i2 = TYPE_DOMAIN (t2); 11001debfc3dSmrg 11011debfc3dSmrg if (i1 && i2 11021debfc3dSmrg && TYPE_MAX_VALUE (i1) 11031debfc3dSmrg && TYPE_MAX_VALUE (i2) 11041debfc3dSmrg && !operand_equal_p (TYPE_MAX_VALUE (i1), 11051debfc3dSmrg TYPE_MAX_VALUE (i2), 0)) 11061debfc3dSmrg { 11071debfc3dSmrg inform (loc, 11081debfc3dSmrg "array types have different bounds"); 11091debfc3dSmrg return; 11101debfc3dSmrg } 11111debfc3dSmrg } 11121debfc3dSmrg if ((POINTER_TYPE_P (t1) || TREE_CODE (t1) == ARRAY_TYPE) 11131debfc3dSmrg && type_mismatch_p (TREE_TYPE (t1), TREE_TYPE (t2))) 11141debfc3dSmrg warn_types_mismatch (TREE_TYPE (t1), TREE_TYPE (t2), loc_t1, loc_t2); 11151debfc3dSmrg else if (TREE_CODE (t1) == METHOD_TYPE 11161debfc3dSmrg || TREE_CODE (t1) == FUNCTION_TYPE) 11171debfc3dSmrg { 11181debfc3dSmrg tree parms1 = NULL, parms2 = NULL; 11191debfc3dSmrg int count = 1; 11201debfc3dSmrg 11211debfc3dSmrg if (type_mismatch_p (TREE_TYPE (t1), TREE_TYPE (t2))) 11221debfc3dSmrg { 11231debfc3dSmrg inform (loc, "return value type mismatch"); 11241debfc3dSmrg warn_types_mismatch (TREE_TYPE (t1), TREE_TYPE (t2), loc_t1, 11251debfc3dSmrg loc_t2); 11261debfc3dSmrg return; 11271debfc3dSmrg } 11281debfc3dSmrg if (prototype_p (t1) && prototype_p (t2)) 11291debfc3dSmrg for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2); 11301debfc3dSmrg parms1 && parms2; 11311debfc3dSmrg parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2), 11321debfc3dSmrg count++) 11331debfc3dSmrg { 11341debfc3dSmrg if (type_mismatch_p (TREE_VALUE (parms1), TREE_VALUE (parms2))) 11351debfc3dSmrg { 11361debfc3dSmrg if (count == 1 && TREE_CODE (t1) == METHOD_TYPE) 11371debfc3dSmrg inform (loc, 11381debfc3dSmrg "implicit this pointer type mismatch"); 11391debfc3dSmrg else 11401debfc3dSmrg inform (loc, 11411debfc3dSmrg "type mismatch in parameter %i", 11421debfc3dSmrg count - (TREE_CODE (t1) == METHOD_TYPE)); 11431debfc3dSmrg warn_types_mismatch (TREE_VALUE (parms1), 11441debfc3dSmrg TREE_VALUE (parms2), 11451debfc3dSmrg loc_t1, loc_t2); 11461debfc3dSmrg return; 11471debfc3dSmrg } 11481debfc3dSmrg } 11491debfc3dSmrg if (parms1 || parms2) 11501debfc3dSmrg { 11511debfc3dSmrg inform (loc, 11521debfc3dSmrg "types have different parameter counts"); 11531debfc3dSmrg return; 11541debfc3dSmrg } 11551debfc3dSmrg } 11561debfc3dSmrg } 11571debfc3dSmrg return; 11581debfc3dSmrg } 11591debfc3dSmrg 1160c0a68be4Smrg if (types_odr_comparable (t1, t2) 1161c0a68be4Smrg /* We make assign integers mangled names to be able to handle 1162c0a68be4Smrg signed/unsigned chars. Accepting them here would however lead to 1163*8feb0f0bSmrg confusing message like 1164c0a68be4Smrg "type ‘const int’ itself violates the C++ One Definition Rule" */ 1165c0a68be4Smrg && TREE_CODE (t1) != INTEGER_TYPE 1166c0a68be4Smrg && types_same_for_odr (t1, t2)) 11671debfc3dSmrg inform (loc_t1, 11681debfc3dSmrg "type %qT itself violates the C++ One Definition Rule", t1); 11691debfc3dSmrg /* Prevent pointless warnings like "struct aa" should match "struct aa". */ 11701debfc3dSmrg else if (TYPE_NAME (t1) == TYPE_NAME (t2) 11711debfc3dSmrg && TREE_CODE (t1) == TREE_CODE (t2) && !loc_t2_useful) 11721debfc3dSmrg return; 11731debfc3dSmrg else 11741debfc3dSmrg inform (loc_t1, "type %qT should match type %qT", 11751debfc3dSmrg t1, t2); 11761debfc3dSmrg if (loc_t2_useful) 11771debfc3dSmrg inform (loc_t2, "the incompatible type is defined here"); 11781debfc3dSmrg } 11791debfc3dSmrg 1180*8feb0f0bSmrg /* Return true if T should be ignored in TYPE_FIELDS for ODR comparison. */ 1181a2dc1f3fSmrg 1182a2dc1f3fSmrg static bool 1183a2dc1f3fSmrg skip_in_fields_list_p (tree t) 1184a2dc1f3fSmrg { 1185a2dc1f3fSmrg if (TREE_CODE (t) != FIELD_DECL) 1186a2dc1f3fSmrg return true; 1187a2dc1f3fSmrg /* C++ FE introduces zero sized fields depending on -std setting, see 1188a2dc1f3fSmrg PR89358. */ 1189a2dc1f3fSmrg if (DECL_SIZE (t) 1190a2dc1f3fSmrg && integer_zerop (DECL_SIZE (t)) 1191a2dc1f3fSmrg && DECL_ARTIFICIAL (t) 1192a2dc1f3fSmrg && DECL_IGNORED_P (t) 1193a2dc1f3fSmrg && !DECL_NAME (t)) 1194a2dc1f3fSmrg return true; 1195a2dc1f3fSmrg return false; 1196a2dc1f3fSmrg } 1197a2dc1f3fSmrg 11981debfc3dSmrg /* Compare T1 and T2, report ODR violations if WARN is true and set 11991debfc3dSmrg WARNED to true if anything is reported. Return true if types match. 12001debfc3dSmrg If true is returned, the types are also compatible in the sense of 12011debfc3dSmrg gimple_canonical_types_compatible_p. 12021debfc3dSmrg If LOC1 and LOC2 is not UNKNOWN_LOCATION it may be used to output a warning 12031debfc3dSmrg about the type if the type itself do not have location. */ 12041debfc3dSmrg 12051debfc3dSmrg static bool 12061debfc3dSmrg odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, 12071debfc3dSmrg hash_set<type_pair> *visited, 12081debfc3dSmrg location_t loc1, location_t loc2) 12091debfc3dSmrg { 12101debfc3dSmrg /* Check first for the obvious case of pointer identity. */ 12111debfc3dSmrg if (t1 == t2) 12121debfc3dSmrg return true; 12131debfc3dSmrg 12141debfc3dSmrg /* Can't be the same type if the types don't have the same code. */ 12151debfc3dSmrg if (TREE_CODE (t1) != TREE_CODE (t2)) 12161debfc3dSmrg { 12171debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 12181debfc3dSmrg G_("a different type is defined in another translation unit")); 12191debfc3dSmrg return false; 12201debfc3dSmrg } 12211debfc3dSmrg 1222c0a68be4Smrg if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1)) 1223c0a68be4Smrg && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1))) 1224c0a68be4Smrg || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2)) 1225c0a68be4Smrg && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2)))) 12261debfc3dSmrg { 12271debfc3dSmrg /* We cannot trip this when comparing ODR types, only when trying to 12281debfc3dSmrg match different ODR derivations from different declarations. 12291debfc3dSmrg So WARN should be always false. */ 12301debfc3dSmrg gcc_assert (!warn); 12311debfc3dSmrg return false; 12321debfc3dSmrg } 12331debfc3dSmrg 12341debfc3dSmrg /* Non-aggregate types can be handled cheaply. */ 12351debfc3dSmrg if (INTEGRAL_TYPE_P (t1) 12361debfc3dSmrg || SCALAR_FLOAT_TYPE_P (t1) 12371debfc3dSmrg || FIXED_POINT_TYPE_P (t1) 12381debfc3dSmrg || TREE_CODE (t1) == VECTOR_TYPE 12391debfc3dSmrg || TREE_CODE (t1) == COMPLEX_TYPE 12401debfc3dSmrg || TREE_CODE (t1) == OFFSET_TYPE 12411debfc3dSmrg || POINTER_TYPE_P (t1)) 12421debfc3dSmrg { 12431debfc3dSmrg if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2)) 12441debfc3dSmrg { 12451debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 12461debfc3dSmrg G_("a type with different precision is defined " 12471debfc3dSmrg "in another translation unit")); 12481debfc3dSmrg return false; 12491debfc3dSmrg } 12501debfc3dSmrg if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)) 12511debfc3dSmrg { 12521debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 12531debfc3dSmrg G_("a type with different signedness is defined " 12541debfc3dSmrg "in another translation unit")); 12551debfc3dSmrg return false; 12561debfc3dSmrg } 12571debfc3dSmrg 12581debfc3dSmrg if (TREE_CODE (t1) == INTEGER_TYPE 12591debfc3dSmrg && TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)) 12601debfc3dSmrg { 12611debfc3dSmrg /* char WRT uint_8? */ 12621debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 12631debfc3dSmrg G_("a different type is defined in another " 12641debfc3dSmrg "translation unit")); 12651debfc3dSmrg return false; 12661debfc3dSmrg } 12671debfc3dSmrg 12681debfc3dSmrg /* For canonical type comparisons we do not want to build SCCs 12691debfc3dSmrg so we cannot compare pointed-to types. But we can, for now, 12701debfc3dSmrg require the same pointed-to type kind and match what 12711debfc3dSmrg useless_type_conversion_p would do. */ 12721debfc3dSmrg if (POINTER_TYPE_P (t1)) 12731debfc3dSmrg { 12741debfc3dSmrg if (TYPE_ADDR_SPACE (TREE_TYPE (t1)) 12751debfc3dSmrg != TYPE_ADDR_SPACE (TREE_TYPE (t2))) 12761debfc3dSmrg { 12771debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 12781debfc3dSmrg G_("it is defined as a pointer in different address " 12791debfc3dSmrg "space in another translation unit")); 12801debfc3dSmrg return false; 12811debfc3dSmrg } 12821debfc3dSmrg 12831debfc3dSmrg if (!odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2), 12841debfc3dSmrg visited, loc1, loc2)) 12851debfc3dSmrg { 12861debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 12871debfc3dSmrg G_("it is defined as a pointer to different type " 12881debfc3dSmrg "in another translation unit")); 12891debfc3dSmrg if (warn && warned) 12901debfc3dSmrg warn_types_mismatch (TREE_TYPE (t1), TREE_TYPE (t2), 12911debfc3dSmrg loc1, loc2); 12921debfc3dSmrg return false; 12931debfc3dSmrg } 12941debfc3dSmrg } 12951debfc3dSmrg 12961debfc3dSmrg if ((TREE_CODE (t1) == VECTOR_TYPE || TREE_CODE (t1) == COMPLEX_TYPE) 12971debfc3dSmrg && !odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2), 12981debfc3dSmrg visited, loc1, loc2)) 12991debfc3dSmrg { 13001debfc3dSmrg /* Probably specific enough. */ 13011debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 13021debfc3dSmrg G_("a different type is defined " 13031debfc3dSmrg "in another translation unit")); 13041debfc3dSmrg if (warn && warned) 13051debfc3dSmrg warn_types_mismatch (TREE_TYPE (t1), TREE_TYPE (t2), loc1, loc2); 13061debfc3dSmrg return false; 13071debfc3dSmrg } 13081debfc3dSmrg } 13091debfc3dSmrg /* Do type-specific comparisons. */ 13101debfc3dSmrg else switch (TREE_CODE (t1)) 13111debfc3dSmrg { 13121debfc3dSmrg case ARRAY_TYPE: 13131debfc3dSmrg { 13141debfc3dSmrg /* Array types are the same if the element types are the same and 13151debfc3dSmrg the number of elements are the same. */ 13161debfc3dSmrg if (!odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2), 13171debfc3dSmrg visited, loc1, loc2)) 13181debfc3dSmrg { 13191debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 13201debfc3dSmrg G_("a different type is defined in another " 13211debfc3dSmrg "translation unit")); 13221debfc3dSmrg if (warn && warned) 13231debfc3dSmrg warn_types_mismatch (TREE_TYPE (t1), TREE_TYPE (t2), loc1, loc2); 13241debfc3dSmrg } 13251debfc3dSmrg gcc_assert (TYPE_STRING_FLAG (t1) == TYPE_STRING_FLAG (t2)); 13261debfc3dSmrg gcc_assert (TYPE_NONALIASED_COMPONENT (t1) 13271debfc3dSmrg == TYPE_NONALIASED_COMPONENT (t2)); 13281debfc3dSmrg 13291debfc3dSmrg tree i1 = TYPE_DOMAIN (t1); 13301debfc3dSmrg tree i2 = TYPE_DOMAIN (t2); 13311debfc3dSmrg 13321debfc3dSmrg /* For an incomplete external array, the type domain can be 13331debfc3dSmrg NULL_TREE. Check this condition also. */ 13341debfc3dSmrg if (i1 == NULL_TREE || i2 == NULL_TREE) 1335c0a68be4Smrg return type_variants_equivalent_p (t1, t2); 13361debfc3dSmrg 13371debfc3dSmrg tree min1 = TYPE_MIN_VALUE (i1); 13381debfc3dSmrg tree min2 = TYPE_MIN_VALUE (i2); 13391debfc3dSmrg tree max1 = TYPE_MAX_VALUE (i1); 13401debfc3dSmrg tree max2 = TYPE_MAX_VALUE (i2); 13411debfc3dSmrg 13421debfc3dSmrg /* In C++, minimums should be always 0. */ 13431debfc3dSmrg gcc_assert (min1 == min2); 13441debfc3dSmrg if (!operand_equal_p (max1, max2, 0)) 13451debfc3dSmrg { 13461debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 13471debfc3dSmrg G_("an array of different size is defined " 13481debfc3dSmrg "in another translation unit")); 13491debfc3dSmrg return false; 13501debfc3dSmrg } 13511debfc3dSmrg } 13521debfc3dSmrg break; 13531debfc3dSmrg 13541debfc3dSmrg case METHOD_TYPE: 13551debfc3dSmrg case FUNCTION_TYPE: 13561debfc3dSmrg /* Function types are the same if the return type and arguments types 13571debfc3dSmrg are the same. */ 13581debfc3dSmrg if (!odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2), 13591debfc3dSmrg visited, loc1, loc2)) 13601debfc3dSmrg { 13611debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 13621debfc3dSmrg G_("has different return value " 13631debfc3dSmrg "in another translation unit")); 13641debfc3dSmrg if (warn && warned) 13651debfc3dSmrg warn_types_mismatch (TREE_TYPE (t1), TREE_TYPE (t2), loc1, loc2); 13661debfc3dSmrg return false; 13671debfc3dSmrg } 13681debfc3dSmrg 13691debfc3dSmrg if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2) 13701debfc3dSmrg || !prototype_p (t1) || !prototype_p (t2)) 1371c0a68be4Smrg return type_variants_equivalent_p (t1, t2); 13721debfc3dSmrg else 13731debfc3dSmrg { 13741debfc3dSmrg tree parms1, parms2; 13751debfc3dSmrg 13761debfc3dSmrg for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2); 13771debfc3dSmrg parms1 && parms2; 13781debfc3dSmrg parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2)) 13791debfc3dSmrg { 13801debfc3dSmrg if (!odr_subtypes_equivalent_p 1381c0a68be4Smrg (TREE_VALUE (parms1), TREE_VALUE (parms2), 1382c0a68be4Smrg visited, loc1, loc2)) 13831debfc3dSmrg { 13841debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 13851debfc3dSmrg G_("has different parameters in another " 13861debfc3dSmrg "translation unit")); 13871debfc3dSmrg if (warn && warned) 13881debfc3dSmrg warn_types_mismatch (TREE_VALUE (parms1), 13891debfc3dSmrg TREE_VALUE (parms2), loc1, loc2); 13901debfc3dSmrg return false; 13911debfc3dSmrg } 13921debfc3dSmrg } 13931debfc3dSmrg 13941debfc3dSmrg if (parms1 || parms2) 13951debfc3dSmrg { 13961debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 13971debfc3dSmrg G_("has different parameters " 13981debfc3dSmrg "in another translation unit")); 13991debfc3dSmrg return false; 14001debfc3dSmrg } 14011debfc3dSmrg 1402c0a68be4Smrg return type_variants_equivalent_p (t1, t2); 14031debfc3dSmrg } 14041debfc3dSmrg 14051debfc3dSmrg case RECORD_TYPE: 14061debfc3dSmrg case UNION_TYPE: 14071debfc3dSmrg case QUAL_UNION_TYPE: 14081debfc3dSmrg { 14091debfc3dSmrg tree f1, f2; 14101debfc3dSmrg 14111debfc3dSmrg /* For aggregate types, all the fields must be the same. */ 14121debfc3dSmrg if (COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2)) 14131debfc3dSmrg { 14141debfc3dSmrg if (TYPE_BINFO (t1) && TYPE_BINFO (t2) 14151debfc3dSmrg && polymorphic_type_binfo_p (TYPE_BINFO (t1)) 14161debfc3dSmrg != polymorphic_type_binfo_p (TYPE_BINFO (t2))) 14171debfc3dSmrg { 14181debfc3dSmrg if (polymorphic_type_binfo_p (TYPE_BINFO (t1))) 14191debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 14201debfc3dSmrg G_("a type defined in another translation unit " 14211debfc3dSmrg "is not polymorphic")); 14221debfc3dSmrg else 14231debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 14241debfc3dSmrg G_("a type defined in another translation unit " 14251debfc3dSmrg "is polymorphic")); 14261debfc3dSmrg return false; 14271debfc3dSmrg } 14281debfc3dSmrg for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2); 14291debfc3dSmrg f1 || f2; 14301debfc3dSmrg f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) 14311debfc3dSmrg { 14321debfc3dSmrg /* Skip non-fields. */ 1433a2dc1f3fSmrg while (f1 && skip_in_fields_list_p (f1)) 14341debfc3dSmrg f1 = TREE_CHAIN (f1); 1435a2dc1f3fSmrg while (f2 && skip_in_fields_list_p (f2)) 14361debfc3dSmrg f2 = TREE_CHAIN (f2); 14371debfc3dSmrg if (!f1 || !f2) 14381debfc3dSmrg break; 14391debfc3dSmrg if (DECL_VIRTUAL_P (f1) != DECL_VIRTUAL_P (f2)) 14401debfc3dSmrg { 14411debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 14421debfc3dSmrg G_("a type with different virtual table pointers" 14431debfc3dSmrg " is defined in another translation unit")); 14441debfc3dSmrg return false; 14451debfc3dSmrg } 14461debfc3dSmrg if (DECL_ARTIFICIAL (f1) != DECL_ARTIFICIAL (f2)) 14471debfc3dSmrg { 14481debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 14491debfc3dSmrg G_("a type with different bases is defined " 14501debfc3dSmrg "in another translation unit")); 14511debfc3dSmrg return false; 14521debfc3dSmrg } 14531debfc3dSmrg if (DECL_NAME (f1) != DECL_NAME (f2) 14541debfc3dSmrg && !DECL_ARTIFICIAL (f1)) 14551debfc3dSmrg { 14561debfc3dSmrg warn_odr (t1, t2, f1, f2, warn, warned, 14571debfc3dSmrg G_("a field with different name is defined " 14581debfc3dSmrg "in another translation unit")); 14591debfc3dSmrg return false; 14601debfc3dSmrg } 14611debfc3dSmrg if (!odr_subtypes_equivalent_p (TREE_TYPE (f1), 1462c0a68be4Smrg TREE_TYPE (f2), 1463c0a68be4Smrg visited, loc1, loc2)) 14641debfc3dSmrg { 14651debfc3dSmrg /* Do not warn about artificial fields and just go into 14661debfc3dSmrg generic field mismatch warning. */ 14671debfc3dSmrg if (DECL_ARTIFICIAL (f1)) 14681debfc3dSmrg break; 14691debfc3dSmrg 14701debfc3dSmrg warn_odr (t1, t2, f1, f2, warn, warned, 14711debfc3dSmrg G_("a field of same name but different type " 14721debfc3dSmrg "is defined in another translation unit")); 14731debfc3dSmrg if (warn && warned) 14741debfc3dSmrg warn_types_mismatch (TREE_TYPE (f1), TREE_TYPE (f2), loc1, loc2); 14751debfc3dSmrg return false; 14761debfc3dSmrg } 14771debfc3dSmrg if (!gimple_compare_field_offset (f1, f2)) 14781debfc3dSmrg { 14791debfc3dSmrg /* Do not warn about artificial fields and just go into 14801debfc3dSmrg generic field mismatch warning. */ 14811debfc3dSmrg if (DECL_ARTIFICIAL (f1)) 14821debfc3dSmrg break; 14831debfc3dSmrg warn_odr (t1, t2, f1, f2, warn, warned, 14841debfc3dSmrg G_("fields have different layout " 14851debfc3dSmrg "in another translation unit")); 14861debfc3dSmrg return false; 14871debfc3dSmrg } 14881debfc3dSmrg if (DECL_BIT_FIELD (f1) != DECL_BIT_FIELD (f2)) 14891debfc3dSmrg { 14901debfc3dSmrg warn_odr (t1, t2, f1, f2, warn, warned, 1491c0a68be4Smrg G_("one field is a bitfield while the other " 1492c0a68be4Smrg "is not")); 14931debfc3dSmrg return false; 14941debfc3dSmrg } 14951debfc3dSmrg else 14961debfc3dSmrg gcc_assert (DECL_NONADDRESSABLE_P (f1) 14971debfc3dSmrg == DECL_NONADDRESSABLE_P (f2)); 14981debfc3dSmrg } 14991debfc3dSmrg 15001debfc3dSmrg /* If one aggregate has more fields than the other, they 15011debfc3dSmrg are not the same. */ 15021debfc3dSmrg if (f1 || f2) 15031debfc3dSmrg { 15041debfc3dSmrg if ((f1 && DECL_VIRTUAL_P (f1)) || (f2 && DECL_VIRTUAL_P (f2))) 15051debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 15061debfc3dSmrg G_("a type with different virtual table pointers" 15071debfc3dSmrg " is defined in another translation unit")); 15081debfc3dSmrg else if ((f1 && DECL_ARTIFICIAL (f1)) 15091debfc3dSmrg || (f2 && DECL_ARTIFICIAL (f2))) 15101debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 15111debfc3dSmrg G_("a type with different bases is defined " 15121debfc3dSmrg "in another translation unit")); 15131debfc3dSmrg else 15141debfc3dSmrg warn_odr (t1, t2, f1, f2, warn, warned, 15151debfc3dSmrg G_("a type with different number of fields " 15161debfc3dSmrg "is defined in another translation unit")); 15171debfc3dSmrg 15181debfc3dSmrg return false; 15191debfc3dSmrg } 15201debfc3dSmrg } 15211debfc3dSmrg break; 15221debfc3dSmrg } 15231debfc3dSmrg case VOID_TYPE: 15241debfc3dSmrg case NULLPTR_TYPE: 15251debfc3dSmrg break; 15261debfc3dSmrg 15271debfc3dSmrg default: 15281debfc3dSmrg debug_tree (t1); 15291debfc3dSmrg gcc_unreachable (); 15301debfc3dSmrg } 15311debfc3dSmrg 15321debfc3dSmrg /* Those are better to come last as they are utterly uninformative. */ 15331debfc3dSmrg if (TYPE_SIZE (t1) && TYPE_SIZE (t2) 15341debfc3dSmrg && !operand_equal_p (TYPE_SIZE (t1), TYPE_SIZE (t2), 0)) 15351debfc3dSmrg { 15361debfc3dSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 15371debfc3dSmrg G_("a type with different size " 15381debfc3dSmrg "is defined in another translation unit")); 15391debfc3dSmrg return false; 15401debfc3dSmrg } 1541c0a68be4Smrg 1542*8feb0f0bSmrg if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2) 1543*8feb0f0bSmrg && COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2)) 1544*8feb0f0bSmrg { 1545*8feb0f0bSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 1546*8feb0f0bSmrg G_("one type needs to be constructed while the other does not")); 1547*8feb0f0bSmrg gcc_checking_assert (RECORD_OR_UNION_TYPE_P (t1)); 1548*8feb0f0bSmrg return false; 1549*8feb0f0bSmrg } 1550*8feb0f0bSmrg /* There is no really good user facing warning for this. 1551*8feb0f0bSmrg Either the original reason for modes being different is lost during 1552*8feb0f0bSmrg streaming or we should catch earlier warnings. We however must detect 1553*8feb0f0bSmrg the mismatch to avoid type verifier from cmplaining on mismatched 1554*8feb0f0bSmrg types between type and canonical type. See PR91576. */ 1555*8feb0f0bSmrg if (TYPE_MODE (t1) != TYPE_MODE (t2) 1556*8feb0f0bSmrg && COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2)) 1557*8feb0f0bSmrg { 1558*8feb0f0bSmrg warn_odr (t1, t2, NULL, NULL, warn, warned, 1559*8feb0f0bSmrg G_("memory layout mismatch")); 1560*8feb0f0bSmrg return false; 1561*8feb0f0bSmrg } 1562*8feb0f0bSmrg 15631debfc3dSmrg gcc_assert (!TYPE_SIZE_UNIT (t1) || !TYPE_SIZE_UNIT (t2) 15641debfc3dSmrg || operand_equal_p (TYPE_SIZE_UNIT (t1), 15651debfc3dSmrg TYPE_SIZE_UNIT (t2), 0)); 1566c0a68be4Smrg return type_variants_equivalent_p (t1, t2); 15671debfc3dSmrg } 15681debfc3dSmrg 15691debfc3dSmrg /* Return true if TYPE1 and TYPE2 are equivalent for One Definition Rule. */ 15701debfc3dSmrg 15711debfc3dSmrg bool 15721debfc3dSmrg odr_types_equivalent_p (tree type1, tree type2) 15731debfc3dSmrg { 15741debfc3dSmrg gcc_checking_assert (odr_or_derived_type_p (type1) 15751debfc3dSmrg && odr_or_derived_type_p (type2)); 15761debfc3dSmrg 15771debfc3dSmrg hash_set<type_pair> visited; 15781debfc3dSmrg return odr_types_equivalent_p (type1, type2, false, NULL, 15791debfc3dSmrg &visited, UNKNOWN_LOCATION, UNKNOWN_LOCATION); 15801debfc3dSmrg } 15811debfc3dSmrg 15821debfc3dSmrg /* TYPE is equivalent to VAL by ODR, but its tree representation differs 15831debfc3dSmrg from VAL->type. This may happen in LTO where tree merging did not merge 15841debfc3dSmrg all variants of the same type or due to ODR violation. 15851debfc3dSmrg 15861debfc3dSmrg Analyze and report ODR violations and add type to duplicate list. 15871debfc3dSmrg If TYPE is more specified than VAL->type, prevail VAL->type. Also if 15881debfc3dSmrg this is first time we see definition of a class return true so the 15891debfc3dSmrg base types are analyzed. */ 15901debfc3dSmrg 15911debfc3dSmrg static bool 15921debfc3dSmrg add_type_duplicate (odr_type val, tree type) 15931debfc3dSmrg { 15941debfc3dSmrg bool build_bases = false; 15951debfc3dSmrg bool prevail = false; 15961debfc3dSmrg bool odr_must_violate = false; 15971debfc3dSmrg 15981debfc3dSmrg if (!val->types_set) 15991debfc3dSmrg val->types_set = new hash_set<tree>; 16001debfc3dSmrg 16011debfc3dSmrg /* Chose polymorphic type as leader (this happens only in case of ODR 16021debfc3dSmrg violations. */ 16031debfc3dSmrg if ((TREE_CODE (type) == RECORD_TYPE && TYPE_BINFO (type) 16041debfc3dSmrg && polymorphic_type_binfo_p (TYPE_BINFO (type))) 16051debfc3dSmrg && (TREE_CODE (val->type) != RECORD_TYPE || !TYPE_BINFO (val->type) 16061debfc3dSmrg || !polymorphic_type_binfo_p (TYPE_BINFO (val->type)))) 16071debfc3dSmrg { 16081debfc3dSmrg prevail = true; 16091debfc3dSmrg build_bases = true; 16101debfc3dSmrg } 16111debfc3dSmrg /* Always prefer complete type to be the leader. */ 16121debfc3dSmrg else if (!COMPLETE_TYPE_P (val->type) && COMPLETE_TYPE_P (type)) 16131debfc3dSmrg { 16141debfc3dSmrg prevail = true; 1615c0a68be4Smrg if (TREE_CODE (type) == RECORD_TYPE) 16161debfc3dSmrg build_bases = TYPE_BINFO (type); 16171debfc3dSmrg } 16181debfc3dSmrg else if (COMPLETE_TYPE_P (val->type) && !COMPLETE_TYPE_P (type)) 16191debfc3dSmrg ; 16201debfc3dSmrg else if (TREE_CODE (val->type) == RECORD_TYPE 16211debfc3dSmrg && TREE_CODE (type) == RECORD_TYPE 16221debfc3dSmrg && TYPE_BINFO (type) && !TYPE_BINFO (val->type)) 16231debfc3dSmrg { 16241debfc3dSmrg gcc_assert (!val->bases.length ()); 16251debfc3dSmrg build_bases = true; 16261debfc3dSmrg prevail = true; 16271debfc3dSmrg } 16281debfc3dSmrg 16291debfc3dSmrg if (prevail) 16301debfc3dSmrg std::swap (val->type, type); 16311debfc3dSmrg 16321debfc3dSmrg val->types_set->add (type); 16331debfc3dSmrg 1634*8feb0f0bSmrg if (!odr_hash) 1635*8feb0f0bSmrg return false; 16361debfc3dSmrg 1637*8feb0f0bSmrg gcc_checking_assert (can_be_name_hashed_p (type) 1638*8feb0f0bSmrg && can_be_name_hashed_p (val->type)); 16391debfc3dSmrg 16401debfc3dSmrg bool merge = true; 16411debfc3dSmrg bool base_mismatch = false; 16421debfc3dSmrg unsigned int i; 16431debfc3dSmrg bool warned = false; 16441debfc3dSmrg hash_set<type_pair> visited; 16451debfc3dSmrg 16461debfc3dSmrg gcc_assert (in_lto_p); 16471debfc3dSmrg vec_safe_push (val->types, type); 16481debfc3dSmrg 16491debfc3dSmrg /* If both are class types, compare the bases. */ 16501debfc3dSmrg if (COMPLETE_TYPE_P (type) && COMPLETE_TYPE_P (val->type) 16511debfc3dSmrg && TREE_CODE (val->type) == RECORD_TYPE 16521debfc3dSmrg && TREE_CODE (type) == RECORD_TYPE 16531debfc3dSmrg && TYPE_BINFO (val->type) && TYPE_BINFO (type)) 16541debfc3dSmrg { 16551debfc3dSmrg if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) 16561debfc3dSmrg != BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))) 16571debfc3dSmrg { 16581debfc3dSmrg if (!flag_ltrans && !warned && !val->odr_violated) 16591debfc3dSmrg { 16601debfc3dSmrg tree extra_base; 16611debfc3dSmrg warn_odr (type, val->type, NULL, NULL, !warned, &warned, 16621debfc3dSmrg "a type with the same name but different " 16631debfc3dSmrg "number of polymorphic bases is " 16641debfc3dSmrg "defined in another translation unit"); 16651debfc3dSmrg if (warned) 16661debfc3dSmrg { 16671debfc3dSmrg if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) 16681debfc3dSmrg > BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))) 16691debfc3dSmrg extra_base = BINFO_BASE_BINFO 16701debfc3dSmrg (TYPE_BINFO (type), 16711debfc3dSmrg BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))); 16721debfc3dSmrg else 16731debfc3dSmrg extra_base = BINFO_BASE_BINFO 16741debfc3dSmrg (TYPE_BINFO (val->type), 16751debfc3dSmrg BINFO_N_BASE_BINFOS (TYPE_BINFO (type))); 16761debfc3dSmrg tree extra_base_type = BINFO_TYPE (extra_base); 16771debfc3dSmrg inform (DECL_SOURCE_LOCATION (TYPE_NAME (extra_base_type)), 16781debfc3dSmrg "the extra base is defined here"); 16791debfc3dSmrg } 16801debfc3dSmrg } 16811debfc3dSmrg base_mismatch = true; 16821debfc3dSmrg } 16831debfc3dSmrg else 16841debfc3dSmrg for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) 16851debfc3dSmrg { 16861debfc3dSmrg tree base1 = BINFO_BASE_BINFO (TYPE_BINFO (type), i); 16871debfc3dSmrg tree base2 = BINFO_BASE_BINFO (TYPE_BINFO (val->type), i); 16881debfc3dSmrg tree type1 = BINFO_TYPE (base1); 16891debfc3dSmrg tree type2 = BINFO_TYPE (base2); 16901debfc3dSmrg 16911debfc3dSmrg if (types_odr_comparable (type1, type2)) 16921debfc3dSmrg { 16931debfc3dSmrg if (!types_same_for_odr (type1, type2)) 16941debfc3dSmrg base_mismatch = true; 16951debfc3dSmrg } 16961debfc3dSmrg else 16971debfc3dSmrg if (!odr_types_equivalent_p (type1, type2)) 16981debfc3dSmrg base_mismatch = true; 16991debfc3dSmrg if (base_mismatch) 17001debfc3dSmrg { 17011debfc3dSmrg if (!warned && !val->odr_violated) 17021debfc3dSmrg { 17031debfc3dSmrg warn_odr (type, val->type, NULL, NULL, 17041debfc3dSmrg !warned, &warned, 17051debfc3dSmrg "a type with the same name but different base " 17061debfc3dSmrg "type is defined in another translation unit"); 17071debfc3dSmrg if (warned) 17081debfc3dSmrg warn_types_mismatch (type1, type2, 17091debfc3dSmrg UNKNOWN_LOCATION, UNKNOWN_LOCATION); 17101debfc3dSmrg } 17111debfc3dSmrg break; 17121debfc3dSmrg } 17131debfc3dSmrg if (BINFO_OFFSET (base1) != BINFO_OFFSET (base2)) 17141debfc3dSmrg { 17151debfc3dSmrg base_mismatch = true; 17161debfc3dSmrg if (!warned && !val->odr_violated) 17171debfc3dSmrg warn_odr (type, val->type, NULL, NULL, 17181debfc3dSmrg !warned, &warned, 17191debfc3dSmrg "a type with the same name but different base " 17201debfc3dSmrg "layout is defined in another translation unit"); 17211debfc3dSmrg break; 17221debfc3dSmrg } 17231debfc3dSmrg /* One of bases is not of complete type. */ 17241debfc3dSmrg if (!TYPE_BINFO (type1) != !TYPE_BINFO (type2)) 17251debfc3dSmrg { 17261debfc3dSmrg /* If we have a polymorphic type info specified for TYPE1 17271debfc3dSmrg but not for TYPE2 we possibly missed a base when recording 17281debfc3dSmrg VAL->type earlier. 17291debfc3dSmrg Be sure this does not happen. */ 17301debfc3dSmrg if (TYPE_BINFO (type1) 17311debfc3dSmrg && polymorphic_type_binfo_p (TYPE_BINFO (type1)) 17321debfc3dSmrg && !build_bases) 17331debfc3dSmrg odr_must_violate = true; 17341debfc3dSmrg break; 17351debfc3dSmrg } 17361debfc3dSmrg /* One base is polymorphic and the other not. 17371debfc3dSmrg This ought to be diagnosed earlier, but do not ICE in the 17381debfc3dSmrg checking bellow. */ 17391debfc3dSmrg else if (TYPE_BINFO (type1) 17401debfc3dSmrg && polymorphic_type_binfo_p (TYPE_BINFO (type1)) 17411debfc3dSmrg != polymorphic_type_binfo_p (TYPE_BINFO (type2))) 17421debfc3dSmrg { 17431debfc3dSmrg if (!warned && !val->odr_violated) 17441debfc3dSmrg warn_odr (type, val->type, NULL, NULL, 17451debfc3dSmrg !warned, &warned, 17461debfc3dSmrg "a base of the type is polymorphic only in one " 17471debfc3dSmrg "translation unit"); 17481debfc3dSmrg base_mismatch = true; 17491debfc3dSmrg break; 17501debfc3dSmrg } 17511debfc3dSmrg } 17521debfc3dSmrg if (base_mismatch) 17531debfc3dSmrg { 17541debfc3dSmrg merge = false; 17551debfc3dSmrg odr_violation_reported = true; 17561debfc3dSmrg val->odr_violated = true; 17571debfc3dSmrg 17581debfc3dSmrg if (symtab->dump_file) 17591debfc3dSmrg { 17601debfc3dSmrg fprintf (symtab->dump_file, "ODR base violation\n"); 17611debfc3dSmrg 17621debfc3dSmrg print_node (symtab->dump_file, "", val->type, 0); 17631debfc3dSmrg putc ('\n',symtab->dump_file); 17641debfc3dSmrg print_node (symtab->dump_file, "", type, 0); 17651debfc3dSmrg putc ('\n',symtab->dump_file); 17661debfc3dSmrg } 17671debfc3dSmrg } 17681debfc3dSmrg } 17691debfc3dSmrg 1770a2dc1f3fSmrg /* Next compare memory layout. 1771a2dc1f3fSmrg The DECL_SOURCE_LOCATIONs in this invocation came from LTO streaming. 1772a2dc1f3fSmrg We must apply the location cache to ensure that they are valid 1773a2dc1f3fSmrg before we can pass them to odr_types_equivalent_p (PR lto/83121). */ 1774a2dc1f3fSmrg if (lto_location_cache::current_cache) 1775a2dc1f3fSmrg lto_location_cache::current_cache->apply_location_cache (); 1776c0a68be4Smrg /* As a special case we stream mangles names of integer types so we can see 1777c0a68be4Smrg if they are believed to be same even though they have different 1778c0a68be4Smrg representation. Avoid bogus warning on mismatches in these. */ 1779c0a68be4Smrg if (TREE_CODE (type) != INTEGER_TYPE 1780c0a68be4Smrg && TREE_CODE (val->type) != INTEGER_TYPE 1781c0a68be4Smrg && !odr_types_equivalent_p (val->type, type, 17821debfc3dSmrg !flag_ltrans && !val->odr_violated && !warned, 17831debfc3dSmrg &warned, &visited, 17841debfc3dSmrg DECL_SOURCE_LOCATION (TYPE_NAME (val->type)), 17851debfc3dSmrg DECL_SOURCE_LOCATION (TYPE_NAME (type)))) 17861debfc3dSmrg { 17871debfc3dSmrg merge = false; 17881debfc3dSmrg odr_violation_reported = true; 17891debfc3dSmrg val->odr_violated = true; 17901debfc3dSmrg } 17911debfc3dSmrg gcc_assert (val->odr_violated || !odr_must_violate); 17921debfc3dSmrg /* Sanity check that all bases will be build same way again. */ 17931debfc3dSmrg if (flag_checking 17941debfc3dSmrg && COMPLETE_TYPE_P (type) && COMPLETE_TYPE_P (val->type) 17951debfc3dSmrg && TREE_CODE (val->type) == RECORD_TYPE 17961debfc3dSmrg && TREE_CODE (type) == RECORD_TYPE 17971debfc3dSmrg && TYPE_BINFO (val->type) && TYPE_BINFO (type) 17981debfc3dSmrg && !val->odr_violated 17991debfc3dSmrg && !base_mismatch && val->bases.length ()) 18001debfc3dSmrg { 18011debfc3dSmrg unsigned int num_poly_bases = 0; 18021debfc3dSmrg unsigned int j; 18031debfc3dSmrg 18041debfc3dSmrg for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) 18051debfc3dSmrg if (polymorphic_type_binfo_p (BINFO_BASE_BINFO 18061debfc3dSmrg (TYPE_BINFO (type), i))) 18071debfc3dSmrg num_poly_bases++; 18081debfc3dSmrg gcc_assert (num_poly_bases == val->bases.length ()); 18091debfc3dSmrg for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); 18101debfc3dSmrg i++) 18111debfc3dSmrg if (polymorphic_type_binfo_p (BINFO_BASE_BINFO 18121debfc3dSmrg (TYPE_BINFO (type), i))) 18131debfc3dSmrg { 18141debfc3dSmrg odr_type base = get_odr_type 18151debfc3dSmrg (BINFO_TYPE 18161debfc3dSmrg (BINFO_BASE_BINFO (TYPE_BINFO (type), 18171debfc3dSmrg i)), 18181debfc3dSmrg true); 18191debfc3dSmrg gcc_assert (val->bases[j] == base); 18201debfc3dSmrg j++; 18211debfc3dSmrg } 18221debfc3dSmrg } 18231debfc3dSmrg 18241debfc3dSmrg 18251debfc3dSmrg /* Regularize things a little. During LTO same types may come with 18261debfc3dSmrg different BINFOs. Either because their virtual table was 18271debfc3dSmrg not merged by tree merging and only later at decl merging or 18281debfc3dSmrg because one type comes with external vtable, while other 18291debfc3dSmrg with internal. We want to merge equivalent binfos to conserve 18301debfc3dSmrg memory and streaming overhead. 18311debfc3dSmrg 18321debfc3dSmrg The external vtables are more harmful: they contain references 18331debfc3dSmrg to external declarations of methods that may be defined in the 18341debfc3dSmrg merged LTO unit. For this reason we absolutely need to remove 18351debfc3dSmrg them and replace by internal variants. Not doing so will lead 18361debfc3dSmrg to incomplete answers from possible_polymorphic_call_targets. 18371debfc3dSmrg 18381debfc3dSmrg FIXME: disable for now; because ODR types are now build during 18391debfc3dSmrg streaming in, the variants do not need to be linked to the type, 18401debfc3dSmrg yet. We need to do the merging in cleanup pass to be implemented 18411debfc3dSmrg soon. */ 18421debfc3dSmrg if (!flag_ltrans && merge 18431debfc3dSmrg && 0 18441debfc3dSmrg && TREE_CODE (val->type) == RECORD_TYPE 18451debfc3dSmrg && TREE_CODE (type) == RECORD_TYPE 18461debfc3dSmrg && TYPE_BINFO (val->type) && TYPE_BINFO (type) 18471debfc3dSmrg && TYPE_MAIN_VARIANT (type) == type 18481debfc3dSmrg && TYPE_MAIN_VARIANT (val->type) == val->type 18491debfc3dSmrg && BINFO_VTABLE (TYPE_BINFO (val->type)) 18501debfc3dSmrg && BINFO_VTABLE (TYPE_BINFO (type))) 18511debfc3dSmrg { 18521debfc3dSmrg tree master_binfo = TYPE_BINFO (val->type); 18531debfc3dSmrg tree v1 = BINFO_VTABLE (master_binfo); 18541debfc3dSmrg tree v2 = BINFO_VTABLE (TYPE_BINFO (type)); 18551debfc3dSmrg 18561debfc3dSmrg if (TREE_CODE (v1) == POINTER_PLUS_EXPR) 18571debfc3dSmrg { 18581debfc3dSmrg gcc_assert (TREE_CODE (v2) == POINTER_PLUS_EXPR 18591debfc3dSmrg && operand_equal_p (TREE_OPERAND (v1, 1), 18601debfc3dSmrg TREE_OPERAND (v2, 1), 0)); 18611debfc3dSmrg v1 = TREE_OPERAND (TREE_OPERAND (v1, 0), 0); 18621debfc3dSmrg v2 = TREE_OPERAND (TREE_OPERAND (v2, 0), 0); 18631debfc3dSmrg } 18641debfc3dSmrg gcc_assert (DECL_ASSEMBLER_NAME (v1) 18651debfc3dSmrg == DECL_ASSEMBLER_NAME (v2)); 18661debfc3dSmrg 18671debfc3dSmrg if (DECL_EXTERNAL (v1) && !DECL_EXTERNAL (v2)) 18681debfc3dSmrg { 18691debfc3dSmrg unsigned int i; 18701debfc3dSmrg 18711debfc3dSmrg set_type_binfo (val->type, TYPE_BINFO (type)); 18721debfc3dSmrg for (i = 0; i < val->types->length (); i++) 18731debfc3dSmrg { 18741debfc3dSmrg if (TYPE_BINFO ((*val->types)[i]) 18751debfc3dSmrg == master_binfo) 18761debfc3dSmrg set_type_binfo ((*val->types)[i], TYPE_BINFO (type)); 18771debfc3dSmrg } 18781debfc3dSmrg BINFO_TYPE (TYPE_BINFO (type)) = val->type; 18791debfc3dSmrg } 18801debfc3dSmrg else 18811debfc3dSmrg set_type_binfo (type, master_binfo); 18821debfc3dSmrg } 18831debfc3dSmrg return build_bases; 18841debfc3dSmrg } 18851debfc3dSmrg 1886*8feb0f0bSmrg /* REF is OBJ_TYPE_REF, return the class the ref corresponds to. 1887*8feb0f0bSmrg FOR_DUMP_P is true when being called from the dump routines. */ 1888c0a68be4Smrg 1889c0a68be4Smrg tree 1890*8feb0f0bSmrg obj_type_ref_class (const_tree ref, bool for_dump_p) 1891c0a68be4Smrg { 1892c0a68be4Smrg gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF); 1893c0a68be4Smrg ref = TREE_TYPE (ref); 1894c0a68be4Smrg gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE); 1895c0a68be4Smrg ref = TREE_TYPE (ref); 1896c0a68be4Smrg /* We look for type THIS points to. ObjC also builds 1897c0a68be4Smrg OBJ_TYPE_REF with non-method calls, Their first parameter 1898c0a68be4Smrg ID however also corresponds to class type. */ 1899c0a68be4Smrg gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE 1900c0a68be4Smrg || TREE_CODE (ref) == FUNCTION_TYPE); 1901c0a68be4Smrg ref = TREE_VALUE (TYPE_ARG_TYPES (ref)); 1902c0a68be4Smrg gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE); 1903c0a68be4Smrg tree ret = TREE_TYPE (ref); 1904c0a68be4Smrg if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (ret)) 1905c0a68be4Smrg ret = TYPE_CANONICAL (ret); 1906*8feb0f0bSmrg else if (odr_type ot = get_odr_type (ret, !for_dump_p)) 1907*8feb0f0bSmrg ret = ot->type; 1908c0a68be4Smrg else 1909*8feb0f0bSmrg gcc_assert (for_dump_p); 1910c0a68be4Smrg return ret; 1911c0a68be4Smrg } 1912c0a68be4Smrg 19131debfc3dSmrg /* Get ODR type hash entry for TYPE. If INSERT is true, create 19141debfc3dSmrg possibly new entry. */ 19151debfc3dSmrg 19161debfc3dSmrg odr_type 19171debfc3dSmrg get_odr_type (tree type, bool insert) 19181debfc3dSmrg { 19191debfc3dSmrg odr_type_d **slot = NULL; 19201debfc3dSmrg odr_type val = NULL; 19211debfc3dSmrg hashval_t hash; 19221debfc3dSmrg bool build_bases = false; 19231debfc3dSmrg bool insert_to_odr_array = false; 19241debfc3dSmrg int base_id = -1; 19251debfc3dSmrg 1926c0a68be4Smrg type = TYPE_MAIN_VARIANT (type); 1927c0a68be4Smrg if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (type)) 1928c0a68be4Smrg type = TYPE_CANONICAL (type); 19291debfc3dSmrg 1930*8feb0f0bSmrg gcc_checking_assert (can_be_name_hashed_p (type)); 19311debfc3dSmrg 19321debfc3dSmrg hash = hash_odr_name (type); 19331debfc3dSmrg slot = odr_hash->find_slot_with_hash (type, hash, 19341debfc3dSmrg insert ? INSERT : NO_INSERT); 19351debfc3dSmrg 1936*8feb0f0bSmrg if (!slot) 19371debfc3dSmrg return NULL; 19381debfc3dSmrg 19391debfc3dSmrg /* See if we already have entry for type. */ 1940*8feb0f0bSmrg if (*slot) 19411debfc3dSmrg { 19421debfc3dSmrg val = *slot; 19431debfc3dSmrg 1944c0a68be4Smrg if (val->type != type && insert 19451debfc3dSmrg && (!val->types_set || !val->types_set->add (type))) 19461debfc3dSmrg build_bases = add_type_duplicate (val, type); 19471debfc3dSmrg } 19481debfc3dSmrg else 19491debfc3dSmrg { 19501debfc3dSmrg val = ggc_cleared_alloc<odr_type_d> (); 19511debfc3dSmrg val->type = type; 19521debfc3dSmrg val->bases = vNULL; 19531debfc3dSmrg val->derived_types = vNULL; 19541debfc3dSmrg if (type_with_linkage_p (type)) 19551debfc3dSmrg val->anonymous_namespace = type_in_anonymous_namespace_p (type); 19561debfc3dSmrg else 19571debfc3dSmrg val->anonymous_namespace = 0; 19581debfc3dSmrg build_bases = COMPLETE_TYPE_P (val->type); 19591debfc3dSmrg insert_to_odr_array = true; 19601debfc3dSmrg *slot = val; 19611debfc3dSmrg } 19621debfc3dSmrg 19631debfc3dSmrg if (build_bases && TREE_CODE (type) == RECORD_TYPE && TYPE_BINFO (type) 19641debfc3dSmrg && type_with_linkage_p (type) 19651debfc3dSmrg && type == TYPE_MAIN_VARIANT (type)) 19661debfc3dSmrg { 19671debfc3dSmrg tree binfo = TYPE_BINFO (type); 19681debfc3dSmrg unsigned int i; 19691debfc3dSmrg 19701debfc3dSmrg gcc_assert (BINFO_TYPE (TYPE_BINFO (val->type)) == type); 19711debfc3dSmrg 19721debfc3dSmrg val->all_derivations_known = type_all_derivations_known_p (type); 19731debfc3dSmrg for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++) 19741debfc3dSmrg /* For now record only polymorphic types. other are 19751debfc3dSmrg pointless for devirtualization and we cannot precisely 19761debfc3dSmrg determine ODR equivalency of these during LTO. */ 19771debfc3dSmrg if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (binfo, i))) 19781debfc3dSmrg { 19791debfc3dSmrg tree base_type= BINFO_TYPE (BINFO_BASE_BINFO (binfo, i)); 19801debfc3dSmrg odr_type base = get_odr_type (base_type, true); 19811debfc3dSmrg gcc_assert (TYPE_MAIN_VARIANT (base_type) == base_type); 19821debfc3dSmrg base->derived_types.safe_push (val); 19831debfc3dSmrg val->bases.safe_push (base); 19841debfc3dSmrg if (base->id > base_id) 19851debfc3dSmrg base_id = base->id; 19861debfc3dSmrg } 19871debfc3dSmrg } 19881debfc3dSmrg /* Ensure that type always appears after bases. */ 19891debfc3dSmrg if (insert_to_odr_array) 19901debfc3dSmrg { 19911debfc3dSmrg if (odr_types_ptr) 19921debfc3dSmrg val->id = odr_types.length (); 19931debfc3dSmrg vec_safe_push (odr_types_ptr, val); 19941debfc3dSmrg } 19951debfc3dSmrg else if (base_id > val->id) 19961debfc3dSmrg { 19971debfc3dSmrg odr_types[val->id] = 0; 19981debfc3dSmrg /* Be sure we did not recorded any derived types; these may need 19991debfc3dSmrg renumbering too. */ 20001debfc3dSmrg gcc_assert (val->derived_types.length() == 0); 20011debfc3dSmrg val->id = odr_types.length (); 20021debfc3dSmrg vec_safe_push (odr_types_ptr, val); 20031debfc3dSmrg } 20041debfc3dSmrg return val; 20051debfc3dSmrg } 20061debfc3dSmrg 2007*8feb0f0bSmrg /* Return type that in ODR type hash prevailed TYPE. Be careful and punt 2008*8feb0f0bSmrg on ODR violations. */ 2009*8feb0f0bSmrg 2010*8feb0f0bSmrg tree 2011*8feb0f0bSmrg prevailing_odr_type (tree type) 2012*8feb0f0bSmrg { 2013*8feb0f0bSmrg odr_type t = get_odr_type (type, false); 2014*8feb0f0bSmrg if (!t || t->odr_violated) 2015*8feb0f0bSmrg return type; 2016*8feb0f0bSmrg return t->type; 2017*8feb0f0bSmrg } 2018*8feb0f0bSmrg 2019*8feb0f0bSmrg /* Set tbaa_enabled flag for TYPE. */ 2020*8feb0f0bSmrg 2021*8feb0f0bSmrg void 2022*8feb0f0bSmrg enable_odr_based_tbaa (tree type) 2023*8feb0f0bSmrg { 2024*8feb0f0bSmrg odr_type t = get_odr_type (type, true); 2025*8feb0f0bSmrg t->tbaa_enabled = true; 2026*8feb0f0bSmrg } 2027*8feb0f0bSmrg 2028*8feb0f0bSmrg /* True if canonical type of TYPE is determined using ODR name. */ 2029*8feb0f0bSmrg 2030*8feb0f0bSmrg bool 2031*8feb0f0bSmrg odr_based_tbaa_p (const_tree type) 2032*8feb0f0bSmrg { 2033*8feb0f0bSmrg if (!RECORD_OR_UNION_TYPE_P (type)) 2034*8feb0f0bSmrg return false; 2035*8feb0f0bSmrg odr_type t = get_odr_type (const_cast <tree> (type), false); 2036*8feb0f0bSmrg if (!t || !t->tbaa_enabled) 2037*8feb0f0bSmrg return false; 2038*8feb0f0bSmrg return true; 2039*8feb0f0bSmrg } 2040*8feb0f0bSmrg 2041*8feb0f0bSmrg /* Set TYPE_CANONICAL of type and all its variants and duplicates 2042*8feb0f0bSmrg to CANONICAL. */ 2043*8feb0f0bSmrg 2044*8feb0f0bSmrg void 2045*8feb0f0bSmrg set_type_canonical_for_odr_type (tree type, tree canonical) 2046*8feb0f0bSmrg { 2047*8feb0f0bSmrg odr_type t = get_odr_type (type, false); 2048*8feb0f0bSmrg unsigned int i; 2049*8feb0f0bSmrg tree tt; 2050*8feb0f0bSmrg 2051*8feb0f0bSmrg for (tree t2 = t->type; t2; t2 = TYPE_NEXT_VARIANT (t2)) 2052*8feb0f0bSmrg TYPE_CANONICAL (t2) = canonical; 2053*8feb0f0bSmrg if (t->types) 2054*8feb0f0bSmrg FOR_EACH_VEC_ELT (*t->types, i, tt) 2055*8feb0f0bSmrg for (tree t2 = tt; t2; t2 = TYPE_NEXT_VARIANT (t2)) 2056*8feb0f0bSmrg TYPE_CANONICAL (t2) = canonical; 2057*8feb0f0bSmrg } 2058*8feb0f0bSmrg 2059*8feb0f0bSmrg /* Return true if we reported some ODR violation on TYPE. */ 2060*8feb0f0bSmrg 2061c0a68be4Smrg bool 2062c0a68be4Smrg odr_type_violation_reported_p (tree type) 2063c0a68be4Smrg { 2064c0a68be4Smrg return get_odr_type (type, false)->odr_violated; 2065c0a68be4Smrg } 2066c0a68be4Smrg 2067*8feb0f0bSmrg /* Add TYPE of ODR type hash. */ 20681debfc3dSmrg 20691debfc3dSmrg void 20701debfc3dSmrg register_odr_type (tree type) 20711debfc3dSmrg { 20721debfc3dSmrg if (!odr_hash) 20731debfc3dSmrg odr_hash = new odr_hash_type (23); 2074c0a68be4Smrg if (type == TYPE_MAIN_VARIANT (type)) 2075c0a68be4Smrg { 2076*8feb0f0bSmrg /* To get ODR warnings right, first register all sub-types. */ 2077c0a68be4Smrg if (RECORD_OR_UNION_TYPE_P (type) 2078c0a68be4Smrg && COMPLETE_TYPE_P (type)) 2079c0a68be4Smrg { 2080c0a68be4Smrg /* Limit recursion on types which are already registered. */ 2081c0a68be4Smrg odr_type ot = get_odr_type (type, false); 2082c0a68be4Smrg if (ot 2083c0a68be4Smrg && (ot->type == type 2084c0a68be4Smrg || (ot->types_set 2085c0a68be4Smrg && ot->types_set->contains (type)))) 2086c0a68be4Smrg return; 2087c0a68be4Smrg for (tree f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f)) 2088c0a68be4Smrg if (TREE_CODE (f) == FIELD_DECL) 2089c0a68be4Smrg { 2090c0a68be4Smrg tree subtype = TREE_TYPE (f); 2091c0a68be4Smrg 2092c0a68be4Smrg while (TREE_CODE (subtype) == ARRAY_TYPE) 2093c0a68be4Smrg subtype = TREE_TYPE (subtype); 2094c0a68be4Smrg if (type_with_linkage_p (TYPE_MAIN_VARIANT (subtype))) 2095c0a68be4Smrg register_odr_type (TYPE_MAIN_VARIANT (subtype)); 2096c0a68be4Smrg } 2097c0a68be4Smrg if (TYPE_BINFO (type)) 2098c0a68be4Smrg for (unsigned int i = 0; 2099c0a68be4Smrg i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) 2100c0a68be4Smrg register_odr_type (BINFO_TYPE (BINFO_BASE_BINFO 2101c0a68be4Smrg (TYPE_BINFO (type), i))); 2102c0a68be4Smrg } 21031debfc3dSmrg get_odr_type (type, true); 21041debfc3dSmrg } 2105c0a68be4Smrg } 21061debfc3dSmrg 21071debfc3dSmrg /* Return true if type is known to have no derivations. */ 21081debfc3dSmrg 21091debfc3dSmrg bool 21101debfc3dSmrg type_known_to_have_no_derivations_p (tree t) 21111debfc3dSmrg { 21121debfc3dSmrg return (type_all_derivations_known_p (t) 21131debfc3dSmrg && (TYPE_FINAL_P (t) 21141debfc3dSmrg || (odr_hash 21151debfc3dSmrg && !get_odr_type (t, true)->derived_types.length()))); 21161debfc3dSmrg } 21171debfc3dSmrg 21181debfc3dSmrg /* Dump ODR type T and all its derived types. INDENT specifies indentation for 21191debfc3dSmrg recursive printing. */ 21201debfc3dSmrg 21211debfc3dSmrg static void 21221debfc3dSmrg dump_odr_type (FILE *f, odr_type t, int indent=0) 21231debfc3dSmrg { 21241debfc3dSmrg unsigned int i; 21251debfc3dSmrg fprintf (f, "%*s type %i: ", indent * 2, "", t->id); 21261debfc3dSmrg print_generic_expr (f, t->type, TDF_SLIM); 21271debfc3dSmrg fprintf (f, "%s", t->anonymous_namespace ? " (anonymous namespace)":""); 21281debfc3dSmrg fprintf (f, "%s\n", t->all_derivations_known ? " (derivations known)":""); 21291debfc3dSmrg if (TYPE_NAME (t->type)) 21301debfc3dSmrg { 21311debfc3dSmrg if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t->type))) 21321debfc3dSmrg fprintf (f, "%*s mangled name: %s\n", indent * 2, "", 21331debfc3dSmrg IDENTIFIER_POINTER 21341debfc3dSmrg (DECL_ASSEMBLER_NAME (TYPE_NAME (t->type)))); 21351debfc3dSmrg } 21361debfc3dSmrg if (t->bases.length ()) 21371debfc3dSmrg { 21381debfc3dSmrg fprintf (f, "%*s base odr type ids: ", indent * 2, ""); 21391debfc3dSmrg for (i = 0; i < t->bases.length (); i++) 21401debfc3dSmrg fprintf (f, " %i", t->bases[i]->id); 21411debfc3dSmrg fprintf (f, "\n"); 21421debfc3dSmrg } 21431debfc3dSmrg if (t->derived_types.length ()) 21441debfc3dSmrg { 21451debfc3dSmrg fprintf (f, "%*s derived types:\n", indent * 2, ""); 21461debfc3dSmrg for (i = 0; i < t->derived_types.length (); i++) 21471debfc3dSmrg dump_odr_type (f, t->derived_types[i], indent + 1); 21481debfc3dSmrg } 21491debfc3dSmrg fprintf (f, "\n"); 21501debfc3dSmrg } 21511debfc3dSmrg 21521debfc3dSmrg /* Dump the type inheritance graph. */ 21531debfc3dSmrg 21541debfc3dSmrg static void 21551debfc3dSmrg dump_type_inheritance_graph (FILE *f) 21561debfc3dSmrg { 21571debfc3dSmrg unsigned int i; 2158c0a68be4Smrg unsigned int num_all_types = 0, num_types = 0, num_duplicates = 0; 21591debfc3dSmrg if (!odr_types_ptr) 21601debfc3dSmrg return; 21611debfc3dSmrg fprintf (f, "\n\nType inheritance graph:\n"); 21621debfc3dSmrg for (i = 0; i < odr_types.length (); i++) 21631debfc3dSmrg { 21641debfc3dSmrg if (odr_types[i] && odr_types[i]->bases.length () == 0) 21651debfc3dSmrg dump_odr_type (f, odr_types[i]); 21661debfc3dSmrg } 21671debfc3dSmrg for (i = 0; i < odr_types.length (); i++) 21681debfc3dSmrg { 2169c0a68be4Smrg if (!odr_types[i]) 2170c0a68be4Smrg continue; 2171c0a68be4Smrg 2172c0a68be4Smrg num_all_types++; 2173c0a68be4Smrg if (!odr_types[i]->types || !odr_types[i]->types->length ()) 2174c0a68be4Smrg continue; 2175c0a68be4Smrg 2176c0a68be4Smrg /* To aid ODR warnings we also mangle integer constants but do 2177*8feb0f0bSmrg not consider duplicates there. */ 2178c0a68be4Smrg if (TREE_CODE (odr_types[i]->type) == INTEGER_TYPE) 2179c0a68be4Smrg continue; 2180c0a68be4Smrg 2181c0a68be4Smrg /* It is normal to have one duplicate and one normal variant. */ 2182c0a68be4Smrg if (odr_types[i]->types->length () == 1 2183c0a68be4Smrg && COMPLETE_TYPE_P (odr_types[i]->type) 2184c0a68be4Smrg && !COMPLETE_TYPE_P ((*odr_types[i]->types)[0])) 2185c0a68be4Smrg continue; 2186c0a68be4Smrg 2187c0a68be4Smrg num_types ++; 2188c0a68be4Smrg 21891debfc3dSmrg unsigned int j; 21901debfc3dSmrg fprintf (f, "Duplicate tree types for odr type %i\n", i); 21911debfc3dSmrg print_node (f, "", odr_types[i]->type, 0); 2192c0a68be4Smrg print_node (f, "", TYPE_NAME (odr_types[i]->type), 0); 2193c0a68be4Smrg putc ('\n',f); 21941debfc3dSmrg for (j = 0; j < odr_types[i]->types->length (); j++) 21951debfc3dSmrg { 21961debfc3dSmrg tree t; 2197c0a68be4Smrg num_duplicates ++; 21981debfc3dSmrg fprintf (f, "duplicate #%i\n", j); 21991debfc3dSmrg print_node (f, "", (*odr_types[i]->types)[j], 0); 22001debfc3dSmrg t = (*odr_types[i]->types)[j]; 22011debfc3dSmrg while (TYPE_P (t) && TYPE_CONTEXT (t)) 22021debfc3dSmrg { 22031debfc3dSmrg t = TYPE_CONTEXT (t); 22041debfc3dSmrg print_node (f, "", t, 0); 22051debfc3dSmrg } 2206c0a68be4Smrg print_node (f, "", TYPE_NAME ((*odr_types[i]->types)[j]), 0); 22071debfc3dSmrg putc ('\n',f); 22081debfc3dSmrg } 22091debfc3dSmrg } 2210c0a68be4Smrg fprintf (f, "Out of %i types there are %i types with duplicates; " 2211c0a68be4Smrg "%i duplicates overall\n", num_all_types, num_types, num_duplicates); 22121debfc3dSmrg } 2213c0a68be4Smrg 2214c0a68be4Smrg /* Save some WPA->ltrans streaming by freeing stuff needed only for good 2215c0a68be4Smrg ODR warnings. 2216*8feb0f0bSmrg We make TYPE_DECLs to not point back 2217c0a68be4Smrg to the type (which is needed to keep them in the same SCC and preserve 2218c0a68be4Smrg location information to output warnings) and subsequently we make all 2219c0a68be4Smrg TYPE_DECLS of same assembler name equivalent. */ 2220c0a68be4Smrg 2221c0a68be4Smrg static void 2222c0a68be4Smrg free_odr_warning_data () 2223c0a68be4Smrg { 2224c0a68be4Smrg static bool odr_data_freed = false; 2225c0a68be4Smrg 2226c0a68be4Smrg if (odr_data_freed || !flag_wpa || !odr_types_ptr) 2227c0a68be4Smrg return; 2228c0a68be4Smrg 2229c0a68be4Smrg odr_data_freed = true; 2230c0a68be4Smrg 2231c0a68be4Smrg for (unsigned int i = 0; i < odr_types.length (); i++) 2232c0a68be4Smrg if (odr_types[i]) 2233c0a68be4Smrg { 2234c0a68be4Smrg tree t = odr_types[i]->type; 2235c0a68be4Smrg 2236c0a68be4Smrg TREE_TYPE (TYPE_NAME (t)) = void_type_node; 2237c0a68be4Smrg 2238c0a68be4Smrg if (odr_types[i]->types) 2239c0a68be4Smrg for (unsigned int j = 0; j < odr_types[i]->types->length (); j++) 2240c0a68be4Smrg { 2241c0a68be4Smrg tree td = (*odr_types[i]->types)[j]; 2242c0a68be4Smrg 2243c0a68be4Smrg TYPE_NAME (td) = TYPE_NAME (t); 2244c0a68be4Smrg } 2245c0a68be4Smrg } 2246c0a68be4Smrg odr_data_freed = true; 22471debfc3dSmrg } 22481debfc3dSmrg 22491debfc3dSmrg /* Initialize IPA devirt and build inheritance tree graph. */ 22501debfc3dSmrg 22511debfc3dSmrg void 22521debfc3dSmrg build_type_inheritance_graph (void) 22531debfc3dSmrg { 22541debfc3dSmrg struct symtab_node *n; 22551debfc3dSmrg FILE *inheritance_dump_file; 2256a2dc1f3fSmrg dump_flags_t flags; 22571debfc3dSmrg 22581debfc3dSmrg if (odr_hash) 2259c0a68be4Smrg { 2260c0a68be4Smrg free_odr_warning_data (); 22611debfc3dSmrg return; 2262c0a68be4Smrg } 22631debfc3dSmrg timevar_push (TV_IPA_INHERITANCE); 22641debfc3dSmrg inheritance_dump_file = dump_begin (TDI_inheritance, &flags); 22651debfc3dSmrg odr_hash = new odr_hash_type (23); 22661debfc3dSmrg 22671debfc3dSmrg /* We reconstruct the graph starting of types of all methods seen in the 22681debfc3dSmrg unit. */ 22691debfc3dSmrg FOR_EACH_SYMBOL (n) 22701debfc3dSmrg if (is_a <cgraph_node *> (n) 22711debfc3dSmrg && DECL_VIRTUAL_P (n->decl) 22721debfc3dSmrg && n->real_symbol_p ()) 22731debfc3dSmrg get_odr_type (TYPE_METHOD_BASETYPE (TREE_TYPE (n->decl)), true); 22741debfc3dSmrg 22751debfc3dSmrg /* Look also for virtual tables of types that do not define any methods. 22761debfc3dSmrg 22771debfc3dSmrg We need it in a case where class B has virtual base of class A 22781debfc3dSmrg re-defining its virtual method and there is class C with no virtual 22791debfc3dSmrg methods with B as virtual base. 22801debfc3dSmrg 22811debfc3dSmrg Here we output B's virtual method in two variant - for non-virtual 22821debfc3dSmrg and virtual inheritance. B's virtual table has non-virtual version, 22831debfc3dSmrg while C's has virtual. 22841debfc3dSmrg 22851debfc3dSmrg For this reason we need to know about C in order to include both 22861debfc3dSmrg variants of B. More correctly, record_target_from_binfo should 22871debfc3dSmrg add both variants of the method when walking B, but we have no 22881debfc3dSmrg link in between them. 22891debfc3dSmrg 22901debfc3dSmrg We rely on fact that either the method is exported and thus we 22911debfc3dSmrg assume it is called externally or C is in anonymous namespace and 22921debfc3dSmrg thus we will see the vtable. */ 22931debfc3dSmrg 22941debfc3dSmrg else if (is_a <varpool_node *> (n) 22951debfc3dSmrg && DECL_VIRTUAL_P (n->decl) 22961debfc3dSmrg && TREE_CODE (DECL_CONTEXT (n->decl)) == RECORD_TYPE 22971debfc3dSmrg && TYPE_BINFO (DECL_CONTEXT (n->decl)) 22981debfc3dSmrg && polymorphic_type_binfo_p (TYPE_BINFO (DECL_CONTEXT (n->decl)))) 22991debfc3dSmrg get_odr_type (TYPE_MAIN_VARIANT (DECL_CONTEXT (n->decl)), true); 23001debfc3dSmrg if (inheritance_dump_file) 23011debfc3dSmrg { 23021debfc3dSmrg dump_type_inheritance_graph (inheritance_dump_file); 23031debfc3dSmrg dump_end (TDI_inheritance, inheritance_dump_file); 23041debfc3dSmrg } 2305c0a68be4Smrg free_odr_warning_data (); 23061debfc3dSmrg timevar_pop (TV_IPA_INHERITANCE); 23071debfc3dSmrg } 23081debfc3dSmrg 23091debfc3dSmrg /* Return true if N has reference from live virtual table 23101debfc3dSmrg (and thus can be a destination of polymorphic call). 23111debfc3dSmrg Be conservatively correct when callgraph is not built or 23121debfc3dSmrg if the method may be referred externally. */ 23131debfc3dSmrg 23141debfc3dSmrg static bool 23151debfc3dSmrg referenced_from_vtable_p (struct cgraph_node *node) 23161debfc3dSmrg { 23171debfc3dSmrg int i; 23181debfc3dSmrg struct ipa_ref *ref; 23191debfc3dSmrg bool found = false; 23201debfc3dSmrg 23211debfc3dSmrg if (node->externally_visible 23221debfc3dSmrg || DECL_EXTERNAL (node->decl) 23231debfc3dSmrg || node->used_from_other_partition) 23241debfc3dSmrg return true; 23251debfc3dSmrg 23261debfc3dSmrg /* Keep this test constant time. 23271debfc3dSmrg It is unlikely this can happen except for the case where speculative 23281debfc3dSmrg devirtualization introduced many speculative edges to this node. 23291debfc3dSmrg In this case the target is very likely alive anyway. */ 23301debfc3dSmrg if (node->ref_list.referring.length () > 100) 23311debfc3dSmrg return true; 23321debfc3dSmrg 23331debfc3dSmrg /* We need references built. */ 23341debfc3dSmrg if (symtab->state <= CONSTRUCTION) 23351debfc3dSmrg return true; 23361debfc3dSmrg 23371debfc3dSmrg for (i = 0; node->iterate_referring (i, ref); i++) 23381debfc3dSmrg if ((ref->use == IPA_REF_ALIAS 23391debfc3dSmrg && referenced_from_vtable_p (dyn_cast<cgraph_node *> (ref->referring))) 23401debfc3dSmrg || (ref->use == IPA_REF_ADDR 23411debfc3dSmrg && VAR_P (ref->referring->decl) 23421debfc3dSmrg && DECL_VIRTUAL_P (ref->referring->decl))) 23431debfc3dSmrg { 23441debfc3dSmrg found = true; 23451debfc3dSmrg break; 23461debfc3dSmrg } 23471debfc3dSmrg return found; 23481debfc3dSmrg } 23491debfc3dSmrg 23501debfc3dSmrg /* Return if TARGET is cxa_pure_virtual. */ 23511debfc3dSmrg 23521debfc3dSmrg static bool 23531debfc3dSmrg is_cxa_pure_virtual_p (tree target) 23541debfc3dSmrg { 23551debfc3dSmrg return target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE 23561debfc3dSmrg && DECL_NAME (target) 2357a2dc1f3fSmrg && id_equal (DECL_NAME (target), 23581debfc3dSmrg "__cxa_pure_virtual"); 23591debfc3dSmrg } 23601debfc3dSmrg 23611debfc3dSmrg /* If TARGET has associated node, record it in the NODES array. 23621debfc3dSmrg CAN_REFER specify if program can refer to the target directly. 23631debfc3dSmrg if TARGET is unknown (NULL) or it cannot be inserted (for example because 23641debfc3dSmrg its body was already removed and there is no way to refer to it), clear 23651debfc3dSmrg COMPLETEP. */ 23661debfc3dSmrg 23671debfc3dSmrg static void 23681debfc3dSmrg maybe_record_node (vec <cgraph_node *> &nodes, 23691debfc3dSmrg tree target, hash_set<tree> *inserted, 23701debfc3dSmrg bool can_refer, 23711debfc3dSmrg bool *completep) 23721debfc3dSmrg { 23731debfc3dSmrg struct cgraph_node *target_node, *alias_target; 23741debfc3dSmrg enum availability avail; 23751debfc3dSmrg bool pure_virtual = is_cxa_pure_virtual_p (target); 23761debfc3dSmrg 23771debfc3dSmrg /* __builtin_unreachable do not need to be added into 23781debfc3dSmrg list of targets; the runtime effect of calling them is undefined. 23791debfc3dSmrg Only "real" virtual methods should be accounted. */ 23801debfc3dSmrg if (target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE && !pure_virtual) 23811debfc3dSmrg return; 23821debfc3dSmrg 23831debfc3dSmrg if (!can_refer) 23841debfc3dSmrg { 23851debfc3dSmrg /* The only case when method of anonymous namespace becomes unreferable 23861debfc3dSmrg is when we completely optimized it out. */ 23871debfc3dSmrg if (flag_ltrans 23881debfc3dSmrg || !target 23891debfc3dSmrg || !type_in_anonymous_namespace_p (DECL_CONTEXT (target))) 23901debfc3dSmrg *completep = false; 23911debfc3dSmrg return; 23921debfc3dSmrg } 23931debfc3dSmrg 23941debfc3dSmrg if (!target) 23951debfc3dSmrg return; 23961debfc3dSmrg 23971debfc3dSmrg target_node = cgraph_node::get (target); 23981debfc3dSmrg 23991debfc3dSmrg /* Prefer alias target over aliases, so we do not get confused by 24001debfc3dSmrg fake duplicates. */ 24011debfc3dSmrg if (target_node) 24021debfc3dSmrg { 24031debfc3dSmrg alias_target = target_node->ultimate_alias_target (&avail); 24041debfc3dSmrg if (target_node != alias_target 24051debfc3dSmrg && avail >= AVAIL_AVAILABLE 24061debfc3dSmrg && target_node->get_availability ()) 24071debfc3dSmrg target_node = alias_target; 24081debfc3dSmrg } 24091debfc3dSmrg 24101debfc3dSmrg /* Method can only be called by polymorphic call if any 24111debfc3dSmrg of vtables referring to it are alive. 24121debfc3dSmrg 24131debfc3dSmrg While this holds for non-anonymous functions, too, there are 24141debfc3dSmrg cases where we want to keep them in the list; for example 24151debfc3dSmrg inline functions with -fno-weak are static, but we still 24161debfc3dSmrg may devirtualize them when instance comes from other unit. 24171debfc3dSmrg The same holds for LTO. 24181debfc3dSmrg 24191debfc3dSmrg Currently we ignore these functions in speculative devirtualization. 24201debfc3dSmrg ??? Maybe it would make sense to be more aggressive for LTO even 24211debfc3dSmrg elsewhere. */ 24221debfc3dSmrg if (!flag_ltrans 24231debfc3dSmrg && !pure_virtual 24241debfc3dSmrg && type_in_anonymous_namespace_p (DECL_CONTEXT (target)) 24251debfc3dSmrg && (!target_node 24261debfc3dSmrg || !referenced_from_vtable_p (target_node))) 24271debfc3dSmrg ; 24281debfc3dSmrg /* See if TARGET is useful function we can deal with. */ 24291debfc3dSmrg else if (target_node != NULL 24301debfc3dSmrg && (TREE_PUBLIC (target) 24311debfc3dSmrg || DECL_EXTERNAL (target) 24321debfc3dSmrg || target_node->definition) 24331debfc3dSmrg && target_node->real_symbol_p ()) 24341debfc3dSmrg { 2435*8feb0f0bSmrg gcc_assert (!target_node->inlined_to); 24361debfc3dSmrg gcc_assert (target_node->real_symbol_p ()); 24371debfc3dSmrg /* When sanitizing, do not assume that __cxa_pure_virtual is not called 24381debfc3dSmrg by valid program. */ 24391debfc3dSmrg if (flag_sanitize & SANITIZE_UNREACHABLE) 24401debfc3dSmrg ; 24411debfc3dSmrg /* Only add pure virtual if it is the only possible target. This way 24421debfc3dSmrg we will preserve the diagnostics about pure virtual called in many 24431debfc3dSmrg cases without disabling optimization in other. */ 24441debfc3dSmrg else if (pure_virtual) 24451debfc3dSmrg { 24461debfc3dSmrg if (nodes.length ()) 24471debfc3dSmrg return; 24481debfc3dSmrg } 24491debfc3dSmrg /* If we found a real target, take away cxa_pure_virtual. */ 24501debfc3dSmrg else if (!pure_virtual && nodes.length () == 1 24511debfc3dSmrg && is_cxa_pure_virtual_p (nodes[0]->decl)) 24521debfc3dSmrg nodes.pop (); 24531debfc3dSmrg if (pure_virtual && nodes.length ()) 24541debfc3dSmrg return; 24551debfc3dSmrg if (!inserted->add (target)) 24561debfc3dSmrg { 24571debfc3dSmrg cached_polymorphic_call_targets->add (target_node); 24581debfc3dSmrg nodes.safe_push (target_node); 24591debfc3dSmrg } 24601debfc3dSmrg } 24611debfc3dSmrg else if (!completep) 24621debfc3dSmrg ; 24631debfc3dSmrg /* We have definition of __cxa_pure_virtual that is not accessible (it is 24641debfc3dSmrg optimized out or partitioned to other unit) so we cannot add it. When 24651debfc3dSmrg not sanitizing, there is nothing to do. 24661debfc3dSmrg Otherwise declare the list incomplete. */ 24671debfc3dSmrg else if (pure_virtual) 24681debfc3dSmrg { 24691debfc3dSmrg if (flag_sanitize & SANITIZE_UNREACHABLE) 24701debfc3dSmrg *completep = false; 24711debfc3dSmrg } 24721debfc3dSmrg else if (flag_ltrans 24731debfc3dSmrg || !type_in_anonymous_namespace_p (DECL_CONTEXT (target))) 24741debfc3dSmrg *completep = false; 24751debfc3dSmrg } 24761debfc3dSmrg 24771debfc3dSmrg /* See if BINFO's type matches OUTER_TYPE. If so, look up 24781debfc3dSmrg BINFO of subtype of OTR_TYPE at OFFSET and in that BINFO find 24791debfc3dSmrg method in vtable and insert method to NODES array 24801debfc3dSmrg or BASES_TO_CONSIDER if this array is non-NULL. 24811debfc3dSmrg Otherwise recurse to base BINFOs. 24821debfc3dSmrg This matches what get_binfo_at_offset does, but with offset 24831debfc3dSmrg being unknown. 24841debfc3dSmrg 24851debfc3dSmrg TYPE_BINFOS is a stack of BINFOS of types with defined 24861debfc3dSmrg virtual table seen on way from class type to BINFO. 24871debfc3dSmrg 24881debfc3dSmrg MATCHED_VTABLES tracks virtual tables we already did lookup 24891debfc3dSmrg for virtual function in. INSERTED tracks nodes we already 24901debfc3dSmrg inserted. 24911debfc3dSmrg 24921debfc3dSmrg ANONYMOUS is true if BINFO is part of anonymous namespace. 24931debfc3dSmrg 24941debfc3dSmrg Clear COMPLETEP when we hit unreferable target. 24951debfc3dSmrg */ 24961debfc3dSmrg 24971debfc3dSmrg static void 24981debfc3dSmrg record_target_from_binfo (vec <cgraph_node *> &nodes, 24991debfc3dSmrg vec <tree> *bases_to_consider, 25001debfc3dSmrg tree binfo, 25011debfc3dSmrg tree otr_type, 25021debfc3dSmrg vec <tree> &type_binfos, 25031debfc3dSmrg HOST_WIDE_INT otr_token, 25041debfc3dSmrg tree outer_type, 25051debfc3dSmrg HOST_WIDE_INT offset, 25061debfc3dSmrg hash_set<tree> *inserted, 25071debfc3dSmrg hash_set<tree> *matched_vtables, 25081debfc3dSmrg bool anonymous, 25091debfc3dSmrg bool *completep) 25101debfc3dSmrg { 25111debfc3dSmrg tree type = BINFO_TYPE (binfo); 25121debfc3dSmrg int i; 25131debfc3dSmrg tree base_binfo; 25141debfc3dSmrg 25151debfc3dSmrg 25161debfc3dSmrg if (BINFO_VTABLE (binfo)) 25171debfc3dSmrg type_binfos.safe_push (binfo); 25181debfc3dSmrg if (types_same_for_odr (type, outer_type)) 25191debfc3dSmrg { 25201debfc3dSmrg int i; 25211debfc3dSmrg tree type_binfo = NULL; 25221debfc3dSmrg 25231debfc3dSmrg /* Look up BINFO with virtual table. For normal types it is always last 25241debfc3dSmrg binfo on stack. */ 25251debfc3dSmrg for (i = type_binfos.length () - 1; i >= 0; i--) 25261debfc3dSmrg if (BINFO_OFFSET (type_binfos[i]) == BINFO_OFFSET (binfo)) 25271debfc3dSmrg { 25281debfc3dSmrg type_binfo = type_binfos[i]; 25291debfc3dSmrg break; 25301debfc3dSmrg } 25311debfc3dSmrg if (BINFO_VTABLE (binfo)) 25321debfc3dSmrg type_binfos.pop (); 25331debfc3dSmrg /* If this is duplicated BINFO for base shared by virtual inheritance, 25341debfc3dSmrg we may not have its associated vtable. This is not a problem, since 25351debfc3dSmrg we will walk it on the other path. */ 25361debfc3dSmrg if (!type_binfo) 25371debfc3dSmrg return; 25381debfc3dSmrg tree inner_binfo = get_binfo_at_offset (type_binfo, 25391debfc3dSmrg offset, otr_type); 25401debfc3dSmrg if (!inner_binfo) 25411debfc3dSmrg { 25421debfc3dSmrg gcc_assert (odr_violation_reported); 25431debfc3dSmrg return; 25441debfc3dSmrg } 25451debfc3dSmrg /* For types in anonymous namespace first check if the respective vtable 25461debfc3dSmrg is alive. If not, we know the type can't be called. */ 25471debfc3dSmrg if (!flag_ltrans && anonymous) 25481debfc3dSmrg { 25491debfc3dSmrg tree vtable = BINFO_VTABLE (inner_binfo); 25501debfc3dSmrg varpool_node *vnode; 25511debfc3dSmrg 25521debfc3dSmrg if (TREE_CODE (vtable) == POINTER_PLUS_EXPR) 25531debfc3dSmrg vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0); 25541debfc3dSmrg vnode = varpool_node::get (vtable); 25551debfc3dSmrg if (!vnode || !vnode->definition) 25561debfc3dSmrg return; 25571debfc3dSmrg } 25581debfc3dSmrg gcc_assert (inner_binfo); 25591debfc3dSmrg if (bases_to_consider 25601debfc3dSmrg ? !matched_vtables->contains (BINFO_VTABLE (inner_binfo)) 25611debfc3dSmrg : !matched_vtables->add (BINFO_VTABLE (inner_binfo))) 25621debfc3dSmrg { 25631debfc3dSmrg bool can_refer; 25641debfc3dSmrg tree target = gimple_get_virt_method_for_binfo (otr_token, 25651debfc3dSmrg inner_binfo, 25661debfc3dSmrg &can_refer); 25671debfc3dSmrg if (!bases_to_consider) 25681debfc3dSmrg maybe_record_node (nodes, target, inserted, can_refer, completep); 25691debfc3dSmrg /* Destructors are never called via construction vtables. */ 25701debfc3dSmrg else if (!target || !DECL_CXX_DESTRUCTOR_P (target)) 25711debfc3dSmrg bases_to_consider->safe_push (target); 25721debfc3dSmrg } 25731debfc3dSmrg return; 25741debfc3dSmrg } 25751debfc3dSmrg 25761debfc3dSmrg /* Walk bases. */ 25771debfc3dSmrg for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) 25781debfc3dSmrg /* Walking bases that have no virtual method is pointless exercise. */ 25791debfc3dSmrg if (polymorphic_type_binfo_p (base_binfo)) 25801debfc3dSmrg record_target_from_binfo (nodes, bases_to_consider, base_binfo, otr_type, 25811debfc3dSmrg type_binfos, 25821debfc3dSmrg otr_token, outer_type, offset, inserted, 25831debfc3dSmrg matched_vtables, anonymous, completep); 25841debfc3dSmrg if (BINFO_VTABLE (binfo)) 25851debfc3dSmrg type_binfos.pop (); 25861debfc3dSmrg } 25871debfc3dSmrg 25881debfc3dSmrg /* Look up virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN) 25891debfc3dSmrg of TYPE, insert them to NODES, recurse into derived nodes. 25901debfc3dSmrg INSERTED is used to avoid duplicate insertions of methods into NODES. 25911debfc3dSmrg MATCHED_VTABLES are used to avoid duplicate walking vtables. 25921debfc3dSmrg Clear COMPLETEP if unreferable target is found. 25931debfc3dSmrg 25941debfc3dSmrg If CONSIDER_CONSTRUCTION is true, record to BASES_TO_CONSIDER 25951debfc3dSmrg all cases where BASE_SKIPPED is true (because the base is abstract 25961debfc3dSmrg class). */ 25971debfc3dSmrg 25981debfc3dSmrg static void 25991debfc3dSmrg possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes, 26001debfc3dSmrg hash_set<tree> *inserted, 26011debfc3dSmrg hash_set<tree> *matched_vtables, 26021debfc3dSmrg tree otr_type, 26031debfc3dSmrg odr_type type, 26041debfc3dSmrg HOST_WIDE_INT otr_token, 26051debfc3dSmrg tree outer_type, 26061debfc3dSmrg HOST_WIDE_INT offset, 26071debfc3dSmrg bool *completep, 26081debfc3dSmrg vec <tree> &bases_to_consider, 26091debfc3dSmrg bool consider_construction) 26101debfc3dSmrg { 26111debfc3dSmrg tree binfo = TYPE_BINFO (type->type); 26121debfc3dSmrg unsigned int i; 26131debfc3dSmrg auto_vec <tree, 8> type_binfos; 26141debfc3dSmrg bool possibly_instantiated = type_possibly_instantiated_p (type->type); 26151debfc3dSmrg 26161debfc3dSmrg /* We may need to consider types w/o instances because of possible derived 26171debfc3dSmrg types using their methods either directly or via construction vtables. 26181debfc3dSmrg We are safe to skip them when all derivations are known, since we will 26191debfc3dSmrg handle them later. 26201debfc3dSmrg This is done by recording them to BASES_TO_CONSIDER array. */ 26211debfc3dSmrg if (possibly_instantiated || consider_construction) 26221debfc3dSmrg { 26231debfc3dSmrg record_target_from_binfo (nodes, 26241debfc3dSmrg (!possibly_instantiated 26251debfc3dSmrg && type_all_derivations_known_p (type->type)) 26261debfc3dSmrg ? &bases_to_consider : NULL, 26271debfc3dSmrg binfo, otr_type, type_binfos, otr_token, 26281debfc3dSmrg outer_type, offset, 26291debfc3dSmrg inserted, matched_vtables, 26301debfc3dSmrg type->anonymous_namespace, completep); 26311debfc3dSmrg } 26321debfc3dSmrg for (i = 0; i < type->derived_types.length (); i++) 26331debfc3dSmrg possible_polymorphic_call_targets_1 (nodes, inserted, 26341debfc3dSmrg matched_vtables, 26351debfc3dSmrg otr_type, 26361debfc3dSmrg type->derived_types[i], 26371debfc3dSmrg otr_token, outer_type, offset, completep, 26381debfc3dSmrg bases_to_consider, consider_construction); 26391debfc3dSmrg } 26401debfc3dSmrg 26411debfc3dSmrg /* Cache of queries for polymorphic call targets. 26421debfc3dSmrg 26431debfc3dSmrg Enumerating all call targets may get expensive when there are many 26441debfc3dSmrg polymorphic calls in the program, so we memoize all the previous 26451debfc3dSmrg queries and avoid duplicated work. */ 26461debfc3dSmrg 2647*8feb0f0bSmrg class polymorphic_call_target_d 26481debfc3dSmrg { 2649*8feb0f0bSmrg public: 26501debfc3dSmrg HOST_WIDE_INT otr_token; 26511debfc3dSmrg ipa_polymorphic_call_context context; 26521debfc3dSmrg odr_type type; 26531debfc3dSmrg vec <cgraph_node *> targets; 26541debfc3dSmrg tree decl_warning; 26551debfc3dSmrg int type_warning; 2656a2dc1f3fSmrg unsigned int n_odr_types; 26571debfc3dSmrg bool complete; 26581debfc3dSmrg bool speculative; 26591debfc3dSmrg }; 26601debfc3dSmrg 26611debfc3dSmrg /* Polymorphic call target cache helpers. */ 26621debfc3dSmrg 26631debfc3dSmrg struct polymorphic_call_target_hasher 26641debfc3dSmrg : pointer_hash <polymorphic_call_target_d> 26651debfc3dSmrg { 26661debfc3dSmrg static inline hashval_t hash (const polymorphic_call_target_d *); 26671debfc3dSmrg static inline bool equal (const polymorphic_call_target_d *, 26681debfc3dSmrg const polymorphic_call_target_d *); 26691debfc3dSmrg static inline void remove (polymorphic_call_target_d *); 26701debfc3dSmrg }; 26711debfc3dSmrg 26721debfc3dSmrg /* Return the computed hashcode for ODR_QUERY. */ 26731debfc3dSmrg 26741debfc3dSmrg inline hashval_t 26751debfc3dSmrg polymorphic_call_target_hasher::hash (const polymorphic_call_target_d *odr_query) 26761debfc3dSmrg { 26771debfc3dSmrg inchash::hash hstate (odr_query->otr_token); 26781debfc3dSmrg 2679a2dc1f3fSmrg hstate.add_hwi (odr_query->type->id); 26801debfc3dSmrg hstate.merge_hash (TYPE_UID (odr_query->context.outer_type)); 2681a2dc1f3fSmrg hstate.add_hwi (odr_query->context.offset); 2682a2dc1f3fSmrg hstate.add_hwi (odr_query->n_odr_types); 26831debfc3dSmrg 26841debfc3dSmrg if (odr_query->context.speculative_outer_type) 26851debfc3dSmrg { 26861debfc3dSmrg hstate.merge_hash (TYPE_UID (odr_query->context.speculative_outer_type)); 2687a2dc1f3fSmrg hstate.add_hwi (odr_query->context.speculative_offset); 26881debfc3dSmrg } 26891debfc3dSmrg hstate.add_flag (odr_query->speculative); 26901debfc3dSmrg hstate.add_flag (odr_query->context.maybe_in_construction); 26911debfc3dSmrg hstate.add_flag (odr_query->context.maybe_derived_type); 26921debfc3dSmrg hstate.add_flag (odr_query->context.speculative_maybe_derived_type); 26931debfc3dSmrg hstate.commit_flag (); 26941debfc3dSmrg return hstate.end (); 26951debfc3dSmrg } 26961debfc3dSmrg 26971debfc3dSmrg /* Compare cache entries T1 and T2. */ 26981debfc3dSmrg 26991debfc3dSmrg inline bool 27001debfc3dSmrg polymorphic_call_target_hasher::equal (const polymorphic_call_target_d *t1, 27011debfc3dSmrg const polymorphic_call_target_d *t2) 27021debfc3dSmrg { 27031debfc3dSmrg return (t1->type == t2->type && t1->otr_token == t2->otr_token 27041debfc3dSmrg && t1->speculative == t2->speculative 27051debfc3dSmrg && t1->context.offset == t2->context.offset 27061debfc3dSmrg && t1->context.speculative_offset == t2->context.speculative_offset 27071debfc3dSmrg && t1->context.outer_type == t2->context.outer_type 27081debfc3dSmrg && t1->context.speculative_outer_type == t2->context.speculative_outer_type 27091debfc3dSmrg && t1->context.maybe_in_construction 27101debfc3dSmrg == t2->context.maybe_in_construction 27111debfc3dSmrg && t1->context.maybe_derived_type == t2->context.maybe_derived_type 27121debfc3dSmrg && (t1->context.speculative_maybe_derived_type 2713a2dc1f3fSmrg == t2->context.speculative_maybe_derived_type) 2714a2dc1f3fSmrg /* Adding new type may affect outcome of target search. */ 2715a2dc1f3fSmrg && t1->n_odr_types == t2->n_odr_types); 27161debfc3dSmrg } 27171debfc3dSmrg 27181debfc3dSmrg /* Remove entry in polymorphic call target cache hash. */ 27191debfc3dSmrg 27201debfc3dSmrg inline void 27211debfc3dSmrg polymorphic_call_target_hasher::remove (polymorphic_call_target_d *v) 27221debfc3dSmrg { 27231debfc3dSmrg v->targets.release (); 27241debfc3dSmrg free (v); 27251debfc3dSmrg } 27261debfc3dSmrg 27271debfc3dSmrg /* Polymorphic call target query cache. */ 27281debfc3dSmrg 27291debfc3dSmrg typedef hash_table<polymorphic_call_target_hasher> 27301debfc3dSmrg polymorphic_call_target_hash_type; 27311debfc3dSmrg static polymorphic_call_target_hash_type *polymorphic_call_target_hash; 27321debfc3dSmrg 27331debfc3dSmrg /* Destroy polymorphic call target query cache. */ 27341debfc3dSmrg 27351debfc3dSmrg static void 27361debfc3dSmrg free_polymorphic_call_targets_hash () 27371debfc3dSmrg { 27381debfc3dSmrg if (cached_polymorphic_call_targets) 27391debfc3dSmrg { 27401debfc3dSmrg delete polymorphic_call_target_hash; 27411debfc3dSmrg polymorphic_call_target_hash = NULL; 27421debfc3dSmrg delete cached_polymorphic_call_targets; 27431debfc3dSmrg cached_polymorphic_call_targets = NULL; 27441debfc3dSmrg } 27451debfc3dSmrg } 27461debfc3dSmrg 2747a2dc1f3fSmrg /* Force rebuilding type inheritance graph from scratch. 2748a2dc1f3fSmrg This is use to make sure that we do not keep references to types 2749a2dc1f3fSmrg which was not visible to free_lang_data. */ 2750a2dc1f3fSmrg 2751a2dc1f3fSmrg void 2752a2dc1f3fSmrg rebuild_type_inheritance_graph () 2753a2dc1f3fSmrg { 2754a2dc1f3fSmrg if (!odr_hash) 2755a2dc1f3fSmrg return; 2756a2dc1f3fSmrg delete odr_hash; 2757a2dc1f3fSmrg odr_hash = NULL; 2758a2dc1f3fSmrg odr_types_ptr = NULL; 2759a2dc1f3fSmrg free_polymorphic_call_targets_hash (); 2760a2dc1f3fSmrg } 2761a2dc1f3fSmrg 27621debfc3dSmrg /* When virtual function is removed, we may need to flush the cache. */ 27631debfc3dSmrg 27641debfc3dSmrg static void 27651debfc3dSmrg devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED) 27661debfc3dSmrg { 27671debfc3dSmrg if (cached_polymorphic_call_targets 2768*8feb0f0bSmrg && !thunk_expansion 27691debfc3dSmrg && cached_polymorphic_call_targets->contains (n)) 27701debfc3dSmrg free_polymorphic_call_targets_hash (); 27711debfc3dSmrg } 27721debfc3dSmrg 27731debfc3dSmrg /* Look up base of BINFO that has virtual table VTABLE with OFFSET. */ 27741debfc3dSmrg 27751debfc3dSmrg tree 27761debfc3dSmrg subbinfo_with_vtable_at_offset (tree binfo, unsigned HOST_WIDE_INT offset, 27771debfc3dSmrg tree vtable) 27781debfc3dSmrg { 27791debfc3dSmrg tree v = BINFO_VTABLE (binfo); 27801debfc3dSmrg int i; 27811debfc3dSmrg tree base_binfo; 27821debfc3dSmrg unsigned HOST_WIDE_INT this_offset; 27831debfc3dSmrg 27841debfc3dSmrg if (v) 27851debfc3dSmrg { 27861debfc3dSmrg if (!vtable_pointer_value_to_vtable (v, &v, &this_offset)) 27871debfc3dSmrg gcc_unreachable (); 27881debfc3dSmrg 27891debfc3dSmrg if (offset == this_offset 27901debfc3dSmrg && DECL_ASSEMBLER_NAME (v) == DECL_ASSEMBLER_NAME (vtable)) 27911debfc3dSmrg return binfo; 27921debfc3dSmrg } 27931debfc3dSmrg 27941debfc3dSmrg for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) 27951debfc3dSmrg if (polymorphic_type_binfo_p (base_binfo)) 27961debfc3dSmrg { 27971debfc3dSmrg base_binfo = subbinfo_with_vtable_at_offset (base_binfo, offset, vtable); 27981debfc3dSmrg if (base_binfo) 27991debfc3dSmrg return base_binfo; 28001debfc3dSmrg } 28011debfc3dSmrg return NULL; 28021debfc3dSmrg } 28031debfc3dSmrg 28041debfc3dSmrg /* T is known constant value of virtual table pointer. 28051debfc3dSmrg Store virtual table to V and its offset to OFFSET. 28061debfc3dSmrg Return false if T does not look like virtual table reference. */ 28071debfc3dSmrg 28081debfc3dSmrg bool 28091debfc3dSmrg vtable_pointer_value_to_vtable (const_tree t, tree *v, 28101debfc3dSmrg unsigned HOST_WIDE_INT *offset) 28111debfc3dSmrg { 28121debfc3dSmrg /* We expect &MEM[(void *)&virtual_table + 16B]. 28131debfc3dSmrg We obtain object's BINFO from the context of the virtual table. 28141debfc3dSmrg This one contains pointer to virtual table represented via 28151debfc3dSmrg POINTER_PLUS_EXPR. Verify that this pointer matches what 28161debfc3dSmrg we propagated through. 28171debfc3dSmrg 28181debfc3dSmrg In the case of virtual inheritance, the virtual tables may 28191debfc3dSmrg be nested, i.e. the offset may be different from 16 and we may 28201debfc3dSmrg need to dive into the type representation. */ 28211debfc3dSmrg if (TREE_CODE (t) == ADDR_EXPR 28221debfc3dSmrg && TREE_CODE (TREE_OPERAND (t, 0)) == MEM_REF 28231debfc3dSmrg && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) == ADDR_EXPR 28241debfc3dSmrg && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == INTEGER_CST 28251debfc3dSmrg && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 0)) 28261debfc3dSmrg == VAR_DECL) 28271debfc3dSmrg && DECL_VIRTUAL_P (TREE_OPERAND (TREE_OPERAND 28281debfc3dSmrg (TREE_OPERAND (t, 0), 0), 0))) 28291debfc3dSmrg { 28301debfc3dSmrg *v = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 0); 28311debfc3dSmrg *offset = tree_to_uhwi (TREE_OPERAND (TREE_OPERAND (t, 0), 1)); 28321debfc3dSmrg return true; 28331debfc3dSmrg } 28341debfc3dSmrg 28351debfc3dSmrg /* Alternative representation, used by C++ frontend is POINTER_PLUS_EXPR. 28361debfc3dSmrg We need to handle it when T comes from static variable initializer or 28371debfc3dSmrg BINFO. */ 28381debfc3dSmrg if (TREE_CODE (t) == POINTER_PLUS_EXPR) 28391debfc3dSmrg { 28401debfc3dSmrg *offset = tree_to_uhwi (TREE_OPERAND (t, 1)); 28411debfc3dSmrg t = TREE_OPERAND (t, 0); 28421debfc3dSmrg } 28431debfc3dSmrg else 28441debfc3dSmrg *offset = 0; 28451debfc3dSmrg 28461debfc3dSmrg if (TREE_CODE (t) != ADDR_EXPR) 28471debfc3dSmrg return false; 28481debfc3dSmrg *v = TREE_OPERAND (t, 0); 28491debfc3dSmrg return true; 28501debfc3dSmrg } 28511debfc3dSmrg 28521debfc3dSmrg /* T is known constant value of virtual table pointer. Return BINFO of the 28531debfc3dSmrg instance type. */ 28541debfc3dSmrg 28551debfc3dSmrg tree 28561debfc3dSmrg vtable_pointer_value_to_binfo (const_tree t) 28571debfc3dSmrg { 28581debfc3dSmrg tree vtable; 28591debfc3dSmrg unsigned HOST_WIDE_INT offset; 28601debfc3dSmrg 28611debfc3dSmrg if (!vtable_pointer_value_to_vtable (t, &vtable, &offset)) 28621debfc3dSmrg return NULL_TREE; 28631debfc3dSmrg 28641debfc3dSmrg /* FIXME: for stores of construction vtables we return NULL, 28651debfc3dSmrg because we do not have BINFO for those. Eventually we should fix 28661debfc3dSmrg our representation to allow this case to be handled, too. 28671debfc3dSmrg In the case we see store of BINFO we however may assume 28681debfc3dSmrg that standard folding will be able to cope with it. */ 28691debfc3dSmrg return subbinfo_with_vtable_at_offset (TYPE_BINFO (DECL_CONTEXT (vtable)), 28701debfc3dSmrg offset, vtable); 28711debfc3dSmrg } 28721debfc3dSmrg 28731debfc3dSmrg /* Walk bases of OUTER_TYPE that contain OTR_TYPE at OFFSET. 28741debfc3dSmrg Look up their respective virtual methods for OTR_TOKEN and OTR_TYPE 28751debfc3dSmrg and insert them in NODES. 28761debfc3dSmrg 28771debfc3dSmrg MATCHED_VTABLES and INSERTED is used to avoid duplicated work. */ 28781debfc3dSmrg 28791debfc3dSmrg static void 28801debfc3dSmrg record_targets_from_bases (tree otr_type, 28811debfc3dSmrg HOST_WIDE_INT otr_token, 28821debfc3dSmrg tree outer_type, 28831debfc3dSmrg HOST_WIDE_INT offset, 28841debfc3dSmrg vec <cgraph_node *> &nodes, 28851debfc3dSmrg hash_set<tree> *inserted, 28861debfc3dSmrg hash_set<tree> *matched_vtables, 28871debfc3dSmrg bool *completep) 28881debfc3dSmrg { 28891debfc3dSmrg while (true) 28901debfc3dSmrg { 28911debfc3dSmrg HOST_WIDE_INT pos, size; 28921debfc3dSmrg tree base_binfo; 28931debfc3dSmrg tree fld; 28941debfc3dSmrg 28951debfc3dSmrg if (types_same_for_odr (outer_type, otr_type)) 28961debfc3dSmrg return; 28971debfc3dSmrg 28981debfc3dSmrg for (fld = TYPE_FIELDS (outer_type); fld; fld = DECL_CHAIN (fld)) 28991debfc3dSmrg { 29001debfc3dSmrg if (TREE_CODE (fld) != FIELD_DECL) 29011debfc3dSmrg continue; 29021debfc3dSmrg 29031debfc3dSmrg pos = int_bit_position (fld); 29041debfc3dSmrg size = tree_to_shwi (DECL_SIZE (fld)); 29051debfc3dSmrg if (pos <= offset && (pos + size) > offset 29061debfc3dSmrg /* Do not get confused by zero sized bases. */ 29071debfc3dSmrg && polymorphic_type_binfo_p (TYPE_BINFO (TREE_TYPE (fld)))) 29081debfc3dSmrg break; 29091debfc3dSmrg } 29101debfc3dSmrg /* Within a class type we should always find corresponding fields. */ 29111debfc3dSmrg gcc_assert (fld && TREE_CODE (TREE_TYPE (fld)) == RECORD_TYPE); 29121debfc3dSmrg 29131debfc3dSmrg /* Nonbase types should have been stripped by outer_class_type. */ 29141debfc3dSmrg gcc_assert (DECL_ARTIFICIAL (fld)); 29151debfc3dSmrg 29161debfc3dSmrg outer_type = TREE_TYPE (fld); 29171debfc3dSmrg offset -= pos; 29181debfc3dSmrg 29191debfc3dSmrg base_binfo = get_binfo_at_offset (TYPE_BINFO (outer_type), 29201debfc3dSmrg offset, otr_type); 29211debfc3dSmrg if (!base_binfo) 29221debfc3dSmrg { 29231debfc3dSmrg gcc_assert (odr_violation_reported); 29241debfc3dSmrg return; 29251debfc3dSmrg } 29261debfc3dSmrg gcc_assert (base_binfo); 29271debfc3dSmrg if (!matched_vtables->add (BINFO_VTABLE (base_binfo))) 29281debfc3dSmrg { 29291debfc3dSmrg bool can_refer; 29301debfc3dSmrg tree target = gimple_get_virt_method_for_binfo (otr_token, 29311debfc3dSmrg base_binfo, 29321debfc3dSmrg &can_refer); 29331debfc3dSmrg if (!target || ! DECL_CXX_DESTRUCTOR_P (target)) 29341debfc3dSmrg maybe_record_node (nodes, target, inserted, can_refer, completep); 29351debfc3dSmrg matched_vtables->add (BINFO_VTABLE (base_binfo)); 29361debfc3dSmrg } 29371debfc3dSmrg } 29381debfc3dSmrg } 29391debfc3dSmrg 29401debfc3dSmrg /* When virtual table is removed, we may need to flush the cache. */ 29411debfc3dSmrg 29421debfc3dSmrg static void 29431debfc3dSmrg devirt_variable_node_removal_hook (varpool_node *n, 29441debfc3dSmrg void *d ATTRIBUTE_UNUSED) 29451debfc3dSmrg { 29461debfc3dSmrg if (cached_polymorphic_call_targets 29471debfc3dSmrg && DECL_VIRTUAL_P (n->decl) 29481debfc3dSmrg && type_in_anonymous_namespace_p (DECL_CONTEXT (n->decl))) 29491debfc3dSmrg free_polymorphic_call_targets_hash (); 29501debfc3dSmrg } 29511debfc3dSmrg 29521debfc3dSmrg /* Record about how many calls would benefit from given type to be final. */ 29531debfc3dSmrg 29541debfc3dSmrg struct odr_type_warn_count 29551debfc3dSmrg { 29561debfc3dSmrg tree type; 29571debfc3dSmrg int count; 2958a2dc1f3fSmrg profile_count dyn_count; 29591debfc3dSmrg }; 29601debfc3dSmrg 29611debfc3dSmrg /* Record about how many calls would benefit from given method to be final. */ 29621debfc3dSmrg 29631debfc3dSmrg struct decl_warn_count 29641debfc3dSmrg { 29651debfc3dSmrg tree decl; 29661debfc3dSmrg int count; 2967a2dc1f3fSmrg profile_count dyn_count; 29681debfc3dSmrg }; 29691debfc3dSmrg 29701debfc3dSmrg /* Information about type and decl warnings. */ 29711debfc3dSmrg 2972*8feb0f0bSmrg class final_warning_record 29731debfc3dSmrg { 2974*8feb0f0bSmrg public: 2975a2dc1f3fSmrg /* If needed grow type_warnings vector and initialize new decl_warn_count 2976a2dc1f3fSmrg to have dyn_count set to profile_count::zero (). */ 2977a2dc1f3fSmrg void grow_type_warnings (unsigned newlen); 2978a2dc1f3fSmrg 2979a2dc1f3fSmrg profile_count dyn_count; 29801debfc3dSmrg auto_vec<odr_type_warn_count> type_warnings; 29811debfc3dSmrg hash_map<tree, decl_warn_count> decl_warnings; 29821debfc3dSmrg }; 2983a2dc1f3fSmrg 2984a2dc1f3fSmrg void 2985a2dc1f3fSmrg final_warning_record::grow_type_warnings (unsigned newlen) 2986a2dc1f3fSmrg { 2987a2dc1f3fSmrg unsigned len = type_warnings.length (); 2988a2dc1f3fSmrg if (newlen > len) 2989a2dc1f3fSmrg { 2990a2dc1f3fSmrg type_warnings.safe_grow_cleared (newlen); 2991a2dc1f3fSmrg for (unsigned i = len; i < newlen; i++) 2992a2dc1f3fSmrg type_warnings[i].dyn_count = profile_count::zero (); 2993a2dc1f3fSmrg } 2994a2dc1f3fSmrg } 2995a2dc1f3fSmrg 2996*8feb0f0bSmrg class final_warning_record *final_warning_records; 29971debfc3dSmrg 29981debfc3dSmrg /* Return vector containing possible targets of polymorphic call of type 29991debfc3dSmrg OTR_TYPE calling method OTR_TOKEN within type of OTR_OUTER_TYPE and OFFSET. 30001debfc3dSmrg If INCLUDE_BASES is true, walk also base types of OUTER_TYPES containing 30011debfc3dSmrg OTR_TYPE and include their virtual method. This is useful for types 30021debfc3dSmrg possibly in construction or destruction where the virtual table may 3003*8feb0f0bSmrg temporarily change to one of base types. INCLUDE_DERIVED_TYPES make 30041debfc3dSmrg us to walk the inheritance graph for all derivations. 30051debfc3dSmrg 30061debfc3dSmrg If COMPLETEP is non-NULL, store true if the list is complete. 30071debfc3dSmrg CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry 30081debfc3dSmrg in the target cache. If user needs to visit every target list 30091debfc3dSmrg just once, it can memoize them. 30101debfc3dSmrg 30111debfc3dSmrg If SPECULATIVE is set, the list will not contain targets that 30121debfc3dSmrg are not speculatively taken. 30131debfc3dSmrg 30141debfc3dSmrg Returned vector is placed into cache. It is NOT caller's responsibility 30151debfc3dSmrg to free it. The vector can be freed on cgraph_remove_node call if 30161debfc3dSmrg the particular node is a virtual function present in the cache. */ 30171debfc3dSmrg 30181debfc3dSmrg vec <cgraph_node *> 30191debfc3dSmrg possible_polymorphic_call_targets (tree otr_type, 30201debfc3dSmrg HOST_WIDE_INT otr_token, 30211debfc3dSmrg ipa_polymorphic_call_context context, 30221debfc3dSmrg bool *completep, 30231debfc3dSmrg void **cache_token, 30241debfc3dSmrg bool speculative) 30251debfc3dSmrg { 30261debfc3dSmrg static struct cgraph_node_hook_list *node_removal_hook_holder; 30271debfc3dSmrg vec <cgraph_node *> nodes = vNULL; 30281debfc3dSmrg auto_vec <tree, 8> bases_to_consider; 30291debfc3dSmrg odr_type type, outer_type; 30301debfc3dSmrg polymorphic_call_target_d key; 30311debfc3dSmrg polymorphic_call_target_d **slot; 30321debfc3dSmrg unsigned int i; 30331debfc3dSmrg tree binfo, target; 30341debfc3dSmrg bool complete; 30351debfc3dSmrg bool can_refer = false; 30361debfc3dSmrg bool skipped = false; 30371debfc3dSmrg 30381debfc3dSmrg otr_type = TYPE_MAIN_VARIANT (otr_type); 30391debfc3dSmrg 30401debfc3dSmrg /* If ODR is not initialized or the context is invalid, return empty 30411debfc3dSmrg incomplete list. */ 30421debfc3dSmrg if (!odr_hash || context.invalid || !TYPE_BINFO (otr_type)) 30431debfc3dSmrg { 30441debfc3dSmrg if (completep) 30451debfc3dSmrg *completep = context.invalid; 30461debfc3dSmrg if (cache_token) 30471debfc3dSmrg *cache_token = NULL; 30481debfc3dSmrg return nodes; 30491debfc3dSmrg } 30501debfc3dSmrg 30511debfc3dSmrg /* Do not bother to compute speculative info when user do not asks for it. */ 30521debfc3dSmrg if (!speculative || !context.speculative_outer_type) 30531debfc3dSmrg context.clear_speculation (); 30541debfc3dSmrg 30551debfc3dSmrg type = get_odr_type (otr_type, true); 30561debfc3dSmrg 30571debfc3dSmrg /* Recording type variants would waste results cache. */ 30581debfc3dSmrg gcc_assert (!context.outer_type 30591debfc3dSmrg || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type); 30601debfc3dSmrg 30611debfc3dSmrg /* Look up the outer class type we want to walk. 30621debfc3dSmrg If we fail to do so, the context is invalid. */ 30631debfc3dSmrg if ((context.outer_type || context.speculative_outer_type) 30641debfc3dSmrg && !context.restrict_to_inner_class (otr_type)) 30651debfc3dSmrg { 30661debfc3dSmrg if (completep) 30671debfc3dSmrg *completep = true; 30681debfc3dSmrg if (cache_token) 30691debfc3dSmrg *cache_token = NULL; 30701debfc3dSmrg return nodes; 30711debfc3dSmrg } 30721debfc3dSmrg gcc_assert (!context.invalid); 30731debfc3dSmrg 30741debfc3dSmrg /* Check that restrict_to_inner_class kept the main variant. */ 30751debfc3dSmrg gcc_assert (!context.outer_type 30761debfc3dSmrg || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type); 30771debfc3dSmrg 30781debfc3dSmrg /* We canonicalize our query, so we do not need extra hashtable entries. */ 30791debfc3dSmrg 30801debfc3dSmrg /* Without outer type, we have no use for offset. Just do the 30811debfc3dSmrg basic search from inner type. */ 30821debfc3dSmrg if (!context.outer_type) 30831debfc3dSmrg context.clear_outer_type (otr_type); 30841debfc3dSmrg /* We need to update our hierarchy if the type does not exist. */ 30851debfc3dSmrg outer_type = get_odr_type (context.outer_type, true); 30861debfc3dSmrg /* If the type is complete, there are no derivations. */ 30871debfc3dSmrg if (TYPE_FINAL_P (outer_type->type)) 30881debfc3dSmrg context.maybe_derived_type = false; 30891debfc3dSmrg 30901debfc3dSmrg /* Initialize query cache. */ 30911debfc3dSmrg if (!cached_polymorphic_call_targets) 30921debfc3dSmrg { 30931debfc3dSmrg cached_polymorphic_call_targets = new hash_set<cgraph_node *>; 30941debfc3dSmrg polymorphic_call_target_hash 30951debfc3dSmrg = new polymorphic_call_target_hash_type (23); 30961debfc3dSmrg if (!node_removal_hook_holder) 30971debfc3dSmrg { 30981debfc3dSmrg node_removal_hook_holder = 30991debfc3dSmrg symtab->add_cgraph_removal_hook (&devirt_node_removal_hook, NULL); 31001debfc3dSmrg symtab->add_varpool_removal_hook (&devirt_variable_node_removal_hook, 31011debfc3dSmrg NULL); 31021debfc3dSmrg } 31031debfc3dSmrg } 31041debfc3dSmrg 31051debfc3dSmrg if (in_lto_p) 31061debfc3dSmrg { 31071debfc3dSmrg if (context.outer_type != otr_type) 31081debfc3dSmrg context.outer_type 31091debfc3dSmrg = get_odr_type (context.outer_type, true)->type; 31101debfc3dSmrg if (context.speculative_outer_type) 31111debfc3dSmrg context.speculative_outer_type 31121debfc3dSmrg = get_odr_type (context.speculative_outer_type, true)->type; 31131debfc3dSmrg } 31141debfc3dSmrg 31151debfc3dSmrg /* Look up cached answer. */ 31161debfc3dSmrg key.type = type; 31171debfc3dSmrg key.otr_token = otr_token; 31181debfc3dSmrg key.speculative = speculative; 31191debfc3dSmrg key.context = context; 3120a2dc1f3fSmrg key.n_odr_types = odr_types.length (); 31211debfc3dSmrg slot = polymorphic_call_target_hash->find_slot (&key, INSERT); 31221debfc3dSmrg if (cache_token) 31231debfc3dSmrg *cache_token = (void *)*slot; 31241debfc3dSmrg if (*slot) 31251debfc3dSmrg { 31261debfc3dSmrg if (completep) 31271debfc3dSmrg *completep = (*slot)->complete; 31281debfc3dSmrg if ((*slot)->type_warning && final_warning_records) 31291debfc3dSmrg { 31301debfc3dSmrg final_warning_records->type_warnings[(*slot)->type_warning - 1].count++; 3131a2dc1f3fSmrg if (!final_warning_records->type_warnings 3132a2dc1f3fSmrg [(*slot)->type_warning - 1].dyn_count.initialized_p ()) 3133a2dc1f3fSmrg final_warning_records->type_warnings 3134a2dc1f3fSmrg [(*slot)->type_warning - 1].dyn_count = profile_count::zero (); 3135a2dc1f3fSmrg if (final_warning_records->dyn_count > 0) 31361debfc3dSmrg final_warning_records->type_warnings[(*slot)->type_warning - 1].dyn_count 3137a2dc1f3fSmrg = final_warning_records->type_warnings[(*slot)->type_warning - 1].dyn_count 3138a2dc1f3fSmrg + final_warning_records->dyn_count; 31391debfc3dSmrg } 31401debfc3dSmrg if (!speculative && (*slot)->decl_warning && final_warning_records) 31411debfc3dSmrg { 31421debfc3dSmrg struct decl_warn_count *c = 31431debfc3dSmrg final_warning_records->decl_warnings.get ((*slot)->decl_warning); 31441debfc3dSmrg c->count++; 3145a2dc1f3fSmrg if (final_warning_records->dyn_count > 0) 31461debfc3dSmrg c->dyn_count += final_warning_records->dyn_count; 31471debfc3dSmrg } 31481debfc3dSmrg return (*slot)->targets; 31491debfc3dSmrg } 31501debfc3dSmrg 31511debfc3dSmrg complete = true; 31521debfc3dSmrg 31531debfc3dSmrg /* Do actual search. */ 31541debfc3dSmrg timevar_push (TV_IPA_VIRTUAL_CALL); 31551debfc3dSmrg *slot = XCNEW (polymorphic_call_target_d); 31561debfc3dSmrg if (cache_token) 31571debfc3dSmrg *cache_token = (void *)*slot; 31581debfc3dSmrg (*slot)->type = type; 31591debfc3dSmrg (*slot)->otr_token = otr_token; 31601debfc3dSmrg (*slot)->context = context; 31611debfc3dSmrg (*slot)->speculative = speculative; 31621debfc3dSmrg 31631debfc3dSmrg hash_set<tree> inserted; 31641debfc3dSmrg hash_set<tree> matched_vtables; 31651debfc3dSmrg 31661debfc3dSmrg /* First insert targets we speculatively identified as likely. */ 31671debfc3dSmrg if (context.speculative_outer_type) 31681debfc3dSmrg { 31691debfc3dSmrg odr_type speculative_outer_type; 31701debfc3dSmrg bool speculation_complete = true; 31711debfc3dSmrg 31721debfc3dSmrg /* First insert target from type itself and check if it may have 31731debfc3dSmrg derived types. */ 31741debfc3dSmrg speculative_outer_type = get_odr_type (context.speculative_outer_type, true); 31751debfc3dSmrg if (TYPE_FINAL_P (speculative_outer_type->type)) 31761debfc3dSmrg context.speculative_maybe_derived_type = false; 31771debfc3dSmrg binfo = get_binfo_at_offset (TYPE_BINFO (speculative_outer_type->type), 31781debfc3dSmrg context.speculative_offset, otr_type); 31791debfc3dSmrg if (binfo) 31801debfc3dSmrg target = gimple_get_virt_method_for_binfo (otr_token, binfo, 31811debfc3dSmrg &can_refer); 31821debfc3dSmrg else 31831debfc3dSmrg target = NULL; 31841debfc3dSmrg 31851debfc3dSmrg /* In the case we get complete method, we don't need 31861debfc3dSmrg to walk derivations. */ 31871debfc3dSmrg if (target && DECL_FINAL_P (target)) 31881debfc3dSmrg context.speculative_maybe_derived_type = false; 31891debfc3dSmrg if (type_possibly_instantiated_p (speculative_outer_type->type)) 31901debfc3dSmrg maybe_record_node (nodes, target, &inserted, can_refer, &speculation_complete); 31911debfc3dSmrg if (binfo) 31921debfc3dSmrg matched_vtables.add (BINFO_VTABLE (binfo)); 31931debfc3dSmrg 31941debfc3dSmrg 31951debfc3dSmrg /* Next walk recursively all derived types. */ 31961debfc3dSmrg if (context.speculative_maybe_derived_type) 31971debfc3dSmrg for (i = 0; i < speculative_outer_type->derived_types.length(); i++) 31981debfc3dSmrg possible_polymorphic_call_targets_1 (nodes, &inserted, 31991debfc3dSmrg &matched_vtables, 32001debfc3dSmrg otr_type, 32011debfc3dSmrg speculative_outer_type->derived_types[i], 32021debfc3dSmrg otr_token, speculative_outer_type->type, 32031debfc3dSmrg context.speculative_offset, 32041debfc3dSmrg &speculation_complete, 32051debfc3dSmrg bases_to_consider, 32061debfc3dSmrg false); 32071debfc3dSmrg } 32081debfc3dSmrg 32091debfc3dSmrg if (!speculative || !nodes.length ()) 32101debfc3dSmrg { 32111debfc3dSmrg /* First see virtual method of type itself. */ 32121debfc3dSmrg binfo = get_binfo_at_offset (TYPE_BINFO (outer_type->type), 32131debfc3dSmrg context.offset, otr_type); 32141debfc3dSmrg if (binfo) 32151debfc3dSmrg target = gimple_get_virt_method_for_binfo (otr_token, binfo, 32161debfc3dSmrg &can_refer); 32171debfc3dSmrg else 32181debfc3dSmrg { 32191debfc3dSmrg gcc_assert (odr_violation_reported); 32201debfc3dSmrg target = NULL; 32211debfc3dSmrg } 32221debfc3dSmrg 32231debfc3dSmrg /* Destructors are never called through construction virtual tables, 32241debfc3dSmrg because the type is always known. */ 32251debfc3dSmrg if (target && DECL_CXX_DESTRUCTOR_P (target)) 32261debfc3dSmrg context.maybe_in_construction = false; 32271debfc3dSmrg 32281debfc3dSmrg if (target) 32291debfc3dSmrg { 32301debfc3dSmrg /* In the case we get complete method, we don't need 32311debfc3dSmrg to walk derivations. */ 32321debfc3dSmrg if (DECL_FINAL_P (target)) 32331debfc3dSmrg context.maybe_derived_type = false; 32341debfc3dSmrg } 32351debfc3dSmrg 32361debfc3dSmrg /* If OUTER_TYPE is abstract, we know we are not seeing its instance. */ 32371debfc3dSmrg if (type_possibly_instantiated_p (outer_type->type)) 32381debfc3dSmrg maybe_record_node (nodes, target, &inserted, can_refer, &complete); 32391debfc3dSmrg else 32401debfc3dSmrg skipped = true; 32411debfc3dSmrg 32421debfc3dSmrg if (binfo) 32431debfc3dSmrg matched_vtables.add (BINFO_VTABLE (binfo)); 32441debfc3dSmrg 32451debfc3dSmrg /* Next walk recursively all derived types. */ 32461debfc3dSmrg if (context.maybe_derived_type) 32471debfc3dSmrg { 32481debfc3dSmrg for (i = 0; i < outer_type->derived_types.length(); i++) 32491debfc3dSmrg possible_polymorphic_call_targets_1 (nodes, &inserted, 32501debfc3dSmrg &matched_vtables, 32511debfc3dSmrg otr_type, 32521debfc3dSmrg outer_type->derived_types[i], 32531debfc3dSmrg otr_token, outer_type->type, 32541debfc3dSmrg context.offset, &complete, 32551debfc3dSmrg bases_to_consider, 32561debfc3dSmrg context.maybe_in_construction); 32571debfc3dSmrg 32581debfc3dSmrg if (!outer_type->all_derivations_known) 32591debfc3dSmrg { 32601debfc3dSmrg if (!speculative && final_warning_records 32611debfc3dSmrg && nodes.length () == 1 32621debfc3dSmrg && TREE_CODE (TREE_TYPE (nodes[0]->decl)) == METHOD_TYPE) 32631debfc3dSmrg { 32641debfc3dSmrg if (complete 32651debfc3dSmrg && warn_suggest_final_types 32661debfc3dSmrg && !outer_type->derived_types.length ()) 32671debfc3dSmrg { 3268a2dc1f3fSmrg final_warning_records->grow_type_warnings 3269a2dc1f3fSmrg (outer_type->id); 32701debfc3dSmrg final_warning_records->type_warnings[outer_type->id].count++; 3271a2dc1f3fSmrg if (!final_warning_records->type_warnings 3272a2dc1f3fSmrg [outer_type->id].dyn_count.initialized_p ()) 3273a2dc1f3fSmrg final_warning_records->type_warnings 3274a2dc1f3fSmrg [outer_type->id].dyn_count = profile_count::zero (); 32751debfc3dSmrg final_warning_records->type_warnings[outer_type->id].dyn_count 32761debfc3dSmrg += final_warning_records->dyn_count; 32771debfc3dSmrg final_warning_records->type_warnings[outer_type->id].type 32781debfc3dSmrg = outer_type->type; 32791debfc3dSmrg (*slot)->type_warning = outer_type->id + 1; 32801debfc3dSmrg } 32811debfc3dSmrg if (complete 32821debfc3dSmrg && warn_suggest_final_methods 32831debfc3dSmrg && types_same_for_odr (DECL_CONTEXT (nodes[0]->decl), 32841debfc3dSmrg outer_type->type)) 32851debfc3dSmrg { 32861debfc3dSmrg bool existed; 32871debfc3dSmrg struct decl_warn_count &c = 32881debfc3dSmrg final_warning_records->decl_warnings.get_or_insert 32891debfc3dSmrg (nodes[0]->decl, &existed); 32901debfc3dSmrg 32911debfc3dSmrg if (existed) 32921debfc3dSmrg { 32931debfc3dSmrg c.count++; 32941debfc3dSmrg c.dyn_count += final_warning_records->dyn_count; 32951debfc3dSmrg } 32961debfc3dSmrg else 32971debfc3dSmrg { 32981debfc3dSmrg c.count = 1; 32991debfc3dSmrg c.dyn_count = final_warning_records->dyn_count; 33001debfc3dSmrg c.decl = nodes[0]->decl; 33011debfc3dSmrg } 33021debfc3dSmrg (*slot)->decl_warning = nodes[0]->decl; 33031debfc3dSmrg } 33041debfc3dSmrg } 33051debfc3dSmrg complete = false; 33061debfc3dSmrg } 33071debfc3dSmrg } 33081debfc3dSmrg 33091debfc3dSmrg if (!speculative) 33101debfc3dSmrg { 33111debfc3dSmrg /* Destructors are never called through construction virtual tables, 33121debfc3dSmrg because the type is always known. One of entries may be 33131debfc3dSmrg cxa_pure_virtual so look to at least two of them. */ 33141debfc3dSmrg if (context.maybe_in_construction) 33151debfc3dSmrg for (i =0 ; i < MIN (nodes.length (), 2); i++) 33161debfc3dSmrg if (DECL_CXX_DESTRUCTOR_P (nodes[i]->decl)) 33171debfc3dSmrg context.maybe_in_construction = false; 33181debfc3dSmrg if (context.maybe_in_construction) 33191debfc3dSmrg { 33201debfc3dSmrg if (type != outer_type 33211debfc3dSmrg && (!skipped 33221debfc3dSmrg || (context.maybe_derived_type 33231debfc3dSmrg && !type_all_derivations_known_p (outer_type->type)))) 33241debfc3dSmrg record_targets_from_bases (otr_type, otr_token, outer_type->type, 33251debfc3dSmrg context.offset, nodes, &inserted, 33261debfc3dSmrg &matched_vtables, &complete); 33271debfc3dSmrg if (skipped) 33281debfc3dSmrg maybe_record_node (nodes, target, &inserted, can_refer, &complete); 33291debfc3dSmrg for (i = 0; i < bases_to_consider.length(); i++) 33301debfc3dSmrg maybe_record_node (nodes, bases_to_consider[i], &inserted, can_refer, &complete); 33311debfc3dSmrg } 33321debfc3dSmrg } 33331debfc3dSmrg } 33341debfc3dSmrg 33351debfc3dSmrg (*slot)->targets = nodes; 33361debfc3dSmrg (*slot)->complete = complete; 3337a2dc1f3fSmrg (*slot)->n_odr_types = odr_types.length (); 33381debfc3dSmrg if (completep) 33391debfc3dSmrg *completep = complete; 33401debfc3dSmrg 33411debfc3dSmrg timevar_pop (TV_IPA_VIRTUAL_CALL); 33421debfc3dSmrg return nodes; 33431debfc3dSmrg } 33441debfc3dSmrg 33451debfc3dSmrg bool 33461debfc3dSmrg add_decl_warning (const tree &key ATTRIBUTE_UNUSED, const decl_warn_count &value, 33471debfc3dSmrg vec<const decl_warn_count*> *vec) 33481debfc3dSmrg { 33491debfc3dSmrg vec->safe_push (&value); 33501debfc3dSmrg return true; 33511debfc3dSmrg } 33521debfc3dSmrg 33531debfc3dSmrg /* Dump target list TARGETS into FILE. */ 33541debfc3dSmrg 33551debfc3dSmrg static void 3356c0a68be4Smrg dump_targets (FILE *f, vec <cgraph_node *> targets, bool verbose) 33571debfc3dSmrg { 33581debfc3dSmrg unsigned int i; 33591debfc3dSmrg 33601debfc3dSmrg for (i = 0; i < targets.length (); i++) 33611debfc3dSmrg { 33621debfc3dSmrg char *name = NULL; 33631debfc3dSmrg if (in_lto_p) 33641debfc3dSmrg name = cplus_demangle_v3 (targets[i]->asm_name (), 0); 3365*8feb0f0bSmrg fprintf (f, " %s", name ? name : targets[i]->dump_name ()); 33661debfc3dSmrg if (in_lto_p) 33671debfc3dSmrg free (name); 33681debfc3dSmrg if (!targets[i]->definition) 33691debfc3dSmrg fprintf (f, " (no definition%s)", 33701debfc3dSmrg DECL_DECLARED_INLINE_P (targets[i]->decl) 33711debfc3dSmrg ? " inline" : ""); 3372c0a68be4Smrg /* With many targets for every call polymorphic dumps are going to 3373c0a68be4Smrg be quadratic in size. */ 3374c0a68be4Smrg if (i > 10 && !verbose) 3375c0a68be4Smrg { 3376c0a68be4Smrg fprintf (f, " ... and %i more targets\n", targets.length () - i); 3377c0a68be4Smrg return; 3378c0a68be4Smrg } 33791debfc3dSmrg } 33801debfc3dSmrg fprintf (f, "\n"); 33811debfc3dSmrg } 33821debfc3dSmrg 33831debfc3dSmrg /* Dump all possible targets of a polymorphic call. */ 33841debfc3dSmrg 33851debfc3dSmrg void 33861debfc3dSmrg dump_possible_polymorphic_call_targets (FILE *f, 33871debfc3dSmrg tree otr_type, 33881debfc3dSmrg HOST_WIDE_INT otr_token, 3389c0a68be4Smrg const ipa_polymorphic_call_context &ctx, 3390c0a68be4Smrg bool verbose) 33911debfc3dSmrg { 33921debfc3dSmrg vec <cgraph_node *> targets; 33931debfc3dSmrg bool final; 33941debfc3dSmrg odr_type type = get_odr_type (TYPE_MAIN_VARIANT (otr_type), false); 33951debfc3dSmrg unsigned int len; 33961debfc3dSmrg 33971debfc3dSmrg if (!type) 33981debfc3dSmrg return; 33991debfc3dSmrg targets = possible_polymorphic_call_targets (otr_type, otr_token, 34001debfc3dSmrg ctx, 34011debfc3dSmrg &final, NULL, false); 34021debfc3dSmrg fprintf (f, " Targets of polymorphic call of type %i:", type->id); 34031debfc3dSmrg print_generic_expr (f, type->type, TDF_SLIM); 34041debfc3dSmrg fprintf (f, " token %i\n", (int)otr_token); 34051debfc3dSmrg 34061debfc3dSmrg ctx.dump (f); 34071debfc3dSmrg 34081debfc3dSmrg fprintf (f, " %s%s%s%s\n ", 34091debfc3dSmrg final ? "This is a complete list." : 34101debfc3dSmrg "This is partial list; extra targets may be defined in other units.", 34111debfc3dSmrg ctx.maybe_in_construction ? " (base types included)" : "", 34121debfc3dSmrg ctx.maybe_derived_type ? " (derived types included)" : "", 34131debfc3dSmrg ctx.speculative_maybe_derived_type ? " (speculative derived types included)" : ""); 34141debfc3dSmrg len = targets.length (); 3415c0a68be4Smrg dump_targets (f, targets, verbose); 34161debfc3dSmrg 34171debfc3dSmrg targets = possible_polymorphic_call_targets (otr_type, otr_token, 34181debfc3dSmrg ctx, 34191debfc3dSmrg &final, NULL, true); 34201debfc3dSmrg if (targets.length () != len) 34211debfc3dSmrg { 34221debfc3dSmrg fprintf (f, " Speculative targets:"); 3423c0a68be4Smrg dump_targets (f, targets, verbose); 34241debfc3dSmrg } 34251debfc3dSmrg /* Ugly: during callgraph construction the target cache may get populated 34261debfc3dSmrg before all targets are found. While this is harmless (because all local 34271debfc3dSmrg types are discovered and only in those case we devirtualize fully and we 34281debfc3dSmrg don't do speculative devirtualization before IPA stage) it triggers 34291debfc3dSmrg assert here when dumping at that stage also populates the case with 34301debfc3dSmrg speculative targets. Quietly ignore this. */ 34311debfc3dSmrg gcc_assert (symtab->state < IPA_SSA || targets.length () <= len); 34321debfc3dSmrg fprintf (f, "\n"); 34331debfc3dSmrg } 34341debfc3dSmrg 34351debfc3dSmrg 34361debfc3dSmrg /* Return true if N can be possibly target of a polymorphic call of 34371debfc3dSmrg OTR_TYPE/OTR_TOKEN. */ 34381debfc3dSmrg 34391debfc3dSmrg bool 34401debfc3dSmrg possible_polymorphic_call_target_p (tree otr_type, 34411debfc3dSmrg HOST_WIDE_INT otr_token, 34421debfc3dSmrg const ipa_polymorphic_call_context &ctx, 34431debfc3dSmrg struct cgraph_node *n) 34441debfc3dSmrg { 34451debfc3dSmrg vec <cgraph_node *> targets; 34461debfc3dSmrg unsigned int i; 34471debfc3dSmrg bool final; 34481debfc3dSmrg 3449*8feb0f0bSmrg if (fndecl_built_in_p (n->decl, BUILT_IN_UNREACHABLE) 3450*8feb0f0bSmrg || fndecl_built_in_p (n->decl, BUILT_IN_TRAP)) 34511debfc3dSmrg return true; 34521debfc3dSmrg 34531debfc3dSmrg if (is_cxa_pure_virtual_p (n->decl)) 34541debfc3dSmrg return true; 34551debfc3dSmrg 34561debfc3dSmrg if (!odr_hash) 34571debfc3dSmrg return true; 34581debfc3dSmrg targets = possible_polymorphic_call_targets (otr_type, otr_token, ctx, &final); 34591debfc3dSmrg for (i = 0; i < targets.length (); i++) 34601debfc3dSmrg if (n->semantically_equivalent_p (targets[i])) 34611debfc3dSmrg return true; 34621debfc3dSmrg 34631debfc3dSmrg /* At a moment we allow middle end to dig out new external declarations 34641debfc3dSmrg as a targets of polymorphic calls. */ 34651debfc3dSmrg if (!final && !n->definition) 34661debfc3dSmrg return true; 34671debfc3dSmrg return false; 34681debfc3dSmrg } 34691debfc3dSmrg 34701debfc3dSmrg 34711debfc3dSmrg 34721debfc3dSmrg /* Return true if N can be possibly target of a polymorphic call of 34731debfc3dSmrg OBJ_TYPE_REF expression REF in STMT. */ 34741debfc3dSmrg 34751debfc3dSmrg bool 34761debfc3dSmrg possible_polymorphic_call_target_p (tree ref, 34771debfc3dSmrg gimple *stmt, 34781debfc3dSmrg struct cgraph_node *n) 34791debfc3dSmrg { 34801debfc3dSmrg ipa_polymorphic_call_context context (current_function_decl, ref, stmt); 34811debfc3dSmrg tree call_fn = gimple_call_fn (stmt); 34821debfc3dSmrg 34831debfc3dSmrg return possible_polymorphic_call_target_p (obj_type_ref_class (call_fn), 34841debfc3dSmrg tree_to_uhwi 34851debfc3dSmrg (OBJ_TYPE_REF_TOKEN (call_fn)), 34861debfc3dSmrg context, 34871debfc3dSmrg n); 34881debfc3dSmrg } 34891debfc3dSmrg 34901debfc3dSmrg 34911debfc3dSmrg /* After callgraph construction new external nodes may appear. 34921debfc3dSmrg Add them into the graph. */ 34931debfc3dSmrg 34941debfc3dSmrg void 34951debfc3dSmrg update_type_inheritance_graph (void) 34961debfc3dSmrg { 34971debfc3dSmrg struct cgraph_node *n; 34981debfc3dSmrg 34991debfc3dSmrg if (!odr_hash) 35001debfc3dSmrg return; 35011debfc3dSmrg free_polymorphic_call_targets_hash (); 35021debfc3dSmrg timevar_push (TV_IPA_INHERITANCE); 35031debfc3dSmrg /* We reconstruct the graph starting from types of all methods seen in the 35041debfc3dSmrg unit. */ 35051debfc3dSmrg FOR_EACH_FUNCTION (n) 35061debfc3dSmrg if (DECL_VIRTUAL_P (n->decl) 35071debfc3dSmrg && !n->definition 35081debfc3dSmrg && n->real_symbol_p ()) 35091debfc3dSmrg get_odr_type (TYPE_METHOD_BASETYPE (TREE_TYPE (n->decl)), true); 35101debfc3dSmrg timevar_pop (TV_IPA_INHERITANCE); 35111debfc3dSmrg } 35121debfc3dSmrg 35131debfc3dSmrg 35141debfc3dSmrg /* Return true if N looks like likely target of a polymorphic call. 35151debfc3dSmrg Rule out cxa_pure_virtual, noreturns, function declared cold and 35161debfc3dSmrg other obvious cases. */ 35171debfc3dSmrg 35181debfc3dSmrg bool 35191debfc3dSmrg likely_target_p (struct cgraph_node *n) 35201debfc3dSmrg { 35211debfc3dSmrg int flags; 35221debfc3dSmrg /* cxa_pure_virtual and similar things are not likely. */ 35231debfc3dSmrg if (TREE_CODE (TREE_TYPE (n->decl)) != METHOD_TYPE) 35241debfc3dSmrg return false; 35251debfc3dSmrg flags = flags_from_decl_or_type (n->decl); 35261debfc3dSmrg if (flags & ECF_NORETURN) 35271debfc3dSmrg return false; 35281debfc3dSmrg if (lookup_attribute ("cold", 35291debfc3dSmrg DECL_ATTRIBUTES (n->decl))) 35301debfc3dSmrg return false; 35311debfc3dSmrg if (n->frequency < NODE_FREQUENCY_NORMAL) 35321debfc3dSmrg return false; 35331debfc3dSmrg /* If there are no live virtual tables referring the target, 35341debfc3dSmrg the only way the target can be called is an instance coming from other 35351debfc3dSmrg compilation unit; speculative devirtualization is built around an 35361debfc3dSmrg assumption that won't happen. */ 35371debfc3dSmrg if (!referenced_from_vtable_p (n)) 35381debfc3dSmrg return false; 35391debfc3dSmrg return true; 35401debfc3dSmrg } 35411debfc3dSmrg 35421debfc3dSmrg /* Compare type warning records P1 and P2 and choose one with larger count; 35431debfc3dSmrg helper for qsort. */ 35441debfc3dSmrg 3545*8feb0f0bSmrg static int 35461debfc3dSmrg type_warning_cmp (const void *p1, const void *p2) 35471debfc3dSmrg { 35481debfc3dSmrg const odr_type_warn_count *t1 = (const odr_type_warn_count *)p1; 35491debfc3dSmrg const odr_type_warn_count *t2 = (const odr_type_warn_count *)p2; 35501debfc3dSmrg 35511debfc3dSmrg if (t1->dyn_count < t2->dyn_count) 35521debfc3dSmrg return 1; 35531debfc3dSmrg if (t1->dyn_count > t2->dyn_count) 35541debfc3dSmrg return -1; 35551debfc3dSmrg return t2->count - t1->count; 35561debfc3dSmrg } 35571debfc3dSmrg 35581debfc3dSmrg /* Compare decl warning records P1 and P2 and choose one with larger count; 35591debfc3dSmrg helper for qsort. */ 35601debfc3dSmrg 3561*8feb0f0bSmrg static int 35621debfc3dSmrg decl_warning_cmp (const void *p1, const void *p2) 35631debfc3dSmrg { 35641debfc3dSmrg const decl_warn_count *t1 = *(const decl_warn_count * const *)p1; 35651debfc3dSmrg const decl_warn_count *t2 = *(const decl_warn_count * const *)p2; 35661debfc3dSmrg 35671debfc3dSmrg if (t1->dyn_count < t2->dyn_count) 35681debfc3dSmrg return 1; 35691debfc3dSmrg if (t1->dyn_count > t2->dyn_count) 35701debfc3dSmrg return -1; 35711debfc3dSmrg return t2->count - t1->count; 35721debfc3dSmrg } 35731debfc3dSmrg 35741debfc3dSmrg 35751debfc3dSmrg /* Try to speculatively devirtualize call to OTR_TYPE with OTR_TOKEN with 35761debfc3dSmrg context CTX. */ 35771debfc3dSmrg 35781debfc3dSmrg struct cgraph_node * 35791debfc3dSmrg try_speculative_devirtualization (tree otr_type, HOST_WIDE_INT otr_token, 35801debfc3dSmrg ipa_polymorphic_call_context ctx) 35811debfc3dSmrg { 35821debfc3dSmrg vec <cgraph_node *>targets 35831debfc3dSmrg = possible_polymorphic_call_targets 35841debfc3dSmrg (otr_type, otr_token, ctx, NULL, NULL, true); 35851debfc3dSmrg unsigned int i; 35861debfc3dSmrg struct cgraph_node *likely_target = NULL; 35871debfc3dSmrg 35881debfc3dSmrg for (i = 0; i < targets.length (); i++) 35891debfc3dSmrg if (likely_target_p (targets[i])) 35901debfc3dSmrg { 35911debfc3dSmrg if (likely_target) 35921debfc3dSmrg return NULL; 35931debfc3dSmrg likely_target = targets[i]; 35941debfc3dSmrg } 35951debfc3dSmrg if (!likely_target 35961debfc3dSmrg ||!likely_target->definition 35971debfc3dSmrg || DECL_EXTERNAL (likely_target->decl)) 35981debfc3dSmrg return NULL; 35991debfc3dSmrg 36001debfc3dSmrg /* Don't use an implicitly-declared destructor (c++/58678). */ 36011debfc3dSmrg struct cgraph_node *non_thunk_target 36021debfc3dSmrg = likely_target->function_symbol (); 36031debfc3dSmrg if (DECL_ARTIFICIAL (non_thunk_target->decl)) 36041debfc3dSmrg return NULL; 36051debfc3dSmrg if (likely_target->get_availability () <= AVAIL_INTERPOSABLE 36061debfc3dSmrg && likely_target->can_be_discarded_p ()) 36071debfc3dSmrg return NULL; 36081debfc3dSmrg return likely_target; 36091debfc3dSmrg } 36101debfc3dSmrg 36111debfc3dSmrg /* The ipa-devirt pass. 36121debfc3dSmrg When polymorphic call has only one likely target in the unit, 36131debfc3dSmrg turn it into a speculative call. */ 36141debfc3dSmrg 36151debfc3dSmrg static unsigned int 36161debfc3dSmrg ipa_devirt (void) 36171debfc3dSmrg { 36181debfc3dSmrg struct cgraph_node *n; 36191debfc3dSmrg hash_set<void *> bad_call_targets; 36201debfc3dSmrg struct cgraph_edge *e; 36211debfc3dSmrg 36221debfc3dSmrg int npolymorphic = 0, nspeculated = 0, nconverted = 0, ncold = 0; 36231debfc3dSmrg int nmultiple = 0, noverwritable = 0, ndevirtualized = 0, nnotdefined = 0; 36241debfc3dSmrg int nwrong = 0, nok = 0, nexternal = 0, nartificial = 0; 36251debfc3dSmrg int ndropped = 0; 36261debfc3dSmrg 36271debfc3dSmrg if (!odr_types_ptr) 36281debfc3dSmrg return 0; 36291debfc3dSmrg 36301debfc3dSmrg if (dump_file) 36311debfc3dSmrg dump_type_inheritance_graph (dump_file); 36321debfc3dSmrg 36331debfc3dSmrg /* We can output -Wsuggest-final-methods and -Wsuggest-final-types warnings. 36341debfc3dSmrg This is implemented by setting up final_warning_records that are updated 36351debfc3dSmrg by get_polymorphic_call_targets. 36361debfc3dSmrg We need to clear cache in this case to trigger recomputation of all 36371debfc3dSmrg entries. */ 36381debfc3dSmrg if (warn_suggest_final_methods || warn_suggest_final_types) 36391debfc3dSmrg { 36401debfc3dSmrg final_warning_records = new (final_warning_record); 3641a2dc1f3fSmrg final_warning_records->dyn_count = profile_count::zero (); 3642a2dc1f3fSmrg final_warning_records->grow_type_warnings (odr_types.length ()); 36431debfc3dSmrg free_polymorphic_call_targets_hash (); 36441debfc3dSmrg } 36451debfc3dSmrg 36461debfc3dSmrg FOR_EACH_DEFINED_FUNCTION (n) 36471debfc3dSmrg { 36481debfc3dSmrg bool update = false; 36491debfc3dSmrg if (!opt_for_fn (n->decl, flag_devirtualize)) 36501debfc3dSmrg continue; 36511debfc3dSmrg if (dump_file && n->indirect_calls) 3652a2dc1f3fSmrg fprintf (dump_file, "\n\nProcesing function %s\n", 3653a2dc1f3fSmrg n->dump_name ()); 36541debfc3dSmrg for (e = n->indirect_calls; e; e = e->next_callee) 36551debfc3dSmrg if (e->indirect_info->polymorphic) 36561debfc3dSmrg { 36571debfc3dSmrg struct cgraph_node *likely_target = NULL; 36581debfc3dSmrg void *cache_token; 36591debfc3dSmrg bool final; 36601debfc3dSmrg 36611debfc3dSmrg if (final_warning_records) 3662a2dc1f3fSmrg final_warning_records->dyn_count = e->count.ipa (); 36631debfc3dSmrg 36641debfc3dSmrg vec <cgraph_node *>targets 36651debfc3dSmrg = possible_polymorphic_call_targets 36661debfc3dSmrg (e, &final, &cache_token, true); 36671debfc3dSmrg unsigned int i; 36681debfc3dSmrg 36691debfc3dSmrg /* Trigger warnings by calculating non-speculative targets. */ 36701debfc3dSmrg if (warn_suggest_final_methods || warn_suggest_final_types) 36711debfc3dSmrg possible_polymorphic_call_targets (e); 36721debfc3dSmrg 36731debfc3dSmrg if (dump_file) 36741debfc3dSmrg dump_possible_polymorphic_call_targets 3675c0a68be4Smrg (dump_file, e, (dump_flags & TDF_DETAILS)); 36761debfc3dSmrg 36771debfc3dSmrg npolymorphic++; 36781debfc3dSmrg 36791debfc3dSmrg /* See if the call can be devirtualized by means of ipa-prop's 36801debfc3dSmrg polymorphic call context propagation. If not, we can just 36811debfc3dSmrg forget about this call being polymorphic and avoid some heavy 36821debfc3dSmrg lifting in remove_unreachable_nodes that will otherwise try to 36831debfc3dSmrg keep all possible targets alive until inlining and in the inliner 36841debfc3dSmrg itself. 36851debfc3dSmrg 36861debfc3dSmrg This may need to be revisited once we add further ways to use 3687*8feb0f0bSmrg the may edges, but it is a reasonable thing to do right now. */ 36881debfc3dSmrg 36891debfc3dSmrg if ((e->indirect_info->param_index == -1 36901debfc3dSmrg || (!opt_for_fn (n->decl, flag_devirtualize_speculatively) 36911debfc3dSmrg && e->indirect_info->vptr_changed)) 36921debfc3dSmrg && !flag_ltrans_devirtualize) 36931debfc3dSmrg { 36941debfc3dSmrg e->indirect_info->polymorphic = false; 36951debfc3dSmrg ndropped++; 36961debfc3dSmrg if (dump_file) 36971debfc3dSmrg fprintf (dump_file, "Dropping polymorphic call info;" 36981debfc3dSmrg " it cannot be used by ipa-prop\n"); 36991debfc3dSmrg } 37001debfc3dSmrg 37011debfc3dSmrg if (!opt_for_fn (n->decl, flag_devirtualize_speculatively)) 37021debfc3dSmrg continue; 37031debfc3dSmrg 37041debfc3dSmrg if (!e->maybe_hot_p ()) 37051debfc3dSmrg { 37061debfc3dSmrg if (dump_file) 37071debfc3dSmrg fprintf (dump_file, "Call is cold\n\n"); 37081debfc3dSmrg ncold++; 37091debfc3dSmrg continue; 37101debfc3dSmrg } 37111debfc3dSmrg if (e->speculative) 37121debfc3dSmrg { 37131debfc3dSmrg if (dump_file) 37141debfc3dSmrg fprintf (dump_file, "Call is already speculated\n\n"); 37151debfc3dSmrg nspeculated++; 37161debfc3dSmrg 37171debfc3dSmrg /* When dumping see if we agree with speculation. */ 37181debfc3dSmrg if (!dump_file) 37191debfc3dSmrg continue; 37201debfc3dSmrg } 37211debfc3dSmrg if (bad_call_targets.contains (cache_token)) 37221debfc3dSmrg { 37231debfc3dSmrg if (dump_file) 37241debfc3dSmrg fprintf (dump_file, "Target list is known to be useless\n\n"); 37251debfc3dSmrg nmultiple++; 37261debfc3dSmrg continue; 37271debfc3dSmrg } 37281debfc3dSmrg for (i = 0; i < targets.length (); i++) 37291debfc3dSmrg if (likely_target_p (targets[i])) 37301debfc3dSmrg { 37311debfc3dSmrg if (likely_target) 37321debfc3dSmrg { 37331debfc3dSmrg likely_target = NULL; 37341debfc3dSmrg if (dump_file) 37351debfc3dSmrg fprintf (dump_file, "More than one likely target\n\n"); 37361debfc3dSmrg nmultiple++; 37371debfc3dSmrg break; 37381debfc3dSmrg } 37391debfc3dSmrg likely_target = targets[i]; 37401debfc3dSmrg } 37411debfc3dSmrg if (!likely_target) 37421debfc3dSmrg { 37431debfc3dSmrg bad_call_targets.add (cache_token); 37441debfc3dSmrg continue; 37451debfc3dSmrg } 37461debfc3dSmrg /* This is reached only when dumping; check if we agree or disagree 37471debfc3dSmrg with the speculation. */ 37481debfc3dSmrg if (e->speculative) 37491debfc3dSmrg { 3750*8feb0f0bSmrg bool found = e->speculative_call_for_target (likely_target); 3751*8feb0f0bSmrg if (found) 37521debfc3dSmrg { 37531debfc3dSmrg fprintf (dump_file, "We agree with speculation\n\n"); 37541debfc3dSmrg nok++; 37551debfc3dSmrg } 37561debfc3dSmrg else 37571debfc3dSmrg { 37581debfc3dSmrg fprintf (dump_file, "We disagree with speculation\n\n"); 37591debfc3dSmrg nwrong++; 37601debfc3dSmrg } 37611debfc3dSmrg continue; 37621debfc3dSmrg } 37631debfc3dSmrg if (!likely_target->definition) 37641debfc3dSmrg { 37651debfc3dSmrg if (dump_file) 37661debfc3dSmrg fprintf (dump_file, "Target is not a definition\n\n"); 37671debfc3dSmrg nnotdefined++; 37681debfc3dSmrg continue; 37691debfc3dSmrg } 37701debfc3dSmrg /* Do not introduce new references to external symbols. While we 37711debfc3dSmrg can handle these just well, it is common for programs to 37721debfc3dSmrg incorrectly with headers defining methods they are linked 37731debfc3dSmrg with. */ 37741debfc3dSmrg if (DECL_EXTERNAL (likely_target->decl)) 37751debfc3dSmrg { 37761debfc3dSmrg if (dump_file) 37771debfc3dSmrg fprintf (dump_file, "Target is external\n\n"); 37781debfc3dSmrg nexternal++; 37791debfc3dSmrg continue; 37801debfc3dSmrg } 37811debfc3dSmrg /* Don't use an implicitly-declared destructor (c++/58678). */ 37821debfc3dSmrg struct cgraph_node *non_thunk_target 37831debfc3dSmrg = likely_target->function_symbol (); 37841debfc3dSmrg if (DECL_ARTIFICIAL (non_thunk_target->decl)) 37851debfc3dSmrg { 37861debfc3dSmrg if (dump_file) 37871debfc3dSmrg fprintf (dump_file, "Target is artificial\n\n"); 37881debfc3dSmrg nartificial++; 37891debfc3dSmrg continue; 37901debfc3dSmrg } 37911debfc3dSmrg if (likely_target->get_availability () <= AVAIL_INTERPOSABLE 37921debfc3dSmrg && likely_target->can_be_discarded_p ()) 37931debfc3dSmrg { 37941debfc3dSmrg if (dump_file) 37951debfc3dSmrg fprintf (dump_file, "Target is overwritable\n\n"); 37961debfc3dSmrg noverwritable++; 37971debfc3dSmrg continue; 37981debfc3dSmrg } 37991debfc3dSmrg else if (dbg_cnt (devirt)) 38001debfc3dSmrg { 38011debfc3dSmrg if (dump_enabled_p ()) 38021debfc3dSmrg { 3803c0a68be4Smrg dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt, 3804a2dc1f3fSmrg "speculatively devirtualizing call " 3805a2dc1f3fSmrg "in %s to %s\n", 3806a2dc1f3fSmrg n->dump_name (), 3807a2dc1f3fSmrg likely_target->dump_name ()); 38081debfc3dSmrg } 38091debfc3dSmrg if (!likely_target->can_be_discarded_p ()) 38101debfc3dSmrg { 38111debfc3dSmrg cgraph_node *alias; 38121debfc3dSmrg alias = dyn_cast<cgraph_node *> (likely_target->noninterposable_alias ()); 38131debfc3dSmrg if (alias) 38141debfc3dSmrg likely_target = alias; 38151debfc3dSmrg } 38161debfc3dSmrg nconverted++; 38171debfc3dSmrg update = true; 38181debfc3dSmrg e->make_speculative 3819a2dc1f3fSmrg (likely_target, e->count.apply_scale (8, 10)); 38201debfc3dSmrg } 38211debfc3dSmrg } 38221debfc3dSmrg if (update) 3823a2dc1f3fSmrg ipa_update_overall_fn_summary (n); 38241debfc3dSmrg } 38251debfc3dSmrg if (warn_suggest_final_methods || warn_suggest_final_types) 38261debfc3dSmrg { 38271debfc3dSmrg if (warn_suggest_final_types) 38281debfc3dSmrg { 38291debfc3dSmrg final_warning_records->type_warnings.qsort (type_warning_cmp); 38301debfc3dSmrg for (unsigned int i = 0; 38311debfc3dSmrg i < final_warning_records->type_warnings.length (); i++) 38321debfc3dSmrg if (final_warning_records->type_warnings[i].count) 38331debfc3dSmrg { 38341debfc3dSmrg tree type = final_warning_records->type_warnings[i].type; 38351debfc3dSmrg int count = final_warning_records->type_warnings[i].count; 3836a2dc1f3fSmrg profile_count dyn_count 38371debfc3dSmrg = final_warning_records->type_warnings[i].dyn_count; 38381debfc3dSmrg 3839a2dc1f3fSmrg if (!(dyn_count > 0)) 38401debfc3dSmrg warning_n (DECL_SOURCE_LOCATION (TYPE_NAME (type)), 38411debfc3dSmrg OPT_Wsuggest_final_types, count, 38421debfc3dSmrg "Declaring type %qD final " 38431debfc3dSmrg "would enable devirtualization of %i call", 38441debfc3dSmrg "Declaring type %qD final " 38451debfc3dSmrg "would enable devirtualization of %i calls", 38461debfc3dSmrg type, 38471debfc3dSmrg count); 38481debfc3dSmrg else 38491debfc3dSmrg warning_n (DECL_SOURCE_LOCATION (TYPE_NAME (type)), 38501debfc3dSmrg OPT_Wsuggest_final_types, count, 38511debfc3dSmrg "Declaring type %qD final " 38521debfc3dSmrg "would enable devirtualization of %i call " 38531debfc3dSmrg "executed %lli times", 38541debfc3dSmrg "Declaring type %qD final " 38551debfc3dSmrg "would enable devirtualization of %i calls " 38561debfc3dSmrg "executed %lli times", 38571debfc3dSmrg type, 38581debfc3dSmrg count, 3859a2dc1f3fSmrg (long long) dyn_count.to_gcov_type ()); 38601debfc3dSmrg } 38611debfc3dSmrg } 38621debfc3dSmrg 38631debfc3dSmrg if (warn_suggest_final_methods) 38641debfc3dSmrg { 38651debfc3dSmrg auto_vec<const decl_warn_count*> decl_warnings_vec; 38661debfc3dSmrg 38671debfc3dSmrg final_warning_records->decl_warnings.traverse 38681debfc3dSmrg <vec<const decl_warn_count *> *, add_decl_warning> (&decl_warnings_vec); 38691debfc3dSmrg decl_warnings_vec.qsort (decl_warning_cmp); 38701debfc3dSmrg for (unsigned int i = 0; i < decl_warnings_vec.length (); i++) 38711debfc3dSmrg { 38721debfc3dSmrg tree decl = decl_warnings_vec[i]->decl; 38731debfc3dSmrg int count = decl_warnings_vec[i]->count; 3874a2dc1f3fSmrg profile_count dyn_count 3875a2dc1f3fSmrg = decl_warnings_vec[i]->dyn_count; 38761debfc3dSmrg 3877a2dc1f3fSmrg if (!(dyn_count > 0)) 38781debfc3dSmrg if (DECL_CXX_DESTRUCTOR_P (decl)) 38791debfc3dSmrg warning_n (DECL_SOURCE_LOCATION (decl), 38801debfc3dSmrg OPT_Wsuggest_final_methods, count, 38811debfc3dSmrg "Declaring virtual destructor of %qD final " 38821debfc3dSmrg "would enable devirtualization of %i call", 38831debfc3dSmrg "Declaring virtual destructor of %qD final " 38841debfc3dSmrg "would enable devirtualization of %i calls", 38851debfc3dSmrg DECL_CONTEXT (decl), count); 38861debfc3dSmrg else 38871debfc3dSmrg warning_n (DECL_SOURCE_LOCATION (decl), 38881debfc3dSmrg OPT_Wsuggest_final_methods, count, 38891debfc3dSmrg "Declaring method %qD final " 38901debfc3dSmrg "would enable devirtualization of %i call", 38911debfc3dSmrg "Declaring method %qD final " 38921debfc3dSmrg "would enable devirtualization of %i calls", 38931debfc3dSmrg decl, count); 38941debfc3dSmrg else if (DECL_CXX_DESTRUCTOR_P (decl)) 38951debfc3dSmrg warning_n (DECL_SOURCE_LOCATION (decl), 38961debfc3dSmrg OPT_Wsuggest_final_methods, count, 38971debfc3dSmrg "Declaring virtual destructor of %qD final " 38981debfc3dSmrg "would enable devirtualization of %i call " 38991debfc3dSmrg "executed %lli times", 39001debfc3dSmrg "Declaring virtual destructor of %qD final " 39011debfc3dSmrg "would enable devirtualization of %i calls " 39021debfc3dSmrg "executed %lli times", 3903a2dc1f3fSmrg DECL_CONTEXT (decl), count, 3904a2dc1f3fSmrg (long long)dyn_count.to_gcov_type ()); 39051debfc3dSmrg else 39061debfc3dSmrg warning_n (DECL_SOURCE_LOCATION (decl), 39071debfc3dSmrg OPT_Wsuggest_final_methods, count, 39081debfc3dSmrg "Declaring method %qD final " 39091debfc3dSmrg "would enable devirtualization of %i call " 39101debfc3dSmrg "executed %lli times", 39111debfc3dSmrg "Declaring method %qD final " 39121debfc3dSmrg "would enable devirtualization of %i calls " 39131debfc3dSmrg "executed %lli times", 3914a2dc1f3fSmrg decl, count, 3915a2dc1f3fSmrg (long long)dyn_count.to_gcov_type ()); 39161debfc3dSmrg } 39171debfc3dSmrg } 39181debfc3dSmrg 39191debfc3dSmrg delete (final_warning_records); 39201debfc3dSmrg final_warning_records = 0; 39211debfc3dSmrg } 39221debfc3dSmrg 39231debfc3dSmrg if (dump_file) 39241debfc3dSmrg fprintf (dump_file, 39251debfc3dSmrg "%i polymorphic calls, %i devirtualized," 39261debfc3dSmrg " %i speculatively devirtualized, %i cold\n" 39271debfc3dSmrg "%i have multiple targets, %i overwritable," 39281debfc3dSmrg " %i already speculated (%i agree, %i disagree)," 39291debfc3dSmrg " %i external, %i not defined, %i artificial, %i infos dropped\n", 39301debfc3dSmrg npolymorphic, ndevirtualized, nconverted, ncold, 39311debfc3dSmrg nmultiple, noverwritable, nspeculated, nok, nwrong, 39321debfc3dSmrg nexternal, nnotdefined, nartificial, ndropped); 39331debfc3dSmrg return ndevirtualized || ndropped ? TODO_remove_functions : 0; 39341debfc3dSmrg } 39351debfc3dSmrg 39361debfc3dSmrg namespace { 39371debfc3dSmrg 39381debfc3dSmrg const pass_data pass_data_ipa_devirt = 39391debfc3dSmrg { 39401debfc3dSmrg IPA_PASS, /* type */ 39411debfc3dSmrg "devirt", /* name */ 39421debfc3dSmrg OPTGROUP_NONE, /* optinfo_flags */ 39431debfc3dSmrg TV_IPA_DEVIRT, /* tv_id */ 39441debfc3dSmrg 0, /* properties_required */ 39451debfc3dSmrg 0, /* properties_provided */ 39461debfc3dSmrg 0, /* properties_destroyed */ 39471debfc3dSmrg 0, /* todo_flags_start */ 39481debfc3dSmrg ( TODO_dump_symtab ), /* todo_flags_finish */ 39491debfc3dSmrg }; 39501debfc3dSmrg 39511debfc3dSmrg class pass_ipa_devirt : public ipa_opt_pass_d 39521debfc3dSmrg { 39531debfc3dSmrg public: 39541debfc3dSmrg pass_ipa_devirt (gcc::context *ctxt) 39551debfc3dSmrg : ipa_opt_pass_d (pass_data_ipa_devirt, ctxt, 39561debfc3dSmrg NULL, /* generate_summary */ 39571debfc3dSmrg NULL, /* write_summary */ 39581debfc3dSmrg NULL, /* read_summary */ 39591debfc3dSmrg NULL, /* write_optimization_summary */ 39601debfc3dSmrg NULL, /* read_optimization_summary */ 39611debfc3dSmrg NULL, /* stmt_fixup */ 39621debfc3dSmrg 0, /* function_transform_todo_flags_start */ 39631debfc3dSmrg NULL, /* function_transform */ 39641debfc3dSmrg NULL) /* variable_transform */ 39651debfc3dSmrg {} 39661debfc3dSmrg 39671debfc3dSmrg /* opt_pass methods: */ 39681debfc3dSmrg virtual bool gate (function *) 39691debfc3dSmrg { 39701debfc3dSmrg /* In LTO, always run the IPA passes and decide on function basis if the 39711debfc3dSmrg pass is enabled. */ 39721debfc3dSmrg if (in_lto_p) 39731debfc3dSmrg return true; 39741debfc3dSmrg return (flag_devirtualize 39751debfc3dSmrg && (flag_devirtualize_speculatively 39761debfc3dSmrg || (warn_suggest_final_methods 39771debfc3dSmrg || warn_suggest_final_types)) 39781debfc3dSmrg && optimize); 39791debfc3dSmrg } 39801debfc3dSmrg 39811debfc3dSmrg virtual unsigned int execute (function *) { return ipa_devirt (); } 39821debfc3dSmrg 39831debfc3dSmrg }; // class pass_ipa_devirt 39841debfc3dSmrg 39851debfc3dSmrg } // anon namespace 39861debfc3dSmrg 39871debfc3dSmrg ipa_opt_pass_d * 39881debfc3dSmrg make_pass_ipa_devirt (gcc::context *ctxt) 39891debfc3dSmrg { 39901debfc3dSmrg return new pass_ipa_devirt (ctxt); 39911debfc3dSmrg } 39921debfc3dSmrg 3993*8feb0f0bSmrg /* Print ODR name of a TYPE if available. 3994*8feb0f0bSmrg Use demangler when option DEMANGLE is used. */ 3995*8feb0f0bSmrg 3996*8feb0f0bSmrg DEBUG_FUNCTION void 3997*8feb0f0bSmrg debug_tree_odr_name (tree type, bool demangle) 3998*8feb0f0bSmrg { 3999*8feb0f0bSmrg const char *odr = get_odr_name_for_type (type); 4000*8feb0f0bSmrg if (demangle) 4001*8feb0f0bSmrg { 4002*8feb0f0bSmrg const int opts = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; 4003*8feb0f0bSmrg odr = cplus_demangle (odr, opts); 4004*8feb0f0bSmrg } 4005*8feb0f0bSmrg 4006*8feb0f0bSmrg fprintf (stderr, "%s\n", odr); 4007*8feb0f0bSmrg } 4008*8feb0f0bSmrg 4009*8feb0f0bSmrg /* Register ODR enum so we later stream record about its values. */ 4010*8feb0f0bSmrg 4011*8feb0f0bSmrg void 4012*8feb0f0bSmrg register_odr_enum (tree t) 4013*8feb0f0bSmrg { 4014*8feb0f0bSmrg if (flag_lto) 4015*8feb0f0bSmrg vec_safe_push (odr_enums, t); 4016*8feb0f0bSmrg } 4017*8feb0f0bSmrg 4018*8feb0f0bSmrg /* Write ODR enums to LTO stream file. */ 4019*8feb0f0bSmrg 4020*8feb0f0bSmrg static void 4021*8feb0f0bSmrg ipa_odr_summary_write (void) 4022*8feb0f0bSmrg { 4023*8feb0f0bSmrg if (!odr_enums && !odr_enum_map) 4024*8feb0f0bSmrg return; 4025*8feb0f0bSmrg struct output_block *ob = create_output_block (LTO_section_odr_types); 4026*8feb0f0bSmrg unsigned int i; 4027*8feb0f0bSmrg tree t; 4028*8feb0f0bSmrg 4029*8feb0f0bSmrg if (odr_enums) 4030*8feb0f0bSmrg { 4031*8feb0f0bSmrg streamer_write_uhwi (ob, odr_enums->length ()); 4032*8feb0f0bSmrg 4033*8feb0f0bSmrg /* For every ODR enum stream out 4034*8feb0f0bSmrg - its ODR name 4035*8feb0f0bSmrg - number of values, 4036*8feb0f0bSmrg - value names and constant their represent 4037*8feb0f0bSmrg - bitpack of locations so we can do good diagnostics. */ 4038*8feb0f0bSmrg FOR_EACH_VEC_ELT (*odr_enums, i, t) 4039*8feb0f0bSmrg { 4040*8feb0f0bSmrg streamer_write_string (ob, ob->main_stream, 4041*8feb0f0bSmrg IDENTIFIER_POINTER 4042*8feb0f0bSmrg (DECL_ASSEMBLER_NAME (TYPE_NAME (t))), 4043*8feb0f0bSmrg true); 4044*8feb0f0bSmrg 4045*8feb0f0bSmrg int n = 0; 4046*8feb0f0bSmrg for (tree e = TYPE_VALUES (t); e; e = TREE_CHAIN (e)) 4047*8feb0f0bSmrg n++; 4048*8feb0f0bSmrg streamer_write_uhwi (ob, n); 4049*8feb0f0bSmrg for (tree e = TYPE_VALUES (t); e; e = TREE_CHAIN (e)) 4050*8feb0f0bSmrg { 4051*8feb0f0bSmrg streamer_write_string (ob, ob->main_stream, 4052*8feb0f0bSmrg IDENTIFIER_POINTER (TREE_PURPOSE (e)), 4053*8feb0f0bSmrg true); 4054*8feb0f0bSmrg streamer_write_wide_int (ob, 4055*8feb0f0bSmrg wi::to_wide (DECL_INITIAL 4056*8feb0f0bSmrg (TREE_VALUE (e)))); 4057*8feb0f0bSmrg } 4058*8feb0f0bSmrg 4059*8feb0f0bSmrg bitpack_d bp = bitpack_create (ob->main_stream); 4060*8feb0f0bSmrg lto_output_location (ob, &bp, DECL_SOURCE_LOCATION (TYPE_NAME (t))); 4061*8feb0f0bSmrg for (tree e = TYPE_VALUES (t); e; e = TREE_CHAIN (e)) 4062*8feb0f0bSmrg lto_output_location (ob, &bp, 4063*8feb0f0bSmrg DECL_SOURCE_LOCATION (TREE_VALUE (e))); 4064*8feb0f0bSmrg streamer_write_bitpack (&bp); 4065*8feb0f0bSmrg } 4066*8feb0f0bSmrg vec_free (odr_enums); 4067*8feb0f0bSmrg odr_enums = NULL; 4068*8feb0f0bSmrg } 4069*8feb0f0bSmrg /* During LTO incremental linking we already have streamed in types. */ 4070*8feb0f0bSmrg else if (odr_enum_map) 4071*8feb0f0bSmrg { 4072*8feb0f0bSmrg gcc_checking_assert (!odr_enums); 4073*8feb0f0bSmrg streamer_write_uhwi (ob, odr_enum_map->elements ()); 4074*8feb0f0bSmrg 4075*8feb0f0bSmrg hash_map<nofree_string_hash, odr_enum>::iterator iter 4076*8feb0f0bSmrg = odr_enum_map->begin (); 4077*8feb0f0bSmrg for (; iter != odr_enum_map->end (); ++iter) 4078*8feb0f0bSmrg { 4079*8feb0f0bSmrg odr_enum &this_enum = (*iter).second; 4080*8feb0f0bSmrg streamer_write_string (ob, ob->main_stream, (*iter).first, true); 4081*8feb0f0bSmrg 4082*8feb0f0bSmrg streamer_write_uhwi (ob, this_enum.vals.length ()); 4083*8feb0f0bSmrg for (unsigned j = 0; j < this_enum.vals.length (); j++) 4084*8feb0f0bSmrg { 4085*8feb0f0bSmrg streamer_write_string (ob, ob->main_stream, 4086*8feb0f0bSmrg this_enum.vals[j].name, true); 4087*8feb0f0bSmrg streamer_write_wide_int (ob, this_enum.vals[j].val); 4088*8feb0f0bSmrg } 4089*8feb0f0bSmrg 4090*8feb0f0bSmrg bitpack_d bp = bitpack_create (ob->main_stream); 4091*8feb0f0bSmrg lto_output_location (ob, &bp, this_enum.locus); 4092*8feb0f0bSmrg for (unsigned j = 0; j < this_enum.vals.length (); j++) 4093*8feb0f0bSmrg lto_output_location (ob, &bp, this_enum.vals[j].locus); 4094*8feb0f0bSmrg streamer_write_bitpack (&bp); 4095*8feb0f0bSmrg } 4096*8feb0f0bSmrg 4097*8feb0f0bSmrg delete odr_enum_map; 4098*8feb0f0bSmrg obstack_free (&odr_enum_obstack, NULL); 4099*8feb0f0bSmrg odr_enum_map = NULL; 4100*8feb0f0bSmrg } 4101*8feb0f0bSmrg 4102*8feb0f0bSmrg produce_asm (ob, NULL); 4103*8feb0f0bSmrg destroy_output_block (ob); 4104*8feb0f0bSmrg } 4105*8feb0f0bSmrg 4106*8feb0f0bSmrg /* Write ODR enums from LTO stream file and warn on mismatches. */ 4107*8feb0f0bSmrg 4108*8feb0f0bSmrg static void 4109*8feb0f0bSmrg ipa_odr_read_section (struct lto_file_decl_data *file_data, const char *data, 4110*8feb0f0bSmrg size_t len) 4111*8feb0f0bSmrg { 4112*8feb0f0bSmrg const struct lto_function_header *header 4113*8feb0f0bSmrg = (const struct lto_function_header *) data; 4114*8feb0f0bSmrg const int cfg_offset = sizeof (struct lto_function_header); 4115*8feb0f0bSmrg const int main_offset = cfg_offset + header->cfg_size; 4116*8feb0f0bSmrg const int string_offset = main_offset + header->main_size; 4117*8feb0f0bSmrg class data_in *data_in; 4118*8feb0f0bSmrg 4119*8feb0f0bSmrg lto_input_block ib ((const char *) data + main_offset, header->main_size, 4120*8feb0f0bSmrg file_data->mode_table); 4121*8feb0f0bSmrg 4122*8feb0f0bSmrg data_in 4123*8feb0f0bSmrg = lto_data_in_create (file_data, (const char *) data + string_offset, 4124*8feb0f0bSmrg header->string_size, vNULL); 4125*8feb0f0bSmrg unsigned int n = streamer_read_uhwi (&ib); 4126*8feb0f0bSmrg 4127*8feb0f0bSmrg if (!odr_enum_map) 4128*8feb0f0bSmrg { 4129*8feb0f0bSmrg gcc_obstack_init (&odr_enum_obstack); 4130*8feb0f0bSmrg odr_enum_map = new (hash_map <nofree_string_hash, odr_enum>); 4131*8feb0f0bSmrg } 4132*8feb0f0bSmrg 4133*8feb0f0bSmrg for (unsigned i = 0; i < n; i++) 4134*8feb0f0bSmrg { 4135*8feb0f0bSmrg const char *rname = streamer_read_string (data_in, &ib); 4136*8feb0f0bSmrg unsigned int nvals = streamer_read_uhwi (&ib); 4137*8feb0f0bSmrg char *name; 4138*8feb0f0bSmrg 4139*8feb0f0bSmrg obstack_grow (&odr_enum_obstack, rname, strlen (rname) + 1); 4140*8feb0f0bSmrg name = XOBFINISH (&odr_enum_obstack, char *); 4141*8feb0f0bSmrg 4142*8feb0f0bSmrg bool existed_p; 4143*8feb0f0bSmrg class odr_enum &this_enum 4144*8feb0f0bSmrg = odr_enum_map->get_or_insert (xstrdup (name), &existed_p); 4145*8feb0f0bSmrg 4146*8feb0f0bSmrg /* If this is first time we see the enum, remember its definition. */ 4147*8feb0f0bSmrg if (!existed_p) 4148*8feb0f0bSmrg { 4149*8feb0f0bSmrg this_enum.vals.safe_grow_cleared (nvals); 4150*8feb0f0bSmrg this_enum.warned = false; 4151*8feb0f0bSmrg if (dump_file) 4152*8feb0f0bSmrg fprintf (dump_file, "enum %s\n{\n", name); 4153*8feb0f0bSmrg for (unsigned j = 0; j < nvals; j++) 4154*8feb0f0bSmrg { 4155*8feb0f0bSmrg const char *val_name = streamer_read_string (data_in, &ib); 4156*8feb0f0bSmrg obstack_grow (&odr_enum_obstack, val_name, strlen (val_name) + 1); 4157*8feb0f0bSmrg this_enum.vals[j].name = XOBFINISH (&odr_enum_obstack, char *); 4158*8feb0f0bSmrg this_enum.vals[j].val = streamer_read_wide_int (&ib); 4159*8feb0f0bSmrg if (dump_file) 4160*8feb0f0bSmrg fprintf (dump_file, " %s = " HOST_WIDE_INT_PRINT_DEC ",\n", 4161*8feb0f0bSmrg val_name, wi::fits_shwi_p (this_enum.vals[j].val) 4162*8feb0f0bSmrg ? this_enum.vals[j].val.to_shwi () : -1); 4163*8feb0f0bSmrg } 4164*8feb0f0bSmrg bitpack_d bp = streamer_read_bitpack (&ib); 4165*8feb0f0bSmrg stream_input_location (&this_enum.locus, &bp, data_in); 4166*8feb0f0bSmrg for (unsigned j = 0; j < nvals; j++) 4167*8feb0f0bSmrg stream_input_location (&this_enum.vals[j].locus, &bp, data_in); 4168*8feb0f0bSmrg data_in->location_cache.apply_location_cache (); 4169*8feb0f0bSmrg if (dump_file) 4170*8feb0f0bSmrg fprintf (dump_file, "}\n"); 4171*8feb0f0bSmrg } 4172*8feb0f0bSmrg /* If we already have definition, compare it with new one and output 4173*8feb0f0bSmrg warnings if they differs. */ 4174*8feb0f0bSmrg else 4175*8feb0f0bSmrg { 4176*8feb0f0bSmrg int do_warning = -1; 4177*8feb0f0bSmrg char *warn_name = NULL; 4178*8feb0f0bSmrg wide_int warn_value = wi::zero (1); 4179*8feb0f0bSmrg 4180*8feb0f0bSmrg if (dump_file) 4181*8feb0f0bSmrg fprintf (dump_file, "Comparing enum %s\n", name); 4182*8feb0f0bSmrg 4183*8feb0f0bSmrg /* Look for differences which we will warn about later once locations 4184*8feb0f0bSmrg are streamed. */ 4185*8feb0f0bSmrg for (unsigned j = 0; j < nvals; j++) 4186*8feb0f0bSmrg { 4187*8feb0f0bSmrg const char *id = streamer_read_string (data_in, &ib); 4188*8feb0f0bSmrg wide_int val = streamer_read_wide_int (&ib); 4189*8feb0f0bSmrg 4190*8feb0f0bSmrg if (do_warning != -1 || j >= this_enum.vals.length ()) 4191*8feb0f0bSmrg continue; 4192*8feb0f0bSmrg if (strcmp (id, this_enum.vals[j].name) 4193*8feb0f0bSmrg || val != this_enum.vals[j].val) 4194*8feb0f0bSmrg { 4195*8feb0f0bSmrg warn_name = xstrdup (id); 4196*8feb0f0bSmrg warn_value = val; 4197*8feb0f0bSmrg do_warning = j; 4198*8feb0f0bSmrg if (dump_file) 4199*8feb0f0bSmrg fprintf (dump_file, " Different on entry %i\n", j); 4200*8feb0f0bSmrg } 4201*8feb0f0bSmrg } 4202*8feb0f0bSmrg 4203*8feb0f0bSmrg /* Stream in locations, but do not apply them unless we are going 4204*8feb0f0bSmrg to warn. */ 4205*8feb0f0bSmrg bitpack_d bp = streamer_read_bitpack (&ib); 4206*8feb0f0bSmrg location_t locus; 4207*8feb0f0bSmrg 4208*8feb0f0bSmrg stream_input_location (&locus, &bp, data_in); 4209*8feb0f0bSmrg 4210*8feb0f0bSmrg /* Did we find a difference? */ 4211*8feb0f0bSmrg if (do_warning != -1 || nvals != this_enum.vals.length ()) 4212*8feb0f0bSmrg { 4213*8feb0f0bSmrg data_in->location_cache.apply_location_cache (); 4214*8feb0f0bSmrg 4215*8feb0f0bSmrg const int opts = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES; 4216*8feb0f0bSmrg char *dmgname = cplus_demangle (name, opts); 4217*8feb0f0bSmrg if (this_enum.warned 4218*8feb0f0bSmrg || !warning_at (this_enum.locus, 4219*8feb0f0bSmrg OPT_Wodr, "type %qs violates the " 4220*8feb0f0bSmrg "C++ One Definition Rule", 4221*8feb0f0bSmrg dmgname)) 4222*8feb0f0bSmrg do_warning = -1; 4223*8feb0f0bSmrg else 4224*8feb0f0bSmrg { 4225*8feb0f0bSmrg this_enum.warned = true; 4226*8feb0f0bSmrg if (do_warning == -1) 4227*8feb0f0bSmrg inform (locus, 4228*8feb0f0bSmrg "an enum with different number of values is defined" 4229*8feb0f0bSmrg " in another translation unit"); 4230*8feb0f0bSmrg else if (warn_name) 4231*8feb0f0bSmrg inform (locus, 4232*8feb0f0bSmrg "an enum with different value name" 4233*8feb0f0bSmrg " is defined in another translation unit"); 4234*8feb0f0bSmrg else 4235*8feb0f0bSmrg inform (locus, 4236*8feb0f0bSmrg "an enum with different values" 4237*8feb0f0bSmrg " is defined in another translation unit"); 4238*8feb0f0bSmrg } 4239*8feb0f0bSmrg } 4240*8feb0f0bSmrg else 4241*8feb0f0bSmrg data_in->location_cache.revert_location_cache (); 4242*8feb0f0bSmrg 4243*8feb0f0bSmrg /* Finally look up for location of the actual value that diverged. */ 4244*8feb0f0bSmrg for (unsigned j = 0; j < nvals; j++) 4245*8feb0f0bSmrg { 4246*8feb0f0bSmrg location_t id_locus; 4247*8feb0f0bSmrg 4248*8feb0f0bSmrg data_in->location_cache.revert_location_cache (); 4249*8feb0f0bSmrg stream_input_location (&id_locus, &bp, data_in); 4250*8feb0f0bSmrg 4251*8feb0f0bSmrg if ((int) j == do_warning) 4252*8feb0f0bSmrg { 4253*8feb0f0bSmrg data_in->location_cache.apply_location_cache (); 4254*8feb0f0bSmrg 4255*8feb0f0bSmrg if (strcmp (warn_name, this_enum.vals[j].name)) 4256*8feb0f0bSmrg inform (this_enum.vals[j].locus, 4257*8feb0f0bSmrg "name %qs differs from name %qs defined" 4258*8feb0f0bSmrg " in another translation unit", 4259*8feb0f0bSmrg this_enum.vals[j].name, warn_name); 4260*8feb0f0bSmrg /* FIXME: In case there is easy way to print wide_ints, 4261*8feb0f0bSmrg perhaps we could do it here instead of overlfow checpl. */ 4262*8feb0f0bSmrg else if (wi::fits_shwi_p (this_enum.vals[j].val) 4263*8feb0f0bSmrg && wi::fits_shwi_p (warn_value)) 4264*8feb0f0bSmrg inform (this_enum.vals[j].locus, 4265*8feb0f0bSmrg "name %qs is defined to " HOST_WIDE_INT_PRINT_DEC 4266*8feb0f0bSmrg " while another translation unit defines " 4267*8feb0f0bSmrg "it as " HOST_WIDE_INT_PRINT_DEC, 4268*8feb0f0bSmrg warn_name, this_enum.vals[j].val.to_shwi (), 4269*8feb0f0bSmrg warn_value.to_shwi ()); 4270*8feb0f0bSmrg else 4271*8feb0f0bSmrg inform (this_enum.vals[j].locus, 4272*8feb0f0bSmrg "name %qs is defined to different value " 4273*8feb0f0bSmrg "in another translation unit", 4274*8feb0f0bSmrg warn_name); 4275*8feb0f0bSmrg 4276*8feb0f0bSmrg inform (id_locus, 4277*8feb0f0bSmrg "mismatching definition"); 4278*8feb0f0bSmrg } 4279*8feb0f0bSmrg else 4280*8feb0f0bSmrg data_in->location_cache.revert_location_cache (); 4281*8feb0f0bSmrg } 4282*8feb0f0bSmrg if (warn_name) 4283*8feb0f0bSmrg free (warn_name); 4284*8feb0f0bSmrg obstack_free (&odr_enum_obstack, name); 4285*8feb0f0bSmrg } 4286*8feb0f0bSmrg } 4287*8feb0f0bSmrg lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL, data, 4288*8feb0f0bSmrg len); 4289*8feb0f0bSmrg lto_data_in_delete (data_in); 4290*8feb0f0bSmrg } 4291*8feb0f0bSmrg 4292*8feb0f0bSmrg /* Read all ODR type sections. */ 4293*8feb0f0bSmrg 4294*8feb0f0bSmrg static void 4295*8feb0f0bSmrg ipa_odr_summary_read (void) 4296*8feb0f0bSmrg { 4297*8feb0f0bSmrg struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data (); 4298*8feb0f0bSmrg struct lto_file_decl_data *file_data; 4299*8feb0f0bSmrg unsigned int j = 0; 4300*8feb0f0bSmrg 4301*8feb0f0bSmrg while ((file_data = file_data_vec[j++])) 4302*8feb0f0bSmrg { 4303*8feb0f0bSmrg size_t len; 4304*8feb0f0bSmrg const char *data 4305*8feb0f0bSmrg = lto_get_summary_section_data (file_data, LTO_section_odr_types, 4306*8feb0f0bSmrg &len); 4307*8feb0f0bSmrg if (data) 4308*8feb0f0bSmrg ipa_odr_read_section (file_data, data, len); 4309*8feb0f0bSmrg } 4310*8feb0f0bSmrg /* Enum info is used only to produce warnings. Only case we will need it 4311*8feb0f0bSmrg again is streaming for incremental LTO. */ 4312*8feb0f0bSmrg if (flag_incremental_link != INCREMENTAL_LINK_LTO) 4313*8feb0f0bSmrg { 4314*8feb0f0bSmrg delete odr_enum_map; 4315*8feb0f0bSmrg obstack_free (&odr_enum_obstack, NULL); 4316*8feb0f0bSmrg odr_enum_map = NULL; 4317*8feb0f0bSmrg } 4318*8feb0f0bSmrg } 4319*8feb0f0bSmrg 4320*8feb0f0bSmrg namespace { 4321*8feb0f0bSmrg 4322*8feb0f0bSmrg const pass_data pass_data_ipa_odr = 4323*8feb0f0bSmrg { 4324*8feb0f0bSmrg IPA_PASS, /* type */ 4325*8feb0f0bSmrg "odr", /* name */ 4326*8feb0f0bSmrg OPTGROUP_NONE, /* optinfo_flags */ 4327*8feb0f0bSmrg TV_IPA_ODR, /* tv_id */ 4328*8feb0f0bSmrg 0, /* properties_required */ 4329*8feb0f0bSmrg 0, /* properties_provided */ 4330*8feb0f0bSmrg 0, /* properties_destroyed */ 4331*8feb0f0bSmrg 0, /* todo_flags_start */ 4332*8feb0f0bSmrg 0, /* todo_flags_finish */ 4333*8feb0f0bSmrg }; 4334*8feb0f0bSmrg 4335*8feb0f0bSmrg class pass_ipa_odr : public ipa_opt_pass_d 4336*8feb0f0bSmrg { 4337*8feb0f0bSmrg public: 4338*8feb0f0bSmrg pass_ipa_odr (gcc::context *ctxt) 4339*8feb0f0bSmrg : ipa_opt_pass_d (pass_data_ipa_odr, ctxt, 4340*8feb0f0bSmrg NULL, /* generate_summary */ 4341*8feb0f0bSmrg ipa_odr_summary_write, /* write_summary */ 4342*8feb0f0bSmrg ipa_odr_summary_read, /* read_summary */ 4343*8feb0f0bSmrg NULL, /* write_optimization_summary */ 4344*8feb0f0bSmrg NULL, /* read_optimization_summary */ 4345*8feb0f0bSmrg NULL, /* stmt_fixup */ 4346*8feb0f0bSmrg 0, /* function_transform_todo_flags_start */ 4347*8feb0f0bSmrg NULL, /* function_transform */ 4348*8feb0f0bSmrg NULL) /* variable_transform */ 4349*8feb0f0bSmrg {} 4350*8feb0f0bSmrg 4351*8feb0f0bSmrg /* opt_pass methods: */ 4352*8feb0f0bSmrg virtual bool gate (function *) 4353*8feb0f0bSmrg { 4354*8feb0f0bSmrg return (in_lto_p || flag_lto); 4355*8feb0f0bSmrg } 4356*8feb0f0bSmrg 4357*8feb0f0bSmrg virtual unsigned int execute (function *) 4358*8feb0f0bSmrg { 4359*8feb0f0bSmrg return 0; 4360*8feb0f0bSmrg } 4361*8feb0f0bSmrg 4362*8feb0f0bSmrg }; // class pass_ipa_odr 4363*8feb0f0bSmrg 4364*8feb0f0bSmrg } // anon namespace 4365*8feb0f0bSmrg 4366*8feb0f0bSmrg ipa_opt_pass_d * 4367*8feb0f0bSmrg make_pass_ipa_odr (gcc::context *ctxt) 4368*8feb0f0bSmrg { 4369*8feb0f0bSmrg return new pass_ipa_odr (ctxt); 4370*8feb0f0bSmrg } 4371*8feb0f0bSmrg 4372*8feb0f0bSmrg 43731debfc3dSmrg #include "gt-ipa-devirt.h" 4374