xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/ipa-devirt.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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