File: | build/gcc/ipa-devirt.cc |
Warning: | line 4284, column 9 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Basic IPA utilities for type inheritance graph construction and | |||
2 | devirtualization. | |||
3 | Copyright (C) 2013-2023 Free Software Foundation, Inc. | |||
4 | Contributed by Jan Hubicka | |||
5 | ||||
6 | This file is part of GCC. | |||
7 | ||||
8 | GCC is free software; you can redistribute it and/or modify it under | |||
9 | the terms of the GNU General Public License as published by the Free | |||
10 | Software Foundation; either version 3, or (at your option) any later | |||
11 | version. | |||
12 | ||||
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |||
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
16 | for more details. | |||
17 | ||||
18 | You should have received a copy of the GNU General Public License | |||
19 | along with GCC; see the file COPYING3. If not see | |||
20 | <http://www.gnu.org/licenses/>. */ | |||
21 | ||||
22 | /* Brief vocabulary: | |||
23 | ODR = One Definition Rule | |||
24 | In short, the ODR states that: | |||
25 | 1 In any translation unit, a template, type, function, or object can | |||
26 | have no more than one definition. Some of these can have any number | |||
27 | of declarations. A definition provides an instance. | |||
28 | 2 In the entire program, an object or non-inline function cannot have | |||
29 | more than one definition; if an object or function is used, it must | |||
30 | have exactly one definition. You can declare an object or function | |||
31 | that is never used, in which case you don't have to provide | |||
32 | a definition. In no event can there be more than one definition. | |||
33 | 3 Some things, like types, templates, and extern inline functions, can | |||
34 | be defined in more than one translation unit. For a given entity, | |||
35 | each definition must be the same. Non-extern objects and functions | |||
36 | in different translation units are different entities, even if their | |||
37 | names and types are the same. | |||
38 | ||||
39 | OTR = OBJ_TYPE_REF | |||
40 | This is the Gimple representation of type information of a polymorphic call. | |||
41 | It contains two parameters: | |||
42 | otr_type is a type of class whose method is called. | |||
43 | otr_token is the index into virtual table where address is taken. | |||
44 | ||||
45 | BINFO | |||
46 | This is the type inheritance information attached to each tree | |||
47 | RECORD_TYPE by the C++ frontend. It provides information about base | |||
48 | types and virtual tables. | |||
49 | ||||
50 | BINFO is linked to the RECORD_TYPE by TYPE_BINFO. | |||
51 | BINFO also links to its type by BINFO_TYPE and to the virtual table by | |||
52 | BINFO_VTABLE. | |||
53 | ||||
54 | Base types of a given type are enumerated by BINFO_BASE_BINFO | |||
55 | vector. Members of this vectors are not BINFOs associated | |||
56 | with a base type. Rather they are new copies of BINFOs | |||
57 | (base BINFOs). Their virtual tables may differ from | |||
58 | virtual table of the base type. Also BINFO_OFFSET specifies | |||
59 | offset of the base within the type. | |||
60 | ||||
61 | In the case of single inheritance, the virtual table is shared | |||
62 | and BINFO_VTABLE of base BINFO is NULL. In the case of multiple | |||
63 | inheritance the individual virtual tables are pointer to by | |||
64 | BINFO_VTABLE of base binfos (that differs of BINFO_VTABLE of | |||
65 | binfo associated to the base type). | |||
66 | ||||
67 | BINFO lookup for a given base type and offset can be done by | |||
68 | get_binfo_at_offset. It returns proper BINFO whose virtual table | |||
69 | can be used for lookup of virtual methods associated with the | |||
70 | base type. | |||
71 | ||||
72 | token | |||
73 | This is an index of virtual method in virtual table associated | |||
74 | to the type defining it. Token can be looked up from OBJ_TYPE_REF | |||
75 | or from DECL_VINDEX of a given virtual table. | |||
76 | ||||
77 | polymorphic (indirect) call | |||
78 | This is callgraph representation of virtual method call. Every | |||
79 | polymorphic call contains otr_type and otr_token taken from | |||
80 | original OBJ_TYPE_REF at callgraph construction time. | |||
81 | ||||
82 | What we do here: | |||
83 | ||||
84 | build_type_inheritance_graph triggers a construction of the type inheritance | |||
85 | graph. | |||
86 | ||||
87 | We reconstruct it based on types of methods we see in the unit. | |||
88 | This means that the graph is not complete. Types with no methods are not | |||
89 | inserted into the graph. Also types without virtual methods are not | |||
90 | represented at all, though it may be easy to add this. | |||
91 | ||||
92 | The inheritance graph is represented as follows: | |||
93 | ||||
94 | Vertices are structures odr_type. Every odr_type may correspond | |||
95 | to one or more tree type nodes that are equivalent by ODR rule. | |||
96 | (the multiple type nodes appear only with linktime optimization) | |||
97 | ||||
98 | Edges are represented by odr_type->base and odr_type->derived_types. | |||
99 | At the moment we do not track offsets of types for multiple inheritance. | |||
100 | Adding this is easy. | |||
101 | ||||
102 | possible_polymorphic_call_targets returns, given an parameters found in | |||
103 | indirect polymorphic edge all possible polymorphic call targets of the call. | |||
104 | ||||
105 | pass_ipa_devirt performs simple speculative devirtualization. | |||
106 | */ | |||
107 | ||||
108 | #include "config.h" | |||
109 | #include "system.h" | |||
110 | #include "coretypes.h" | |||
111 | #include "backend.h" | |||
112 | #include "rtl.h" | |||
113 | #include "tree.h" | |||
114 | #include "gimple.h" | |||
115 | #include "alloc-pool.h" | |||
116 | #include "tree-pass.h" | |||
117 | #include "cgraph.h" | |||
118 | #include "lto-streamer.h" | |||
119 | #include "fold-const.h" | |||
120 | #include "print-tree.h" | |||
121 | #include "calls.h" | |||
122 | #include "ipa-utils.h" | |||
123 | #include "gimple-iterator.h" | |||
124 | #include "gimple-fold.h" | |||
125 | #include "symbol-summary.h" | |||
126 | #include "tree-vrp.h" | |||
127 | #include "ipa-prop.h" | |||
128 | #include "ipa-fnsummary.h" | |||
129 | #include "demangle.h" | |||
130 | #include "dbgcnt.h" | |||
131 | #include "gimple-pretty-print.h" | |||
132 | #include "intl.h" | |||
133 | #include "stringpool.h" | |||
134 | #include "attribs.h" | |||
135 | #include "data-streamer.h" | |||
136 | #include "lto-streamer.h" | |||
137 | #include "streamer-hooks.h" | |||
138 | ||||
139 | /* Hash based set of pairs of types. */ | |||
140 | struct type_pair | |||
141 | { | |||
142 | tree first; | |||
143 | tree second; | |||
144 | }; | |||
145 | ||||
146 | template <> | |||
147 | struct default_hash_traits <type_pair> | |||
148 | : typed_noop_remove <type_pair> | |||
149 | { | |||
150 | GTY((skip)) typedef type_pair value_type; | |||
151 | GTY((skip)) typedef type_pair compare_type; | |||
152 | static hashval_t | |||
153 | hash (type_pair p) | |||
154 | { | |||
155 | return TYPE_UID (p.first)((tree_class_check ((p.first), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 155, __FUNCTION__))->type_common.uid) ^ TYPE_UID (p.second)((tree_class_check ((p.second), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 155, __FUNCTION__))->type_common.uid); | |||
156 | } | |||
157 | static const bool empty_zero_p = true; | |||
158 | static bool | |||
159 | is_empty (type_pair p) | |||
160 | { | |||
161 | return p.first == NULL__null; | |||
162 | } | |||
163 | static bool | |||
164 | is_deleted (type_pair p ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
165 | { | |||
166 | return false; | |||
167 | } | |||
168 | static bool | |||
169 | equal (const type_pair &a, const type_pair &b) | |||
170 | { | |||
171 | return a.first==b.first && a.second == b.second; | |||
172 | } | |||
173 | static void | |||
174 | mark_empty (type_pair &e) | |||
175 | { | |||
176 | e.first = NULL__null; | |||
177 | } | |||
178 | }; | |||
179 | ||||
180 | /* HACK alert: this is used to communicate with ipa-inline-transform that | |||
181 | thunk is being expanded and there is no need to clear the polymorphic | |||
182 | call target cache. */ | |||
183 | bool thunk_expansion; | |||
184 | ||||
185 | static bool odr_types_equivalent_p (tree, tree, bool, bool *, | |||
186 | hash_set<type_pair> *, | |||
187 | location_t, location_t); | |||
188 | static void warn_odr (tree t1, tree t2, tree st1, tree st2, | |||
189 | bool warn, bool *warned, const char *reason); | |||
190 | ||||
191 | static bool odr_violation_reported = false; | |||
192 | ||||
193 | ||||
194 | /* Pointer set of all call targets appearing in the cache. */ | |||
195 | static hash_set<cgraph_node *> *cached_polymorphic_call_targets; | |||
196 | ||||
197 | /* The node of type inheritance graph. For each type unique in | |||
198 | One Definition Rule (ODR) sense, we produce one node linking all | |||
199 | main variants of types equivalent to it, bases and derived types. */ | |||
200 | ||||
201 | struct GTY(()) odr_type_d | |||
202 | { | |||
203 | /* leader type. */ | |||
204 | tree type; | |||
205 | /* All bases; built only for main variants of types. */ | |||
206 | vec<odr_type> GTY((skip)) bases; | |||
207 | /* All derived types with virtual methods seen in unit; | |||
208 | built only for main variants of types. */ | |||
209 | vec<odr_type> GTY((skip)) derived_types; | |||
210 | ||||
211 | /* All equivalent types, if more than one. */ | |||
212 | vec<tree, va_gc> *types; | |||
213 | /* Set of all equivalent types, if NON-NULL. */ | |||
214 | hash_set<tree> * GTY((skip)) types_set; | |||
215 | ||||
216 | /* Unique ID indexing the type in odr_types array. */ | |||
217 | int id; | |||
218 | /* Is it in anonymous namespace? */ | |||
219 | bool anonymous_namespace; | |||
220 | /* Do we know about all derivations of given type? */ | |||
221 | bool all_derivations_known; | |||
222 | /* Did we report ODR violation here? */ | |||
223 | bool odr_violated; | |||
224 | /* Set when virtual table without RTTI prevailed table with. */ | |||
225 | bool rtti_broken; | |||
226 | /* Set when the canonical type is determined using the type name. */ | |||
227 | bool tbaa_enabled; | |||
228 | }; | |||
229 | ||||
230 | /* Return TRUE if all derived types of T are known and thus | |||
231 | we may consider the walk of derived type complete. | |||
232 | ||||
233 | This is typically true only for final anonymous namespace types and types | |||
234 | defined within functions (that may be COMDAT and thus shared across units, | |||
235 | but with the same set of derived types). */ | |||
236 | ||||
237 | bool | |||
238 | type_all_derivations_known_p (const_tree t) | |||
239 | { | |||
240 | if (TYPE_FINAL_P (t)((tree_check3 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 240, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->base.default_def_flag)) | |||
241 | return true; | |||
242 | if (flag_ltransglobal_options.x_flag_ltrans) | |||
243 | return false; | |||
244 | /* Non-C++ types may have IDENTIFIER_NODE here, do not crash. */ | |||
245 | if (!TYPE_NAME (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 245, __FUNCTION__))->type_common.name) || TREE_CODE (TYPE_NAME (t))((enum tree_code) (((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 245, __FUNCTION__))->type_common.name))->base.code) != TYPE_DECL) | |||
246 | return true; | |||
247 | if (type_in_anonymous_namespace_p (t)) | |||
248 | return true; | |||
249 | return (decl_function_context (TYPE_NAME (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 249, __FUNCTION__))->type_common.name)) != NULL__null); | |||
250 | } | |||
251 | ||||
252 | /* Return TRUE if type's constructors are all visible. */ | |||
253 | ||||
254 | static bool | |||
255 | type_all_ctors_visible_p (tree t) | |||
256 | { | |||
257 | return !flag_ltransglobal_options.x_flag_ltrans | |||
258 | && symtab->state >= CONSTRUCTION | |||
259 | /* We cannot always use type_all_derivations_known_p. | |||
260 | For function local types we must assume case where | |||
261 | the function is COMDAT and shared in between units. | |||
262 | ||||
263 | TODO: These cases are quite easy to get, but we need | |||
264 | to keep track of C++ privatizing via -Wno-weak | |||
265 | as well as the IPA privatizing. */ | |||
266 | && type_in_anonymous_namespace_p (t); | |||
267 | } | |||
268 | ||||
269 | /* Return TRUE if type may have instance. */ | |||
270 | ||||
271 | static bool | |||
272 | type_possibly_instantiated_p (tree t) | |||
273 | { | |||
274 | tree vtable; | |||
275 | varpool_node *vnode; | |||
276 | ||||
277 | /* TODO: Add abstract types here. */ | |||
278 | if (!type_all_ctors_visible_p (t)) | |||
279 | return true; | |||
280 | ||||
281 | vtable = BINFO_VTABLE (TYPE_BINFO (t))((tree_check ((((tree_check3 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 281, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 281, __FUNCTION__, (TREE_BINFO)))->binfo.vtable); | |||
282 | if (TREE_CODE (vtable)((enum tree_code) (vtable)->base.code) == POINTER_PLUS_EXPR) | |||
283 | vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((vtable), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 283, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 283, __FUNCTION__))))); | |||
284 | vnode = varpool_node::get (vtable); | |||
285 | return vnode && vnode->definition; | |||
286 | } | |||
287 | ||||
288 | /* Return true if T or type derived from T may have instance. */ | |||
289 | ||||
290 | static bool | |||
291 | type_or_derived_type_possibly_instantiated_p (odr_type t) | |||
292 | { | |||
293 | if (type_possibly_instantiated_p (t->type)) | |||
294 | return true; | |||
295 | for (auto derived : t->derived_types) | |||
296 | if (type_or_derived_type_possibly_instantiated_p (derived)) | |||
297 | return true; | |||
298 | return false; | |||
299 | } | |||
300 | ||||
301 | /* Hash used to unify ODR types based on their mangled name and for anonymous | |||
302 | namespace types. */ | |||
303 | ||||
304 | struct odr_name_hasher : pointer_hash <odr_type_d> | |||
305 | { | |||
306 | typedef union tree_node *compare_type; | |||
307 | static inline hashval_t hash (const odr_type_d *); | |||
308 | static inline bool equal (const odr_type_d *, const tree_node *); | |||
309 | static inline void remove (odr_type_d *); | |||
310 | }; | |||
311 | ||||
312 | static bool | |||
313 | can_be_name_hashed_p (tree t) | |||
314 | { | |||
315 | return (!in_lto_pglobal_options.x_in_lto_p || odr_type_p (t)); | |||
316 | } | |||
317 | ||||
318 | /* Hash type by its ODR name. */ | |||
319 | ||||
320 | static hashval_t | |||
321 | hash_odr_name (const_tree t) | |||
322 | { | |||
323 | gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t)((void)(!(((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 323, __FUNCTION__))->type_common.main_variant) == t) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 323, __FUNCTION__), 0 : 0)); | |||
324 | ||||
325 | /* If not in LTO, all main variants are unique, so we can do | |||
326 | pointer hash. */ | |||
327 | if (!in_lto_pglobal_options.x_in_lto_p) | |||
328 | return htab_hash_pointer (t); | |||
329 | ||||
330 | /* Anonymous types are unique. */ | |||
331 | if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t)) | |||
332 | return htab_hash_pointer (t); | |||
333 | ||||
334 | gcc_checking_assert (TYPE_NAME (t)((void)(!(((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 334, __FUNCTION__))->type_common.name) && (((contains_struct_check ((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 335, __FUNCTION__))->type_common.name)), (TS_DECL_WITH_VIS ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 335, __FUNCTION__))->decl_with_vis.assembler_name) != (tree ) __null)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 335, __FUNCTION__), 0 : 0)) | |||
335 | && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t)))((void)(!(((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 334, __FUNCTION__))->type_common.name) && (((contains_struct_check ((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 335, __FUNCTION__))->type_common.name)), (TS_DECL_WITH_VIS ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 335, __FUNCTION__))->decl_with_vis.assembler_name) != (tree ) __null)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 335, __FUNCTION__), 0 : 0)); | |||
336 | return IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (TYPE_NAME (t)))((tree_check ((decl_assembler_name (((tree_class_check ((t), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 336, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 336, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.hash_value ); | |||
337 | } | |||
338 | ||||
339 | /* Return the computed hashcode for ODR_TYPE. */ | |||
340 | ||||
341 | inline hashval_t | |||
342 | odr_name_hasher::hash (const odr_type_d *odr_type) | |||
343 | { | |||
344 | return hash_odr_name (odr_type->type); | |||
345 | } | |||
346 | ||||
347 | /* For languages with One Definition Rule, work out if | |||
348 | types are the same based on their name. | |||
349 | ||||
350 | This is non-trivial for LTO where minor differences in | |||
351 | the type representation may have prevented type merging | |||
352 | to merge two copies of otherwise equivalent type. | |||
353 | ||||
354 | Until we start streaming mangled type names, this function works | |||
355 | only for polymorphic types. | |||
356 | */ | |||
357 | ||||
358 | bool | |||
359 | types_same_for_odr (const_tree type1, const_tree type2) | |||
360 | { | |||
361 | gcc_checking_assert (TYPE_P (type1) && TYPE_P (type2))((void)(!((tree_code_type_tmpl <0>::tree_code_type[(int ) (((enum tree_code) (type1)->base.code))] == tcc_type) && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (type2)->base.code))] == tcc_type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 361, __FUNCTION__), 0 : 0)); | |||
362 | ||||
363 | type1 = TYPE_MAIN_VARIANT (type1)((tree_class_check ((type1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 363, __FUNCTION__))->type_common.main_variant); | |||
364 | type2 = TYPE_MAIN_VARIANT (type2)((tree_class_check ((type2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 364, __FUNCTION__))->type_common.main_variant); | |||
365 | ||||
366 | if (type1 == type2) | |||
367 | return true; | |||
368 | ||||
369 | if (!in_lto_pglobal_options.x_in_lto_p) | |||
370 | return false; | |||
371 | ||||
372 | /* Anonymous namespace types are never duplicated. */ | |||
373 | if ((type_with_linkage_p (type1) && type_in_anonymous_namespace_p (type1)) | |||
374 | || (type_with_linkage_p (type2) && type_in_anonymous_namespace_p (type2))) | |||
375 | return false; | |||
376 | ||||
377 | /* If both type has mangled defined check if they are same. | |||
378 | Watch for anonymous types which are all mangled as "<anon">. */ | |||
379 | if (!type_with_linkage_p (type1) || !type_with_linkage_p (type2)) | |||
380 | return false; | |||
381 | if (type_in_anonymous_namespace_p (type1) | |||
382 | || type_in_anonymous_namespace_p (type2)) | |||
383 | return false; | |||
384 | return (DECL_ASSEMBLER_NAME (TYPE_NAME (type1))decl_assembler_name (((tree_class_check ((type1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 384, __FUNCTION__))->type_common.name)) | |||
385 | == DECL_ASSEMBLER_NAME (TYPE_NAME (type2))decl_assembler_name (((tree_class_check ((type2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 385, __FUNCTION__))->type_common.name))); | |||
386 | } | |||
387 | ||||
388 | /* Return true if we can decide on ODR equivalency. | |||
389 | ||||
390 | In non-LTO it is always decide, in LTO however it depends in the type has | |||
391 | ODR info attached. */ | |||
392 | ||||
393 | bool | |||
394 | types_odr_comparable (tree t1, tree t2) | |||
395 | { | |||
396 | return (!in_lto_pglobal_options.x_in_lto_p | |||
397 | || TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 397, __FUNCTION__))->type_common.main_variant) == TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 397, __FUNCTION__))->type_common.main_variant) | |||
398 | || (odr_type_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 398, __FUNCTION__))->type_common.main_variant)) | |||
399 | && odr_type_p (TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 399, __FUNCTION__))->type_common.main_variant)))); | |||
400 | } | |||
401 | ||||
402 | /* Return true if T1 and T2 are ODR equivalent. If ODR equivalency is not | |||
403 | known, be conservative and return false. */ | |||
404 | ||||
405 | bool | |||
406 | types_must_be_same_for_odr (tree t1, tree t2) | |||
407 | { | |||
408 | if (types_odr_comparable (t1, t2)) | |||
409 | return types_same_for_odr (t1, t2); | |||
410 | else | |||
411 | return TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 411, __FUNCTION__))->type_common.main_variant) == TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 411, __FUNCTION__))->type_common.main_variant); | |||
412 | } | |||
413 | ||||
414 | /* If T is compound type, return type it is based on. */ | |||
415 | ||||
416 | static tree | |||
417 | compound_type_base (const_tree t) | |||
418 | { | |||
419 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_TYPE | |||
420 | || POINTER_TYPE_P (t)(((enum tree_code) (t)->base.code) == POINTER_TYPE || ((enum tree_code) (t)->base.code) == REFERENCE_TYPE) | |||
421 | || TREE_CODE (t)((enum tree_code) (t)->base.code) == COMPLEX_TYPE | |||
422 | || VECTOR_TYPE_P (t)(((enum tree_code) (t)->base.code) == VECTOR_TYPE)) | |||
423 | return TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 423, __FUNCTION__))->typed.type); | |||
424 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == METHOD_TYPE) | |||
425 | return TYPE_METHOD_BASETYPE (t)((tree_check2 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 425, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .maxval); | |||
426 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == OFFSET_TYPE) | |||
427 | return TYPE_OFFSET_BASETYPE (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 427, __FUNCTION__, (OFFSET_TYPE)))->type_non_common.maxval ); | |||
428 | return NULL_TREE(tree) __null; | |||
429 | } | |||
430 | ||||
431 | /* Return true if T is either ODR type or compound type based from it. | |||
432 | If the function return true, we know that T is a type originating from C++ | |||
433 | source even at link-time. */ | |||
434 | ||||
435 | bool | |||
436 | odr_or_derived_type_p (const_tree t) | |||
437 | { | |||
438 | do | |||
439 | { | |||
440 | if (odr_type_p (TYPE_MAIN_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 440, __FUNCTION__))->type_common.main_variant))) | |||
441 | return true; | |||
442 | /* Function type is a tricky one. Basically we can consider it | |||
443 | ODR derived if return type or any of the parameters is. | |||
444 | We need to check all parameters because LTO streaming merges | |||
445 | common types (such as void) and they are not considered ODR then. */ | |||
446 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == FUNCTION_TYPE) | |||
447 | { | |||
448 | if (TYPE_METHOD_BASETYPE (t)((tree_check2 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 448, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .maxval)) | |||
449 | t = TYPE_METHOD_BASETYPE (t)((tree_check2 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 449, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .maxval); | |||
450 | else | |||
451 | { | |||
452 | if (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 452, __FUNCTION__))->typed.type) && odr_or_derived_type_p (TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 452, __FUNCTION__))->typed.type))) | |||
453 | return true; | |||
454 | for (t = TYPE_ARG_TYPES (t)((tree_check2 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 454, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); t; t = TREE_CHAIN (t)((contains_struct_check ((t), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 454, __FUNCTION__))->common.chain)) | |||
455 | if (odr_or_derived_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (t))((tree_class_check ((((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 455, __FUNCTION__, (TREE_LIST)))->list.value)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 455, __FUNCTION__))->type_common.main_variant))) | |||
456 | return true; | |||
457 | return false; | |||
458 | } | |||
459 | } | |||
460 | else | |||
461 | t = compound_type_base (t); | |||
462 | } | |||
463 | while (t); | |||
464 | return t; | |||
465 | } | |||
466 | ||||
467 | /* Compare types T1 and T2 and return true if they are | |||
468 | equivalent. */ | |||
469 | ||||
470 | inline bool | |||
471 | odr_name_hasher::equal (const odr_type_d *o1, const tree_node *t2) | |||
472 | { | |||
473 | tree t1 = o1->type; | |||
474 | ||||
475 | gcc_checking_assert (TYPE_MAIN_VARIANT (t2) == t2)((void)(!(((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 475, __FUNCTION__))->type_common.main_variant) == t2) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 475, __FUNCTION__), 0 : 0)); | |||
476 | gcc_checking_assert (TYPE_MAIN_VARIANT (t1) == t1)((void)(!(((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 476, __FUNCTION__))->type_common.main_variant) == t1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 476, __FUNCTION__), 0 : 0)); | |||
477 | if (t1 == t2) | |||
478 | return true; | |||
479 | if (!in_lto_pglobal_options.x_in_lto_p) | |||
480 | return false; | |||
481 | /* Check for anonymous namespaces. */ | |||
482 | if ((type_with_linkage_p (t1) && type_in_anonymous_namespace_p (t1)) | |||
483 | || (type_with_linkage_p (t2) && type_in_anonymous_namespace_p (t2))) | |||
484 | return false; | |||
485 | gcc_checking_assert (DECL_ASSEMBLER_NAME (TYPE_NAME (t1)))((void)(!(decl_assembler_name (((tree_class_check ((t1), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 485, __FUNCTION__))->type_common.name))) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 485, __FUNCTION__), 0 : 0)); | |||
486 | gcc_checking_assert (DECL_ASSEMBLER_NAME (TYPE_NAME (t2)))((void)(!(decl_assembler_name (((tree_class_check ((t2), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 486, __FUNCTION__))->type_common.name))) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 486, __FUNCTION__), 0 : 0)); | |||
487 | return (DECL_ASSEMBLER_NAME (TYPE_NAME (t1))decl_assembler_name (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 487, __FUNCTION__))->type_common.name)) | |||
488 | == DECL_ASSEMBLER_NAME (TYPE_NAME (t2))decl_assembler_name (((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 488, __FUNCTION__))->type_common.name))); | |||
489 | } | |||
490 | ||||
491 | /* Free ODR type V. */ | |||
492 | ||||
493 | inline void | |||
494 | odr_name_hasher::remove (odr_type_d *v) | |||
495 | { | |||
496 | v->bases.release (); | |||
497 | v->derived_types.release (); | |||
498 | if (v->types_set) | |||
499 | delete v->types_set; | |||
500 | ggc_free (v); | |||
501 | } | |||
502 | ||||
503 | /* ODR type hash used to look up ODR type based on tree type node. */ | |||
504 | ||||
505 | typedef hash_table<odr_name_hasher> odr_hash_type; | |||
506 | static odr_hash_type *odr_hash; | |||
507 | ||||
508 | /* ODR types are also stored into ODR_TYPE vector to allow consistent | |||
509 | walking. Bases appear before derived types. Vector is garbage collected | |||
510 | so we won't end up visiting empty types. */ | |||
511 | ||||
512 | static GTY(()) vec <odr_type, va_gc> *odr_types_ptr; | |||
513 | #define odr_types(*odr_types_ptr) (*odr_types_ptr) | |||
514 | ||||
515 | /* All enums defined and accessible for the unit. */ | |||
516 | static GTY(()) vec <tree, va_gc> *odr_enums; | |||
517 | ||||
518 | /* Information we hold about value defined by an enum type. */ | |||
519 | struct odr_enum_val | |||
520 | { | |||
521 | const char *name; | |||
522 | wide_int val; | |||
523 | location_t locus; | |||
524 | }; | |||
525 | ||||
526 | /* Information about enum values. */ | |||
527 | struct odr_enum | |||
528 | { | |||
529 | location_t locus; | |||
530 | auto_vec<odr_enum_val, 0> vals; | |||
531 | bool warned; | |||
532 | }; | |||
533 | ||||
534 | /* A table of all ODR enum definitions. */ | |||
535 | static hash_map <nofree_string_hash, odr_enum> *odr_enum_map = NULL__null; | |||
536 | static struct obstack odr_enum_obstack; | |||
537 | ||||
538 | /* Set TYPE_BINFO of TYPE and its variants to BINFO. */ | |||
539 | void | |||
540 | set_type_binfo (tree type, tree binfo) | |||
541 | { | |||
542 | for (; type; type = TYPE_NEXT_VARIANT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 542, __FUNCTION__))->type_common.next_variant)) | |||
543 | if (COMPLETE_TYPE_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 543, __FUNCTION__))->type_common.size) != (tree) __null)) | |||
544 | TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 544, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) = binfo; | |||
545 | else | |||
546 | gcc_assert (!TYPE_BINFO (type))((void)(!(!((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 546, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 546, __FUNCTION__), 0 : 0)); | |||
547 | } | |||
548 | ||||
549 | /* Return true if type variants match. | |||
550 | This assumes that we already verified that T1 and T2 are variants of the | |||
551 | same type. */ | |||
552 | ||||
553 | static bool | |||
554 | type_variants_equivalent_p (tree t1, tree t2) | |||
555 | { | |||
556 | if (TYPE_QUALS (t1)((int) ((((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8)))) != TYPE_QUALS (t2)((int) ((((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.readonly_flag) * TYPE_QUAL_CONST ) | (((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.volatile_flag) * TYPE_QUAL_VOLATILE ) | (((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.u.bits.atomic_flag) * TYPE_QUAL_ATOMIC ) | (((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->type_common.restrict_flag) * TYPE_QUAL_RESTRICT ) | (((((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 556, __FUNCTION__))->base.u.bits.address_space) & 0xFF ) << 8))))) | |||
557 | return false; | |||
558 | ||||
559 | if (comp_type_attributes (t1, t2) != 1) | |||
560 | return false; | |||
561 | ||||
562 | if (COMPLETE_TYPE_P (t1)(((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 562, __FUNCTION__))->type_common.size) != (tree) __null) && COMPLETE_TYPE_P (t2)(((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 562, __FUNCTION__))->type_common.size) != (tree) __null) | |||
563 | && TYPE_ALIGN (t1)(((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 563, __FUNCTION__))->type_common.align) ? ((unsigned)1) << (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 563, __FUNCTION__))->type_common.align) - 1) : 0) != TYPE_ALIGN (t2)(((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 563, __FUNCTION__))->type_common.align) ? ((unsigned)1) << (((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 563, __FUNCTION__))->type_common.align) - 1) : 0)) | |||
564 | return false; | |||
565 | ||||
566 | return true; | |||
567 | } | |||
568 | ||||
569 | /* Compare T1 and T2 based on name or structure. */ | |||
570 | ||||
571 | static bool | |||
572 | odr_subtypes_equivalent_p (tree t1, tree t2, | |||
573 | hash_set<type_pair> *visited, | |||
574 | location_t loc1, location_t loc2) | |||
575 | { | |||
576 | ||||
577 | /* This can happen in incomplete types that should be handled earlier. */ | |||
578 | gcc_assert (t1 && t2)((void)(!(t1 && t2) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 578, __FUNCTION__), 0 : 0)); | |||
579 | ||||
580 | if (t1 == t2) | |||
581 | return true; | |||
582 | ||||
583 | /* Anonymous namespace types must match exactly. */ | |||
584 | if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 584, __FUNCTION__))->type_common.main_variant)) | |||
585 | && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 585, __FUNCTION__))->type_common.main_variant))) | |||
586 | || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 586, __FUNCTION__))->type_common.main_variant)) | |||
587 | && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 587, __FUNCTION__))->type_common.main_variant)))) | |||
588 | return false; | |||
589 | ||||
590 | /* For ODR types be sure to compare their names. | |||
591 | To support -Wno-odr-type-merging we allow one type to be non-ODR | |||
592 | and other ODR even though it is a violation. */ | |||
593 | if (types_odr_comparable (t1, t2)) | |||
594 | { | |||
595 | if (t1 != t2 | |||
596 | && odr_type_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 596, __FUNCTION__))->type_common.main_variant)) | |||
597 | && get_odr_type (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 597, __FUNCTION__))->type_common.main_variant), true)->odr_violated) | |||
598 | return false; | |||
599 | if (!types_same_for_odr (t1, t2)) | |||
600 | return false; | |||
601 | if (!type_variants_equivalent_p (t1, t2)) | |||
602 | return false; | |||
603 | /* Limit recursion: If subtypes are ODR types and we know | |||
604 | that they are same, be happy. */ | |||
605 | if (odr_type_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 605, __FUNCTION__))->type_common.main_variant))) | |||
606 | return true; | |||
607 | } | |||
608 | ||||
609 | /* Component types, builtins and possibly violating ODR types | |||
610 | have to be compared structurally. */ | |||
611 | if (TREE_CODE (t1)((enum tree_code) (t1)->base.code) != TREE_CODE (t2)((enum tree_code) (t2)->base.code)) | |||
612 | return false; | |||
613 | if (AGGREGATE_TYPE_P (t1)(((enum tree_code) (t1)->base.code) == ARRAY_TYPE || (((enum tree_code) (t1)->base.code) == RECORD_TYPE || ((enum tree_code ) (t1)->base.code) == UNION_TYPE || ((enum tree_code) (t1) ->base.code) == QUAL_UNION_TYPE)) | |||
614 | && (TYPE_NAME (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 614, __FUNCTION__))->type_common.name) == NULL_TREE(tree) __null) != (TYPE_NAME (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 614, __FUNCTION__))->type_common.name) == NULL_TREE(tree) __null)) | |||
615 | return false; | |||
616 | ||||
617 | type_pair pair={TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 617, __FUNCTION__))->type_common.main_variant), TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 617, __FUNCTION__))->type_common.main_variant)}; | |||
618 | if (TYPE_UID (TYPE_MAIN_VARIANT (t1))((tree_class_check ((((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 618, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 618, __FUNCTION__))->type_common.uid) > TYPE_UID (TYPE_MAIN_VARIANT (t2))((tree_class_check ((((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 618, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 618, __FUNCTION__))->type_common.uid)) | |||
619 | { | |||
620 | pair.first = TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 620, __FUNCTION__))->type_common.main_variant); | |||
621 | pair.second = TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 621, __FUNCTION__))->type_common.main_variant); | |||
622 | } | |||
623 | if (visited->add (pair)) | |||
624 | return true; | |||
625 | if (!odr_types_equivalent_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 625, __FUNCTION__))->type_common.main_variant), TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 625, __FUNCTION__))->type_common.main_variant), | |||
626 | false, NULL__null, visited, loc1, loc2)) | |||
627 | return false; | |||
628 | if (!type_variants_equivalent_p (t1, t2)) | |||
629 | return false; | |||
630 | return true; | |||
631 | } | |||
632 | ||||
633 | /* Return true if DECL1 and DECL2 are identical methods. Consider | |||
634 | name equivalent to name.localalias.xyz. */ | |||
635 | ||||
636 | static bool | |||
637 | methods_equal_p (tree decl1, tree decl2) | |||
638 | { | |||
639 | if (DECL_ASSEMBLER_NAME (decl1)decl_assembler_name (decl1) == DECL_ASSEMBLER_NAME (decl2)decl_assembler_name (decl2)) | |||
640 | return true; | |||
641 | const char sep = symbol_table::symbol_suffix_separator (); | |||
642 | ||||
643 | const char *name1 = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl1))((const char *) (tree_check ((decl_assembler_name (decl1)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 643, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); | |||
644 | const char *ptr1 = strchr (name1, sep); | |||
645 | int len1 = ptr1 ? ptr1 - name1 : strlen (name1); | |||
646 | ||||
647 | const char *name2 = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl2))((const char *) (tree_check ((decl_assembler_name (decl2)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 647, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); | |||
648 | const char *ptr2 = strchr (name2, sep); | |||
649 | int len2 = ptr2 ? ptr2 - name2 : strlen (name2); | |||
650 | ||||
651 | if (len1 != len2) | |||
652 | return false; | |||
653 | return !strncmp (name1, name2, len1); | |||
654 | } | |||
655 | ||||
656 | /* Compare two virtual tables, PREVAILING and VTABLE and output ODR | |||
657 | violation warnings. */ | |||
658 | ||||
659 | void | |||
660 | compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable) | |||
661 | { | |||
662 | int n1, n2; | |||
663 | ||||
664 | if (DECL_VIRTUAL_P (prevailing->decl)((contains_struct_check ((prevailing->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 664, __FUNCTION__))->decl_common.virtual_flag) != DECL_VIRTUAL_P (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 664, __FUNCTION__))->decl_common.virtual_flag)) | |||
665 | { | |||
666 | odr_violation_reported = true; | |||
667 | if (DECL_VIRTUAL_P (prevailing->decl)((contains_struct_check ((prevailing->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 667, __FUNCTION__))->decl_common.virtual_flag)) | |||
668 | { | |||
669 | varpool_node *tmp = prevailing; | |||
670 | prevailing = vtable; | |||
671 | vtable = tmp; | |||
672 | } | |||
673 | auto_diagnostic_group d; | |||
674 | if (warning_at (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 675, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 675, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 675, __FUNCTION__))->decl_minimal.locus) | |||
675 | (TYPE_NAME (DECL_CONTEXT (vtable->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 675, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 675, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 675, __FUNCTION__))->decl_minimal.locus), | |||
676 | OPT_Wodr, | |||
677 | "virtual table of type %qD violates one definition rule", | |||
678 | DECL_CONTEXT (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 678, __FUNCTION__))->decl_minimal.context))) | |||
679 | inform (DECL_SOURCE_LOCATION (prevailing->decl)((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 679, __FUNCTION__))->decl_minimal.locus), | |||
680 | "variable of same assembler name as the virtual table is " | |||
681 | "defined in another translation unit"); | |||
682 | return; | |||
683 | } | |||
684 | if (!prevailing->definition || !vtable->definition) | |||
685 | return; | |||
686 | ||||
687 | /* If we do not stream ODR type info, do not bother to do useful compare. */ | |||
688 | if (!TYPE_BINFO (DECL_CONTEXT (vtable->decl))((tree_check3 ((((contains_struct_check ((vtable->decl), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 688, __FUNCTION__))->decl_minimal.context)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 688, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
689 | || !polymorphic_type_binfo_p (TYPE_BINFO (DECL_CONTEXT (vtable->decl))((tree_check3 ((((contains_struct_check ((vtable->decl), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 689, __FUNCTION__))->decl_minimal.context)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 689, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval))) | |||
690 | return; | |||
691 | ||||
692 | odr_type class_type = get_odr_type (DECL_CONTEXT (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 692, __FUNCTION__))->decl_minimal.context), true); | |||
693 | ||||
694 | if (class_type->odr_violated) | |||
695 | return; | |||
696 | ||||
697 | for (n1 = 0, n2 = 0; true; n1++, n2++) | |||
698 | { | |||
699 | struct ipa_ref *ref1, *ref2; | |||
700 | bool end1, end2; | |||
701 | ||||
702 | end1 = !prevailing->iterate_reference (n1, ref1); | |||
703 | end2 = !vtable->iterate_reference (n2, ref2); | |||
704 | ||||
705 | /* !DECL_VIRTUAL_P means RTTI entry; | |||
706 | We warn when RTTI is lost because non-RTTI prevails; we silently | |||
707 | accept the other case. */ | |||
708 | while (!end2 | |||
709 | && (end1 | |||
710 | || (methods_equal_p (ref1->referred->decl, | |||
711 | ref2->referred->decl) | |||
712 | && TREE_CODE (ref1->referred->decl)((enum tree_code) (ref1->referred->decl)->base.code) == FUNCTION_DECL)) | |||
713 | && TREE_CODE (ref2->referred->decl)((enum tree_code) (ref2->referred->decl)->base.code) != FUNCTION_DECL) | |||
714 | { | |||
715 | if (!class_type->rtti_broken) | |||
716 | { | |||
717 | auto_diagnostic_group d; | |||
718 | if (warning_at (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 719, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 719, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 719, __FUNCTION__))->decl_minimal.locus) | |||
719 | (TYPE_NAME (DECL_CONTEXT (vtable->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 719, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 719, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 719, __FUNCTION__))->decl_minimal.locus), | |||
720 | OPT_Wodr, | |||
721 | "virtual table of type %qD contains RTTI " | |||
722 | "information", | |||
723 | DECL_CONTEXT (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 723, __FUNCTION__))->decl_minimal.context))) | |||
724 | { | |||
725 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 726, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 726, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 726, __FUNCTION__))->decl_minimal.locus) | |||
726 | (TYPE_NAME (DECL_CONTEXT (prevailing->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 726, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 726, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 726, __FUNCTION__))->decl_minimal.locus), | |||
727 | "but is prevailed by one without from other" | |||
728 | " translation unit"); | |||
729 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 730, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 730, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 730, __FUNCTION__))->decl_minimal.locus) | |||
730 | (TYPE_NAME (DECL_CONTEXT (prevailing->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 730, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 730, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 730, __FUNCTION__))->decl_minimal.locus), | |||
731 | "RTTI will not work on this type"); | |||
732 | class_type->rtti_broken = true; | |||
733 | } | |||
734 | } | |||
735 | n2++; | |||
736 | end2 = !vtable->iterate_reference (n2, ref2); | |||
737 | } | |||
738 | while (!end1 | |||
739 | && (end2 | |||
740 | || (methods_equal_p (ref2->referred->decl, ref1->referred->decl) | |||
741 | && TREE_CODE (ref2->referred->decl)((enum tree_code) (ref2->referred->decl)->base.code) == FUNCTION_DECL)) | |||
742 | && TREE_CODE (ref1->referred->decl)((enum tree_code) (ref1->referred->decl)->base.code) != FUNCTION_DECL) | |||
743 | { | |||
744 | n1++; | |||
745 | end1 = !prevailing->iterate_reference (n1, ref1); | |||
746 | } | |||
747 | ||||
748 | /* Finished? */ | |||
749 | if (end1 && end2) | |||
750 | { | |||
751 | /* Extra paranoia; compare the sizes. We do not have information | |||
752 | about virtual inheritance offsets, so just be sure that these | |||
753 | match. | |||
754 | Do this as very last check so the not very informative error | |||
755 | is not output too often. */ | |||
756 | if (DECL_SIZE (prevailing->decl)((contains_struct_check ((prevailing->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 756, __FUNCTION__))->decl_common.size) != DECL_SIZE (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 756, __FUNCTION__))->decl_common.size)) | |||
757 | { | |||
758 | class_type->odr_violated = true; | |||
759 | auto_diagnostic_group d; | |||
760 | tree ctx = TYPE_NAME (DECL_CONTEXT (vtable->decl))((tree_class_check ((((contains_struct_check ((vtable->decl ), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 760, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 760, __FUNCTION__))->type_common.name); | |||
761 | if (warning_at (DECL_SOURCE_LOCATION (ctx)((contains_struct_check ((ctx), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 761, __FUNCTION__))->decl_minimal.locus), OPT_Wodr, | |||
762 | "virtual table of type %qD violates " | |||
763 | "one definition rule", | |||
764 | DECL_CONTEXT (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 764, __FUNCTION__))->decl_minimal.context))) | |||
765 | { | |||
766 | ctx = TYPE_NAME (DECL_CONTEXT (prevailing->decl))((tree_class_check ((((contains_struct_check ((prevailing-> decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 766, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 766, __FUNCTION__))->type_common.name); | |||
767 | inform (DECL_SOURCE_LOCATION (ctx)((contains_struct_check ((ctx), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 767, __FUNCTION__))->decl_minimal.locus), | |||
768 | "the conflicting type defined in another translation" | |||
769 | " unit has virtual table of different size"); | |||
770 | } | |||
771 | } | |||
772 | return; | |||
773 | } | |||
774 | ||||
775 | if (!end1 && !end2) | |||
776 | { | |||
777 | if (methods_equal_p (ref1->referred->decl, ref2->referred->decl)) | |||
778 | continue; | |||
779 | ||||
780 | class_type->odr_violated = true; | |||
781 | ||||
782 | /* If the loops above stopped on non-virtual pointer, we have | |||
783 | mismatch in RTTI information mangling. */ | |||
784 | if (TREE_CODE (ref1->referred->decl)((enum tree_code) (ref1->referred->decl)->base.code) != FUNCTION_DECL | |||
785 | && TREE_CODE (ref2->referred->decl)((enum tree_code) (ref2->referred->decl)->base.code) != FUNCTION_DECL) | |||
786 | { | |||
787 | auto_diagnostic_group d; | |||
788 | if (warning_at (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 789, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 789, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 789, __FUNCTION__))->decl_minimal.locus) | |||
789 | (TYPE_NAME (DECL_CONTEXT (vtable->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 789, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 789, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 789, __FUNCTION__))->decl_minimal.locus), | |||
790 | OPT_Wodr, | |||
791 | "virtual table of type %qD violates " | |||
792 | "one definition rule", | |||
793 | DECL_CONTEXT (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 793, __FUNCTION__))->decl_minimal.context))) | |||
794 | { | |||
795 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 796, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 796, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 796, __FUNCTION__))->decl_minimal.locus) | |||
796 | (TYPE_NAME (DECL_CONTEXT (prevailing->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 796, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 796, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 796, __FUNCTION__))->decl_minimal.locus), | |||
797 | "the conflicting type defined in another translation " | |||
798 | "unit with different RTTI information"); | |||
799 | } | |||
800 | return; | |||
801 | } | |||
802 | /* At this point both REF1 and REF2 points either to virtual table | |||
803 | or virtual method. If one points to virtual table and other to | |||
804 | method we can complain the same way as if one table was shorter | |||
805 | than other pointing out the extra method. */ | |||
806 | if (TREE_CODE (ref1->referred->decl)((enum tree_code) (ref1->referred->decl)->base.code) | |||
807 | != TREE_CODE (ref2->referred->decl)((enum tree_code) (ref2->referred->decl)->base.code)) | |||
808 | { | |||
809 | if (VAR_P (ref1->referred->decl)(((enum tree_code) (ref1->referred->decl)->base.code ) == VAR_DECL)) | |||
810 | end1 = true; | |||
811 | else if (VAR_P (ref2->referred->decl)(((enum tree_code) (ref2->referred->decl)->base.code ) == VAR_DECL)) | |||
812 | end2 = true; | |||
813 | } | |||
814 | } | |||
815 | ||||
816 | class_type->odr_violated = true; | |||
817 | ||||
818 | /* Complain about size mismatch. Either we have too many virtual | |||
819 | functions or too many virtual table pointers. */ | |||
820 | if (end1 || end2) | |||
821 | { | |||
822 | if (end1) | |||
823 | { | |||
824 | varpool_node *tmp = prevailing; | |||
825 | prevailing = vtable; | |||
826 | vtable = tmp; | |||
827 | ref1 = ref2; | |||
828 | } | |||
829 | auto_diagnostic_group d; | |||
830 | if (warning_at (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 831, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 831, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 831, __FUNCTION__))->decl_minimal.locus) | |||
831 | (TYPE_NAME (DECL_CONTEXT (vtable->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 831, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 831, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 831, __FUNCTION__))->decl_minimal.locus), | |||
832 | OPT_Wodr, | |||
833 | "virtual table of type %qD violates " | |||
834 | "one definition rule", | |||
835 | DECL_CONTEXT (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 835, __FUNCTION__))->decl_minimal.context))) | |||
836 | { | |||
837 | if (TREE_CODE (ref1->referring->decl)((enum tree_code) (ref1->referring->decl)->base.code ) == FUNCTION_DECL) | |||
838 | { | |||
839 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 840, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 840, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 840, __FUNCTION__))->decl_minimal.locus) | |||
840 | (TYPE_NAME (DECL_CONTEXT (prevailing->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 840, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 840, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 840, __FUNCTION__))->decl_minimal.locus), | |||
841 | "the conflicting type defined in another translation " | |||
842 | "unit"); | |||
843 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((ref1->referring->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 844, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 844, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 844, __FUNCTION__))->decl_minimal.locus) | |||
844 | (TYPE_NAME (DECL_CONTEXT (ref1->referring->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((ref1->referring->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 844, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 844, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 844, __FUNCTION__))->decl_minimal.locus), | |||
845 | "contains additional virtual method %qD", | |||
846 | ref1->referred->decl); | |||
847 | } | |||
848 | else | |||
849 | { | |||
850 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 851, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 851, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 851, __FUNCTION__))->decl_minimal.locus) | |||
851 | (TYPE_NAME (DECL_CONTEXT (prevailing->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 851, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 851, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 851, __FUNCTION__))->decl_minimal.locus), | |||
852 | "the conflicting type defined in another translation " | |||
853 | "unit has virtual table with more entries"); | |||
854 | } | |||
855 | } | |||
856 | return; | |||
857 | } | |||
858 | ||||
859 | /* And in the last case we have either mismatch in between two virtual | |||
860 | methods or two virtual table pointers. */ | |||
861 | auto_diagnostic_group d; | |||
862 | if (warning_at (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 863, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 863, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 863, __FUNCTION__))->decl_minimal.locus) | |||
863 | (TYPE_NAME (DECL_CONTEXT (vtable->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 863, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 863, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 863, __FUNCTION__))->decl_minimal.locus), OPT_Wodr, | |||
864 | "virtual table of type %qD violates " | |||
865 | "one definition rule", | |||
866 | DECL_CONTEXT (vtable->decl)((contains_struct_check ((vtable->decl), (TS_DECL_MINIMAL) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 866, __FUNCTION__))->decl_minimal.context))) | |||
867 | { | |||
868 | if (TREE_CODE (ref1->referred->decl)((enum tree_code) (ref1->referred->decl)->base.code) == FUNCTION_DECL) | |||
869 | { | |||
870 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 871, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 871, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 871, __FUNCTION__))->decl_minimal.locus) | |||
871 | (TYPE_NAME (DECL_CONTEXT (prevailing->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 871, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 871, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 871, __FUNCTION__))->decl_minimal.locus), | |||
872 | "the conflicting type defined in another translation " | |||
873 | "unit"); | |||
874 | gcc_assert (TREE_CODE (ref2->referred->decl)((void)(!(((enum tree_code) (ref2->referred->decl)-> base.code) == FUNCTION_DECL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 875, __FUNCTION__), 0 : 0)) | |||
875 | == FUNCTION_DECL)((void)(!(((enum tree_code) (ref2->referred->decl)-> base.code) == FUNCTION_DECL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 875, __FUNCTION__), 0 : 0)); | |||
876 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((ref1->referred->ultimate_alias_target ()->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 877, __FUNCTION__))->decl_minimal.locus) | |||
877 | (ref1->referred->ultimate_alias_target ()->decl)((contains_struct_check ((ref1->referred->ultimate_alias_target ()->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 877, __FUNCTION__))->decl_minimal.locus), | |||
878 | "virtual method %qD", | |||
879 | ref1->referred->ultimate_alias_target ()->decl); | |||
880 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((ref2->referred->ultimate_alias_target ()->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 881, __FUNCTION__))->decl_minimal.locus) | |||
881 | (ref2->referred->ultimate_alias_target ()->decl)((contains_struct_check ((ref2->referred->ultimate_alias_target ()->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 881, __FUNCTION__))->decl_minimal.locus), | |||
882 | "ought to match virtual method %qD but does not", | |||
883 | ref2->referred->ultimate_alias_target ()->decl); | |||
884 | } | |||
885 | else | |||
886 | inform (DECL_SOURCE_LOCATION((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 887, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 887, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 887, __FUNCTION__))->decl_minimal.locus) | |||
887 | (TYPE_NAME (DECL_CONTEXT (prevailing->decl)))((contains_struct_check ((((tree_class_check ((((contains_struct_check ((prevailing->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 887, __FUNCTION__))->decl_minimal.context)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 887, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 887, __FUNCTION__))->decl_minimal.locus), | |||
888 | "the conflicting type defined in another translation " | |||
889 | "unit has virtual table with different contents"); | |||
890 | return; | |||
891 | } | |||
892 | } | |||
893 | } | |||
894 | ||||
895 | /* Output ODR violation warning about T1 and T2 with REASON. | |||
896 | Display location of ST1 and ST2 if REASON speaks about field or | |||
897 | method of the type. | |||
898 | If WARN is false, do nothing. Set WARNED if warning was indeed | |||
899 | output. */ | |||
900 | ||||
901 | static void | |||
902 | warn_odr (tree t1, tree t2, tree st1, tree st2, | |||
903 | bool warn, bool *warned, const char *reason) | |||
904 | { | |||
905 | tree decl2 = TYPE_NAME (TYPE_MAIN_VARIANT (t2))((tree_class_check ((((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 905, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 905, __FUNCTION__))->type_common.name); | |||
906 | if (warned) | |||
907 | *warned = false; | |||
908 | ||||
909 | if (!warn || !TYPE_NAME(TYPE_MAIN_VARIANT (t1))((tree_class_check ((((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 909, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 909, __FUNCTION__))->type_common.name)) | |||
910 | return; | |||
911 | ||||
912 | /* ODR warnings are output during LTO streaming; we must apply location | |||
913 | cache for potential warnings to be output correctly. */ | |||
914 | if (lto_location_cache::current_cache) | |||
915 | lto_location_cache::current_cache->apply_location_cache (); | |||
916 | ||||
917 | auto_diagnostic_group d; | |||
918 | if (t1 != TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 918, __FUNCTION__))->type_common.main_variant) | |||
919 | && TYPE_NAME (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 919, __FUNCTION__))->type_common.name) != TYPE_NAME (TYPE_MAIN_VARIANT (t1))((tree_class_check ((((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 919, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 919, __FUNCTION__))->type_common.name)) | |||
920 | { | |||
921 | if (!warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (TYPE_MAIN_VARIANT (t1)))((contains_struct_check ((((tree_class_check ((((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 921, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 921, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 921, __FUNCTION__))->decl_minimal.locus), | |||
922 | OPT_Wodr, "type %qT (typedef of %qT) violates the " | |||
923 | "C++ One Definition Rule", | |||
924 | t1, TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 924, __FUNCTION__))->type_common.main_variant))) | |||
925 | return; | |||
926 | } | |||
927 | else | |||
928 | { | |||
929 | if (!warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (TYPE_MAIN_VARIANT (t1)))((contains_struct_check ((((tree_class_check ((((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 929, __FUNCTION__))->type_common.main_variant)), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 929, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 929, __FUNCTION__))->decl_minimal.locus), | |||
930 | OPT_Wodr, "type %qT violates the C++ One Definition Rule", | |||
931 | t1)) | |||
932 | return; | |||
933 | } | |||
934 | if (!st1 && !st2) | |||
935 | ; | |||
936 | /* For FIELD_DECL support also case where one of fields is | |||
937 | NULL - this is used when the structures have mismatching number of | |||
938 | elements. */ | |||
939 | else if (!st1 || TREE_CODE (st1)((enum tree_code) (st1)->base.code) == FIELD_DECL) | |||
940 | { | |||
941 | inform (DECL_SOURCE_LOCATION (decl2)((contains_struct_check ((decl2), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 941, __FUNCTION__))->decl_minimal.locus), | |||
942 | "a different type is defined in another translation unit"); | |||
943 | if (!st1) | |||
944 | { | |||
945 | st1 = st2; | |||
946 | st2 = NULL__null; | |||
947 | } | |||
948 | inform (DECL_SOURCE_LOCATION (st1)((contains_struct_check ((st1), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 948, __FUNCTION__))->decl_minimal.locus), | |||
949 | "the first difference of corresponding definitions is field %qD", | |||
950 | st1); | |||
951 | if (st2) | |||
952 | decl2 = st2; | |||
953 | } | |||
954 | else if (TREE_CODE (st1)((enum tree_code) (st1)->base.code) == FUNCTION_DECL) | |||
955 | { | |||
956 | inform (DECL_SOURCE_LOCATION (decl2)((contains_struct_check ((decl2), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 956, __FUNCTION__))->decl_minimal.locus), | |||
957 | "a different type is defined in another translation unit"); | |||
958 | inform (DECL_SOURCE_LOCATION (st1)((contains_struct_check ((st1), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 958, __FUNCTION__))->decl_minimal.locus), | |||
959 | "the first difference of corresponding definitions is method %qD", | |||
960 | st1); | |||
961 | decl2 = st2; | |||
962 | } | |||
963 | else | |||
964 | return; | |||
965 | inform (DECL_SOURCE_LOCATION (decl2)((contains_struct_check ((decl2), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 965, __FUNCTION__))->decl_minimal.locus), reason); | |||
966 | ||||
967 | if (warned) | |||
968 | *warned = true; | |||
969 | } | |||
970 | ||||
971 | /* Return true if T1 and T2 are incompatible and we want to recursively | |||
972 | dive into them from warn_type_mismatch to give sensible answer. */ | |||
973 | ||||
974 | static bool | |||
975 | type_mismatch_p (tree t1, tree t2) | |||
976 | { | |||
977 | if (odr_or_derived_type_p (t1) && odr_or_derived_type_p (t2) | |||
978 | && !odr_types_equivalent_p (t1, t2)) | |||
979 | return true; | |||
980 | return !types_compatible_p (t1, t2); | |||
981 | } | |||
982 | ||||
983 | ||||
984 | /* Types T1 and T2 was found to be incompatible in a context they can't | |||
985 | (either used to declare a symbol of same assembler name or unified by | |||
986 | ODR rule). We already output warning about this, but if possible, output | |||
987 | extra information on how the types mismatch. | |||
988 | ||||
989 | This is hard to do in general. We basically handle the common cases. | |||
990 | ||||
991 | If LOC1 and LOC2 are meaningful locations, use it in the case the types | |||
992 | themselves do not have one. */ | |||
993 | ||||
994 | void | |||
995 | warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2) | |||
996 | { | |||
997 | /* Location of type is known only if it has TYPE_NAME and the name is | |||
998 | TYPE_DECL. */ | |||
999 | location_t loc_t1 = TYPE_NAME (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 999, __FUNCTION__))->type_common.name) && TREE_CODE (TYPE_NAME (t1))((enum tree_code) (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 999, __FUNCTION__))->type_common.name))->base.code) == TYPE_DECL | |||
1000 | ? DECL_SOURCE_LOCATION (TYPE_NAME (t1))((contains_struct_check ((((tree_class_check ((t1), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1000, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1000, __FUNCTION__))->decl_minimal.locus) | |||
1001 | : UNKNOWN_LOCATION((location_t) 0); | |||
1002 | location_t loc_t2 = TYPE_NAME (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1002, __FUNCTION__))->type_common.name) && TREE_CODE (TYPE_NAME (t2))((enum tree_code) (((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1002, __FUNCTION__))->type_common.name))->base.code) == TYPE_DECL | |||
1003 | ? DECL_SOURCE_LOCATION (TYPE_NAME (t2))((contains_struct_check ((((tree_class_check ((t2), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1003, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1003, __FUNCTION__))->decl_minimal.locus) | |||
1004 | : UNKNOWN_LOCATION((location_t) 0); | |||
1005 | bool loc_t2_useful = false; | |||
1006 | ||||
1007 | /* With LTO it is a common case that the location of both types match. | |||
1008 | See if T2 has a location that is different from T1. If so, we will | |||
1009 | inform user about the location. | |||
1010 | Do not consider the location passed to us in LOC1/LOC2 as those are | |||
1011 | already output. */ | |||
1012 | if (loc_t2 > BUILTINS_LOCATION((location_t) 1) && loc_t2 != loc_t1) | |||
1013 | { | |||
1014 | if (loc_t1 <= BUILTINS_LOCATION((location_t) 1)) | |||
1015 | loc_t2_useful = true; | |||
1016 | else | |||
1017 | { | |||
1018 | expanded_location xloc1 = expand_location (loc_t1); | |||
1019 | expanded_location xloc2 = expand_location (loc_t2); | |||
1020 | ||||
1021 | if (strcmp (xloc1.file, xloc2.file) | |||
1022 | || xloc1.line != xloc2.line | |||
1023 | || xloc1.column != xloc2.column) | |||
1024 | loc_t2_useful = true; | |||
1025 | } | |||
1026 | } | |||
1027 | ||||
1028 | if (loc_t1 <= BUILTINS_LOCATION((location_t) 1)) | |||
1029 | loc_t1 = loc1; | |||
1030 | if (loc_t2 <= BUILTINS_LOCATION((location_t) 1)) | |||
1031 | loc_t2 = loc2; | |||
1032 | ||||
1033 | location_t loc = loc_t1 <= BUILTINS_LOCATION((location_t) 1) ? loc_t2 : loc_t1; | |||
1034 | ||||
1035 | /* It is a quite common bug to reference anonymous namespace type in | |||
1036 | non-anonymous namespace class. */ | |||
1037 | tree mt1 = TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1037, __FUNCTION__))->type_common.main_variant); | |||
1038 | tree mt2 = TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1038, __FUNCTION__))->type_common.main_variant); | |||
1039 | if ((type_with_linkage_p (mt1) | |||
1040 | && type_in_anonymous_namespace_p (mt1)) | |||
1041 | || (type_with_linkage_p (mt2) | |||
1042 | && type_in_anonymous_namespace_p (mt2))) | |||
1043 | { | |||
1044 | if (!type_with_linkage_p (mt1) | |||
1045 | || !type_in_anonymous_namespace_p (mt1)) | |||
1046 | { | |||
1047 | std::swap (t1, t2); | |||
1048 | std::swap (mt1, mt2); | |||
1049 | std::swap (loc_t1, loc_t2); | |||
1050 | } | |||
1051 | gcc_assert (TYPE_NAME (mt1)((void)(!(((tree_class_check ((mt1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1051, __FUNCTION__))->type_common.name) && ((enum tree_code) (((tree_class_check ((mt1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1052, __FUNCTION__))->type_common.name))->base.code) == TYPE_DECL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1052, __FUNCTION__), 0 : 0)) | |||
1052 | && TREE_CODE (TYPE_NAME (mt1)) == TYPE_DECL)((void)(!(((tree_class_check ((mt1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1051, __FUNCTION__))->type_common.name) && ((enum tree_code) (((tree_class_check ((mt1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1052, __FUNCTION__))->type_common.name))->base.code) == TYPE_DECL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1052, __FUNCTION__), 0 : 0)); | |||
1053 | tree n1 = TYPE_NAME (mt1)((tree_class_check ((mt1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1053, __FUNCTION__))->type_common.name); | |||
1054 | tree n2 = TYPE_NAME (mt2)((tree_class_check ((mt2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1054, __FUNCTION__))->type_common.name) ? TYPE_NAME (mt2)((tree_class_check ((mt2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1054, __FUNCTION__))->type_common.name) : NULL__null; | |||
1055 | ||||
1056 | if (TREE_CODE (n1)((enum tree_code) (n1)->base.code) == TYPE_DECL) | |||
1057 | n1 = DECL_NAME (n1)((contains_struct_check ((n1), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1057, __FUNCTION__))->decl_minimal.name); | |||
1058 | if (n2 && TREE_CODE (n2)((enum tree_code) (n2)->base.code) == TYPE_DECL) | |||
1059 | n2 = DECL_NAME (n2)((contains_struct_check ((n2), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1059, __FUNCTION__))->decl_minimal.name); | |||
1060 | /* Most of the time, the type names will match, do not be unnecessarily | |||
1061 | verbose. */ | |||
1062 | if (n1 != n2) | |||
1063 | inform (loc_t1, | |||
1064 | "type %qT defined in anonymous namespace cannot match " | |||
1065 | "type %qT across the translation unit boundary", | |||
1066 | t1, t2); | |||
1067 | else | |||
1068 | inform (loc_t1, | |||
1069 | "type %qT defined in anonymous namespace cannot match " | |||
1070 | "across the translation unit boundary", | |||
1071 | t1); | |||
1072 | if (loc_t2_useful) | |||
1073 | inform (loc_t2, | |||
1074 | "the incompatible type defined in another translation unit"); | |||
1075 | return; | |||
1076 | } | |||
1077 | /* If types have mangled ODR names and they are different, it is most | |||
1078 | informative to output those. | |||
1079 | This also covers types defined in different namespaces. */ | |||
1080 | const char *odr1 = get_odr_name_for_type (mt1); | |||
1081 | const char *odr2 = get_odr_name_for_type (mt2); | |||
1082 | if (odr1 != NULL__null && odr2 != NULL__null && odr1 != odr2) | |||
1083 | { | |||
1084 | const int opts = DMGL_PARAMS(1 << 0) | DMGL_ANSI(1 << 1) | DMGL_TYPES(1 << 4); | |||
1085 | char *name1 = xstrdup (cplus_demangle (odr1, opts)); | |||
1086 | char *name2 = cplus_demangle (odr2, opts); | |||
1087 | if (name1 && name2 && strcmp (name1, name2)) | |||
1088 | { | |||
1089 | inform (loc_t1, | |||
1090 | "type name %qs should match type name %qs", | |||
1091 | name1, name2); | |||
1092 | if (loc_t2_useful) | |||
1093 | inform (loc_t2, | |||
1094 | "the incompatible type is defined here"); | |||
1095 | free (name1); | |||
1096 | return; | |||
1097 | } | |||
1098 | free (name1); | |||
1099 | } | |||
1100 | /* A tricky case are compound types. Often they appear the same in source | |||
1101 | code and the mismatch is dragged in by type they are build from. | |||
1102 | Look for those differences in subtypes and try to be informative. In other | |||
1103 | cases just output nothing because the source code is probably different | |||
1104 | and in this case we already output a all necessary info. */ | |||
1105 | if (!TYPE_NAME (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1105, __FUNCTION__))->type_common.name) || !TYPE_NAME (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1105, __FUNCTION__))->type_common.name)) | |||
1106 | { | |||
1107 | if (TREE_CODE (t1)((enum tree_code) (t1)->base.code) == TREE_CODE (t2)((enum tree_code) (t2)->base.code)) | |||
1108 | { | |||
1109 | if (TREE_CODE (t1)((enum tree_code) (t1)->base.code) == ARRAY_TYPE | |||
1110 | && COMPLETE_TYPE_P (t1)(((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1110, __FUNCTION__))->type_common.size) != (tree) __null ) && COMPLETE_TYPE_P (t2)(((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1110, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
1111 | { | |||
1112 | tree i1 = TYPE_DOMAIN (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1112, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ); | |||
1113 | tree i2 = TYPE_DOMAIN (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1113, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ); | |||
1114 | ||||
1115 | if (i1 && i2 | |||
1116 | && TYPE_MAX_VALUE (i1)((tree_check5 ((i1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1116, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ) | |||
1117 | && TYPE_MAX_VALUE (i2)((tree_check5 ((i2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1117, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ) | |||
1118 | && !operand_equal_p (TYPE_MAX_VALUE (i1)((tree_check5 ((i1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1118, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ), | |||
1119 | TYPE_MAX_VALUE (i2)((tree_check5 ((i2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1119, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ), 0)) | |||
1120 | { | |||
1121 | inform (loc, | |||
1122 | "array types have different bounds"); | |||
1123 | return; | |||
1124 | } | |||
1125 | } | |||
1126 | if ((POINTER_TYPE_P (t1)(((enum tree_code) (t1)->base.code) == POINTER_TYPE || ((enum tree_code) (t1)->base.code) == REFERENCE_TYPE) || TREE_CODE (t1)((enum tree_code) (t1)->base.code) == ARRAY_TYPE) | |||
1127 | && type_mismatch_p (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1127, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1127, __FUNCTION__))->typed.type))) | |||
1128 | warn_types_mismatch (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1128, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1128, __FUNCTION__))->typed.type), loc_t1, loc_t2); | |||
1129 | else if (TREE_CODE (t1)((enum tree_code) (t1)->base.code) == METHOD_TYPE | |||
1130 | || TREE_CODE (t1)((enum tree_code) (t1)->base.code) == FUNCTION_TYPE) | |||
1131 | { | |||
1132 | tree parms1 = NULL__null, parms2 = NULL__null; | |||
1133 | int count = 1; | |||
1134 | ||||
1135 | if (type_mismatch_p (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1135, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1135, __FUNCTION__))->typed.type))) | |||
1136 | { | |||
1137 | inform (loc, "return value type mismatch"); | |||
1138 | warn_types_mismatch (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1138, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1138, __FUNCTION__))->typed.type), loc_t1, | |||
1139 | loc_t2); | |||
1140 | return; | |||
1141 | } | |||
1142 | if (prototype_p (t1) && prototype_p (t2)) | |||
1143 | for (parms1 = TYPE_ARG_TYPES (t1)((tree_check2 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1143, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values), parms2 = TYPE_ARG_TYPES (t2)((tree_check2 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1143, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); | |||
1144 | parms1 && parms2; | |||
1145 | parms1 = TREE_CHAIN (parms1)((contains_struct_check ((parms1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1145, __FUNCTION__))->common.chain), parms2 = TREE_CHAIN (parms2)((contains_struct_check ((parms2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1145, __FUNCTION__))->common.chain), | |||
1146 | count++) | |||
1147 | { | |||
1148 | if (type_mismatch_p (TREE_VALUE (parms1)((tree_check ((parms1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1148, __FUNCTION__, (TREE_LIST)))->list.value), TREE_VALUE (parms2)((tree_check ((parms2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1148, __FUNCTION__, (TREE_LIST)))->list.value))) | |||
1149 | { | |||
1150 | if (count == 1 && TREE_CODE (t1)((enum tree_code) (t1)->base.code) == METHOD_TYPE) | |||
1151 | inform (loc, | |||
1152 | "implicit this pointer type mismatch"); | |||
1153 | else | |||
1154 | inform (loc, | |||
1155 | "type mismatch in parameter %i", | |||
1156 | count - (TREE_CODE (t1)((enum tree_code) (t1)->base.code) == METHOD_TYPE)); | |||
1157 | warn_types_mismatch (TREE_VALUE (parms1)((tree_check ((parms1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1157, __FUNCTION__, (TREE_LIST)))->list.value), | |||
1158 | TREE_VALUE (parms2)((tree_check ((parms2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1158, __FUNCTION__, (TREE_LIST)))->list.value), | |||
1159 | loc_t1, loc_t2); | |||
1160 | return; | |||
1161 | } | |||
1162 | } | |||
1163 | if (parms1 || parms2) | |||
1164 | { | |||
1165 | inform (loc, | |||
1166 | "types have different parameter counts"); | |||
1167 | return; | |||
1168 | } | |||
1169 | } | |||
1170 | } | |||
1171 | return; | |||
1172 | } | |||
1173 | ||||
1174 | if (types_odr_comparable (t1, t2) | |||
1175 | /* We make assign integers mangled names to be able to handle | |||
1176 | signed/unsigned chars. Accepting them here would however lead to | |||
1177 | confusing message like | |||
1178 | "type ‘const int’ itself violates the C++ One Definition Rule" */ | |||
1179 | && TREE_CODE (t1)((enum tree_code) (t1)->base.code) != INTEGER_TYPE | |||
1180 | && types_same_for_odr (t1, t2)) | |||
1181 | inform (loc_t1, | |||
1182 | "type %qT itself violates the C++ One Definition Rule", t1); | |||
1183 | /* Prevent pointless warnings like "struct aa" should match "struct aa". */ | |||
1184 | else if (TYPE_NAME (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1184, __FUNCTION__))->type_common.name) == TYPE_NAME (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1184, __FUNCTION__))->type_common.name) | |||
1185 | && TREE_CODE (t1)((enum tree_code) (t1)->base.code) == TREE_CODE (t2)((enum tree_code) (t2)->base.code) && !loc_t2_useful) | |||
1186 | return; | |||
1187 | else | |||
1188 | inform (loc_t1, "type %qT should match type %qT", | |||
1189 | t1, t2); | |||
1190 | if (loc_t2_useful) | |||
1191 | inform (loc_t2, "the incompatible type is defined here"); | |||
1192 | } | |||
1193 | ||||
1194 | /* Return true if T should be ignored in TYPE_FIELDS for ODR comparison. */ | |||
1195 | ||||
1196 | static bool | |||
1197 | skip_in_fields_list_p (tree t) | |||
1198 | { | |||
1199 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) != FIELD_DECL) | |||
1200 | return true; | |||
1201 | /* C++ FE introduces zero sized fields depending on -std setting, see | |||
1202 | PR89358. */ | |||
1203 | if (DECL_SIZE (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1203, __FUNCTION__))->decl_common.size) | |||
1204 | && integer_zerop (DECL_SIZE (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1204, __FUNCTION__))->decl_common.size)) | |||
1205 | && DECL_ARTIFICIAL (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1205, __FUNCTION__))->decl_common.artificial_flag) | |||
1206 | && DECL_IGNORED_P (t)((contains_struct_check ((t), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1206, __FUNCTION__))->decl_common.ignored_flag) | |||
1207 | && !DECL_NAME (t)((contains_struct_check ((t), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1207, __FUNCTION__))->decl_minimal.name)) | |||
1208 | return true; | |||
1209 | return false; | |||
1210 | } | |||
1211 | ||||
1212 | /* Compare T1 and T2, report ODR violations if WARN is true and set | |||
1213 | WARNED to true if anything is reported. Return true if types match. | |||
1214 | If true is returned, the types are also compatible in the sense of | |||
1215 | gimple_canonical_types_compatible_p. | |||
1216 | If LOC1 and LOC2 is not UNKNOWN_LOCATION it may be used to output a warning | |||
1217 | about the type if the type itself do not have location. */ | |||
1218 | ||||
1219 | static bool | |||
1220 | odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, | |||
1221 | hash_set<type_pair> *visited, | |||
1222 | location_t loc1, location_t loc2) | |||
1223 | { | |||
1224 | /* Check first for the obvious case of pointer identity. */ | |||
1225 | if (t1 == t2) | |||
1226 | return true; | |||
1227 | ||||
1228 | /* Can't be the same type if the types don't have the same code. */ | |||
1229 | if (TREE_CODE (t1)((enum tree_code) (t1)->base.code) != TREE_CODE (t2)((enum tree_code) (t2)->base.code)) | |||
1230 | { | |||
1231 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1232 | G_("a different type is defined in another translation unit")"a different type is defined in another translation unit"); | |||
1233 | return false; | |||
1234 | } | |||
1235 | ||||
1236 | if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1236, __FUNCTION__))->type_common.main_variant)) | |||
1237 | && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1237, __FUNCTION__))->type_common.main_variant))) | |||
1238 | || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1238, __FUNCTION__))->type_common.main_variant)) | |||
1239 | && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1239, __FUNCTION__))->type_common.main_variant)))) | |||
1240 | { | |||
1241 | /* We cannot trip this when comparing ODR types, only when trying to | |||
1242 | match different ODR derivations from different declarations. | |||
1243 | So WARN should be always false. */ | |||
1244 | gcc_assert (!warn)((void)(!(!warn) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1244, __FUNCTION__), 0 : 0)); | |||
1245 | return false; | |||
1246 | } | |||
1247 | ||||
1248 | /* Non-aggregate types can be handled cheaply. */ | |||
1249 | if (INTEGRAL_TYPE_P (t1)(((enum tree_code) (t1)->base.code) == ENUMERAL_TYPE || (( enum tree_code) (t1)->base.code) == BOOLEAN_TYPE || ((enum tree_code) (t1)->base.code) == INTEGER_TYPE) | |||
1250 | || SCALAR_FLOAT_TYPE_P (t1)(((enum tree_code) (t1)->base.code) == REAL_TYPE) | |||
1251 | || FIXED_POINT_TYPE_P (t1)(((enum tree_code) (t1)->base.code) == FIXED_POINT_TYPE) | |||
1252 | || TREE_CODE (t1)((enum tree_code) (t1)->base.code) == VECTOR_TYPE | |||
1253 | || TREE_CODE (t1)((enum tree_code) (t1)->base.code) == COMPLEX_TYPE | |||
1254 | || TREE_CODE (t1)((enum tree_code) (t1)->base.code) == OFFSET_TYPE | |||
1255 | || POINTER_TYPE_P (t1)(((enum tree_code) (t1)->base.code) == POINTER_TYPE || ((enum tree_code) (t1)->base.code) == REFERENCE_TYPE)) | |||
1256 | { | |||
1257 | if (TYPE_PRECISION (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1257, __FUNCTION__))->type_common.precision) != TYPE_PRECISION (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1257, __FUNCTION__))->type_common.precision)) | |||
1258 | { | |||
1259 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1260 | G_("a type with different precision is defined ""a type with different precision is defined " "in another translation unit" | |||
1261 | "in another translation unit")"a type with different precision is defined " "in another translation unit"); | |||
1262 | return false; | |||
1263 | } | |||
1264 | if (TYPE_UNSIGNED (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1264, __FUNCTION__))->base.u.bits.unsigned_flag) != TYPE_UNSIGNED (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1264, __FUNCTION__))->base.u.bits.unsigned_flag)) | |||
1265 | { | |||
1266 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1267 | G_("a type with different signedness is defined ""a type with different signedness is defined " "in another translation unit" | |||
1268 | "in another translation unit")"a type with different signedness is defined " "in another translation unit"); | |||
1269 | return false; | |||
1270 | } | |||
1271 | ||||
1272 | if (TREE_CODE (t1)((enum tree_code) (t1)->base.code) == INTEGER_TYPE | |||
1273 | && TYPE_STRING_FLAG (t1)((tree_check2 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1273, __FUNCTION__, (ARRAY_TYPE), (INTEGER_TYPE)))->type_common .string_flag) != TYPE_STRING_FLAG (t2)((tree_check2 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1273, __FUNCTION__, (ARRAY_TYPE), (INTEGER_TYPE)))->type_common .string_flag)) | |||
1274 | { | |||
1275 | /* char WRT uint_8? */ | |||
1276 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1277 | G_("a different type is defined in another ""a different type is defined in another " "translation unit" | |||
1278 | "translation unit")"a different type is defined in another " "translation unit"); | |||
1279 | return false; | |||
1280 | } | |||
1281 | ||||
1282 | /* For canonical type comparisons we do not want to build SCCs | |||
1283 | so we cannot compare pointed-to types. But we can, for now, | |||
1284 | require the same pointed-to type kind and match what | |||
1285 | useless_type_conversion_p would do. */ | |||
1286 | if (POINTER_TYPE_P (t1)(((enum tree_code) (t1)->base.code) == POINTER_TYPE || ((enum tree_code) (t1)->base.code) == REFERENCE_TYPE)) | |||
1287 | { | |||
1288 | if (TYPE_ADDR_SPACE (TREE_TYPE (t1))((tree_class_check ((((contains_struct_check ((t1), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1288, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1288, __FUNCTION__))->base.u.bits.address_space) | |||
1289 | != TYPE_ADDR_SPACE (TREE_TYPE (t2))((tree_class_check ((((contains_struct_check ((t2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1289, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1289, __FUNCTION__))->base.u.bits.address_space)) | |||
1290 | { | |||
1291 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1292 | G_("it is defined as a pointer in different address ""it is defined as a pointer in different address " "space in another translation unit" | |||
1293 | "space in another translation unit")"it is defined as a pointer in different address " "space in another translation unit"); | |||
1294 | return false; | |||
1295 | } | |||
1296 | ||||
1297 | if (!odr_subtypes_equivalent_p (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1297, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1297, __FUNCTION__))->typed.type), | |||
1298 | visited, loc1, loc2)) | |||
1299 | { | |||
1300 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1301 | G_("it is defined as a pointer to different type ""it is defined as a pointer to different type " "in another translation unit" | |||
1302 | "in another translation unit")"it is defined as a pointer to different type " "in another translation unit"); | |||
1303 | if (warn && (warned == NULL__null || *warned)) | |||
1304 | warn_types_mismatch (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1304, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1304, __FUNCTION__))->typed.type), | |||
1305 | loc1, loc2); | |||
1306 | return false; | |||
1307 | } | |||
1308 | } | |||
1309 | ||||
1310 | if ((TREE_CODE (t1)((enum tree_code) (t1)->base.code) == VECTOR_TYPE || TREE_CODE (t1)((enum tree_code) (t1)->base.code) == COMPLEX_TYPE) | |||
1311 | && !odr_subtypes_equivalent_p (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1311, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1311, __FUNCTION__))->typed.type), | |||
1312 | visited, loc1, loc2)) | |||
1313 | { | |||
1314 | /* Probably specific enough. */ | |||
1315 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1316 | G_("a different type is defined ""a different type is defined " "in another translation unit" | |||
1317 | "in another translation unit")"a different type is defined " "in another translation unit"); | |||
1318 | if (warn && (warned == NULL__null || *warned)) | |||
1319 | warn_types_mismatch (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1319, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1319, __FUNCTION__))->typed.type), loc1, loc2); | |||
1320 | return false; | |||
1321 | } | |||
1322 | } | |||
1323 | /* Do type-specific comparisons. */ | |||
1324 | else switch (TREE_CODE (t1)((enum tree_code) (t1)->base.code)) | |||
1325 | { | |||
1326 | case ARRAY_TYPE: | |||
1327 | { | |||
1328 | /* Array types are the same if the element types are the same and | |||
1329 | the number of elements are the same. */ | |||
1330 | if (!odr_subtypes_equivalent_p (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1330, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1330, __FUNCTION__))->typed.type), | |||
1331 | visited, loc1, loc2)) | |||
1332 | { | |||
1333 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1334 | G_("a different type is defined in another ""a different type is defined in another " "translation unit" | |||
1335 | "translation unit")"a different type is defined in another " "translation unit"); | |||
1336 | if (warn && (warned == NULL__null || *warned)) | |||
1337 | warn_types_mismatch (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1337, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1337, __FUNCTION__))->typed.type), loc1, loc2); | |||
1338 | } | |||
1339 | gcc_assert (TYPE_STRING_FLAG (t1) == TYPE_STRING_FLAG (t2))((void)(!(((tree_check2 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1339, __FUNCTION__, (ARRAY_TYPE), (INTEGER_TYPE)))->type_common .string_flag) == ((tree_check2 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1339, __FUNCTION__, (ARRAY_TYPE), (INTEGER_TYPE)))->type_common .string_flag)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1339, __FUNCTION__), 0 : 0)); | |||
1340 | gcc_assert (TYPE_NONALIASED_COMPONENT (t1)((void)(!(((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1340, __FUNCTION__, (ARRAY_TYPE)))->type_common.transparent_aggr_flag ) == ((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1341, __FUNCTION__, (ARRAY_TYPE)))->type_common.transparent_aggr_flag )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1341, __FUNCTION__), 0 : 0)) | |||
1341 | == TYPE_NONALIASED_COMPONENT (t2))((void)(!(((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1340, __FUNCTION__, (ARRAY_TYPE)))->type_common.transparent_aggr_flag ) == ((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1341, __FUNCTION__, (ARRAY_TYPE)))->type_common.transparent_aggr_flag )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1341, __FUNCTION__), 0 : 0)); | |||
1342 | ||||
1343 | tree i1 = TYPE_DOMAIN (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1343, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ); | |||
1344 | tree i2 = TYPE_DOMAIN (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1344, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values ); | |||
1345 | ||||
1346 | /* For an incomplete external array, the type domain can be | |||
1347 | NULL_TREE. Check this condition also. */ | |||
1348 | if (i1 == NULL_TREE(tree) __null || i2 == NULL_TREE(tree) __null) | |||
1349 | return type_variants_equivalent_p (t1, t2); | |||
1350 | ||||
1351 | tree min1 = TYPE_MIN_VALUE (i1)((tree_check5 ((i1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1351, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval ); | |||
1352 | tree min2 = TYPE_MIN_VALUE (i2)((tree_check5 ((i2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1352, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval ); | |||
1353 | tree max1 = TYPE_MAX_VALUE (i1)((tree_check5 ((i1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1353, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ); | |||
1354 | tree max2 = TYPE_MAX_VALUE (i2)((tree_check5 ((i2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1354, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ); | |||
1355 | ||||
1356 | /* In C++, minimums should be always 0. */ | |||
1357 | gcc_assert (min1 == min2)((void)(!(min1 == min2) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1357, __FUNCTION__), 0 : 0)); | |||
1358 | if (!operand_equal_p (max1, max2, 0)) | |||
1359 | { | |||
1360 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1361 | G_("an array of different size is defined ""an array of different size is defined " "in another translation unit" | |||
1362 | "in another translation unit")"an array of different size is defined " "in another translation unit"); | |||
1363 | return false; | |||
1364 | } | |||
1365 | } | |||
1366 | break; | |||
1367 | ||||
1368 | case METHOD_TYPE: | |||
1369 | case FUNCTION_TYPE: | |||
1370 | /* Function types are the same if the return type and arguments types | |||
1371 | are the same. */ | |||
1372 | if (!odr_subtypes_equivalent_p (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1372, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1372, __FUNCTION__))->typed.type), | |||
1373 | visited, loc1, loc2)) | |||
1374 | { | |||
1375 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1376 | G_("has different return value ""has different return value " "in another translation unit" | |||
1377 | "in another translation unit")"has different return value " "in another translation unit"); | |||
1378 | if (warn && (warned == NULL__null || *warned)) | |||
1379 | warn_types_mismatch (TREE_TYPE (t1)((contains_struct_check ((t1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1379, __FUNCTION__))->typed.type), TREE_TYPE (t2)((contains_struct_check ((t2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1379, __FUNCTION__))->typed.type), loc1, loc2); | |||
1380 | return false; | |||
1381 | } | |||
1382 | ||||
1383 | if (TYPE_ARG_TYPES (t1)((tree_check2 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1383, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values) == TYPE_ARG_TYPES (t2)((tree_check2 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1383, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values) | |||
1384 | || !prototype_p (t1) || !prototype_p (t2)) | |||
1385 | return type_variants_equivalent_p (t1, t2); | |||
1386 | else | |||
1387 | { | |||
1388 | tree parms1, parms2; | |||
1389 | ||||
1390 | for (parms1 = TYPE_ARG_TYPES (t1)((tree_check2 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1390, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values), parms2 = TYPE_ARG_TYPES (t2)((tree_check2 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1390, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values); | |||
1391 | parms1 && parms2; | |||
1392 | parms1 = TREE_CHAIN (parms1)((contains_struct_check ((parms1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1392, __FUNCTION__))->common.chain), parms2 = TREE_CHAIN (parms2)((contains_struct_check ((parms2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1392, __FUNCTION__))->common.chain)) | |||
1393 | { | |||
1394 | if (!odr_subtypes_equivalent_p | |||
1395 | (TREE_VALUE (parms1)((tree_check ((parms1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1395, __FUNCTION__, (TREE_LIST)))->list.value), TREE_VALUE (parms2)((tree_check ((parms2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1395, __FUNCTION__, (TREE_LIST)))->list.value), | |||
1396 | visited, loc1, loc2)) | |||
1397 | { | |||
1398 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1399 | G_("has different parameters in another ""has different parameters in another " "translation unit" | |||
1400 | "translation unit")"has different parameters in another " "translation unit"); | |||
1401 | if (warn && (warned == NULL__null || *warned)) | |||
1402 | warn_types_mismatch (TREE_VALUE (parms1)((tree_check ((parms1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1402, __FUNCTION__, (TREE_LIST)))->list.value), | |||
1403 | TREE_VALUE (parms2)((tree_check ((parms2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1403, __FUNCTION__, (TREE_LIST)))->list.value), loc1, loc2); | |||
1404 | return false; | |||
1405 | } | |||
1406 | } | |||
1407 | ||||
1408 | if (parms1 || parms2) | |||
1409 | { | |||
1410 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1411 | G_("has different parameters ""has different parameters " "in another translation unit" | |||
1412 | "in another translation unit")"has different parameters " "in another translation unit"); | |||
1413 | return false; | |||
1414 | } | |||
1415 | ||||
1416 | return type_variants_equivalent_p (t1, t2); | |||
1417 | } | |||
1418 | ||||
1419 | case RECORD_TYPE: | |||
1420 | case UNION_TYPE: | |||
1421 | case QUAL_UNION_TYPE: | |||
1422 | { | |||
1423 | tree f1, f2; | |||
1424 | ||||
1425 | /* For aggregate types, all the fields must be the same. */ | |||
1426 | if (COMPLETE_TYPE_P (t1)(((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1426, __FUNCTION__))->type_common.size) != (tree) __null ) && COMPLETE_TYPE_P (t2)(((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1426, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
1427 | { | |||
1428 | if (TYPE_BINFO (t1)((tree_check3 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1428, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) && TYPE_BINFO (t2)((tree_check3 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1428, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1429 | && polymorphic_type_binfo_p (TYPE_BINFO (t1)((tree_check3 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1429, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
1430 | != polymorphic_type_binfo_p (TYPE_BINFO (t2)((tree_check3 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1430, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval))) | |||
1431 | { | |||
1432 | if (polymorphic_type_binfo_p (TYPE_BINFO (t1)((tree_check3 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1432, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval))) | |||
1433 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1434 | G_("a type defined in another translation unit ""a type defined in another translation unit " "is not polymorphic" | |||
1435 | "is not polymorphic")"a type defined in another translation unit " "is not polymorphic"); | |||
1436 | else | |||
1437 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1438 | G_("a type defined in another translation unit ""a type defined in another translation unit " "is polymorphic" | |||
1439 | "is polymorphic")"a type defined in another translation unit " "is polymorphic"); | |||
1440 | return false; | |||
1441 | } | |||
1442 | for (f1 = TYPE_FIELDS (t1)((tree_check3 ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1442, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values), f2 = TYPE_FIELDS (t2)((tree_check3 ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1442, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); | |||
1443 | f1 || f2; | |||
1444 | f1 = TREE_CHAIN (f1)((contains_struct_check ((f1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1444, __FUNCTION__))->common.chain), f2 = TREE_CHAIN (f2)((contains_struct_check ((f2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1444, __FUNCTION__))->common.chain)) | |||
1445 | { | |||
1446 | /* Skip non-fields. */ | |||
1447 | while (f1 && skip_in_fields_list_p (f1)) | |||
1448 | f1 = TREE_CHAIN (f1)((contains_struct_check ((f1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1448, __FUNCTION__))->common.chain); | |||
1449 | while (f2 && skip_in_fields_list_p (f2)) | |||
1450 | f2 = TREE_CHAIN (f2)((contains_struct_check ((f2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1450, __FUNCTION__))->common.chain); | |||
1451 | if (!f1 || !f2) | |||
1452 | break; | |||
1453 | if (DECL_VIRTUAL_P (f1)((contains_struct_check ((f1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1453, __FUNCTION__))->decl_common.virtual_flag) != DECL_VIRTUAL_P (f2)((contains_struct_check ((f2), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1453, __FUNCTION__))->decl_common.virtual_flag)) | |||
1454 | { | |||
1455 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1456 | G_("a type with different virtual table pointers""a type with different virtual table pointers" " is defined in another translation unit" | |||
1457 | " is defined in another translation unit")"a type with different virtual table pointers" " is defined in another translation unit"); | |||
1458 | return false; | |||
1459 | } | |||
1460 | if (DECL_ARTIFICIAL (f1)((contains_struct_check ((f1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1460, __FUNCTION__))->decl_common.artificial_flag) != DECL_ARTIFICIAL (f2)((contains_struct_check ((f2), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1460, __FUNCTION__))->decl_common.artificial_flag)) | |||
1461 | { | |||
1462 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1463 | G_("a type with different bases is defined ""a type with different bases is defined " "in another translation unit" | |||
1464 | "in another translation unit")"a type with different bases is defined " "in another translation unit"); | |||
1465 | return false; | |||
1466 | } | |||
1467 | if (DECL_NAME (f1)((contains_struct_check ((f1), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1467, __FUNCTION__))->decl_minimal.name) != DECL_NAME (f2)((contains_struct_check ((f2), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1467, __FUNCTION__))->decl_minimal.name) | |||
1468 | && !DECL_ARTIFICIAL (f1)((contains_struct_check ((f1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1468, __FUNCTION__))->decl_common.artificial_flag)) | |||
1469 | { | |||
1470 | warn_odr (t1, t2, f1, f2, warn, warned, | |||
1471 | G_("a field with different name is defined ""a field with different name is defined " "in another translation unit" | |||
1472 | "in another translation unit")"a field with different name is defined " "in another translation unit"); | |||
1473 | return false; | |||
1474 | } | |||
1475 | if (!odr_subtypes_equivalent_p (TREE_TYPE (f1)((contains_struct_check ((f1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1475, __FUNCTION__))->typed.type), | |||
1476 | TREE_TYPE (f2)((contains_struct_check ((f2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1476, __FUNCTION__))->typed.type), | |||
1477 | visited, loc1, loc2)) | |||
1478 | { | |||
1479 | /* Do not warn about artificial fields and just go into | |||
1480 | generic field mismatch warning. */ | |||
1481 | if (DECL_ARTIFICIAL (f1)((contains_struct_check ((f1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1481, __FUNCTION__))->decl_common.artificial_flag)) | |||
1482 | break; | |||
1483 | ||||
1484 | warn_odr (t1, t2, f1, f2, warn, warned, | |||
1485 | G_("a field of same name but different type ""a field of same name but different type " "is defined in another translation unit" | |||
1486 | "is defined in another translation unit")"a field of same name but different type " "is defined in another translation unit"); | |||
1487 | if (warn && (warned == NULL__null || *warned)) | |||
1488 | warn_types_mismatch (TREE_TYPE (f1)((contains_struct_check ((f1), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1488, __FUNCTION__))->typed.type), TREE_TYPE (f2)((contains_struct_check ((f2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1488, __FUNCTION__))->typed.type), loc1, loc2); | |||
1489 | return false; | |||
1490 | } | |||
1491 | if (!gimple_compare_field_offset (f1, f2)) | |||
1492 | { | |||
1493 | /* Do not warn about artificial fields and just go into | |||
1494 | generic field mismatch warning. */ | |||
1495 | if (DECL_ARTIFICIAL (f1)((contains_struct_check ((f1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1495, __FUNCTION__))->decl_common.artificial_flag)) | |||
1496 | break; | |||
1497 | warn_odr (t1, t2, f1, f2, warn, warned, | |||
1498 | G_("fields have different layout ""fields have different layout " "in another translation unit" | |||
1499 | "in another translation unit")"fields have different layout " "in another translation unit"); | |||
1500 | return false; | |||
1501 | } | |||
1502 | if (DECL_BIT_FIELD (f1)((tree_check ((f1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1502, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_1 ) != DECL_BIT_FIELD (f2)((tree_check ((f2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1502, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_1 )) | |||
1503 | { | |||
1504 | warn_odr (t1, t2, f1, f2, warn, warned, | |||
1505 | G_("one field is a bitfield while the other ""one field is a bitfield while the other " "is not" | |||
1506 | "is not")"one field is a bitfield while the other " "is not"); | |||
1507 | return false; | |||
1508 | } | |||
1509 | else | |||
1510 | gcc_assert (DECL_NONADDRESSABLE_P (f1)((void)(!(((tree_check ((f1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1510, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_2 ) == ((tree_check ((f2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1511, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_2 )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1511, __FUNCTION__), 0 : 0)) | |||
1511 | == DECL_NONADDRESSABLE_P (f2))((void)(!(((tree_check ((f1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1510, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_2 ) == ((tree_check ((f2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1511, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_2 )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1511, __FUNCTION__), 0 : 0)); | |||
1512 | } | |||
1513 | ||||
1514 | /* If one aggregate has more fields than the other, they | |||
1515 | are not the same. */ | |||
1516 | if (f1 || f2) | |||
1517 | { | |||
1518 | if ((f1 && DECL_VIRTUAL_P (f1)((contains_struct_check ((f1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1518, __FUNCTION__))->decl_common.virtual_flag)) || (f2 && DECL_VIRTUAL_P (f2)((contains_struct_check ((f2), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1518, __FUNCTION__))->decl_common.virtual_flag))) | |||
1519 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1520 | G_("a type with different virtual table pointers""a type with different virtual table pointers" " is defined in another translation unit" | |||
1521 | " is defined in another translation unit")"a type with different virtual table pointers" " is defined in another translation unit"); | |||
1522 | else if ((f1 && DECL_ARTIFICIAL (f1)((contains_struct_check ((f1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1522, __FUNCTION__))->decl_common.artificial_flag)) | |||
1523 | || (f2 && DECL_ARTIFICIAL (f2)((contains_struct_check ((f2), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1523, __FUNCTION__))->decl_common.artificial_flag))) | |||
1524 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1525 | G_("a type with different bases is defined ""a type with different bases is defined " "in another translation unit" | |||
1526 | "in another translation unit")"a type with different bases is defined " "in another translation unit"); | |||
1527 | else | |||
1528 | warn_odr (t1, t2, f1, f2, warn, warned, | |||
1529 | G_("a type with different number of fields ""a type with different number of fields " "is defined in another translation unit" | |||
1530 | "is defined in another translation unit")"a type with different number of fields " "is defined in another translation unit"); | |||
1531 | ||||
1532 | return false; | |||
1533 | } | |||
1534 | } | |||
1535 | break; | |||
1536 | } | |||
1537 | case VOID_TYPE: | |||
1538 | case OPAQUE_TYPE: | |||
1539 | case NULLPTR_TYPE: | |||
1540 | break; | |||
1541 | ||||
1542 | default: | |||
1543 | debug_tree (t1); | |||
1544 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1544, __FUNCTION__)); | |||
1545 | } | |||
1546 | ||||
1547 | /* Those are better to come last as they are utterly uninformative. */ | |||
1548 | if (TYPE_SIZE (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1548, __FUNCTION__))->type_common.size) && TYPE_SIZE (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1548, __FUNCTION__))->type_common.size) | |||
1549 | && !operand_equal_p (TYPE_SIZE (t1)((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1549, __FUNCTION__))->type_common.size), TYPE_SIZE (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1549, __FUNCTION__))->type_common.size), 0)) | |||
1550 | { | |||
1551 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1552 | G_("a type with different size ""a type with different size " "is defined in another translation unit" | |||
1553 | "is defined in another translation unit")"a type with different size " "is defined in another translation unit"); | |||
1554 | return false; | |||
1555 | } | |||
1556 | ||||
1557 | if (TREE_ADDRESSABLE (t1)((t1)->base.addressable_flag) != TREE_ADDRESSABLE (t2)((t2)->base.addressable_flag) | |||
1558 | && COMPLETE_TYPE_P (t1)(((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1558, __FUNCTION__))->type_common.size) != (tree) __null ) && COMPLETE_TYPE_P (t2)(((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1558, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
1559 | { | |||
1560 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1561 | G_("one type needs to be constructed while the other does not")"one type needs to be constructed while the other does not"); | |||
1562 | gcc_checking_assert (RECORD_OR_UNION_TYPE_P (t1))((void)(!((((enum tree_code) (t1)->base.code) == RECORD_TYPE || ((enum tree_code) (t1)->base.code) == UNION_TYPE || (( enum tree_code) (t1)->base.code) == QUAL_UNION_TYPE)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1562, __FUNCTION__), 0 : 0)); | |||
1563 | return false; | |||
1564 | } | |||
1565 | /* There is no really good user facing warning for this. | |||
1566 | Either the original reason for modes being different is lost during | |||
1567 | streaming or we should catch earlier warnings. We however must detect | |||
1568 | the mismatch to avoid type verifier from cmplaining on mismatched | |||
1569 | types between type and canonical type. See PR91576. */ | |||
1570 | if (TYPE_MODE (t1)((((enum tree_code) ((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1570, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (t1) : (t1)->type_common.mode) != TYPE_MODE (t2)((((enum tree_code) ((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1570, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode (t2) : (t2)->type_common.mode) | |||
1571 | && COMPLETE_TYPE_P (t1)(((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1571, __FUNCTION__))->type_common.size) != (tree) __null ) && COMPLETE_TYPE_P (t2)(((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1571, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
1572 | { | |||
1573 | warn_odr (t1, t2, NULL__null, NULL__null, warn, warned, | |||
1574 | G_("memory layout mismatch")"memory layout mismatch"); | |||
1575 | return false; | |||
1576 | } | |||
1577 | ||||
1578 | gcc_assert (!TYPE_SIZE_UNIT (t1) || !TYPE_SIZE_UNIT (t2)((void)(!(!((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1578, __FUNCTION__))->type_common.size_unit) || !((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1578, __FUNCTION__))->type_common.size_unit) || operand_equal_p (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1579, __FUNCTION__))->type_common.size_unit), ((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1580, __FUNCTION__))->type_common.size_unit), 0)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1580, __FUNCTION__), 0 : 0)) | |||
1579 | || operand_equal_p (TYPE_SIZE_UNIT (t1),((void)(!(!((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1578, __FUNCTION__))->type_common.size_unit) || !((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1578, __FUNCTION__))->type_common.size_unit) || operand_equal_p (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1579, __FUNCTION__))->type_common.size_unit), ((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1580, __FUNCTION__))->type_common.size_unit), 0)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1580, __FUNCTION__), 0 : 0)) | |||
1580 | TYPE_SIZE_UNIT (t2), 0))((void)(!(!((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1578, __FUNCTION__))->type_common.size_unit) || !((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1578, __FUNCTION__))->type_common.size_unit) || operand_equal_p (((tree_class_check ((t1), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1579, __FUNCTION__))->type_common.size_unit), ((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1580, __FUNCTION__))->type_common.size_unit), 0)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1580, __FUNCTION__), 0 : 0)); | |||
1581 | return type_variants_equivalent_p (t1, t2); | |||
1582 | } | |||
1583 | ||||
1584 | /* Return true if TYPE1 and TYPE2 are equivalent for One Definition Rule. */ | |||
1585 | ||||
1586 | bool | |||
1587 | odr_types_equivalent_p (tree type1, tree type2) | |||
1588 | { | |||
1589 | gcc_checking_assert (odr_or_derived_type_p (type1)((void)(!(odr_or_derived_type_p (type1) && odr_or_derived_type_p (type2)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1590, __FUNCTION__), 0 : 0)) | |||
1590 | && odr_or_derived_type_p (type2))((void)(!(odr_or_derived_type_p (type1) && odr_or_derived_type_p (type2)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1590, __FUNCTION__), 0 : 0)); | |||
1591 | ||||
1592 | hash_set<type_pair> visited; | |||
1593 | return odr_types_equivalent_p (type1, type2, false, NULL__null, | |||
1594 | &visited, UNKNOWN_LOCATION((location_t) 0), UNKNOWN_LOCATION((location_t) 0)); | |||
1595 | } | |||
1596 | ||||
1597 | /* TYPE is equivalent to VAL by ODR, but its tree representation differs | |||
1598 | from VAL->type. This may happen in LTO where tree merging did not merge | |||
1599 | all variants of the same type or due to ODR violation. | |||
1600 | ||||
1601 | Analyze and report ODR violations and add type to duplicate list. | |||
1602 | If TYPE is more specified than VAL->type, prevail VAL->type. Also if | |||
1603 | this is first time we see definition of a class return true so the | |||
1604 | base types are analyzed. */ | |||
1605 | ||||
1606 | static bool | |||
1607 | add_type_duplicate (odr_type val, tree type) | |||
1608 | { | |||
1609 | bool build_bases = false; | |||
1610 | bool prevail = false; | |||
1611 | bool odr_must_violate = false; | |||
1612 | ||||
1613 | if (!val->types_set) | |||
1614 | val->types_set = new hash_set<tree>; | |||
1615 | ||||
1616 | /* Chose polymorphic type as leader (this happens only in case of ODR | |||
1617 | violations. */ | |||
1618 | if ((TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE && TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1618, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1619 | && polymorphic_type_binfo_p (TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1619, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval))) | |||
1620 | && (TREE_CODE (val->type)((enum tree_code) (val->type)->base.code) != RECORD_TYPE || !TYPE_BINFO (val->type)((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1620, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1621 | || !polymorphic_type_binfo_p (TYPE_BINFO (val->type)((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1621, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)))) | |||
1622 | { | |||
1623 | prevail = true; | |||
1624 | build_bases = true; | |||
1625 | } | |||
1626 | /* Always prefer complete type to be the leader. */ | |||
1627 | else if (!COMPLETE_TYPE_P (val->type)(((tree_class_check ((val->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1627, __FUNCTION__))->type_common.size) != (tree) __null ) && COMPLETE_TYPE_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1627, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
1628 | { | |||
1629 | prevail = true; | |||
1630 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE) | |||
1631 | build_bases = TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1631, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval); | |||
1632 | } | |||
1633 | else if (COMPLETE_TYPE_P (val->type)(((tree_class_check ((val->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1633, __FUNCTION__))->type_common.size) != (tree) __null ) && !COMPLETE_TYPE_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1633, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
1634 | ; | |||
1635 | else if (TREE_CODE (val->type)((enum tree_code) (val->type)->base.code) == RECORD_TYPE | |||
1636 | && TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE | |||
1637 | && TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1637, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) && !TYPE_BINFO (val->type)((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1637, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
1638 | { | |||
1639 | gcc_assert (!val->bases.length ())((void)(!(!val->bases.length ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1639, __FUNCTION__), 0 : 0)); | |||
1640 | build_bases = true; | |||
1641 | prevail = true; | |||
1642 | } | |||
1643 | ||||
1644 | if (prevail) | |||
1645 | std::swap (val->type, type); | |||
1646 | ||||
1647 | val->types_set->add (type); | |||
1648 | ||||
1649 | if (!odr_hash) | |||
1650 | return false; | |||
1651 | ||||
1652 | gcc_checking_assert (can_be_name_hashed_p (type)((void)(!(can_be_name_hashed_p (type) && can_be_name_hashed_p (val->type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1653, __FUNCTION__), 0 : 0)) | |||
1653 | && can_be_name_hashed_p (val->type))((void)(!(can_be_name_hashed_p (type) && can_be_name_hashed_p (val->type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1653, __FUNCTION__), 0 : 0)); | |||
1654 | ||||
1655 | bool merge = true; | |||
1656 | bool base_mismatch = false; | |||
1657 | unsigned int i; | |||
1658 | bool warned = false; | |||
1659 | hash_set<type_pair> visited; | |||
1660 | ||||
1661 | gcc_assert (in_lto_p)((void)(!(global_options.x_in_lto_p) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1661, __FUNCTION__), 0 : 0)); | |||
1662 | vec_safe_push (val->types, type); | |||
1663 | ||||
1664 | /* If both are class types, compare the bases. */ | |||
1665 | if (COMPLETE_TYPE_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1665, __FUNCTION__))->type_common.size) != (tree) __null ) && COMPLETE_TYPE_P (val->type)(((tree_class_check ((val->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1665, __FUNCTION__))->type_common.size) != (tree) __null ) | |||
1666 | && TREE_CODE (val->type)((enum tree_code) (val->type)->base.code) == RECORD_TYPE | |||
1667 | && TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE | |||
1668 | && TYPE_BINFO (val->type)((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1668, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) && TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1668, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
1669 | { | |||
1670 | if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type))((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1670, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1670, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()) | |||
1671 | != BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))((&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1671, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1671, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ())) | |||
1672 | { | |||
1673 | if (!flag_ltransglobal_options.x_flag_ltrans && !warned && !val->odr_violated) | |||
1674 | { | |||
1675 | tree extra_base; | |||
1676 | warn_odr (type, val->type, NULL__null, NULL__null, !warned, &warned, | |||
1677 | "a type with the same name but different " | |||
1678 | "number of polymorphic bases is " | |||
1679 | "defined in another translation unit"); | |||
1680 | if (warned) | |||
1681 | { | |||
1682 | if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type))((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1682, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1682, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()) | |||
1683 | > BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))((&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1683, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1683, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ())) | |||
1684 | extra_base = BINFO_BASE_BINFO((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1685, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (((&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()))]) | |||
1685 | (TYPE_BINFO (type),((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1685, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (((&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()))]) | |||
1686 | BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type)))((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1685, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (((&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1686, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()))]); | |||
1687 | else | |||
1688 | extra_base = BINFO_BASE_BINFO((*(&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1689, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()))]) | |||
1689 | (TYPE_BINFO (val->type),((*(&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1689, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()))]) | |||
1690 | BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))((*(&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1689, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1690, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()))]); | |||
1691 | tree extra_base_type = BINFO_TYPE (extra_base)((contains_struct_check (((tree_check ((extra_base), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1691, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1691, __FUNCTION__))->typed.type); | |||
1692 | inform (DECL_SOURCE_LOCATION (TYPE_NAME (extra_base_type))((contains_struct_check ((((tree_class_check ((extra_base_type ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1692, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1692, __FUNCTION__))->decl_minimal.locus), | |||
1693 | "the extra base is defined here"); | |||
1694 | } | |||
1695 | } | |||
1696 | base_mismatch = true; | |||
1697 | } | |||
1698 | else | |||
1699 | for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type))((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1699, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1699, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()); i++) | |||
1700 | { | |||
1701 | tree base1 = BINFO_BASE_BINFO (TYPE_BINFO (type), i)((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1701, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1701, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)]); | |||
1702 | tree base2 = BINFO_BASE_BINFO (TYPE_BINFO (val->type), i)((*(&(tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1702, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1702, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)]); | |||
1703 | tree type1 = BINFO_TYPE (base1)((contains_struct_check (((tree_check ((base1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1703, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1703, __FUNCTION__))->typed.type); | |||
1704 | tree type2 = BINFO_TYPE (base2)((contains_struct_check (((tree_check ((base2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1704, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1704, __FUNCTION__))->typed.type); | |||
1705 | ||||
1706 | if (types_odr_comparable (type1, type2)) | |||
1707 | { | |||
1708 | if (!types_same_for_odr (type1, type2)) | |||
1709 | base_mismatch = true; | |||
1710 | } | |||
1711 | else | |||
1712 | if (!odr_types_equivalent_p (type1, type2)) | |||
1713 | base_mismatch = true; | |||
1714 | if (base_mismatch) | |||
1715 | { | |||
1716 | if (!warned && !val->odr_violated) | |||
1717 | { | |||
1718 | warn_odr (type, val->type, NULL__null, NULL__null, | |||
1719 | !warned, &warned, | |||
1720 | "a type with the same name but different base " | |||
1721 | "type is defined in another translation unit"); | |||
1722 | if (warned) | |||
1723 | warn_types_mismatch (type1, type2, | |||
1724 | UNKNOWN_LOCATION((location_t) 0), UNKNOWN_LOCATION((location_t) 0)); | |||
1725 | } | |||
1726 | break; | |||
1727 | } | |||
1728 | if (BINFO_OFFSET (base1)((tree_check ((base1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1728, __FUNCTION__, (TREE_BINFO)))->binfo.offset) != BINFO_OFFSET (base2)((tree_check ((base2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1728, __FUNCTION__, (TREE_BINFO)))->binfo.offset)) | |||
1729 | { | |||
1730 | base_mismatch = true; | |||
1731 | if (!warned && !val->odr_violated) | |||
1732 | warn_odr (type, val->type, NULL__null, NULL__null, | |||
1733 | !warned, &warned, | |||
1734 | "a type with the same name but different base " | |||
1735 | "layout is defined in another translation unit"); | |||
1736 | break; | |||
1737 | } | |||
1738 | /* One of bases is not of complete type. */ | |||
1739 | if (!TYPE_BINFO (type1)((tree_check3 ((type1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1739, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) != !TYPE_BINFO (type2)((tree_check3 ((type2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1739, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
1740 | { | |||
1741 | /* If we have a polymorphic type info specified for TYPE1 | |||
1742 | but not for TYPE2 we possibly missed a base when recording | |||
1743 | VAL->type earlier. | |||
1744 | Be sure this does not happen. */ | |||
1745 | if (TYPE_BINFO (type1)((tree_check3 ((type1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1745, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1746 | && polymorphic_type_binfo_p (TYPE_BINFO (type1)((tree_check3 ((type1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1746, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
1747 | && !build_bases) | |||
1748 | odr_must_violate = true; | |||
1749 | break; | |||
1750 | } | |||
1751 | /* One base is polymorphic and the other not. | |||
1752 | This ought to be diagnosed earlier, but do not ICE in the | |||
1753 | checking bellow. */ | |||
1754 | else if (TYPE_BINFO (type1)((tree_check3 ((type1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1754, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1755 | && polymorphic_type_binfo_p (TYPE_BINFO (type1)((tree_check3 ((type1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1755, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
1756 | != polymorphic_type_binfo_p (TYPE_BINFO (type2)((tree_check3 ((type2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1756, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval))) | |||
1757 | { | |||
1758 | if (!warned && !val->odr_violated) | |||
1759 | warn_odr (type, val->type, NULL__null, NULL__null, | |||
1760 | !warned, &warned, | |||
1761 | "a base of the type is polymorphic only in one " | |||
1762 | "translation unit"); | |||
1763 | base_mismatch = true; | |||
1764 | break; | |||
1765 | } | |||
1766 | } | |||
1767 | if (base_mismatch) | |||
1768 | { | |||
1769 | merge = false; | |||
1770 | odr_violation_reported = true; | |||
1771 | val->odr_violated = true; | |||
1772 | ||||
1773 | if (symtab->dump_file) | |||
1774 | { | |||
1775 | fprintf (symtab->dump_file, "ODR base violation\n"); | |||
1776 | ||||
1777 | print_node (symtab->dump_file, "", val->type, 0); | |||
1778 | putc ('\n',symtab->dump_file); | |||
1779 | print_node (symtab->dump_file, "", type, 0); | |||
1780 | putc ('\n',symtab->dump_file); | |||
1781 | } | |||
1782 | } | |||
1783 | } | |||
1784 | ||||
1785 | /* Next compare memory layout. | |||
1786 | The DECL_SOURCE_LOCATIONs in this invocation came from LTO streaming. | |||
1787 | We must apply the location cache to ensure that they are valid | |||
1788 | before we can pass them to odr_types_equivalent_p (PR lto/83121). */ | |||
1789 | if (lto_location_cache::current_cache) | |||
1790 | lto_location_cache::current_cache->apply_location_cache (); | |||
1791 | /* As a special case we stream mangles names of integer types so we can see | |||
1792 | if they are believed to be same even though they have different | |||
1793 | representation. Avoid bogus warning on mismatches in these. */ | |||
1794 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) != INTEGER_TYPE | |||
1795 | && TREE_CODE (val->type)((enum tree_code) (val->type)->base.code) != INTEGER_TYPE | |||
1796 | && !odr_types_equivalent_p (val->type, type, | |||
1797 | !flag_ltransglobal_options.x_flag_ltrans && !val->odr_violated && !warned, | |||
1798 | &warned, &visited, | |||
1799 | DECL_SOURCE_LOCATION (TYPE_NAME (val->type))((contains_struct_check ((((tree_class_check ((val->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1799, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1799, __FUNCTION__))->decl_minimal.locus), | |||
1800 | DECL_SOURCE_LOCATION (TYPE_NAME (type))((contains_struct_check ((((tree_class_check ((type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1800, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1800, __FUNCTION__))->decl_minimal.locus))) | |||
1801 | { | |||
1802 | merge = false; | |||
1803 | odr_violation_reported = true; | |||
1804 | val->odr_violated = true; | |||
1805 | } | |||
1806 | gcc_assert (val->odr_violated || !odr_must_violate)((void)(!(val->odr_violated || !odr_must_violate) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1806, __FUNCTION__), 0 : 0)); | |||
1807 | /* Sanity check that all bases will be build same way again. */ | |||
1808 | if (flag_checkingglobal_options.x_flag_checking | |||
1809 | && COMPLETE_TYPE_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1809, __FUNCTION__))->type_common.size) != (tree) __null ) && COMPLETE_TYPE_P (val->type)(((tree_class_check ((val->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1809, __FUNCTION__))->type_common.size) != (tree) __null ) | |||
1810 | && TREE_CODE (val->type)((enum tree_code) (val->type)->base.code) == RECORD_TYPE | |||
1811 | && TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE | |||
1812 | && TYPE_BINFO (val->type)((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1812, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) && TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1812, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1813 | && !val->odr_violated | |||
1814 | && !base_mismatch && val->bases.length ()) | |||
1815 | { | |||
1816 | unsigned int num_poly_bases = 0; | |||
1817 | unsigned int j; | |||
1818 | ||||
1819 | for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type))((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1819, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1819, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()); i++) | |||
1820 | if (polymorphic_type_binfo_p (BINFO_BASE_BINFO((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1821, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1821, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)]) | |||
1821 | (TYPE_BINFO (type), i)((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1821, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1821, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)]))) | |||
1822 | num_poly_bases++; | |||
1823 | gcc_assert (num_poly_bases == val->bases.length ())((void)(!(num_poly_bases == val->bases.length ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1823, __FUNCTION__), 0 : 0)); | |||
1824 | for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type))((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1824, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1824, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()); | |||
1825 | i++) | |||
1826 | if (polymorphic_type_binfo_p (BINFO_BASE_BINFO((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1827, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1827, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)]) | |||
1827 | (TYPE_BINFO (type), i)((*(&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1827, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1827, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)]))) | |||
1828 | { | |||
1829 | odr_type base = get_odr_type | |||
1830 | (BINFO_TYPE((contains_struct_check (((tree_check ((((*(&(tree_check ( (((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1831, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)])), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__))->typed.type) | |||
1831 | (BINFO_BASE_BINFO (TYPE_BINFO (type),((contains_struct_check (((tree_check ((((*(&(tree_check ( (((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1831, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)])), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__))->typed.type) | |||
1832 | i))((contains_struct_check (((tree_check ((((*(&(tree_check ( (((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1831, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)])), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1832, __FUNCTION__))->typed.type), | |||
1833 | true); | |||
1834 | gcc_assert (val->bases[j] == base)((void)(!(val->bases[j] == base) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1834, __FUNCTION__), 0 : 0)); | |||
1835 | j++; | |||
1836 | } | |||
1837 | } | |||
1838 | ||||
1839 | ||||
1840 | /* Regularize things a little. During LTO same types may come with | |||
1841 | different BINFOs. Either because their virtual table was | |||
1842 | not merged by tree merging and only later at decl merging or | |||
1843 | because one type comes with external vtable, while other | |||
1844 | with internal. We want to merge equivalent binfos to conserve | |||
1845 | memory and streaming overhead. | |||
1846 | ||||
1847 | The external vtables are more harmful: they contain references | |||
1848 | to external declarations of methods that may be defined in the | |||
1849 | merged LTO unit. For this reason we absolutely need to remove | |||
1850 | them and replace by internal variants. Not doing so will lead | |||
1851 | to incomplete answers from possible_polymorphic_call_targets. | |||
1852 | ||||
1853 | FIXME: disable for now; because ODR types are now build during | |||
1854 | streaming in, the variants do not need to be linked to the type, | |||
1855 | yet. We need to do the merging in cleanup pass to be implemented | |||
1856 | soon. */ | |||
1857 | if (!flag_ltransglobal_options.x_flag_ltrans && merge | |||
1858 | && 0 | |||
1859 | && TREE_CODE (val->type)((enum tree_code) (val->type)->base.code) == RECORD_TYPE | |||
1860 | && TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE | |||
1861 | && TYPE_BINFO (val->type)((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1861, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) && TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1861, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1862 | && TYPE_MAIN_VARIANT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1862, __FUNCTION__))->type_common.main_variant) == type | |||
1863 | && TYPE_MAIN_VARIANT (val->type)((tree_class_check ((val->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1863, __FUNCTION__))->type_common.main_variant) == val->type | |||
1864 | && BINFO_VTABLE (TYPE_BINFO (val->type))((tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1864, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1864, __FUNCTION__, (TREE_BINFO)))->binfo.vtable) | |||
1865 | && BINFO_VTABLE (TYPE_BINFO (type))((tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1865, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1865, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)) | |||
1866 | { | |||
1867 | tree master_binfo = TYPE_BINFO (val->type)((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1867, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval); | |||
1868 | tree v1 = BINFO_VTABLE (master_binfo)((tree_check ((master_binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1868, __FUNCTION__, (TREE_BINFO)))->binfo.vtable); | |||
1869 | tree v2 = BINFO_VTABLE (TYPE_BINFO (type))((tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1869, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1869, __FUNCTION__, (TREE_BINFO)))->binfo.vtable); | |||
1870 | ||||
1871 | if (TREE_CODE (v1)((enum tree_code) (v1)->base.code) == POINTER_PLUS_EXPR) | |||
1872 | { | |||
1873 | gcc_assert (TREE_CODE (v2) == POINTER_PLUS_EXPR((void)(!(((enum tree_code) (v2)->base.code) == POINTER_PLUS_EXPR && operand_equal_p ((*((const_cast<tree*> (tree_operand_check ((v1), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1874, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((v2), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1875, __FUNCTION__))))), 0)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1875, __FUNCTION__), 0 : 0)) | |||
1874 | && operand_equal_p (TREE_OPERAND (v1, 1),((void)(!(((enum tree_code) (v2)->base.code) == POINTER_PLUS_EXPR && operand_equal_p ((*((const_cast<tree*> (tree_operand_check ((v1), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1874, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((v2), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1875, __FUNCTION__))))), 0)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1875, __FUNCTION__), 0 : 0)) | |||
1875 | TREE_OPERAND (v2, 1), 0))((void)(!(((enum tree_code) (v2)->base.code) == POINTER_PLUS_EXPR && operand_equal_p ((*((const_cast<tree*> (tree_operand_check ((v1), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1874, __FUNCTION__))))), (*((const_cast<tree*> (tree_operand_check ((v2), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1875, __FUNCTION__))))), 0)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1875, __FUNCTION__), 0 : 0)); | |||
1876 | v1 = TREE_OPERAND (TREE_OPERAND (v1, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((v1), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1876, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1876, __FUNCTION__))))); | |||
1877 | v2 = TREE_OPERAND (TREE_OPERAND (v2, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((v2), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1877, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1877, __FUNCTION__))))); | |||
1878 | } | |||
1879 | gcc_assert (DECL_ASSEMBLER_NAME (v1)((void)(!(decl_assembler_name (v1) == decl_assembler_name (v2 )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1880, __FUNCTION__), 0 : 0)) | |||
1880 | == DECL_ASSEMBLER_NAME (v2))((void)(!(decl_assembler_name (v1) == decl_assembler_name (v2 )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1880, __FUNCTION__), 0 : 0)); | |||
1881 | ||||
1882 | if (DECL_EXTERNAL (v1)((contains_struct_check ((v1), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1882, __FUNCTION__))->decl_common.decl_flag_1) && !DECL_EXTERNAL (v2)((contains_struct_check ((v2), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1882, __FUNCTION__))->decl_common.decl_flag_1)) | |||
1883 | { | |||
1884 | unsigned int i; | |||
1885 | ||||
1886 | set_type_binfo (val->type, TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1886, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)); | |||
1887 | for (i = 0; i < val->types->length (); i++) | |||
1888 | { | |||
1889 | if (TYPE_BINFO ((*val->types)[i])((tree_check3 (((*val->types)[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1889, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1890 | == master_binfo) | |||
1891 | set_type_binfo ((*val->types)[i], TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1891, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)); | |||
1892 | } | |||
1893 | BINFO_TYPE (TYPE_BINFO (type))((contains_struct_check (((tree_check ((((tree_check3 ((type) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1893, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1893, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1893, __FUNCTION__))->typed.type) = val->type; | |||
1894 | } | |||
1895 | else | |||
1896 | set_type_binfo (type, master_binfo); | |||
1897 | } | |||
1898 | return build_bases; | |||
1899 | } | |||
1900 | ||||
1901 | /* REF is OBJ_TYPE_REF, return the class the ref corresponds to. | |||
1902 | FOR_DUMP_P is true when being called from the dump routines. */ | |||
1903 | ||||
1904 | tree | |||
1905 | obj_type_ref_class (const_tree ref, bool for_dump_p) | |||
1906 | { | |||
1907 | gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF)((void)(!(((enum tree_code) (ref)->base.code) == OBJ_TYPE_REF ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1907, __FUNCTION__), 0 : 0)); | |||
1908 | ref = TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1908, __FUNCTION__))->typed.type); | |||
1909 | gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE)((void)(!(((enum tree_code) (ref)->base.code) == POINTER_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1909, __FUNCTION__), 0 : 0)); | |||
1910 | ref = TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1910, __FUNCTION__))->typed.type); | |||
1911 | /* We look for type THIS points to. ObjC also builds | |||
1912 | OBJ_TYPE_REF with non-method calls, Their first parameter | |||
1913 | ID however also corresponds to class type. */ | |||
1914 | gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE((void)(!(((enum tree_code) (ref)->base.code) == METHOD_TYPE || ((enum tree_code) (ref)->base.code) == FUNCTION_TYPE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1915, __FUNCTION__), 0 : 0)) | |||
1915 | || TREE_CODE (ref) == FUNCTION_TYPE)((void)(!(((enum tree_code) (ref)->base.code) == METHOD_TYPE || ((enum tree_code) (ref)->base.code) == FUNCTION_TYPE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1915, __FUNCTION__), 0 : 0)); | |||
1916 | ref = TREE_VALUE (TYPE_ARG_TYPES (ref))((tree_check ((((tree_check2 ((ref), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1916, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1916, __FUNCTION__, (TREE_LIST)))->list.value); | |||
1917 | gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE)((void)(!(((enum tree_code) (ref)->base.code) == POINTER_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1917, __FUNCTION__), 0 : 0)); | |||
1918 | tree ret = TREE_TYPE (ref)((contains_struct_check ((ref), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1918, __FUNCTION__))->typed.type); | |||
1919 | if (!in_lto_pglobal_options.x_in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (ret)(((tree_class_check ((ret), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1919, __FUNCTION__))->type_common.canonical) == (tree) __null )) | |||
1920 | ret = TYPE_CANONICAL (ret)((tree_class_check ((ret), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1920, __FUNCTION__))->type_common.canonical); | |||
1921 | else if (odr_type ot = get_odr_type (ret, !for_dump_p)) | |||
1922 | ret = ot->type; | |||
1923 | else | |||
1924 | gcc_assert (for_dump_p)((void)(!(for_dump_p) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1924, __FUNCTION__), 0 : 0)); | |||
1925 | return ret; | |||
1926 | } | |||
1927 | ||||
1928 | /* Get ODR type hash entry for TYPE. If INSERT is true, create | |||
1929 | possibly new entry. */ | |||
1930 | ||||
1931 | odr_type | |||
1932 | get_odr_type (tree type, bool insert) | |||
1933 | { | |||
1934 | odr_type_d **slot = NULL__null; | |||
1935 | odr_type val = NULL__null; | |||
1936 | hashval_t hash; | |||
1937 | bool build_bases = false; | |||
1938 | bool insert_to_odr_array = false; | |||
1939 | int base_id = -1; | |||
1940 | ||||
1941 | type = TYPE_MAIN_VARIANT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1941, __FUNCTION__))->type_common.main_variant); | |||
1942 | if (!in_lto_pglobal_options.x_in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1942, __FUNCTION__))->type_common.canonical) == (tree) __null )) | |||
1943 | type = TYPE_CANONICAL (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1943, __FUNCTION__))->type_common.canonical); | |||
1944 | ||||
1945 | gcc_checking_assert (can_be_name_hashed_p (type))((void)(!(can_be_name_hashed_p (type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1945, __FUNCTION__), 0 : 0)); | |||
1946 | ||||
1947 | hash = hash_odr_name (type); | |||
1948 | slot = odr_hash->find_slot_with_hash (type, hash, | |||
1949 | insert ? INSERT : NO_INSERT); | |||
1950 | ||||
1951 | if (!slot) | |||
1952 | return NULL__null; | |||
1953 | ||||
1954 | /* See if we already have entry for type. */ | |||
1955 | if (*slot) | |||
1956 | { | |||
1957 | val = *slot; | |||
1958 | ||||
1959 | if (val->type != type && insert | |||
1960 | && (!val->types_set || !val->types_set->add (type))) | |||
1961 | build_bases = add_type_duplicate (val, type); | |||
1962 | } | |||
1963 | else | |||
1964 | { | |||
1965 | val = ggc_cleared_alloc<odr_type_d> (); | |||
1966 | val->type = type; | |||
1967 | val->bases = vNULL; | |||
1968 | val->derived_types = vNULL; | |||
1969 | if (type_with_linkage_p (type)) | |||
1970 | val->anonymous_namespace = type_in_anonymous_namespace_p (type); | |||
1971 | else | |||
1972 | val->anonymous_namespace = 0; | |||
1973 | build_bases = COMPLETE_TYPE_P (val->type)(((tree_class_check ((val->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1973, __FUNCTION__))->type_common.size) != (tree) __null ); | |||
1974 | insert_to_odr_array = true; | |||
1975 | *slot = val; | |||
1976 | } | |||
1977 | ||||
1978 | if (build_bases && TREE_CODE (type)((enum tree_code) (type)->base.code) == RECORD_TYPE && TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1978, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
1979 | && type_with_linkage_p (type) | |||
1980 | && type == TYPE_MAIN_VARIANT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1980, __FUNCTION__))->type_common.main_variant)) | |||
1981 | { | |||
1982 | tree binfo = TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1982, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval); | |||
1983 | unsigned int i; | |||
1984 | ||||
1985 | gcc_assert (BINFO_TYPE (TYPE_BINFO (val->type)) == type)((void)(!(((contains_struct_check (((tree_check ((((tree_check3 ((val->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1985, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1985, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1985, __FUNCTION__))->typed.type) == type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1985, __FUNCTION__), 0 : 0)); | |||
1986 | ||||
1987 | val->all_derivations_known = type_all_derivations_known_p (type); | |||
1988 | for (i = 0; i < BINFO_N_BASE_BINFOS (binfo)((&(tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1988, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()); i++) | |||
1989 | /* For now record only polymorphic types. other are | |||
1990 | pointless for devirtualization and we cannot precisely | |||
1991 | determine ODR equivalency of these during LTO. */ | |||
1992 | if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (binfo, i)((*(&(tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1992, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)]))) | |||
1993 | { | |||
1994 | tree base_type= BINFO_TYPE (BINFO_BASE_BINFO (binfo, i))((contains_struct_check (((tree_check ((((*(&(tree_check ( (binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1994, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)])), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1994, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1994, __FUNCTION__))->typed.type); | |||
1995 | odr_type base = get_odr_type (base_type, true); | |||
1996 | gcc_assert (TYPE_MAIN_VARIANT (base_type) == base_type)((void)(!(((tree_class_check ((base_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1996, __FUNCTION__))->type_common.main_variant) == base_type ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 1996, __FUNCTION__), 0 : 0)); | |||
1997 | base->derived_types.safe_push (val); | |||
1998 | val->bases.safe_push (base); | |||
1999 | if (base->id > base_id) | |||
2000 | base_id = base->id; | |||
2001 | } | |||
2002 | } | |||
2003 | /* Ensure that type always appears after bases. */ | |||
2004 | if (insert_to_odr_array) | |||
2005 | { | |||
2006 | if (odr_types_ptr) | |||
2007 | val->id = odr_types(*odr_types_ptr).length (); | |||
2008 | vec_safe_push (odr_types_ptr, val); | |||
2009 | } | |||
2010 | else if (base_id > val->id) | |||
2011 | { | |||
2012 | odr_types(*odr_types_ptr)[val->id] = 0; | |||
2013 | /* Be sure we did not recorded any derived types; these may need | |||
2014 | renumbering too. */ | |||
2015 | gcc_assert (val->derived_types.length() == 0)((void)(!(val->derived_types.length() == 0) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2015, __FUNCTION__), 0 : 0)); | |||
2016 | val->id = odr_types(*odr_types_ptr).length (); | |||
2017 | vec_safe_push (odr_types_ptr, val); | |||
2018 | } | |||
2019 | return val; | |||
2020 | } | |||
2021 | ||||
2022 | /* Return type that in ODR type hash prevailed TYPE. Be careful and punt | |||
2023 | on ODR violations. */ | |||
2024 | ||||
2025 | tree | |||
2026 | prevailing_odr_type (tree type) | |||
2027 | { | |||
2028 | odr_type t = get_odr_type (type, false); | |||
2029 | if (!t || t->odr_violated) | |||
2030 | return type; | |||
2031 | return t->type; | |||
2032 | } | |||
2033 | ||||
2034 | /* Set tbaa_enabled flag for TYPE. */ | |||
2035 | ||||
2036 | void | |||
2037 | enable_odr_based_tbaa (tree type) | |||
2038 | { | |||
2039 | odr_type t = get_odr_type (type, true); | |||
2040 | t->tbaa_enabled = true; | |||
2041 | } | |||
2042 | ||||
2043 | /* True if canonical type of TYPE is determined using ODR name. */ | |||
2044 | ||||
2045 | bool | |||
2046 | odr_based_tbaa_p (const_tree type) | |||
2047 | { | |||
2048 | if (!RECORD_OR_UNION_TYPE_P (type)(((enum tree_code) (type)->base.code) == RECORD_TYPE || (( enum tree_code) (type)->base.code) == UNION_TYPE || ((enum tree_code) (type)->base.code) == QUAL_UNION_TYPE)) | |||
2049 | return false; | |||
2050 | if (!odr_hash) | |||
2051 | return false; | |||
2052 | odr_type t = get_odr_type (const_cast <tree> (type), false); | |||
2053 | if (!t || !t->tbaa_enabled) | |||
2054 | return false; | |||
2055 | return true; | |||
2056 | } | |||
2057 | ||||
2058 | /* Set TYPE_CANONICAL of type and all its variants and duplicates | |||
2059 | to CANONICAL. */ | |||
2060 | ||||
2061 | void | |||
2062 | set_type_canonical_for_odr_type (tree type, tree canonical) | |||
2063 | { | |||
2064 | odr_type t = get_odr_type (type, false); | |||
2065 | unsigned int i; | |||
2066 | tree tt; | |||
2067 | ||||
2068 | for (tree t2 = t->type; t2; t2 = TYPE_NEXT_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2068, __FUNCTION__))->type_common.next_variant)) | |||
2069 | TYPE_CANONICAL (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2069, __FUNCTION__))->type_common.canonical) = canonical; | |||
2070 | if (t->types) | |||
2071 | FOR_EACH_VEC_ELT (*t->types, i, tt)for (i = 0; (*t->types).iterate ((i), &(tt)); ++(i)) | |||
2072 | for (tree t2 = tt; t2; t2 = TYPE_NEXT_VARIANT (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2072, __FUNCTION__))->type_common.next_variant)) | |||
2073 | TYPE_CANONICAL (t2)((tree_class_check ((t2), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2073, __FUNCTION__))->type_common.canonical) = canonical; | |||
2074 | } | |||
2075 | ||||
2076 | /* Return true if we reported some ODR violation on TYPE. */ | |||
2077 | ||||
2078 | bool | |||
2079 | odr_type_violation_reported_p (tree type) | |||
2080 | { | |||
2081 | return get_odr_type (type, false)->odr_violated; | |||
2082 | } | |||
2083 | ||||
2084 | /* Add TYPE of ODR type hash. */ | |||
2085 | ||||
2086 | void | |||
2087 | register_odr_type (tree type) | |||
2088 | { | |||
2089 | if (!odr_hash) | |||
2090 | odr_hash = new odr_hash_type (23); | |||
2091 | if (type == TYPE_MAIN_VARIANT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2091, __FUNCTION__))->type_common.main_variant)) | |||
2092 | { | |||
2093 | /* To get ODR warnings right, first register all sub-types. */ | |||
2094 | if (RECORD_OR_UNION_TYPE_P (type)(((enum tree_code) (type)->base.code) == RECORD_TYPE || (( enum tree_code) (type)->base.code) == UNION_TYPE || ((enum tree_code) (type)->base.code) == QUAL_UNION_TYPE) | |||
2095 | && COMPLETE_TYPE_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2095, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
2096 | { | |||
2097 | /* Limit recursion on types which are already registered. */ | |||
2098 | odr_type ot = get_odr_type (type, false); | |||
2099 | if (ot | |||
2100 | && (ot->type == type | |||
2101 | || (ot->types_set | |||
2102 | && ot->types_set->contains (type)))) | |||
2103 | return; | |||
2104 | for (tree f = TYPE_FIELDS (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2104, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); f; f = TREE_CHAIN (f)((contains_struct_check ((f), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2104, __FUNCTION__))->common.chain)) | |||
2105 | if (TREE_CODE (f)((enum tree_code) (f)->base.code) == FIELD_DECL) | |||
2106 | { | |||
2107 | tree subtype = TREE_TYPE (f)((contains_struct_check ((f), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2107, __FUNCTION__))->typed.type); | |||
2108 | ||||
2109 | while (TREE_CODE (subtype)((enum tree_code) (subtype)->base.code) == ARRAY_TYPE) | |||
2110 | subtype = TREE_TYPE (subtype)((contains_struct_check ((subtype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2110, __FUNCTION__))->typed.type); | |||
2111 | if (type_with_linkage_p (TYPE_MAIN_VARIANT (subtype)((tree_class_check ((subtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2111, __FUNCTION__))->type_common.main_variant))) | |||
2112 | register_odr_type (TYPE_MAIN_VARIANT (subtype)((tree_class_check ((subtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2112, __FUNCTION__))->type_common.main_variant)); | |||
2113 | } | |||
2114 | if (TYPE_BINFO (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2114, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
2115 | for (unsigned int i = 0; | |||
2116 | i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type))((&(tree_check ((((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2116, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2116, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> length ()); i++) | |||
2117 | register_odr_type (BINFO_TYPE (BINFO_BASE_BINFO((contains_struct_check (((tree_check ((((*(&(tree_check ( (((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)])), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__))->typed.type) | |||
2118 | (TYPE_BINFO (type), i))((contains_struct_check (((tree_check ((((*(&(tree_check ( (((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos))[ (i)])), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2118, __FUNCTION__))->typed.type)); | |||
2119 | } | |||
2120 | get_odr_type (type, true); | |||
2121 | } | |||
2122 | } | |||
2123 | ||||
2124 | /* Return true if type is known to have no derivations. */ | |||
2125 | ||||
2126 | bool | |||
2127 | type_known_to_have_no_derivations_p (tree t) | |||
2128 | { | |||
2129 | return (type_all_derivations_known_p (t) | |||
2130 | && (TYPE_FINAL_P (t)((tree_check3 ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2130, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->base.default_def_flag) | |||
2131 | || (odr_hash | |||
2132 | && !get_odr_type (t, true)->derived_types.length()))); | |||
2133 | } | |||
2134 | ||||
2135 | /* Dump ODR type T and all its derived types. INDENT specifies indentation for | |||
2136 | recursive printing. */ | |||
2137 | ||||
2138 | static void | |||
2139 | dump_odr_type (FILE *f, odr_type t, int indent=0) | |||
2140 | { | |||
2141 | unsigned int i; | |||
2142 | fprintf (f, "%*s type %i: ", indent * 2, "", t->id); | |||
2143 | print_generic_expr (f, t->type, TDF_SLIM); | |||
2144 | fprintf (f, "%s", t->anonymous_namespace ? " (anonymous namespace)":""); | |||
2145 | fprintf (f, "%s\n", t->all_derivations_known ? " (derivations known)":""); | |||
2146 | if (TYPE_NAME (t->type)((tree_class_check ((t->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2146, __FUNCTION__))->type_common.name)) | |||
2147 | { | |||
2148 | if (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t->type))(((contains_struct_check ((((tree_class_check ((t->type), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2148, __FUNCTION__))->type_common.name)), (TS_DECL_WITH_VIS ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2148, __FUNCTION__))->decl_with_vis.assembler_name) != ( tree) __null)) | |||
2149 | fprintf (f, "%*s mangled name: %s\n", indent * 2, "", | |||
2150 | IDENTIFIER_POINTER((const char *) (tree_check ((decl_assembler_name (((tree_class_check ((t->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2151, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2151, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ) | |||
2151 | (DECL_ASSEMBLER_NAME (TYPE_NAME (t->type)))((const char *) (tree_check ((decl_assembler_name (((tree_class_check ((t->type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2151, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2151, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); | |||
2152 | } | |||
2153 | if (t->bases.length ()) | |||
2154 | { | |||
2155 | fprintf (f, "%*s base odr type ids: ", indent * 2, ""); | |||
2156 | for (i = 0; i < t->bases.length (); i++) | |||
2157 | fprintf (f, " %i", t->bases[i]->id); | |||
2158 | fprintf (f, "\n"); | |||
2159 | } | |||
2160 | if (t->derived_types.length ()) | |||
2161 | { | |||
2162 | fprintf (f, "%*s derived types:\n", indent * 2, ""); | |||
2163 | for (i = 0; i < t->derived_types.length (); i++) | |||
2164 | dump_odr_type (f, t->derived_types[i], indent + 1); | |||
2165 | } | |||
2166 | fprintf (f, "\n"); | |||
2167 | } | |||
2168 | ||||
2169 | /* Dump the type inheritance graph. */ | |||
2170 | ||||
2171 | static void | |||
2172 | dump_type_inheritance_graph (FILE *f) | |||
2173 | { | |||
2174 | unsigned int i; | |||
2175 | unsigned int num_all_types = 0, num_types = 0, num_duplicates = 0; | |||
2176 | if (!odr_types_ptr) | |||
2177 | return; | |||
2178 | fprintf (f, "\n\nType inheritance graph:\n"); | |||
2179 | for (i = 0; i < odr_types(*odr_types_ptr).length (); i++) | |||
2180 | { | |||
2181 | if (odr_types(*odr_types_ptr)[i] && odr_types(*odr_types_ptr)[i]->bases.length () == 0) | |||
2182 | dump_odr_type (f, odr_types(*odr_types_ptr)[i]); | |||
2183 | } | |||
2184 | for (i = 0; i < odr_types(*odr_types_ptr).length (); i++) | |||
2185 | { | |||
2186 | if (!odr_types(*odr_types_ptr)[i]) | |||
2187 | continue; | |||
2188 | ||||
2189 | num_all_types++; | |||
2190 | if (!odr_types(*odr_types_ptr)[i]->types || !odr_types(*odr_types_ptr)[i]->types->length ()) | |||
2191 | continue; | |||
2192 | ||||
2193 | /* To aid ODR warnings we also mangle integer constants but do | |||
2194 | not consider duplicates there. */ | |||
2195 | if (TREE_CODE (odr_types[i]->type)((enum tree_code) ((*odr_types_ptr)[i]->type)->base.code ) == INTEGER_TYPE) | |||
2196 | continue; | |||
2197 | ||||
2198 | /* It is normal to have one duplicate and one normal variant. */ | |||
2199 | if (odr_types(*odr_types_ptr)[i]->types->length () == 1 | |||
2200 | && COMPLETE_TYPE_P (odr_types[i]->type)(((tree_class_check (((*odr_types_ptr)[i]->type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2200, __FUNCTION__))->type_common.size) != (tree) __null ) | |||
2201 | && !COMPLETE_TYPE_P ((*odr_types[i]->types)[0])(((tree_class_check (((*(*odr_types_ptr)[i]->types)[0]), ( tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2201, __FUNCTION__))->type_common.size) != (tree) __null )) | |||
2202 | continue; | |||
2203 | ||||
2204 | num_types ++; | |||
2205 | ||||
2206 | unsigned int j; | |||
2207 | fprintf (f, "Duplicate tree types for odr type %i\n", i); | |||
2208 | print_node (f, "", odr_types(*odr_types_ptr)[i]->type, 0); | |||
2209 | print_node (f, "", TYPE_NAME (odr_types[i]->type)((tree_class_check (((*odr_types_ptr)[i]->type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2209, __FUNCTION__))->type_common.name), 0); | |||
2210 | putc ('\n',f); | |||
2211 | for (j = 0; j < odr_types(*odr_types_ptr)[i]->types->length (); j++) | |||
2212 | { | |||
2213 | tree t; | |||
2214 | num_duplicates ++; | |||
2215 | fprintf (f, "duplicate #%i\n", j); | |||
2216 | print_node (f, "", (*odr_types(*odr_types_ptr)[i]->types)[j], 0); | |||
2217 | t = (*odr_types(*odr_types_ptr)[i]->types)[j]; | |||
2218 | while (TYPE_P (t)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (t)->base.code))] == tcc_type) && TYPE_CONTEXT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2218, __FUNCTION__))->type_common.context)) | |||
2219 | { | |||
2220 | t = TYPE_CONTEXT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2220, __FUNCTION__))->type_common.context); | |||
2221 | print_node (f, "", t, 0); | |||
2222 | } | |||
2223 | print_node (f, "", TYPE_NAME ((*odr_types[i]->types)[j])((tree_class_check (((*(*odr_types_ptr)[i]->types)[j]), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2223, __FUNCTION__))->type_common.name), 0); | |||
2224 | putc ('\n',f); | |||
2225 | } | |||
2226 | } | |||
2227 | fprintf (f, "Out of %i types there are %i types with duplicates; " | |||
2228 | "%i duplicates overall\n", num_all_types, num_types, num_duplicates); | |||
2229 | } | |||
2230 | ||||
2231 | /* Save some WPA->ltrans streaming by freeing stuff needed only for good | |||
2232 | ODR warnings. | |||
2233 | We make TYPE_DECLs to not point back | |||
2234 | to the type (which is needed to keep them in the same SCC and preserve | |||
2235 | location information to output warnings) and subsequently we make all | |||
2236 | TYPE_DECLS of same assembler name equivalent. */ | |||
2237 | ||||
2238 | static void | |||
2239 | free_odr_warning_data () | |||
2240 | { | |||
2241 | static bool odr_data_freed = false; | |||
2242 | ||||
2243 | if (odr_data_freed || !flag_wpaglobal_options.x_flag_wpa || !odr_types_ptr) | |||
2244 | return; | |||
2245 | ||||
2246 | odr_data_freed = true; | |||
2247 | ||||
2248 | for (unsigned int i = 0; i < odr_types(*odr_types_ptr).length (); i++) | |||
2249 | if (odr_types(*odr_types_ptr)[i]) | |||
2250 | { | |||
2251 | tree t = odr_types(*odr_types_ptr)[i]->type; | |||
2252 | ||||
2253 | TREE_TYPE (TYPE_NAME (t))((contains_struct_check ((((tree_class_check ((t), (tcc_type) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2253, __FUNCTION__))->type_common.name)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2253, __FUNCTION__))->typed.type) = void_type_nodeglobal_trees[TI_VOID_TYPE]; | |||
2254 | ||||
2255 | if (odr_types(*odr_types_ptr)[i]->types) | |||
2256 | for (unsigned int j = 0; j < odr_types(*odr_types_ptr)[i]->types->length (); j++) | |||
2257 | { | |||
2258 | tree td = (*odr_types(*odr_types_ptr)[i]->types)[j]; | |||
2259 | ||||
2260 | TYPE_NAME (td)((tree_class_check ((td), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2260, __FUNCTION__))->type_common.name) = TYPE_NAME (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2260, __FUNCTION__))->type_common.name); | |||
2261 | } | |||
2262 | } | |||
2263 | odr_data_freed = true; | |||
2264 | } | |||
2265 | ||||
2266 | /* Initialize IPA devirt and build inheritance tree graph. */ | |||
2267 | ||||
2268 | void | |||
2269 | build_type_inheritance_graph (void) | |||
2270 | { | |||
2271 | struct symtab_node *n; | |||
2272 | FILE *inheritance_dump_file; | |||
2273 | dump_flags_t flags; | |||
2274 | ||||
2275 | if (odr_hash) | |||
2276 | { | |||
2277 | free_odr_warning_data (); | |||
2278 | return; | |||
2279 | } | |||
2280 | timevar_push (TV_IPA_INHERITANCE); | |||
2281 | inheritance_dump_file = dump_begin (TDI_inheritance, &flags); | |||
2282 | odr_hash = new odr_hash_type (23); | |||
2283 | ||||
2284 | /* We reconstruct the graph starting of types of all methods seen in the | |||
2285 | unit. */ | |||
2286 | FOR_EACH_SYMBOL (n)for ((n) = symtab->first_symbol (); (n); (n) = (n)->next ) | |||
2287 | if (is_a <cgraph_node *> (n) | |||
2288 | && DECL_VIRTUAL_P (n->decl)((contains_struct_check ((n->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2288, __FUNCTION__))->decl_common.virtual_flag) | |||
2289 | && n->real_symbol_p ()) | |||
2290 | get_odr_type (TYPE_METHOD_BASETYPE (TREE_TYPE (n->decl))((tree_check2 ((((contains_struct_check ((n->decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2290, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2290, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .maxval), true); | |||
2291 | ||||
2292 | /* Look also for virtual tables of types that do not define any methods. | |||
2293 | ||||
2294 | We need it in a case where class B has virtual base of class A | |||
2295 | re-defining its virtual method and there is class C with no virtual | |||
2296 | methods with B as virtual base. | |||
2297 | ||||
2298 | Here we output B's virtual method in two variant - for non-virtual | |||
2299 | and virtual inheritance. B's virtual table has non-virtual version, | |||
2300 | while C's has virtual. | |||
2301 | ||||
2302 | For this reason we need to know about C in order to include both | |||
2303 | variants of B. More correctly, record_target_from_binfo should | |||
2304 | add both variants of the method when walking B, but we have no | |||
2305 | link in between them. | |||
2306 | ||||
2307 | We rely on fact that either the method is exported and thus we | |||
2308 | assume it is called externally or C is in anonymous namespace and | |||
2309 | thus we will see the vtable. */ | |||
2310 | ||||
2311 | else if (is_a <varpool_node *> (n) | |||
2312 | && DECL_VIRTUAL_P (n->decl)((contains_struct_check ((n->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2312, __FUNCTION__))->decl_common.virtual_flag) | |||
2313 | && TREE_CODE (DECL_CONTEXT (n->decl))((enum tree_code) (((contains_struct_check ((n->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2313, __FUNCTION__))->decl_minimal.context))->base.code ) == RECORD_TYPE | |||
2314 | && TYPE_BINFO (DECL_CONTEXT (n->decl))((tree_check3 ((((contains_struct_check ((n->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2314, __FUNCTION__))->decl_minimal.context)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2314, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval) | |||
2315 | && polymorphic_type_binfo_p (TYPE_BINFO (DECL_CONTEXT (n->decl))((tree_check3 ((((contains_struct_check ((n->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2315, __FUNCTION__))->decl_minimal.context)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2315, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval))) | |||
2316 | get_odr_type (TYPE_MAIN_VARIANT (DECL_CONTEXT (n->decl))((tree_class_check ((((contains_struct_check ((n->decl), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2316, __FUNCTION__))->decl_minimal.context)), (tcc_type) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2316, __FUNCTION__))->type_common.main_variant), true); | |||
2317 | if (inheritance_dump_file) | |||
2318 | { | |||
2319 | dump_type_inheritance_graph (inheritance_dump_file); | |||
2320 | dump_end (TDI_inheritance, inheritance_dump_file); | |||
2321 | } | |||
2322 | free_odr_warning_data (); | |||
2323 | timevar_pop (TV_IPA_INHERITANCE); | |||
2324 | } | |||
2325 | ||||
2326 | /* Return true if N has reference from live virtual table | |||
2327 | (and thus can be a destination of polymorphic call). | |||
2328 | Be conservatively correct when callgraph is not built or | |||
2329 | if the method may be referred externally. */ | |||
2330 | ||||
2331 | static bool | |||
2332 | referenced_from_vtable_p (struct cgraph_node *node) | |||
2333 | { | |||
2334 | int i; | |||
2335 | struct ipa_ref *ref; | |||
2336 | bool found = false; | |||
2337 | ||||
2338 | if (node->externally_visible | |||
2339 | || DECL_EXTERNAL (node->decl)((contains_struct_check ((node->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2339, __FUNCTION__))->decl_common.decl_flag_1) | |||
2340 | || node->used_from_other_partition) | |||
2341 | return true; | |||
2342 | ||||
2343 | /* Keep this test constant time. | |||
2344 | It is unlikely this can happen except for the case where speculative | |||
2345 | devirtualization introduced many speculative edges to this node. | |||
2346 | In this case the target is very likely alive anyway. */ | |||
2347 | if (node->ref_list.referring.length () > 100) | |||
2348 | return true; | |||
2349 | ||||
2350 | /* We need references built. */ | |||
2351 | if (symtab->state <= CONSTRUCTION) | |||
2352 | return true; | |||
2353 | ||||
2354 | for (i = 0; node->iterate_referring (i, ref); i++) | |||
2355 | if ((ref->use == IPA_REF_ALIAS | |||
2356 | && referenced_from_vtable_p (dyn_cast<cgraph_node *> (ref->referring))) | |||
2357 | || (ref->use == IPA_REF_ADDR | |||
2358 | && VAR_P (ref->referring->decl)(((enum tree_code) (ref->referring->decl)->base.code ) == VAR_DECL) | |||
2359 | && DECL_VIRTUAL_P (ref->referring->decl)((contains_struct_check ((ref->referring->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2359, __FUNCTION__))->decl_common.virtual_flag))) | |||
2360 | { | |||
2361 | found = true; | |||
2362 | break; | |||
2363 | } | |||
2364 | return found; | |||
2365 | } | |||
2366 | ||||
2367 | /* Return if TARGET is cxa_pure_virtual. */ | |||
2368 | ||||
2369 | static bool | |||
2370 | is_cxa_pure_virtual_p (tree target) | |||
2371 | { | |||
2372 | return target && TREE_CODE (TREE_TYPE (target))((enum tree_code) (((contains_struct_check ((target), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2372, __FUNCTION__))->typed.type))->base.code) != METHOD_TYPE | |||
2373 | && DECL_NAME (target)((contains_struct_check ((target), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2373, __FUNCTION__))->decl_minimal.name) | |||
2374 | && id_equal (DECL_NAME (target)((contains_struct_check ((target), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2374, __FUNCTION__))->decl_minimal.name), | |||
2375 | "__cxa_pure_virtual"); | |||
2376 | } | |||
2377 | ||||
2378 | /* If TARGET has associated node, record it in the NODES array. | |||
2379 | CAN_REFER specify if program can refer to the target directly. | |||
2380 | if TARGET is unknown (NULL) or it cannot be inserted (for example because | |||
2381 | its body was already removed and there is no way to refer to it), clear | |||
2382 | COMPLETEP. */ | |||
2383 | ||||
2384 | static void | |||
2385 | maybe_record_node (vec <cgraph_node *> &nodes, | |||
2386 | tree target, hash_set<tree> *inserted, | |||
2387 | bool can_refer, | |||
2388 | bool *completep) | |||
2389 | { | |||
2390 | struct cgraph_node *target_node, *alias_target; | |||
2391 | enum availability avail; | |||
2392 | bool pure_virtual = is_cxa_pure_virtual_p (target); | |||
2393 | ||||
2394 | /* __builtin_unreachable do not need to be added into | |||
2395 | list of targets; the runtime effect of calling them is undefined. | |||
2396 | Only "real" virtual methods should be accounted. */ | |||
2397 | if (target && TREE_CODE (TREE_TYPE (target))((enum tree_code) (((contains_struct_check ((target), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2397, __FUNCTION__))->typed.type))->base.code) != METHOD_TYPE && !pure_virtual) | |||
2398 | return; | |||
2399 | ||||
2400 | if (!can_refer) | |||
2401 | { | |||
2402 | /* The only case when method of anonymous namespace becomes unreferable | |||
2403 | is when we completely optimized it out. */ | |||
2404 | if (flag_ltransglobal_options.x_flag_ltrans | |||
2405 | || !target | |||
2406 | || !type_in_anonymous_namespace_p (DECL_CONTEXT (target)((contains_struct_check ((target), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2406, __FUNCTION__))->decl_minimal.context))) | |||
2407 | *completep = false; | |||
2408 | return; | |||
2409 | } | |||
2410 | ||||
2411 | if (!target) | |||
2412 | return; | |||
2413 | ||||
2414 | target_node = cgraph_node::get (target); | |||
2415 | ||||
2416 | /* Prefer alias target over aliases, so we do not get confused by | |||
2417 | fake duplicates. */ | |||
2418 | if (target_node) | |||
2419 | { | |||
2420 | alias_target = target_node->ultimate_alias_target (&avail); | |||
2421 | if (target_node != alias_target | |||
2422 | && avail >= AVAIL_AVAILABLE | |||
2423 | && target_node->get_availability ()) | |||
2424 | target_node = alias_target; | |||
2425 | } | |||
2426 | ||||
2427 | /* Method can only be called by polymorphic call if any | |||
2428 | of vtables referring to it are alive. | |||
2429 | ||||
2430 | While this holds for non-anonymous functions, too, there are | |||
2431 | cases where we want to keep them in the list; for example | |||
2432 | inline functions with -fno-weak are static, but we still | |||
2433 | may devirtualize them when instance comes from other unit. | |||
2434 | The same holds for LTO. | |||
2435 | ||||
2436 | Currently we ignore these functions in speculative devirtualization. | |||
2437 | ??? Maybe it would make sense to be more aggressive for LTO even | |||
2438 | elsewhere. */ | |||
2439 | if (!flag_ltransglobal_options.x_flag_ltrans | |||
2440 | && !pure_virtual | |||
2441 | && type_in_anonymous_namespace_p (DECL_CONTEXT (target)((contains_struct_check ((target), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2441, __FUNCTION__))->decl_minimal.context)) | |||
2442 | && (!target_node | |||
2443 | || !referenced_from_vtable_p (target_node))) | |||
2444 | ; | |||
2445 | /* See if TARGET is useful function we can deal with. */ | |||
2446 | else if (target_node != NULL__null | |||
2447 | && (TREE_PUBLIC (target)((target)->base.public_flag) | |||
2448 | || DECL_EXTERNAL (target)((contains_struct_check ((target), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2448, __FUNCTION__))->decl_common.decl_flag_1) | |||
2449 | || target_node->definition) | |||
2450 | && target_node->real_symbol_p ()) | |||
2451 | { | |||
2452 | gcc_assert (!target_node->inlined_to)((void)(!(!target_node->inlined_to) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2452, __FUNCTION__), 0 : 0)); | |||
2453 | gcc_assert (target_node->real_symbol_p ())((void)(!(target_node->real_symbol_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2453, __FUNCTION__), 0 : 0)); | |||
2454 | /* When sanitizing, do not assume that __cxa_pure_virtual is not called | |||
2455 | by valid program. */ | |||
2456 | if (flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_UNREACHABLE) | |||
2457 | ; | |||
2458 | /* Only add pure virtual if it is the only possible target. This way | |||
2459 | we will preserve the diagnostics about pure virtual called in many | |||
2460 | cases without disabling optimization in other. */ | |||
2461 | else if (pure_virtual) | |||
2462 | { | |||
2463 | if (nodes.length ()) | |||
2464 | return; | |||
2465 | } | |||
2466 | /* If we found a real target, take away cxa_pure_virtual. */ | |||
2467 | else if (!pure_virtual && nodes.length () == 1 | |||
2468 | && is_cxa_pure_virtual_p (nodes[0]->decl)) | |||
2469 | nodes.pop (); | |||
2470 | if (pure_virtual && nodes.length ()) | |||
2471 | return; | |||
2472 | if (!inserted->add (target)) | |||
2473 | { | |||
2474 | cached_polymorphic_call_targets->add (target_node); | |||
2475 | nodes.safe_push (target_node); | |||
2476 | } | |||
2477 | } | |||
2478 | else if (!completep) | |||
2479 | ; | |||
2480 | /* We have definition of __cxa_pure_virtual that is not accessible (it is | |||
2481 | optimized out or partitioned to other unit) so we cannot add it. When | |||
2482 | not sanitizing, there is nothing to do. | |||
2483 | Otherwise declare the list incomplete. */ | |||
2484 | else if (pure_virtual) | |||
2485 | { | |||
2486 | if (flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_UNREACHABLE) | |||
2487 | *completep = false; | |||
2488 | } | |||
2489 | else if (flag_ltransglobal_options.x_flag_ltrans | |||
2490 | || !type_in_anonymous_namespace_p (DECL_CONTEXT (target)((contains_struct_check ((target), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2490, __FUNCTION__))->decl_minimal.context))) | |||
2491 | *completep = false; | |||
2492 | } | |||
2493 | ||||
2494 | /* See if BINFO's type matches OUTER_TYPE. If so, look up | |||
2495 | BINFO of subtype of OTR_TYPE at OFFSET and in that BINFO find | |||
2496 | method in vtable and insert method to NODES array | |||
2497 | or BASES_TO_CONSIDER if this array is non-NULL. | |||
2498 | Otherwise recurse to base BINFOs. | |||
2499 | This matches what get_binfo_at_offset does, but with offset | |||
2500 | being unknown. | |||
2501 | ||||
2502 | TYPE_BINFOS is a stack of BINFOS of types with defined | |||
2503 | virtual table seen on way from class type to BINFO. | |||
2504 | ||||
2505 | MATCHED_VTABLES tracks virtual tables we already did lookup | |||
2506 | for virtual function in. INSERTED tracks nodes we already | |||
2507 | inserted. | |||
2508 | ||||
2509 | ANONYMOUS is true if BINFO is part of anonymous namespace. | |||
2510 | ||||
2511 | Clear COMPLETEP when we hit unreferable target. | |||
2512 | */ | |||
2513 | ||||
2514 | static void | |||
2515 | record_target_from_binfo (vec <cgraph_node *> &nodes, | |||
2516 | vec <tree> *bases_to_consider, | |||
2517 | tree binfo, | |||
2518 | tree otr_type, | |||
2519 | vec <tree> &type_binfos, | |||
2520 | HOST_WIDE_INTlong otr_token, | |||
2521 | tree outer_type, | |||
2522 | HOST_WIDE_INTlong offset, | |||
2523 | hash_set<tree> *inserted, | |||
2524 | hash_set<tree> *matched_vtables, | |||
2525 | bool anonymous, | |||
2526 | bool *completep) | |||
2527 | { | |||
2528 | tree type = BINFO_TYPE (binfo)((contains_struct_check (((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2528, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2528, __FUNCTION__))->typed.type); | |||
2529 | int i; | |||
2530 | tree base_binfo; | |||
2531 | ||||
2532 | ||||
2533 | if (BINFO_VTABLE (binfo)((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2533, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)) | |||
2534 | type_binfos.safe_push (binfo); | |||
2535 | if (types_same_for_odr (type, outer_type)) | |||
2536 | { | |||
2537 | int i; | |||
2538 | tree type_binfo = NULL__null; | |||
2539 | ||||
2540 | /* Look up BINFO with virtual table. For normal types it is always last | |||
2541 | binfo on stack. */ | |||
2542 | for (i = type_binfos.length () - 1; i >= 0; i--) | |||
2543 | if (BINFO_OFFSET (type_binfos[i])((tree_check ((type_binfos[i]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2543, __FUNCTION__, (TREE_BINFO)))->binfo.offset) == BINFO_OFFSET (binfo)((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2543, __FUNCTION__, (TREE_BINFO)))->binfo.offset)) | |||
2544 | { | |||
2545 | type_binfo = type_binfos[i]; | |||
2546 | break; | |||
2547 | } | |||
2548 | if (BINFO_VTABLE (binfo)((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2548, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)) | |||
2549 | type_binfos.pop (); | |||
2550 | /* If this is duplicated BINFO for base shared by virtual inheritance, | |||
2551 | we may not have its associated vtable. This is not a problem, since | |||
2552 | we will walk it on the other path. */ | |||
2553 | if (!type_binfo) | |||
2554 | return; | |||
2555 | tree inner_binfo = get_binfo_at_offset (type_binfo, | |||
2556 | offset, otr_type); | |||
2557 | if (!inner_binfo) | |||
2558 | { | |||
2559 | gcc_assert (odr_violation_reported)((void)(!(odr_violation_reported) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2559, __FUNCTION__), 0 : 0)); | |||
2560 | return; | |||
2561 | } | |||
2562 | /* For types in anonymous namespace first check if the respective vtable | |||
2563 | is alive. If not, we know the type can't be called. */ | |||
2564 | if (!flag_ltransglobal_options.x_flag_ltrans && anonymous) | |||
2565 | { | |||
2566 | tree vtable = BINFO_VTABLE (inner_binfo)((tree_check ((inner_binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2566, __FUNCTION__, (TREE_BINFO)))->binfo.vtable); | |||
2567 | varpool_node *vnode; | |||
2568 | ||||
2569 | if (TREE_CODE (vtable)((enum tree_code) (vtable)->base.code) == POINTER_PLUS_EXPR) | |||
2570 | vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((vtable), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2570, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2570, __FUNCTION__))))); | |||
2571 | vnode = varpool_node::get (vtable); | |||
2572 | if (!vnode || !vnode->definition) | |||
2573 | return; | |||
2574 | } | |||
2575 | gcc_assert (inner_binfo)((void)(!(inner_binfo) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2575, __FUNCTION__), 0 : 0)); | |||
2576 | if (bases_to_consider | |||
2577 | ? !matched_vtables->contains (BINFO_VTABLE (inner_binfo)((tree_check ((inner_binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2577, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)) | |||
2578 | : !matched_vtables->add (BINFO_VTABLE (inner_binfo)((tree_check ((inner_binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2578, __FUNCTION__, (TREE_BINFO)))->binfo.vtable))) | |||
2579 | { | |||
2580 | bool can_refer; | |||
2581 | tree target = gimple_get_virt_method_for_binfo (otr_token, | |||
2582 | inner_binfo, | |||
2583 | &can_refer); | |||
2584 | if (!bases_to_consider) | |||
2585 | maybe_record_node (nodes, target, inserted, can_refer, completep); | |||
2586 | /* Destructors are never called via construction vtables. */ | |||
2587 | else if (!target || !DECL_CXX_DESTRUCTOR_P (target)((tree_check ((target), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2587, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | |||
2588 | bases_to_consider->safe_push (target); | |||
2589 | } | |||
2590 | return; | |||
2591 | } | |||
2592 | ||||
2593 | /* Walk bases. */ | |||
2594 | for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo)((&(tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2594, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> iterate ((i), &(base_binfo))); i++) | |||
2595 | /* Walking bases that have no virtual method is pointless exercise. */ | |||
2596 | if (polymorphic_type_binfo_p (base_binfo)) | |||
2597 | record_target_from_binfo (nodes, bases_to_consider, base_binfo, otr_type, | |||
2598 | type_binfos, | |||
2599 | otr_token, outer_type, offset, inserted, | |||
2600 | matched_vtables, anonymous, completep); | |||
2601 | if (BINFO_VTABLE (binfo)((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2601, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)) | |||
2602 | type_binfos.pop (); | |||
2603 | } | |||
2604 | ||||
2605 | /* Look up virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN) | |||
2606 | of TYPE, insert them to NODES, recurse into derived nodes. | |||
2607 | INSERTED is used to avoid duplicate insertions of methods into NODES. | |||
2608 | MATCHED_VTABLES are used to avoid duplicate walking vtables. | |||
2609 | Clear COMPLETEP if unreferable target is found. | |||
2610 | ||||
2611 | If CONSIDER_CONSTRUCTION is true, record to BASES_TO_CONSIDER | |||
2612 | all cases where BASE_SKIPPED is true (because the base is abstract | |||
2613 | class). */ | |||
2614 | ||||
2615 | static void | |||
2616 | possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes, | |||
2617 | hash_set<tree> *inserted, | |||
2618 | hash_set<tree> *matched_vtables, | |||
2619 | tree otr_type, | |||
2620 | odr_type type, | |||
2621 | HOST_WIDE_INTlong otr_token, | |||
2622 | tree outer_type, | |||
2623 | HOST_WIDE_INTlong offset, | |||
2624 | bool *completep, | |||
2625 | vec <tree> &bases_to_consider, | |||
2626 | bool consider_construction) | |||
2627 | { | |||
2628 | tree binfo = TYPE_BINFO (type->type)((tree_check3 ((type->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2628, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval); | |||
2629 | unsigned int i; | |||
2630 | auto_vec <tree, 8> type_binfos; | |||
2631 | bool possibly_instantiated = type_possibly_instantiated_p (type->type); | |||
2632 | ||||
2633 | /* We may need to consider types w/o instances because of possible derived | |||
2634 | types using their methods either directly or via construction vtables. | |||
2635 | We are safe to skip them when all derivations are known, since we will | |||
2636 | handle them later. | |||
2637 | This is done by recording them to BASES_TO_CONSIDER array. */ | |||
2638 | if (possibly_instantiated || consider_construction) | |||
2639 | { | |||
2640 | record_target_from_binfo (nodes, | |||
2641 | (!possibly_instantiated | |||
2642 | && type_all_derivations_known_p (type->type)) | |||
2643 | ? &bases_to_consider : NULL__null, | |||
2644 | binfo, otr_type, type_binfos, otr_token, | |||
2645 | outer_type, offset, | |||
2646 | inserted, matched_vtables, | |||
2647 | type->anonymous_namespace, completep); | |||
2648 | } | |||
2649 | for (i = 0; i < type->derived_types.length (); i++) | |||
2650 | possible_polymorphic_call_targets_1 (nodes, inserted, | |||
2651 | matched_vtables, | |||
2652 | otr_type, | |||
2653 | type->derived_types[i], | |||
2654 | otr_token, outer_type, offset, completep, | |||
2655 | bases_to_consider, consider_construction); | |||
2656 | } | |||
2657 | ||||
2658 | /* Cache of queries for polymorphic call targets. | |||
2659 | ||||
2660 | Enumerating all call targets may get expensive when there are many | |||
2661 | polymorphic calls in the program, so we memoize all the previous | |||
2662 | queries and avoid duplicated work. */ | |||
2663 | ||||
2664 | class polymorphic_call_target_d | |||
2665 | { | |||
2666 | public: | |||
2667 | HOST_WIDE_INTlong otr_token; | |||
2668 | ipa_polymorphic_call_context context; | |||
2669 | odr_type type; | |||
2670 | vec <cgraph_node *> targets; | |||
2671 | tree decl_warning; | |||
2672 | int type_warning; | |||
2673 | unsigned int n_odr_types; | |||
2674 | bool complete; | |||
2675 | bool speculative; | |||
2676 | }; | |||
2677 | ||||
2678 | /* Polymorphic call target cache helpers. */ | |||
2679 | ||||
2680 | struct polymorphic_call_target_hasher | |||
2681 | : pointer_hash <polymorphic_call_target_d> | |||
2682 | { | |||
2683 | static inline hashval_t hash (const polymorphic_call_target_d *); | |||
2684 | static inline bool equal (const polymorphic_call_target_d *, | |||
2685 | const polymorphic_call_target_d *); | |||
2686 | static inline void remove (polymorphic_call_target_d *); | |||
2687 | }; | |||
2688 | ||||
2689 | /* Return the computed hashcode for ODR_QUERY. */ | |||
2690 | ||||
2691 | inline hashval_t | |||
2692 | polymorphic_call_target_hasher::hash (const polymorphic_call_target_d *odr_query) | |||
2693 | { | |||
2694 | inchash::hash hstate (odr_query->otr_token); | |||
2695 | ||||
2696 | hstate.add_hwi (odr_query->type->id); | |||
2697 | hstate.merge_hash (TYPE_UID (odr_query->context.outer_type)((tree_class_check ((odr_query->context.outer_type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2697, __FUNCTION__))->type_common.uid)); | |||
2698 | hstate.add_hwi (odr_query->context.offset); | |||
2699 | hstate.add_hwi (odr_query->n_odr_types); | |||
2700 | ||||
2701 | if (odr_query->context.speculative_outer_type) | |||
2702 | { | |||
2703 | hstate.merge_hash (TYPE_UID (odr_query->context.speculative_outer_type)((tree_class_check ((odr_query->context.speculative_outer_type ), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2703, __FUNCTION__))->type_common.uid)); | |||
2704 | hstate.add_hwi (odr_query->context.speculative_offset); | |||
2705 | } | |||
2706 | hstate.add_flag (odr_query->speculative); | |||
2707 | hstate.add_flag (odr_query->context.maybe_in_construction); | |||
2708 | hstate.add_flag (odr_query->context.maybe_derived_type); | |||
2709 | hstate.add_flag (odr_query->context.speculative_maybe_derived_type); | |||
2710 | hstate.commit_flag (); | |||
2711 | return hstate.end (); | |||
2712 | } | |||
2713 | ||||
2714 | /* Compare cache entries T1 and T2. */ | |||
2715 | ||||
2716 | inline bool | |||
2717 | polymorphic_call_target_hasher::equal (const polymorphic_call_target_d *t1, | |||
2718 | const polymorphic_call_target_d *t2) | |||
2719 | { | |||
2720 | return (t1->type == t2->type && t1->otr_token == t2->otr_token | |||
2721 | && t1->speculative == t2->speculative | |||
2722 | && t1->context.offset == t2->context.offset | |||
2723 | && t1->context.speculative_offset == t2->context.speculative_offset | |||
2724 | && t1->context.outer_type == t2->context.outer_type | |||
2725 | && t1->context.speculative_outer_type == t2->context.speculative_outer_type | |||
2726 | && t1->context.maybe_in_construction | |||
2727 | == t2->context.maybe_in_construction | |||
2728 | && t1->context.maybe_derived_type == t2->context.maybe_derived_type | |||
2729 | && (t1->context.speculative_maybe_derived_type | |||
2730 | == t2->context.speculative_maybe_derived_type) | |||
2731 | /* Adding new type may affect outcome of target search. */ | |||
2732 | && t1->n_odr_types == t2->n_odr_types); | |||
2733 | } | |||
2734 | ||||
2735 | /* Remove entry in polymorphic call target cache hash. */ | |||
2736 | ||||
2737 | inline void | |||
2738 | polymorphic_call_target_hasher::remove (polymorphic_call_target_d *v) | |||
2739 | { | |||
2740 | v->targets.release (); | |||
2741 | free (v); | |||
2742 | } | |||
2743 | ||||
2744 | /* Polymorphic call target query cache. */ | |||
2745 | ||||
2746 | typedef hash_table<polymorphic_call_target_hasher> | |||
2747 | polymorphic_call_target_hash_type; | |||
2748 | static polymorphic_call_target_hash_type *polymorphic_call_target_hash; | |||
2749 | ||||
2750 | /* Destroy polymorphic call target query cache. */ | |||
2751 | ||||
2752 | static void | |||
2753 | free_polymorphic_call_targets_hash () | |||
2754 | { | |||
2755 | if (cached_polymorphic_call_targets) | |||
2756 | { | |||
2757 | delete polymorphic_call_target_hash; | |||
2758 | polymorphic_call_target_hash = NULL__null; | |||
2759 | delete cached_polymorphic_call_targets; | |||
2760 | cached_polymorphic_call_targets = NULL__null; | |||
2761 | } | |||
2762 | } | |||
2763 | ||||
2764 | /* Force rebuilding type inheritance graph from scratch. | |||
2765 | This is use to make sure that we do not keep references to types | |||
2766 | which was not visible to free_lang_data. */ | |||
2767 | ||||
2768 | void | |||
2769 | rebuild_type_inheritance_graph () | |||
2770 | { | |||
2771 | if (!odr_hash) | |||
2772 | return; | |||
2773 | delete odr_hash; | |||
2774 | odr_hash = NULL__null; | |||
2775 | odr_types_ptr = NULL__null; | |||
2776 | free_polymorphic_call_targets_hash (); | |||
2777 | } | |||
2778 | ||||
2779 | /* When virtual function is removed, we may need to flush the cache. */ | |||
2780 | ||||
2781 | static void | |||
2782 | devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
2783 | { | |||
2784 | if (cached_polymorphic_call_targets | |||
2785 | && !thunk_expansion | |||
2786 | && cached_polymorphic_call_targets->contains (n)) | |||
2787 | free_polymorphic_call_targets_hash (); | |||
2788 | } | |||
2789 | ||||
2790 | /* Look up base of BINFO that has virtual table VTABLE with OFFSET. */ | |||
2791 | ||||
2792 | tree | |||
2793 | subbinfo_with_vtable_at_offset (tree binfo, unsigned HOST_WIDE_INTlong offset, | |||
2794 | tree vtable) | |||
2795 | { | |||
2796 | tree v = BINFO_VTABLE (binfo)((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2796, __FUNCTION__, (TREE_BINFO)))->binfo.vtable); | |||
2797 | int i; | |||
2798 | tree base_binfo; | |||
2799 | unsigned HOST_WIDE_INTlong this_offset; | |||
2800 | ||||
2801 | if (v) | |||
2802 | { | |||
2803 | if (!vtable_pointer_value_to_vtable (v, &v, &this_offset)) | |||
2804 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2804, __FUNCTION__)); | |||
2805 | ||||
2806 | if (offset == this_offset | |||
2807 | && DECL_ASSEMBLER_NAME (v)decl_assembler_name (v) == DECL_ASSEMBLER_NAME (vtable)decl_assembler_name (vtable)) | |||
2808 | return binfo; | |||
2809 | } | |||
2810 | ||||
2811 | for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo)((&(tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2811, __FUNCTION__, (TREE_BINFO)))->binfo.base_binfos)-> iterate ((i), &(base_binfo))); i++) | |||
2812 | if (polymorphic_type_binfo_p (base_binfo)) | |||
2813 | { | |||
2814 | base_binfo = subbinfo_with_vtable_at_offset (base_binfo, offset, vtable); | |||
2815 | if (base_binfo) | |||
2816 | return base_binfo; | |||
2817 | } | |||
2818 | return NULL__null; | |||
2819 | } | |||
2820 | ||||
2821 | /* T is known constant value of virtual table pointer. | |||
2822 | Store virtual table to V and its offset to OFFSET. | |||
2823 | Return false if T does not look like virtual table reference. */ | |||
2824 | ||||
2825 | bool | |||
2826 | vtable_pointer_value_to_vtable (const_tree t, tree *v, | |||
2827 | unsigned HOST_WIDE_INTlong *offset) | |||
2828 | { | |||
2829 | /* We expect &MEM[(void *)&virtual_table + 16B]. | |||
2830 | We obtain object's BINFO from the context of the virtual table. | |||
2831 | This one contains pointer to virtual table represented via | |||
2832 | POINTER_PLUS_EXPR. Verify that this pointer matches what | |||
2833 | we propagated through. | |||
2834 | ||||
2835 | In the case of virtual inheritance, the virtual tables may | |||
2836 | be nested, i.e. the offset may be different from 16 and we may | |||
2837 | need to dive into the type representation. */ | |||
2838 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == ADDR_EXPR | |||
2839 | && TREE_CODE (TREE_OPERAND (t, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2839, __FUNCTION__))))))->base.code) == MEM_REF | |||
2840 | && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2840, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2840, __FUNCTION__))))))->base.code) == ADDR_EXPR | |||
2841 | && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2841, __FUNCTION__)))))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2841, __FUNCTION__))))))->base.code) == INTEGER_CST | |||
2842 | && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check (((*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2842, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2842, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2842, __FUNCTION__))))))->base.code) | |||
2843 | == VAR_DECL) | |||
2844 | && DECL_VIRTUAL_P (TREE_OPERAND (TREE_OPERAND((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__)))))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__))->decl_common.virtual_flag) | |||
2845 | (TREE_OPERAND (t, 0), 0), 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__)))))), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2845, __FUNCTION__))->decl_common.virtual_flag)) | |||
2846 | { | |||
2847 | *v = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check (((*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2847, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2847, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2847, __FUNCTION__))))); | |||
2848 | *offset = tree_to_uhwi (TREE_OPERAND (TREE_OPERAND (t, 0), 1)(*((const_cast<tree*> (tree_operand_check (((*((const_cast <tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2848, __FUNCTION__)))))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2848, __FUNCTION__)))))); | |||
2849 | return true; | |||
2850 | } | |||
2851 | ||||
2852 | /* Alternative representation, used by C++ frontend is POINTER_PLUS_EXPR. | |||
2853 | We need to handle it when T comes from static variable initializer or | |||
2854 | BINFO. */ | |||
2855 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) == POINTER_PLUS_EXPR) | |||
2856 | { | |||
2857 | *offset = tree_to_uhwi (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2857, __FUNCTION__)))))); | |||
2858 | t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2858, __FUNCTION__))))); | |||
2859 | } | |||
2860 | else | |||
2861 | *offset = 0; | |||
2862 | ||||
2863 | if (TREE_CODE (t)((enum tree_code) (t)->base.code) != ADDR_EXPR) | |||
2864 | return false; | |||
2865 | *v = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2865, __FUNCTION__))))); | |||
2866 | return true; | |||
2867 | } | |||
2868 | ||||
2869 | /* T is known constant value of virtual table pointer. Return BINFO of the | |||
2870 | instance type. */ | |||
2871 | ||||
2872 | tree | |||
2873 | vtable_pointer_value_to_binfo (const_tree t) | |||
2874 | { | |||
2875 | tree vtable; | |||
2876 | unsigned HOST_WIDE_INTlong offset; | |||
2877 | ||||
2878 | if (!vtable_pointer_value_to_vtable (t, &vtable, &offset)) | |||
2879 | return NULL_TREE(tree) __null; | |||
2880 | ||||
2881 | /* FIXME: for stores of construction vtables we return NULL, | |||
2882 | because we do not have BINFO for those. Eventually we should fix | |||
2883 | our representation to allow this case to be handled, too. | |||
2884 | In the case we see store of BINFO we however may assume | |||
2885 | that standard folding will be able to cope with it. */ | |||
2886 | return subbinfo_with_vtable_at_offset (TYPE_BINFO (DECL_CONTEXT (vtable))((tree_check3 ((((contains_struct_check ((vtable), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2886, __FUNCTION__))->decl_minimal.context)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2886, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval), | |||
2887 | offset, vtable); | |||
2888 | } | |||
2889 | ||||
2890 | /* Walk bases of OUTER_TYPE that contain OTR_TYPE at OFFSET. | |||
2891 | Look up their respective virtual methods for OTR_TOKEN and OTR_TYPE | |||
2892 | and insert them in NODES. | |||
2893 | ||||
2894 | MATCHED_VTABLES and INSERTED is used to avoid duplicated work. */ | |||
2895 | ||||
2896 | static void | |||
2897 | record_targets_from_bases (tree otr_type, | |||
2898 | HOST_WIDE_INTlong otr_token, | |||
2899 | tree outer_type, | |||
2900 | HOST_WIDE_INTlong offset, | |||
2901 | vec <cgraph_node *> &nodes, | |||
2902 | hash_set<tree> *inserted, | |||
2903 | hash_set<tree> *matched_vtables, | |||
2904 | bool *completep) | |||
2905 | { | |||
2906 | while (true) | |||
2907 | { | |||
2908 | HOST_WIDE_INTlong pos, size; | |||
2909 | tree base_binfo; | |||
2910 | tree fld; | |||
2911 | ||||
2912 | if (types_same_for_odr (outer_type, otr_type)) | |||
2913 | return; | |||
2914 | ||||
2915 | for (fld = TYPE_FIELDS (outer_type)((tree_check3 ((outer_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2915, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); fld; fld = DECL_CHAIN (fld)(((contains_struct_check (((contains_struct_check ((fld), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2915, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2915, __FUNCTION__))->common.chain))) | |||
2916 | { | |||
2917 | if (TREE_CODE (fld)((enum tree_code) (fld)->base.code) != FIELD_DECL) | |||
2918 | continue; | |||
2919 | ||||
2920 | pos = int_bit_position (fld); | |||
2921 | size = tree_to_shwi (DECL_SIZE (fld)((contains_struct_check ((fld), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2921, __FUNCTION__))->decl_common.size)); | |||
2922 | if (pos <= offset && (pos + size) > offset | |||
2923 | /* Do not get confused by zero sized bases. */ | |||
2924 | && polymorphic_type_binfo_p (TYPE_BINFO (TREE_TYPE (fld))((tree_check3 ((((contains_struct_check ((fld), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2924, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2924, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval))) | |||
2925 | break; | |||
2926 | } | |||
2927 | /* Within a class type we should always find corresponding fields. */ | |||
2928 | gcc_assert (fld && TREE_CODE (TREE_TYPE (fld)) == RECORD_TYPE)((void)(!(fld && ((enum tree_code) (((contains_struct_check ((fld), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2928, __FUNCTION__))->typed.type))->base.code) == RECORD_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2928, __FUNCTION__), 0 : 0)); | |||
2929 | ||||
2930 | /* Nonbase types should have been stripped by outer_class_type. */ | |||
2931 | gcc_assert (DECL_ARTIFICIAL (fld))((void)(!(((contains_struct_check ((fld), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2931, __FUNCTION__))->decl_common.artificial_flag)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2931, __FUNCTION__), 0 : 0)); | |||
2932 | ||||
2933 | outer_type = TREE_TYPE (fld)((contains_struct_check ((fld), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2933, __FUNCTION__))->typed.type); | |||
2934 | offset -= pos; | |||
2935 | ||||
2936 | base_binfo = get_binfo_at_offset (TYPE_BINFO (outer_type)((tree_check3 ((outer_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2936, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval), | |||
2937 | offset, otr_type); | |||
2938 | if (!base_binfo) | |||
2939 | { | |||
2940 | gcc_assert (odr_violation_reported)((void)(!(odr_violation_reported) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2940, __FUNCTION__), 0 : 0)); | |||
2941 | return; | |||
2942 | } | |||
2943 | gcc_assert (base_binfo)((void)(!(base_binfo) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2943, __FUNCTION__), 0 : 0)); | |||
2944 | if (!matched_vtables->add (BINFO_VTABLE (base_binfo)((tree_check ((base_binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2944, __FUNCTION__, (TREE_BINFO)))->binfo.vtable))) | |||
2945 | { | |||
2946 | bool can_refer; | |||
2947 | tree target = gimple_get_virt_method_for_binfo (otr_token, | |||
2948 | base_binfo, | |||
2949 | &can_refer); | |||
2950 | if (!target || ! DECL_CXX_DESTRUCTOR_P (target)((tree_check ((target), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2950, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | |||
2951 | maybe_record_node (nodes, target, inserted, can_refer, completep); | |||
2952 | matched_vtables->add (BINFO_VTABLE (base_binfo)((tree_check ((base_binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2952, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)); | |||
2953 | } | |||
2954 | } | |||
2955 | } | |||
2956 | ||||
2957 | /* When virtual table is removed, we may need to flush the cache. */ | |||
2958 | ||||
2959 | static void | |||
2960 | devirt_variable_node_removal_hook (varpool_node *n, | |||
2961 | void *d ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
2962 | { | |||
2963 | if (cached_polymorphic_call_targets | |||
2964 | && DECL_VIRTUAL_P (n->decl)((contains_struct_check ((n->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2964, __FUNCTION__))->decl_common.virtual_flag) | |||
2965 | && type_in_anonymous_namespace_p (DECL_CONTEXT (n->decl)((contains_struct_check ((n->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 2965, __FUNCTION__))->decl_minimal.context))) | |||
2966 | free_polymorphic_call_targets_hash (); | |||
2967 | } | |||
2968 | ||||
2969 | /* Record about how many calls would benefit from given type to be final. */ | |||
2970 | ||||
2971 | struct odr_type_warn_count | |||
2972 | { | |||
2973 | tree type; | |||
2974 | int count; | |||
2975 | profile_count dyn_count; | |||
2976 | }; | |||
2977 | ||||
2978 | /* Record about how many calls would benefit from given method to be final. */ | |||
2979 | ||||
2980 | struct decl_warn_count | |||
2981 | { | |||
2982 | tree decl; | |||
2983 | int count; | |||
2984 | profile_count dyn_count; | |||
2985 | }; | |||
2986 | ||||
2987 | /* Information about type and decl warnings. */ | |||
2988 | ||||
2989 | class final_warning_record | |||
2990 | { | |||
2991 | public: | |||
2992 | /* If needed grow type_warnings vector and initialize new decl_warn_count | |||
2993 | to have dyn_count set to profile_count::zero (). */ | |||
2994 | void grow_type_warnings (unsigned newlen); | |||
2995 | ||||
2996 | profile_count dyn_count; | |||
2997 | auto_vec<odr_type_warn_count> type_warnings; | |||
2998 | hash_map<tree, decl_warn_count> decl_warnings; | |||
2999 | }; | |||
3000 | ||||
3001 | void | |||
3002 | final_warning_record::grow_type_warnings (unsigned newlen) | |||
3003 | { | |||
3004 | unsigned len = type_warnings.length (); | |||
3005 | if (newlen > len) | |||
3006 | { | |||
3007 | type_warnings.safe_grow_cleared (newlen, true); | |||
3008 | for (unsigned i = len; i < newlen; i++) | |||
3009 | type_warnings[i].dyn_count = profile_count::zero (); | |||
3010 | } | |||
3011 | } | |||
3012 | ||||
3013 | class final_warning_record *final_warning_records; | |||
3014 | ||||
3015 | /* Return vector containing possible targets of polymorphic call of type | |||
3016 | OTR_TYPE calling method OTR_TOKEN within type of OTR_OUTER_TYPE and OFFSET. | |||
3017 | If INCLUDE_BASES is true, walk also base types of OUTER_TYPES containing | |||
3018 | OTR_TYPE and include their virtual method. This is useful for types | |||
3019 | possibly in construction or destruction where the virtual table may | |||
3020 | temporarily change to one of base types. INCLUDE_DERIVED_TYPES make | |||
3021 | us to walk the inheritance graph for all derivations. | |||
3022 | ||||
3023 | If COMPLETEP is non-NULL, store true if the list is complete. | |||
3024 | CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry | |||
3025 | in the target cache. If user needs to visit every target list | |||
3026 | just once, it can memoize them. | |||
3027 | ||||
3028 | If SPECULATIVE is set, the list will not contain targets that | |||
3029 | are not speculatively taken. | |||
3030 | ||||
3031 | Returned vector is placed into cache. It is NOT caller's responsibility | |||
3032 | to free it. The vector can be freed on cgraph_remove_node call if | |||
3033 | the particular node is a virtual function present in the cache. */ | |||
3034 | ||||
3035 | vec <cgraph_node *> | |||
3036 | possible_polymorphic_call_targets (tree otr_type, | |||
3037 | HOST_WIDE_INTlong otr_token, | |||
3038 | ipa_polymorphic_call_context context, | |||
3039 | bool *completep, | |||
3040 | void **cache_token, | |||
3041 | bool speculative) | |||
3042 | { | |||
3043 | static struct cgraph_node_hook_list *node_removal_hook_holder; | |||
3044 | vec <cgraph_node *> nodes = vNULL; | |||
3045 | auto_vec <tree, 8> bases_to_consider; | |||
3046 | odr_type type, outer_type; | |||
3047 | polymorphic_call_target_d key; | |||
3048 | polymorphic_call_target_d **slot; | |||
3049 | unsigned int i; | |||
3050 | tree binfo, target; | |||
3051 | bool complete; | |||
3052 | bool can_refer = false; | |||
3053 | bool skipped = false; | |||
3054 | ||||
3055 | otr_type = TYPE_MAIN_VARIANT (otr_type)((tree_class_check ((otr_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3055, __FUNCTION__))->type_common.main_variant); | |||
3056 | ||||
3057 | /* If ODR is not initialized or the context is invalid, return empty | |||
3058 | incomplete list. */ | |||
3059 | if (!odr_hash || context.invalid || !TYPE_BINFO (otr_type)((tree_check3 ((otr_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3059, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) | |||
3060 | { | |||
3061 | if (completep) | |||
3062 | *completep = context.invalid; | |||
3063 | if (cache_token) | |||
3064 | *cache_token = NULL__null; | |||
3065 | return nodes; | |||
3066 | } | |||
3067 | ||||
3068 | /* Do not bother to compute speculative info when user do not asks for it. */ | |||
3069 | if (!speculative || !context.speculative_outer_type) | |||
3070 | context.clear_speculation (); | |||
3071 | ||||
3072 | type = get_odr_type (otr_type, true); | |||
3073 | ||||
3074 | /* Recording type variants would waste results cache. */ | |||
3075 | gcc_assert (!context.outer_type((void)(!(!context.outer_type || ((tree_class_check ((context .outer_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3076, __FUNCTION__))->type_common.main_variant) == context .outer_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3076, __FUNCTION__), 0 : 0)) | |||
3076 | || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type)((void)(!(!context.outer_type || ((tree_class_check ((context .outer_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3076, __FUNCTION__))->type_common.main_variant) == context .outer_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3076, __FUNCTION__), 0 : 0)); | |||
3077 | ||||
3078 | /* Look up the outer class type we want to walk. | |||
3079 | If we fail to do so, the context is invalid. */ | |||
3080 | if ((context.outer_type || context.speculative_outer_type) | |||
3081 | && !context.restrict_to_inner_class (otr_type)) | |||
3082 | { | |||
3083 | if (completep) | |||
3084 | *completep = true; | |||
3085 | if (cache_token) | |||
3086 | *cache_token = NULL__null; | |||
3087 | return nodes; | |||
3088 | } | |||
3089 | gcc_assert (!context.invalid)((void)(!(!context.invalid) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3089, __FUNCTION__), 0 : 0)); | |||
3090 | ||||
3091 | /* Check that restrict_to_inner_class kept the main variant. */ | |||
3092 | gcc_assert (!context.outer_type((void)(!(!context.outer_type || ((tree_class_check ((context .outer_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3093, __FUNCTION__))->type_common.main_variant) == context .outer_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3093, __FUNCTION__), 0 : 0)) | |||
3093 | || TYPE_MAIN_VARIANT (context.outer_type) == context.outer_type)((void)(!(!context.outer_type || ((tree_class_check ((context .outer_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3093, __FUNCTION__))->type_common.main_variant) == context .outer_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3093, __FUNCTION__), 0 : 0)); | |||
3094 | ||||
3095 | /* We canonicalize our query, so we do not need extra hashtable entries. */ | |||
3096 | ||||
3097 | /* Without outer type, we have no use for offset. Just do the | |||
3098 | basic search from inner type. */ | |||
3099 | if (!context.outer_type) | |||
3100 | context.clear_outer_type (otr_type); | |||
3101 | /* We need to update our hierarchy if the type does not exist. */ | |||
3102 | outer_type = get_odr_type (context.outer_type, true); | |||
3103 | /* If the type is complete, there are no derivations. */ | |||
3104 | if (TYPE_FINAL_P (outer_type->type)((tree_check3 ((outer_type->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3104, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->base.default_def_flag)) | |||
3105 | context.maybe_derived_type = false; | |||
3106 | ||||
3107 | /* Initialize query cache. */ | |||
3108 | if (!cached_polymorphic_call_targets) | |||
3109 | { | |||
3110 | cached_polymorphic_call_targets = new hash_set<cgraph_node *>; | |||
3111 | polymorphic_call_target_hash | |||
3112 | = new polymorphic_call_target_hash_type (23); | |||
3113 | if (!node_removal_hook_holder) | |||
3114 | { | |||
3115 | node_removal_hook_holder = | |||
3116 | symtab->add_cgraph_removal_hook (&devirt_node_removal_hook, NULL__null); | |||
3117 | symtab->add_varpool_removal_hook (&devirt_variable_node_removal_hook, | |||
3118 | NULL__null); | |||
3119 | } | |||
3120 | } | |||
3121 | ||||
3122 | if (in_lto_pglobal_options.x_in_lto_p) | |||
3123 | { | |||
3124 | if (context.outer_type != otr_type) | |||
3125 | context.outer_type | |||
3126 | = get_odr_type (context.outer_type, true)->type; | |||
3127 | if (context.speculative_outer_type) | |||
3128 | context.speculative_outer_type | |||
3129 | = get_odr_type (context.speculative_outer_type, true)->type; | |||
3130 | } | |||
3131 | ||||
3132 | /* Look up cached answer. */ | |||
3133 | key.type = type; | |||
3134 | key.otr_token = otr_token; | |||
3135 | key.speculative = speculative; | |||
3136 | key.context = context; | |||
3137 | key.n_odr_types = odr_types(*odr_types_ptr).length (); | |||
3138 | slot = polymorphic_call_target_hash->find_slot (&key, INSERT); | |||
3139 | if (cache_token) | |||
3140 | *cache_token = (void *)*slot; | |||
3141 | if (*slot) | |||
3142 | { | |||
3143 | if (completep) | |||
3144 | *completep = (*slot)->complete; | |||
3145 | if ((*slot)->type_warning && final_warning_records) | |||
3146 | { | |||
3147 | final_warning_records->type_warnings[(*slot)->type_warning - 1].count++; | |||
3148 | if (!final_warning_records->type_warnings | |||
3149 | [(*slot)->type_warning - 1].dyn_count.initialized_p ()) | |||
3150 | final_warning_records->type_warnings | |||
3151 | [(*slot)->type_warning - 1].dyn_count = profile_count::zero (); | |||
3152 | if (final_warning_records->dyn_count > 0) | |||
3153 | final_warning_records->type_warnings[(*slot)->type_warning - 1].dyn_count | |||
3154 | = final_warning_records->type_warnings[(*slot)->type_warning - 1].dyn_count | |||
3155 | + final_warning_records->dyn_count; | |||
3156 | } | |||
3157 | if (!speculative && (*slot)->decl_warning && final_warning_records) | |||
3158 | { | |||
3159 | struct decl_warn_count *c = | |||
3160 | final_warning_records->decl_warnings.get ((*slot)->decl_warning); | |||
3161 | c->count++; | |||
3162 | if (final_warning_records->dyn_count > 0) | |||
3163 | c->dyn_count += final_warning_records->dyn_count; | |||
3164 | } | |||
3165 | return (*slot)->targets; | |||
3166 | } | |||
3167 | ||||
3168 | complete = true; | |||
3169 | ||||
3170 | /* Do actual search. */ | |||
3171 | timevar_push (TV_IPA_VIRTUAL_CALL); | |||
3172 | *slot = XCNEW (polymorphic_call_target_d)((polymorphic_call_target_d *) xcalloc (1, sizeof (polymorphic_call_target_d ))); | |||
3173 | if (cache_token) | |||
3174 | *cache_token = (void *)*slot; | |||
3175 | (*slot)->type = type; | |||
3176 | (*slot)->otr_token = otr_token; | |||
3177 | (*slot)->context = context; | |||
3178 | (*slot)->speculative = speculative; | |||
3179 | ||||
3180 | hash_set<tree> inserted; | |||
3181 | hash_set<tree> matched_vtables; | |||
3182 | ||||
3183 | /* First insert targets we speculatively identified as likely. */ | |||
3184 | if (context.speculative_outer_type) | |||
3185 | { | |||
3186 | odr_type speculative_outer_type; | |||
3187 | bool speculation_complete = true; | |||
3188 | bool check_derived_types = false; | |||
3189 | ||||
3190 | /* First insert target from type itself and check if it may have | |||
3191 | derived types. */ | |||
3192 | speculative_outer_type = get_odr_type (context.speculative_outer_type, true); | |||
3193 | if (TYPE_FINAL_P (speculative_outer_type->type)((tree_check3 ((speculative_outer_type->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3193, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->base.default_def_flag)) | |||
3194 | context.speculative_maybe_derived_type = false; | |||
3195 | binfo = get_binfo_at_offset (TYPE_BINFO (speculative_outer_type->type)((tree_check3 ((speculative_outer_type->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3195, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval), | |||
3196 | context.speculative_offset, otr_type); | |||
3197 | if (binfo) | |||
3198 | target = gimple_get_virt_method_for_binfo (otr_token, binfo, | |||
3199 | &can_refer); | |||
3200 | else | |||
3201 | target = NULL__null; | |||
3202 | ||||
3203 | /* In the case we get complete method, we don't need | |||
3204 | to walk derivations. */ | |||
3205 | if (target && DECL_FINAL_P (target)((tree_check ((target), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3205, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.final )) | |||
3206 | context.speculative_maybe_derived_type = false; | |||
3207 | if (check_derived_types | |||
3208 | ? type_or_derived_type_possibly_instantiated_p | |||
3209 | (speculative_outer_type) | |||
3210 | : type_possibly_instantiated_p (speculative_outer_type->type)) | |||
3211 | maybe_record_node (nodes, target, &inserted, can_refer, | |||
3212 | &speculation_complete); | |||
3213 | if (binfo) | |||
3214 | matched_vtables.add (BINFO_VTABLE (binfo)((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3214, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)); | |||
3215 | ||||
3216 | ||||
3217 | /* Next walk recursively all derived types. */ | |||
3218 | if (context.speculative_maybe_derived_type) | |||
3219 | for (i = 0; i < speculative_outer_type->derived_types.length(); i++) | |||
3220 | possible_polymorphic_call_targets_1 (nodes, &inserted, | |||
3221 | &matched_vtables, | |||
3222 | otr_type, | |||
3223 | speculative_outer_type->derived_types[i], | |||
3224 | otr_token, speculative_outer_type->type, | |||
3225 | context.speculative_offset, | |||
3226 | &speculation_complete, | |||
3227 | bases_to_consider, | |||
3228 | false); | |||
3229 | } | |||
3230 | ||||
3231 | if (!speculative || !nodes.length ()) | |||
3232 | { | |||
3233 | bool check_derived_types = false; | |||
3234 | /* First see virtual method of type itself. */ | |||
3235 | binfo = get_binfo_at_offset (TYPE_BINFO (outer_type->type)((tree_check3 ((outer_type->type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3235, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval), | |||
3236 | context.offset, otr_type); | |||
3237 | if (binfo) | |||
3238 | target = gimple_get_virt_method_for_binfo (otr_token, binfo, | |||
3239 | &can_refer); | |||
3240 | else | |||
3241 | { | |||
3242 | gcc_assert (odr_violation_reported)((void)(!(odr_violation_reported) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3242, __FUNCTION__), 0 : 0)); | |||
3243 | target = NULL__null; | |||
3244 | } | |||
3245 | ||||
3246 | /* Destructors are never called through construction virtual tables, | |||
3247 | because the type is always known. */ | |||
3248 | if (target && DECL_CXX_DESTRUCTOR_P (target)((tree_check ((target), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3248, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | |||
3249 | context.maybe_in_construction = false; | |||
3250 | ||||
3251 | /* In the case we get complete method, we don't need | |||
3252 | to walk derivations. */ | |||
3253 | if (target && DECL_FINAL_P (target)((tree_check ((target), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3253, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.final )) | |||
3254 | { | |||
3255 | check_derived_types = true; | |||
3256 | context.maybe_derived_type = false; | |||
3257 | } | |||
3258 | ||||
3259 | /* If OUTER_TYPE is abstract, we know we are not seeing its instance. */ | |||
3260 | if (check_derived_types | |||
3261 | ? type_or_derived_type_possibly_instantiated_p (outer_type) | |||
3262 | : type_possibly_instantiated_p (outer_type->type)) | |||
3263 | maybe_record_node (nodes, target, &inserted, can_refer, &complete); | |||
3264 | else | |||
3265 | skipped = true; | |||
3266 | ||||
3267 | if (binfo) | |||
3268 | matched_vtables.add (BINFO_VTABLE (binfo)((tree_check ((binfo), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3268, __FUNCTION__, (TREE_BINFO)))->binfo.vtable)); | |||
3269 | ||||
3270 | /* Next walk recursively all derived types. */ | |||
3271 | if (context.maybe_derived_type) | |||
3272 | { | |||
3273 | for (i = 0; i < outer_type->derived_types.length(); i++) | |||
3274 | possible_polymorphic_call_targets_1 (nodes, &inserted, | |||
3275 | &matched_vtables, | |||
3276 | otr_type, | |||
3277 | outer_type->derived_types[i], | |||
3278 | otr_token, outer_type->type, | |||
3279 | context.offset, &complete, | |||
3280 | bases_to_consider, | |||
3281 | context.maybe_in_construction); | |||
3282 | ||||
3283 | if (!outer_type->all_derivations_known) | |||
3284 | { | |||
3285 | if (!speculative && final_warning_records | |||
3286 | && nodes.length () == 1 | |||
3287 | && TREE_CODE (TREE_TYPE (nodes[0]->decl))((enum tree_code) (((contains_struct_check ((nodes[0]->decl ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3287, __FUNCTION__))->typed.type))->base.code) == METHOD_TYPE) | |||
3288 | { | |||
3289 | if (complete | |||
3290 | && warn_suggest_final_typesglobal_options.x_warn_suggest_final_types | |||
3291 | && !outer_type->derived_types.length ()) | |||
3292 | { | |||
3293 | final_warning_records->grow_type_warnings | |||
3294 | (outer_type->id); | |||
3295 | final_warning_records->type_warnings[outer_type->id].count++; | |||
3296 | if (!final_warning_records->type_warnings | |||
3297 | [outer_type->id].dyn_count.initialized_p ()) | |||
3298 | final_warning_records->type_warnings | |||
3299 | [outer_type->id].dyn_count = profile_count::zero (); | |||
3300 | final_warning_records->type_warnings[outer_type->id].dyn_count | |||
3301 | += final_warning_records->dyn_count; | |||
3302 | final_warning_records->type_warnings[outer_type->id].type | |||
3303 | = outer_type->type; | |||
3304 | (*slot)->type_warning = outer_type->id + 1; | |||
3305 | } | |||
3306 | if (complete | |||
3307 | && warn_suggest_final_methodsglobal_options.x_warn_suggest_final_methods | |||
3308 | && types_same_for_odr (DECL_CONTEXT (nodes[0]->decl)((contains_struct_check ((nodes[0]->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3308, __FUNCTION__))->decl_minimal.context), | |||
3309 | outer_type->type)) | |||
3310 | { | |||
3311 | bool existed; | |||
3312 | struct decl_warn_count &c = | |||
3313 | final_warning_records->decl_warnings.get_or_insert | |||
3314 | (nodes[0]->decl, &existed); | |||
3315 | ||||
3316 | if (existed) | |||
3317 | { | |||
3318 | c.count++; | |||
3319 | c.dyn_count += final_warning_records->dyn_count; | |||
3320 | } | |||
3321 | else | |||
3322 | { | |||
3323 | c.count = 1; | |||
3324 | c.dyn_count = final_warning_records->dyn_count; | |||
3325 | c.decl = nodes[0]->decl; | |||
3326 | } | |||
3327 | (*slot)->decl_warning = nodes[0]->decl; | |||
3328 | } | |||
3329 | } | |||
3330 | complete = false; | |||
3331 | } | |||
3332 | } | |||
3333 | ||||
3334 | if (!speculative) | |||
3335 | { | |||
3336 | /* Destructors are never called through construction virtual tables, | |||
3337 | because the type is always known. One of entries may be | |||
3338 | cxa_pure_virtual so look to at least two of them. */ | |||
3339 | if (context.maybe_in_construction) | |||
3340 | for (i =0 ; i < MIN (nodes.length (), 2)((nodes.length ()) < (2) ? (nodes.length ()) : (2)); i++) | |||
3341 | if (DECL_CXX_DESTRUCTOR_P (nodes[i]->decl)((tree_check ((nodes[i]->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3341, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | |||
3342 | context.maybe_in_construction = false; | |||
3343 | if (context.maybe_in_construction) | |||
3344 | { | |||
3345 | if (type != outer_type | |||
3346 | && (!skipped | |||
3347 | || (context.maybe_derived_type | |||
3348 | && !type_all_derivations_known_p (outer_type->type)))) | |||
3349 | record_targets_from_bases (otr_type, otr_token, outer_type->type, | |||
3350 | context.offset, nodes, &inserted, | |||
3351 | &matched_vtables, &complete); | |||
3352 | if (skipped) | |||
3353 | maybe_record_node (nodes, target, &inserted, can_refer, &complete); | |||
3354 | for (i = 0; i < bases_to_consider.length(); i++) | |||
3355 | maybe_record_node (nodes, bases_to_consider[i], &inserted, can_refer, &complete); | |||
3356 | } | |||
3357 | } | |||
3358 | } | |||
3359 | ||||
3360 | (*slot)->targets = nodes; | |||
3361 | (*slot)->complete = complete; | |||
3362 | (*slot)->n_odr_types = odr_types(*odr_types_ptr).length (); | |||
3363 | if (completep) | |||
3364 | *completep = complete; | |||
3365 | ||||
3366 | timevar_pop (TV_IPA_VIRTUAL_CALL); | |||
3367 | return nodes; | |||
3368 | } | |||
3369 | ||||
3370 | bool | |||
3371 | add_decl_warning (const tree &key ATTRIBUTE_UNUSED__attribute__ ((__unused__)), const decl_warn_count &value, | |||
3372 | vec<const decl_warn_count*> *vec) | |||
3373 | { | |||
3374 | vec->safe_push (&value); | |||
3375 | return true; | |||
3376 | } | |||
3377 | ||||
3378 | /* Dump target list TARGETS into FILE. */ | |||
3379 | ||||
3380 | static void | |||
3381 | dump_targets (FILE *f, vec <cgraph_node *> targets, bool verbose) | |||
3382 | { | |||
3383 | unsigned int i; | |||
3384 | ||||
3385 | for (i = 0; i < targets.length (); i++) | |||
3386 | { | |||
3387 | char *name = NULL__null; | |||
3388 | if (in_lto_pglobal_options.x_in_lto_p) | |||
3389 | name = cplus_demangle_v3 (targets[i]->asm_name (), 0); | |||
3390 | fprintf (f, " %s", name ? name : targets[i]->dump_name ()); | |||
3391 | if (in_lto_pglobal_options.x_in_lto_p) | |||
3392 | free (name); | |||
3393 | if (!targets[i]->definition) | |||
3394 | fprintf (f, " (no definition%s)", | |||
3395 | DECL_DECLARED_INLINE_P (targets[i]->decl)((tree_check ((targets[i]->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3395, __FUNCTION__, (FUNCTION_DECL)))->function_decl.declared_inline_flag ) | |||
3396 | ? " inline" : ""); | |||
3397 | /* With many targets for every call polymorphic dumps are going to | |||
3398 | be quadratic in size. */ | |||
3399 | if (i > 10 && !verbose) | |||
3400 | { | |||
3401 | fprintf (f, " ... and %i more targets\n", targets.length () - i); | |||
3402 | return; | |||
3403 | } | |||
3404 | } | |||
3405 | fprintf (f, "\n"); | |||
3406 | } | |||
3407 | ||||
3408 | /* Dump all possible targets of a polymorphic call. */ | |||
3409 | ||||
3410 | void | |||
3411 | dump_possible_polymorphic_call_targets (FILE *f, | |||
3412 | tree otr_type, | |||
3413 | HOST_WIDE_INTlong otr_token, | |||
3414 | const ipa_polymorphic_call_context &ctx, | |||
3415 | bool verbose) | |||
3416 | { | |||
3417 | vec <cgraph_node *> targets; | |||
3418 | bool final; | |||
3419 | odr_type type = get_odr_type (TYPE_MAIN_VARIANT (otr_type)((tree_class_check ((otr_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3419, __FUNCTION__))->type_common.main_variant), false); | |||
3420 | unsigned int len; | |||
3421 | ||||
3422 | if (!type) | |||
3423 | return; | |||
3424 | targets = possible_polymorphic_call_targets (otr_type, otr_token, | |||
3425 | ctx, | |||
3426 | &final, NULL__null, false); | |||
3427 | fprintf (f, " Targets of polymorphic call of type %i:", type->id); | |||
3428 | print_generic_expr (f, type->type, TDF_SLIM); | |||
3429 | fprintf (f, " token %i\n", (int)otr_token); | |||
3430 | ||||
3431 | ctx.dump (f); | |||
3432 | ||||
3433 | fprintf (f, " %s%s%s%s\n ", | |||
3434 | final ? "This is a complete list." : | |||
3435 | "This is partial list; extra targets may be defined in other units.", | |||
3436 | ctx.maybe_in_construction ? " (base types included)" : "", | |||
3437 | ctx.maybe_derived_type ? " (derived types included)" : "", | |||
3438 | ctx.speculative_maybe_derived_type ? " (speculative derived types included)" : ""); | |||
3439 | len = targets.length (); | |||
3440 | dump_targets (f, targets, verbose); | |||
3441 | ||||
3442 | targets = possible_polymorphic_call_targets (otr_type, otr_token, | |||
3443 | ctx, | |||
3444 | &final, NULL__null, true); | |||
3445 | if (targets.length () != len) | |||
3446 | { | |||
3447 | fprintf (f, " Speculative targets:"); | |||
3448 | dump_targets (f, targets, verbose); | |||
3449 | } | |||
3450 | /* Ugly: during callgraph construction the target cache may get populated | |||
3451 | before all targets are found. While this is harmless (because all local | |||
3452 | types are discovered and only in those case we devirtualize fully and we | |||
3453 | don't do speculative devirtualization before IPA stage) it triggers | |||
3454 | assert here when dumping at that stage also populates the case with | |||
3455 | speculative targets. Quietly ignore this. */ | |||
3456 | gcc_assert (symtab->state < IPA_SSA || targets.length () <= len)((void)(!(symtab->state < IPA_SSA || targets.length () <= len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3456, __FUNCTION__), 0 : 0)); | |||
3457 | fprintf (f, "\n"); | |||
3458 | } | |||
3459 | ||||
3460 | ||||
3461 | /* Return true if N can be possibly target of a polymorphic call of | |||
3462 | OTR_TYPE/OTR_TOKEN. */ | |||
3463 | ||||
3464 | bool | |||
3465 | possible_polymorphic_call_target_p (tree otr_type, | |||
3466 | HOST_WIDE_INTlong otr_token, | |||
3467 | const ipa_polymorphic_call_context &ctx, | |||
3468 | struct cgraph_node *n) | |||
3469 | { | |||
3470 | vec <cgraph_node *> targets; | |||
3471 | unsigned int i; | |||
3472 | bool final; | |||
3473 | ||||
3474 | if (fndecl_built_in_p (n->decl, BUILT_IN_NORMAL) | |||
3475 | && (DECL_FUNCTION_CODE (n->decl) == BUILT_IN_UNREACHABLE | |||
3476 | || DECL_FUNCTION_CODE (n->decl) == BUILT_IN_TRAP | |||
3477 | || DECL_FUNCTION_CODE (n->decl) == BUILT_IN_UNREACHABLE_TRAP)) | |||
3478 | return true; | |||
3479 | ||||
3480 | if (is_cxa_pure_virtual_p (n->decl)) | |||
3481 | return true; | |||
3482 | ||||
3483 | if (!odr_hash) | |||
3484 | return true; | |||
3485 | targets = possible_polymorphic_call_targets (otr_type, otr_token, ctx, &final); | |||
3486 | for (i = 0; i < targets.length (); i++) | |||
3487 | if (n->semantically_equivalent_p (targets[i])) | |||
3488 | return true; | |||
3489 | ||||
3490 | /* At a moment we allow middle end to dig out new external declarations | |||
3491 | as a targets of polymorphic calls. */ | |||
3492 | if (!final && !n->definition) | |||
3493 | return true; | |||
3494 | return false; | |||
3495 | } | |||
3496 | ||||
3497 | ||||
3498 | ||||
3499 | /* Return true if N can be possibly target of a polymorphic call of | |||
3500 | OBJ_TYPE_REF expression REF in STMT. */ | |||
3501 | ||||
3502 | bool | |||
3503 | possible_polymorphic_call_target_p (tree ref, | |||
3504 | gimple *stmt, | |||
3505 | struct cgraph_node *n) | |||
3506 | { | |||
3507 | ipa_polymorphic_call_context context (current_function_decl, ref, stmt); | |||
3508 | tree call_fn = gimple_call_fn (stmt); | |||
3509 | ||||
3510 | return possible_polymorphic_call_target_p (obj_type_ref_class (call_fn), | |||
3511 | tree_to_uhwi | |||
3512 | (OBJ_TYPE_REF_TOKEN (call_fn)(*((const_cast<tree*> (tree_operand_check (((tree_check ((call_fn), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3512, __FUNCTION__, (OBJ_TYPE_REF)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3512, __FUNCTION__)))))), | |||
3513 | context, | |||
3514 | n); | |||
3515 | } | |||
3516 | ||||
3517 | ||||
3518 | /* After callgraph construction new external nodes may appear. | |||
3519 | Add them into the graph. */ | |||
3520 | ||||
3521 | void | |||
3522 | update_type_inheritance_graph (void) | |||
3523 | { | |||
3524 | struct cgraph_node *n; | |||
3525 | ||||
3526 | if (!odr_hash) | |||
3527 | return; | |||
3528 | free_polymorphic_call_targets_hash (); | |||
3529 | timevar_push (TV_IPA_INHERITANCE); | |||
3530 | /* We reconstruct the graph starting from types of all methods seen in the | |||
3531 | unit. */ | |||
3532 | FOR_EACH_FUNCTION (n)for ((n) = symtab->first_function (); (n); (n) = symtab-> next_function ((n))) | |||
3533 | if (DECL_VIRTUAL_P (n->decl)((contains_struct_check ((n->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3533, __FUNCTION__))->decl_common.virtual_flag) | |||
3534 | && !n->definition | |||
3535 | && n->real_symbol_p ()) | |||
3536 | get_odr_type (TYPE_METHOD_BASETYPE (TREE_TYPE (n->decl))((tree_check2 ((((contains_struct_check ((n->decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3536, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3536, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .maxval), true); | |||
3537 | timevar_pop (TV_IPA_INHERITANCE); | |||
3538 | } | |||
3539 | ||||
3540 | ||||
3541 | /* Return true if N looks like likely target of a polymorphic call. | |||
3542 | Rule out cxa_pure_virtual, noreturns, function declared cold and | |||
3543 | other obvious cases. */ | |||
3544 | ||||
3545 | bool | |||
3546 | likely_target_p (struct cgraph_node *n) | |||
3547 | { | |||
3548 | int flags; | |||
3549 | /* cxa_pure_virtual and similar things are not likely. */ | |||
3550 | if (TREE_CODE (TREE_TYPE (n->decl))((enum tree_code) (((contains_struct_check ((n->decl), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3550, __FUNCTION__))->typed.type))->base.code) != METHOD_TYPE) | |||
3551 | return false; | |||
3552 | flags = flags_from_decl_or_type (n->decl); | |||
3553 | if (flags & ECF_NORETURN(1 << 3)) | |||
3554 | return false; | |||
3555 | if (lookup_attribute ("cold", | |||
3556 | DECL_ATTRIBUTES (n->decl)((contains_struct_check ((n->decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3556, __FUNCTION__))->decl_common.attributes))) | |||
3557 | return false; | |||
3558 | if (n->frequency < NODE_FREQUENCY_NORMAL) | |||
3559 | return false; | |||
3560 | /* If there are no live virtual tables referring the target, | |||
3561 | the only way the target can be called is an instance coming from other | |||
3562 | compilation unit; speculative devirtualization is built around an | |||
3563 | assumption that won't happen. */ | |||
3564 | if (!referenced_from_vtable_p (n)) | |||
3565 | return false; | |||
3566 | return true; | |||
3567 | } | |||
3568 | ||||
3569 | /* Compare type warning records P1 and P2 and choose one with larger count; | |||
3570 | helper for qsort. */ | |||
3571 | ||||
3572 | static int | |||
3573 | type_warning_cmp (const void *p1, const void *p2) | |||
3574 | { | |||
3575 | const odr_type_warn_count *t1 = (const odr_type_warn_count *)p1; | |||
3576 | const odr_type_warn_count *t2 = (const odr_type_warn_count *)p2; | |||
3577 | ||||
3578 | if (t1->dyn_count < t2->dyn_count) | |||
3579 | return 1; | |||
3580 | if (t1->dyn_count > t2->dyn_count) | |||
3581 | return -1; | |||
3582 | return t2->count - t1->count; | |||
3583 | } | |||
3584 | ||||
3585 | /* Compare decl warning records P1 and P2 and choose one with larger count; | |||
3586 | helper for qsort. */ | |||
3587 | ||||
3588 | static int | |||
3589 | decl_warning_cmp (const void *p1, const void *p2) | |||
3590 | { | |||
3591 | const decl_warn_count *t1 = *(const decl_warn_count * const *)p1; | |||
3592 | const decl_warn_count *t2 = *(const decl_warn_count * const *)p2; | |||
3593 | ||||
3594 | if (t1->dyn_count < t2->dyn_count) | |||
3595 | return 1; | |||
3596 | if (t1->dyn_count > t2->dyn_count) | |||
3597 | return -1; | |||
3598 | return t2->count - t1->count; | |||
3599 | } | |||
3600 | ||||
3601 | ||||
3602 | /* Try to speculatively devirtualize call to OTR_TYPE with OTR_TOKEN with | |||
3603 | context CTX. */ | |||
3604 | ||||
3605 | struct cgraph_node * | |||
3606 | try_speculative_devirtualization (tree otr_type, HOST_WIDE_INTlong otr_token, | |||
3607 | ipa_polymorphic_call_context ctx) | |||
3608 | { | |||
3609 | vec <cgraph_node *>targets | |||
3610 | = possible_polymorphic_call_targets | |||
3611 | (otr_type, otr_token, ctx, NULL__null, NULL__null, true); | |||
3612 | unsigned int i; | |||
3613 | struct cgraph_node *likely_target = NULL__null; | |||
3614 | ||||
3615 | for (i = 0; i < targets.length (); i++) | |||
3616 | if (likely_target_p (targets[i])) | |||
3617 | { | |||
3618 | if (likely_target) | |||
3619 | return NULL__null; | |||
3620 | likely_target = targets[i]; | |||
3621 | } | |||
3622 | if (!likely_target | |||
3623 | ||!likely_target->definition | |||
3624 | || DECL_EXTERNAL (likely_target->decl)((contains_struct_check ((likely_target->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3624, __FUNCTION__))->decl_common.decl_flag_1)) | |||
3625 | return NULL__null; | |||
3626 | ||||
3627 | /* Don't use an implicitly-declared destructor (c++/58678). */ | |||
3628 | struct cgraph_node *non_thunk_target | |||
3629 | = likely_target->function_symbol (); | |||
3630 | if (DECL_ARTIFICIAL (non_thunk_target->decl)((contains_struct_check ((non_thunk_target->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3630, __FUNCTION__))->decl_common.artificial_flag)) | |||
3631 | return NULL__null; | |||
3632 | if (likely_target->get_availability () <= AVAIL_INTERPOSABLE | |||
3633 | && likely_target->can_be_discarded_p ()) | |||
3634 | return NULL__null; | |||
3635 | return likely_target; | |||
3636 | } | |||
3637 | ||||
3638 | /* The ipa-devirt pass. | |||
3639 | When polymorphic call has only one likely target in the unit, | |||
3640 | turn it into a speculative call. */ | |||
3641 | ||||
3642 | static unsigned int | |||
3643 | ipa_devirt (void) | |||
3644 | { | |||
3645 | struct cgraph_node *n; | |||
3646 | hash_set<void *> bad_call_targets; | |||
3647 | struct cgraph_edge *e; | |||
3648 | ||||
3649 | int npolymorphic = 0, nspeculated = 0, nconverted = 0, ncold = 0; | |||
3650 | int nmultiple = 0, noverwritable = 0, ndevirtualized = 0, nnotdefined = 0; | |||
3651 | int nwrong = 0, nok = 0, nexternal = 0, nartificial = 0; | |||
3652 | int ndropped = 0; | |||
3653 | ||||
3654 | if (!odr_types_ptr) | |||
3655 | return 0; | |||
3656 | ||||
3657 | if (dump_file) | |||
3658 | dump_type_inheritance_graph (dump_file); | |||
3659 | ||||
3660 | /* We can output -Wsuggest-final-methods and -Wsuggest-final-types warnings. | |||
3661 | This is implemented by setting up final_warning_records that are updated | |||
3662 | by get_polymorphic_call_targets. | |||
3663 | We need to clear cache in this case to trigger recomputation of all | |||
3664 | entries. */ | |||
3665 | if (warn_suggest_final_methodsglobal_options.x_warn_suggest_final_methods || warn_suggest_final_typesglobal_options.x_warn_suggest_final_types) | |||
3666 | { | |||
3667 | final_warning_records = new (final_warning_record); | |||
3668 | final_warning_records->dyn_count = profile_count::zero (); | |||
3669 | final_warning_records->grow_type_warnings (odr_types(*odr_types_ptr).length ()); | |||
3670 | free_polymorphic_call_targets_hash (); | |||
3671 | } | |||
3672 | ||||
3673 | FOR_EACH_DEFINED_FUNCTION (n)for ((n) = symtab->first_defined_function (); (n); (n) = symtab ->next_defined_function ((n))) | |||
3674 | { | |||
3675 | bool update = false; | |||
3676 | if (!opt_for_fn (n->decl, flag_devirtualize)(opts_for_fn (n->decl)->x_flag_devirtualize)) | |||
3677 | continue; | |||
3678 | if (dump_file && n->indirect_calls) | |||
3679 | fprintf (dump_file, "\n\nProcesing function %s\n", | |||
3680 | n->dump_name ()); | |||
3681 | for (e = n->indirect_calls; e; e = e->next_callee) | |||
3682 | if (e->indirect_info->polymorphic) | |||
3683 | { | |||
3684 | struct cgraph_node *likely_target = NULL__null; | |||
3685 | void *cache_token; | |||
3686 | bool final; | |||
3687 | ||||
3688 | if (final_warning_records) | |||
3689 | final_warning_records->dyn_count = e->count.ipa (); | |||
3690 | ||||
3691 | vec <cgraph_node *>targets | |||
3692 | = possible_polymorphic_call_targets | |||
3693 | (e, &final, &cache_token, true); | |||
3694 | unsigned int i; | |||
3695 | ||||
3696 | /* Trigger warnings by calculating non-speculative targets. */ | |||
3697 | if (warn_suggest_final_methodsglobal_options.x_warn_suggest_final_methods || warn_suggest_final_typesglobal_options.x_warn_suggest_final_types) | |||
3698 | possible_polymorphic_call_targets (e); | |||
3699 | ||||
3700 | if (dump_file) | |||
3701 | dump_possible_polymorphic_call_targets | |||
3702 | (dump_file, e, (dump_flags & TDF_DETAILS)); | |||
3703 | ||||
3704 | npolymorphic++; | |||
3705 | ||||
3706 | /* See if the call can be devirtualized by means of ipa-prop's | |||
3707 | polymorphic call context propagation. If not, we can just | |||
3708 | forget about this call being polymorphic and avoid some heavy | |||
3709 | lifting in remove_unreachable_nodes that will otherwise try to | |||
3710 | keep all possible targets alive until inlining and in the inliner | |||
3711 | itself. | |||
3712 | ||||
3713 | This may need to be revisited once we add further ways to use | |||
3714 | the may edges, but it is a reasonable thing to do right now. */ | |||
3715 | ||||
3716 | if ((e->indirect_info->param_index == -1 | |||
3717 | || (!opt_for_fn (n->decl, flag_devirtualize_speculatively)(opts_for_fn (n->decl)->x_flag_devirtualize_speculatively ) | |||
3718 | && e->indirect_info->vptr_changed)) | |||
3719 | && !flag_ltrans_devirtualizeglobal_options.x_flag_ltrans_devirtualize) | |||
3720 | { | |||
3721 | e->indirect_info->polymorphic = false; | |||
3722 | ndropped++; | |||
3723 | if (dump_file) | |||
3724 | fprintf (dump_file, "Dropping polymorphic call info;" | |||
3725 | " it cannot be used by ipa-prop\n"); | |||
3726 | } | |||
3727 | ||||
3728 | if (!opt_for_fn (n->decl, flag_devirtualize_speculatively)(opts_for_fn (n->decl)->x_flag_devirtualize_speculatively )) | |||
3729 | continue; | |||
3730 | ||||
3731 | if (!e->maybe_hot_p ()) | |||
3732 | { | |||
3733 | if (dump_file) | |||
3734 | fprintf (dump_file, "Call is cold\n\n"); | |||
3735 | ncold++; | |||
3736 | continue; | |||
3737 | } | |||
3738 | if (e->speculative) | |||
3739 | { | |||
3740 | if (dump_file) | |||
3741 | fprintf (dump_file, "Call is already speculated\n\n"); | |||
3742 | nspeculated++; | |||
3743 | ||||
3744 | /* When dumping see if we agree with speculation. */ | |||
3745 | if (!dump_file) | |||
3746 | continue; | |||
3747 | } | |||
3748 | if (bad_call_targets.contains (cache_token)) | |||
3749 | { | |||
3750 | if (dump_file) | |||
3751 | fprintf (dump_file, "Target list is known to be useless\n\n"); | |||
3752 | nmultiple++; | |||
3753 | continue; | |||
3754 | } | |||
3755 | for (i = 0; i < targets.length (); i++) | |||
3756 | if (likely_target_p (targets[i])) | |||
3757 | { | |||
3758 | if (likely_target) | |||
3759 | { | |||
3760 | likely_target = NULL__null; | |||
3761 | if (dump_file) | |||
3762 | fprintf (dump_file, "More than one likely target\n\n"); | |||
3763 | nmultiple++; | |||
3764 | break; | |||
3765 | } | |||
3766 | likely_target = targets[i]; | |||
3767 | } | |||
3768 | if (!likely_target) | |||
3769 | { | |||
3770 | bad_call_targets.add (cache_token); | |||
3771 | continue; | |||
3772 | } | |||
3773 | /* This is reached only when dumping; check if we agree or disagree | |||
3774 | with the speculation. */ | |||
3775 | if (e->speculative) | |||
3776 | { | |||
3777 | bool found = e->speculative_call_for_target (likely_target); | |||
3778 | if (found) | |||
3779 | { | |||
3780 | fprintf (dump_file, "We agree with speculation\n\n"); | |||
3781 | nok++; | |||
3782 | } | |||
3783 | else | |||
3784 | { | |||
3785 | fprintf (dump_file, "We disagree with speculation\n\n"); | |||
3786 | nwrong++; | |||
3787 | } | |||
3788 | continue; | |||
3789 | } | |||
3790 | if (!likely_target->definition) | |||
3791 | { | |||
3792 | if (dump_file) | |||
3793 | fprintf (dump_file, "Target is not a definition\n\n"); | |||
3794 | nnotdefined++; | |||
3795 | continue; | |||
3796 | } | |||
3797 | /* Do not introduce new references to external symbols. While we | |||
3798 | can handle these just well, it is common for programs to | |||
3799 | incorrectly with headers defining methods they are linked | |||
3800 | with. */ | |||
3801 | if (DECL_EXTERNAL (likely_target->decl)((contains_struct_check ((likely_target->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3801, __FUNCTION__))->decl_common.decl_flag_1)) | |||
3802 | { | |||
3803 | if (dump_file) | |||
3804 | fprintf (dump_file, "Target is external\n\n"); | |||
3805 | nexternal++; | |||
3806 | continue; | |||
3807 | } | |||
3808 | /* Don't use an implicitly-declared destructor (c++/58678). */ | |||
3809 | struct cgraph_node *non_thunk_target | |||
3810 | = likely_target->function_symbol (); | |||
3811 | if (DECL_ARTIFICIAL (non_thunk_target->decl)((contains_struct_check ((non_thunk_target->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3811, __FUNCTION__))->decl_common.artificial_flag)) | |||
3812 | { | |||
3813 | if (dump_file) | |||
3814 | fprintf (dump_file, "Target is artificial\n\n"); | |||
3815 | nartificial++; | |||
3816 | continue; | |||
3817 | } | |||
3818 | if (likely_target->get_availability () <= AVAIL_INTERPOSABLE | |||
3819 | && likely_target->can_be_discarded_p ()) | |||
3820 | { | |||
3821 | if (dump_file) | |||
3822 | fprintf (dump_file, "Target is overwritable\n\n"); | |||
3823 | noverwritable++; | |||
3824 | continue; | |||
3825 | } | |||
3826 | else if (dbg_cnt (devirt)) | |||
3827 | { | |||
3828 | if (dump_enabled_p ()) | |||
3829 | { | |||
3830 | dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt, | |||
3831 | "speculatively devirtualizing call " | |||
3832 | "in %s to %s\n", | |||
3833 | n->dump_name (), | |||
3834 | likely_target->dump_name ()); | |||
3835 | } | |||
3836 | if (!likely_target->can_be_discarded_p ()) | |||
3837 | { | |||
3838 | cgraph_node *alias; | |||
3839 | alias = dyn_cast<cgraph_node *> (likely_target->noninterposable_alias ()); | |||
3840 | if (alias) | |||
3841 | likely_target = alias; | |||
3842 | } | |||
3843 | nconverted++; | |||
3844 | update = true; | |||
3845 | e->make_speculative | |||
3846 | (likely_target, e->count.apply_scale (8, 10)); | |||
3847 | } | |||
3848 | } | |||
3849 | if (update) | |||
3850 | ipa_update_overall_fn_summary (n); | |||
3851 | } | |||
3852 | if (warn_suggest_final_methodsglobal_options.x_warn_suggest_final_methods || warn_suggest_final_typesglobal_options.x_warn_suggest_final_types) | |||
3853 | { | |||
3854 | if (warn_suggest_final_typesglobal_options.x_warn_suggest_final_types) | |||
3855 | { | |||
3856 | final_warning_records->type_warnings.qsort (type_warning_cmp)qsort (type_warning_cmp); | |||
3857 | for (unsigned int i = 0; | |||
3858 | i < final_warning_records->type_warnings.length (); i++) | |||
3859 | if (final_warning_records->type_warnings[i].count) | |||
3860 | { | |||
3861 | tree type = final_warning_records->type_warnings[i].type; | |||
3862 | int count = final_warning_records->type_warnings[i].count; | |||
3863 | profile_count dyn_count | |||
3864 | = final_warning_records->type_warnings[i].dyn_count; | |||
3865 | ||||
3866 | if (!(dyn_count > 0)) | |||
3867 | warning_n (DECL_SOURCE_LOCATION (TYPE_NAME (type))((contains_struct_check ((((tree_class_check ((type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3867, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3867, __FUNCTION__))->decl_minimal.locus), | |||
3868 | OPT_Wsuggest_final_types, count, | |||
3869 | "Declaring type %qD final " | |||
3870 | "would enable devirtualization of %i call", | |||
3871 | "Declaring type %qD final " | |||
3872 | "would enable devirtualization of %i calls", | |||
3873 | type, | |||
3874 | count); | |||
3875 | else | |||
3876 | warning_n (DECL_SOURCE_LOCATION (TYPE_NAME (type))((contains_struct_check ((((tree_class_check ((type), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3876, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3876, __FUNCTION__))->decl_minimal.locus), | |||
3877 | OPT_Wsuggest_final_types, count, | |||
3878 | "Declaring type %qD final " | |||
3879 | "would enable devirtualization of %i call " | |||
3880 | "executed %lli times", | |||
3881 | "Declaring type %qD final " | |||
3882 | "would enable devirtualization of %i calls " | |||
3883 | "executed %lli times", | |||
3884 | type, | |||
3885 | count, | |||
3886 | (long long) dyn_count.to_gcov_type ()); | |||
3887 | } | |||
3888 | } | |||
3889 | ||||
3890 | if (warn_suggest_final_methodsglobal_options.x_warn_suggest_final_methods) | |||
3891 | { | |||
3892 | auto_vec<const decl_warn_count*> decl_warnings_vec; | |||
3893 | ||||
3894 | final_warning_records->decl_warnings.traverse | |||
3895 | <vec<const decl_warn_count *> *, add_decl_warning> (&decl_warnings_vec); | |||
3896 | decl_warnings_vec.qsort (decl_warning_cmp)qsort (decl_warning_cmp); | |||
3897 | for (unsigned int i = 0; i < decl_warnings_vec.length (); i++) | |||
3898 | { | |||
3899 | tree decl = decl_warnings_vec[i]->decl; | |||
3900 | int count = decl_warnings_vec[i]->count; | |||
3901 | profile_count dyn_count | |||
3902 | = decl_warnings_vec[i]->dyn_count; | |||
3903 | ||||
3904 | if (!(dyn_count > 0)) | |||
3905 | if (DECL_CXX_DESTRUCTOR_P (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3905, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | |||
3906 | warning_n (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3906, __FUNCTION__))->decl_minimal.locus), | |||
3907 | OPT_Wsuggest_final_methods, count, | |||
3908 | "Declaring virtual destructor of %qD final " | |||
3909 | "would enable devirtualization of %i call", | |||
3910 | "Declaring virtual destructor of %qD final " | |||
3911 | "would enable devirtualization of %i calls", | |||
3912 | DECL_CONTEXT (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3912, __FUNCTION__))->decl_minimal.context), count); | |||
3913 | else | |||
3914 | warning_n (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3914, __FUNCTION__))->decl_minimal.locus), | |||
3915 | OPT_Wsuggest_final_methods, count, | |||
3916 | "Declaring method %qD final " | |||
3917 | "would enable devirtualization of %i call", | |||
3918 | "Declaring method %qD final " | |||
3919 | "would enable devirtualization of %i calls", | |||
3920 | decl, count); | |||
3921 | else if (DECL_CXX_DESTRUCTOR_P (decl)((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3921, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.cxx_destructor )) | |||
3922 | warning_n (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3922, __FUNCTION__))->decl_minimal.locus), | |||
3923 | OPT_Wsuggest_final_methods, count, | |||
3924 | "Declaring virtual destructor of %qD final " | |||
3925 | "would enable devirtualization of %i call " | |||
3926 | "executed %lli times", | |||
3927 | "Declaring virtual destructor of %qD final " | |||
3928 | "would enable devirtualization of %i calls " | |||
3929 | "executed %lli times", | |||
3930 | DECL_CONTEXT (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3930, __FUNCTION__))->decl_minimal.context), count, | |||
3931 | (long long)dyn_count.to_gcov_type ()); | |||
3932 | else | |||
3933 | warning_n (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 3933, __FUNCTION__))->decl_minimal.locus), | |||
3934 | OPT_Wsuggest_final_methods, count, | |||
3935 | "Declaring method %qD final " | |||
3936 | "would enable devirtualization of %i call " | |||
3937 | "executed %lli times", | |||
3938 | "Declaring method %qD final " | |||
3939 | "would enable devirtualization of %i calls " | |||
3940 | "executed %lli times", | |||
3941 | decl, count, | |||
3942 | (long long)dyn_count.to_gcov_type ()); | |||
3943 | } | |||
3944 | } | |||
3945 | ||||
3946 | delete (final_warning_records); | |||
3947 | final_warning_records = 0; | |||
3948 | } | |||
3949 | ||||
3950 | if (dump_file) | |||
3951 | fprintf (dump_file, | |||
3952 | "%i polymorphic calls, %i devirtualized," | |||
3953 | " %i speculatively devirtualized, %i cold\n" | |||
3954 | "%i have multiple targets, %i overwritable," | |||
3955 | " %i already speculated (%i agree, %i disagree)," | |||
3956 | " %i external, %i not defined, %i artificial, %i infos dropped\n", | |||
3957 | npolymorphic, ndevirtualized, nconverted, ncold, | |||
3958 | nmultiple, noverwritable, nspeculated, nok, nwrong, | |||
3959 | nexternal, nnotdefined, nartificial, ndropped); | |||
3960 | return ndevirtualized || ndropped ? TODO_remove_functions(1 << 8) : 0; | |||
3961 | } | |||
3962 | ||||
3963 | namespace { | |||
3964 | ||||
3965 | const pass_data pass_data_ipa_devirt = | |||
3966 | { | |||
3967 | IPA_PASS, /* type */ | |||
3968 | "devirt", /* name */ | |||
3969 | OPTGROUP_NONE, /* optinfo_flags */ | |||
3970 | TV_IPA_DEVIRT, /* tv_id */ | |||
3971 | 0, /* properties_required */ | |||
3972 | 0, /* properties_provided */ | |||
3973 | 0, /* properties_destroyed */ | |||
3974 | 0, /* todo_flags_start */ | |||
3975 | ( TODO_dump_symtab(1 << 7) ), /* todo_flags_finish */ | |||
3976 | }; | |||
3977 | ||||
3978 | class pass_ipa_devirt : public ipa_opt_pass_d | |||
3979 | { | |||
3980 | public: | |||
3981 | pass_ipa_devirt (gcc::context *ctxt) | |||
3982 | : ipa_opt_pass_d (pass_data_ipa_devirt, ctxt, | |||
3983 | NULL__null, /* generate_summary */ | |||
3984 | NULL__null, /* write_summary */ | |||
3985 | NULL__null, /* read_summary */ | |||
3986 | NULL__null, /* write_optimization_summary */ | |||
3987 | NULL__null, /* read_optimization_summary */ | |||
3988 | NULL__null, /* stmt_fixup */ | |||
3989 | 0, /* function_transform_todo_flags_start */ | |||
3990 | NULL__null, /* function_transform */ | |||
3991 | NULL__null) /* variable_transform */ | |||
3992 | {} | |||
3993 | ||||
3994 | /* opt_pass methods: */ | |||
3995 | bool gate (function *) final override | |||
3996 | { | |||
3997 | /* In LTO, always run the IPA passes and decide on function basis if the | |||
3998 | pass is enabled. */ | |||
3999 | if (in_lto_pglobal_options.x_in_lto_p) | |||
4000 | return true; | |||
4001 | return (flag_devirtualizeglobal_options.x_flag_devirtualize | |||
4002 | && (flag_devirtualize_speculativelyglobal_options.x_flag_devirtualize_speculatively | |||
4003 | || (warn_suggest_final_methodsglobal_options.x_warn_suggest_final_methods | |||
4004 | || warn_suggest_final_typesglobal_options.x_warn_suggest_final_types)) | |||
4005 | && optimizeglobal_options.x_optimize); | |||
4006 | } | |||
4007 | ||||
4008 | unsigned int execute (function *) final override { return ipa_devirt (); } | |||
4009 | ||||
4010 | }; // class pass_ipa_devirt | |||
4011 | ||||
4012 | } // anon namespace | |||
4013 | ||||
4014 | ipa_opt_pass_d * | |||
4015 | make_pass_ipa_devirt (gcc::context *ctxt) | |||
4016 | { | |||
4017 | return new pass_ipa_devirt (ctxt); | |||
4018 | } | |||
4019 | ||||
4020 | /* Print ODR name of a TYPE if available. | |||
4021 | Use demangler when option DEMANGLE is used. */ | |||
4022 | ||||
4023 | DEBUG_FUNCTION__attribute__ ((__used__)) void | |||
4024 | debug_tree_odr_name (tree type, bool demangle) | |||
4025 | { | |||
4026 | const char *odr = get_odr_name_for_type (type); | |||
4027 | if (demangle) | |||
4028 | { | |||
4029 | const int opts = DMGL_PARAMS(1 << 0) | DMGL_ANSI(1 << 1) | DMGL_TYPES(1 << 4); | |||
4030 | odr = cplus_demangle (odr, opts); | |||
4031 | } | |||
4032 | ||||
4033 | fprintf (stderrstderr, "%s\n", odr); | |||
4034 | } | |||
4035 | ||||
4036 | /* Register ODR enum so we later stream record about its values. */ | |||
4037 | ||||
4038 | void | |||
4039 | register_odr_enum (tree t) | |||
4040 | { | |||
4041 | if (flag_ltoglobal_options.x_flag_lto) | |||
4042 | vec_safe_push (odr_enums, t); | |||
4043 | } | |||
4044 | ||||
4045 | /* Write ODR enums to LTO stream file. */ | |||
4046 | ||||
4047 | static void | |||
4048 | ipa_odr_summary_write (void) | |||
4049 | { | |||
4050 | if (!odr_enums && !odr_enum_map) | |||
4051 | return; | |||
4052 | struct output_block *ob = create_output_block (LTO_section_odr_types); | |||
4053 | unsigned int i; | |||
4054 | tree t; | |||
4055 | ||||
4056 | if (odr_enums) | |||
4057 | { | |||
4058 | streamer_write_uhwi (ob, odr_enums->length ()); | |||
4059 | ||||
4060 | /* For every ODR enum stream out | |||
4061 | - its ODR name | |||
4062 | - number of values, | |||
4063 | - value names and constant their represent | |||
4064 | - bitpack of locations so we can do good diagnostics. */ | |||
4065 | FOR_EACH_VEC_ELT (*odr_enums, i, t)for (i = 0; (*odr_enums).iterate ((i), &(t)); ++(i)) | |||
4066 | { | |||
4067 | streamer_write_string (ob, ob->main_stream, | |||
4068 | IDENTIFIER_POINTER((const char *) (tree_check ((decl_assembler_name (((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4069, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4069, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ) | |||
4069 | (DECL_ASSEMBLER_NAME (TYPE_NAME (t)))((const char *) (tree_check ((decl_assembler_name (((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4069, __FUNCTION__))->type_common.name))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4069, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | |||
4070 | true); | |||
4071 | ||||
4072 | int n = 0; | |||
4073 | for (tree e = TYPE_VALUES (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4073, __FUNCTION__, (ENUMERAL_TYPE)))->type_non_common.values ); e; e = TREE_CHAIN (e)((contains_struct_check ((e), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4073, __FUNCTION__))->common.chain)) | |||
4074 | n++; | |||
4075 | streamer_write_uhwi (ob, n); | |||
4076 | for (tree e = TYPE_VALUES (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4076, __FUNCTION__, (ENUMERAL_TYPE)))->type_non_common.values ); e; e = TREE_CHAIN (e)((contains_struct_check ((e), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4076, __FUNCTION__))->common.chain)) | |||
4077 | { | |||
4078 | streamer_write_string (ob, ob->main_stream, | |||
4079 | IDENTIFIER_POINTER (TREE_PURPOSE (e))((const char *) (tree_check ((((tree_check ((e), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4079, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4079, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), | |||
4080 | true); | |||
4081 | streamer_write_wide_int (ob, | |||
4082 | wi::to_wide (DECL_INITIAL((contains_struct_check ((((tree_check ((e), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4083, __FUNCTION__, (TREE_LIST)))->list.value)), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4083, __FUNCTION__))->decl_common.initial) | |||
4083 | (TREE_VALUE (e))((contains_struct_check ((((tree_check ((e), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4083, __FUNCTION__, (TREE_LIST)))->list.value)), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4083, __FUNCTION__))->decl_common.initial))); | |||
4084 | } | |||
4085 | ||||
4086 | bitpack_d bp = bitpack_create (ob->main_stream); | |||
4087 | lto_output_location (ob, &bp, DECL_SOURCE_LOCATION (TYPE_NAME (t))((contains_struct_check ((((tree_class_check ((t), (tcc_type) , "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4087, __FUNCTION__))->type_common.name)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4087, __FUNCTION__))->decl_minimal.locus)); | |||
4088 | for (tree e = TYPE_VALUES (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4088, __FUNCTION__, (ENUMERAL_TYPE)))->type_non_common.values ); e; e = TREE_CHAIN (e)((contains_struct_check ((e), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4088, __FUNCTION__))->common.chain)) | |||
4089 | lto_output_location (ob, &bp, | |||
4090 | DECL_SOURCE_LOCATION (TREE_VALUE (e))((contains_struct_check ((((tree_check ((e), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4090, __FUNCTION__, (TREE_LIST)))->list.value)), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4090, __FUNCTION__))->decl_minimal.locus)); | |||
4091 | streamer_write_bitpack (&bp); | |||
4092 | } | |||
4093 | vec_free (odr_enums); | |||
4094 | odr_enums = NULL__null; | |||
4095 | } | |||
4096 | /* During LTO incremental linking we already have streamed in types. */ | |||
4097 | else if (odr_enum_map) | |||
4098 | { | |||
4099 | gcc_checking_assert (!odr_enums)((void)(!(!odr_enums) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/ipa-devirt.cc" , 4099, __FUNCTION__), 0 : 0)); | |||
4100 | streamer_write_uhwi (ob, odr_enum_map->elements ()); | |||
4101 | ||||
4102 | hash_map<nofree_string_hash, odr_enum>::iterator iter | |||
4103 | = odr_enum_map->begin (); | |||
4104 | for (; iter != odr_enum_map->end (); ++iter) | |||
4105 | { | |||
4106 | odr_enum &this_enum = (*iter).second; | |||
4107 | streamer_write_string (ob, ob->main_stream, (*iter).first, true); | |||
4108 | ||||
4109 | streamer_write_uhwi (ob, this_enum.vals.length ()); | |||
4110 | for (unsigned j = 0; j < this_enum.vals.length (); j++) | |||
4111 | { | |||
4112 | streamer_write_string (ob, ob->main_stream, | |||
4113 | this_enum.vals[j].name, true); | |||
4114 | streamer_write_wide_int (ob, this_enum.vals[j].val); | |||
4115 | } | |||
4116 | ||||
4117 | bitpack_d bp = bitpack_create (ob->main_stream); | |||
4118 | lto_output_location (ob, &bp, this_enum.locus); | |||
4119 | for (unsigned j = 0; j < this_enum.vals.length (); j++) | |||
4120 | lto_output_location (ob, &bp, this_enum.vals[j].locus); | |||
4121 | streamer_write_bitpack (&bp); | |||
4122 | } | |||
4123 | ||||
4124 | delete odr_enum_map; | |||
4125 | obstack_free (&odr_enum_obstack, NULL)__extension__ ({ struct obstack *__o = (&odr_enum_obstack ); void *__obj = (void *) (__null); if (__obj > (void *) __o ->chunk && __obj < (void *) __o->chunk_limit ) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o, __obj); }); | |||
4126 | odr_enum_map = NULL__null; | |||
4127 | } | |||
4128 | ||||
4129 | produce_asm (ob, NULL__null); | |||
4130 | destroy_output_block (ob); | |||
4131 | } | |||
4132 | ||||
4133 | /* Write ODR enums from LTO stream file and warn on mismatches. */ | |||
4134 | ||||
4135 | static void | |||
4136 | ipa_odr_read_section (struct lto_file_decl_data *file_data, const char *data, | |||
4137 | size_t len) | |||
4138 | { | |||
4139 | const struct lto_function_header *header | |||
4140 | = (const struct lto_function_header *) data; | |||
4141 | const int cfg_offset = sizeof (struct lto_function_header); | |||
4142 | const int main_offset = cfg_offset + header->cfg_size; | |||
4143 | const int string_offset = main_offset + header->main_size; | |||
4144 | class data_in *data_in; | |||
4145 | ||||
4146 | lto_input_block ib ((const char *) data + main_offset, header->main_size, | |||
4147 | file_data->mode_table); | |||
4148 | ||||
4149 | data_in | |||
4150 | = lto_data_in_create (file_data, (const char *) data + string_offset, | |||
4151 | header->string_size, vNULL); | |||
4152 | unsigned int n = streamer_read_uhwi (&ib); | |||
4153 | ||||
4154 | if (!odr_enum_map) | |||
4155 | { | |||
4156 | gcc_obstack_init (&odr_enum_obstack)_obstack_begin (((&odr_enum_obstack)), (memory_block_pool ::block_size), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free )); | |||
4157 | odr_enum_map = new (hash_map <nofree_string_hash, odr_enum>); | |||
4158 | } | |||
4159 | ||||
4160 | for (unsigned i = 0; i < n; i++) | |||
4161 | { | |||
4162 | const char *rname = streamer_read_string (data_in, &ib); | |||
4163 | unsigned int nvals = streamer_read_uhwi (&ib); | |||
4164 | char *name; | |||
4165 | ||||
4166 | obstack_grow (&odr_enum_obstack, rname, strlen (rname) + 1)__extension__ ({ struct obstack *__o = (&odr_enum_obstack ); size_t __len = (strlen (rname) + 1); if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1->next_free); }) < __len) _obstack_newchunk (__o, __len ); memcpy (__o->next_free, rname, __len); __o->next_free += __len; (void) 0; }); | |||
4167 | name = XOBFINISH (&odr_enum_obstack, char *)((char *) __extension__ ({ struct obstack *__o1 = ((&odr_enum_obstack )); void *__value = (void *) __o1->object_base; if (__o1-> next_free == __value) __o1->maybe_empty_object = 1; __o1-> next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1 ->object_base) + (((__o1->next_free) - (__o1->object_base ) + (__o1->alignment_mask)) & ~(__o1->alignment_mask ))) : (char *) (((ptrdiff_t) (__o1->next_free) + (__o1-> alignment_mask)) & ~(__o1->alignment_mask))); if ((size_t ) (__o1->next_free - (char *) __o1->chunk) > (size_t ) (__o1->chunk_limit - (char *) __o1->chunk)) __o1-> next_free = __o1->chunk_limit; __o1->object_base = __o1 ->next_free; __value; })); | |||
4168 | ||||
4169 | bool existed_p; | |||
4170 | class odr_enum &this_enum | |||
4171 | = odr_enum_map->get_or_insert (xstrdup (name), &existed_p); | |||
4172 | ||||
4173 | /* If this is first time we see the enum, remember its definition. */ | |||
4174 | if (!existed_p) | |||
4175 | { | |||
4176 | this_enum.vals.safe_grow_cleared (nvals, true); | |||
4177 | this_enum.warned = false; | |||
4178 | if (dump_file) | |||
4179 | fprintf (dump_file, "enum %s\n{\n", name); | |||
4180 | for (unsigned j = 0; j < nvals; j++) | |||
4181 | { | |||
4182 | const char *val_name = streamer_read_string (data_in, &ib); | |||
4183 | obstack_grow (&odr_enum_obstack, val_name, strlen (val_name) + 1)__extension__ ({ struct obstack *__o = (&odr_enum_obstack ); size_t __len = (strlen (val_name) + 1); if (__extension__ ( { struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1->next_free); }) < __len) _obstack_newchunk (__o , __len); memcpy (__o->next_free, val_name, __len); __o-> next_free += __len; (void) 0; }); | |||
4184 | this_enum.vals[j].name = XOBFINISH (&odr_enum_obstack, char *)((char *) __extension__ ({ struct obstack *__o1 = ((&odr_enum_obstack )); void *__value = (void *) __o1->object_base; if (__o1-> next_free == __value) __o1->maybe_empty_object = 1; __o1-> next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1 ->object_base) + (((__o1->next_free) - (__o1->object_base ) + (__o1->alignment_mask)) & ~(__o1->alignment_mask ))) : (char *) (((ptrdiff_t) (__o1->next_free) + (__o1-> alignment_mask)) & ~(__o1->alignment_mask))); if ((size_t ) (__o1->next_free - (char *) __o1->chunk) > (size_t ) (__o1->chunk_limit - (char *) __o1->chunk)) __o1-> next_free = __o1->chunk_limit; __o1->object_base = __o1 ->next_free; __value; })); | |||
4185 | this_enum.vals[j].val = streamer_read_wide_int (&ib); | |||
4186 | if (dump_file) | |||
4187 | fprintf (dump_file, " %s = " HOST_WIDE_INT_PRINT_DEC"%" "l" "d" ",\n", | |||
4188 | val_name, wi::fits_shwi_p (this_enum.vals[j].val) | |||
4189 | ? this_enum.vals[j].val.to_shwi () : -1); | |||
4190 | } | |||
4191 | bitpack_d bp = streamer_read_bitpack (&ib); | |||
4192 | stream_input_location (&this_enum.locus, &bp, data_in)streamer_hooks.input_location (&this_enum.locus, &bp, data_in); | |||
4193 | for (unsigned j = 0; j < nvals; j++) | |||
4194 | stream_input_location (&this_enum.vals[j].locus, &bp, data_in)streamer_hooks.input_location (&this_enum.vals[j].locus, & bp, data_in); | |||
4195 | data_in->location_cache.apply_location_cache (); | |||
4196 | if (dump_file) | |||
4197 | fprintf (dump_file, "}\n"); | |||
4198 | } | |||
4199 | /* If we already have definition, compare it with new one and output | |||
4200 | warnings if they differs. */ | |||
4201 | else | |||
4202 | { | |||
4203 | int do_warning = -1; | |||
4204 | char *warn_name = NULL__null; | |||
4205 | wide_int warn_value = wi::zero (1); | |||
4206 | ||||
4207 | if (dump_file) | |||
4208 | fprintf (dump_file, "Comparing enum %s\n", name); | |||
4209 | ||||
4210 | /* Look for differences which we will warn about later once locations | |||
4211 | are streamed. */ | |||
4212 | for (unsigned j = 0; j < nvals; j++) | |||
4213 | { | |||
4214 | const char *id = streamer_read_string (data_in, &ib); | |||
4215 | wide_int val = streamer_read_wide_int (&ib); | |||
4216 | ||||
4217 | if (do_warning != -1 || j >= this_enum.vals.length ()) | |||
4218 | continue; | |||
4219 | if (strcmp (id, this_enum.vals[j].name) | |||
4220 | || (val.get_precision() != | |||
4221 | this_enum.vals[j].val.get_precision()) | |||
4222 | || val != this_enum.vals[j].val) | |||
4223 | { | |||
4224 | warn_name = xstrdup (id); | |||
4225 | warn_value = val; | |||
4226 | do_warning = j; | |||
4227 | if (dump_file) | |||
4228 | fprintf (dump_file, " Different on entry %i\n", j); | |||
4229 | } | |||
4230 | } | |||
4231 | ||||
4232 | /* Stream in locations, but do not apply them unless we are going | |||
4233 | to warn. */ | |||
4234 | bitpack_d bp = streamer_read_bitpack (&ib); | |||
4235 | location_t locus; | |||
4236 | ||||
4237 | stream_input_location (&locus, &bp, data_in)streamer_hooks.input_location (&locus, &bp, data_in); | |||
4238 | ||||
4239 | /* Did we find a difference? */ | |||
4240 | if (do_warning != -1 || nvals != this_enum.vals.length ()) | |||
4241 | { | |||
4242 | data_in->location_cache.apply_location_cache (); | |||
4243 | ||||
4244 | const int opts = DMGL_PARAMS(1 << 0) | DMGL_ANSI(1 << 1) | DMGL_TYPES(1 << 4); | |||
4245 | char *dmgname = cplus_demangle (name, opts); | |||
4246 | if (this_enum.warned | |||
4247 | || !warning_at (this_enum.locus, | |||
4248 | OPT_Wodr, "type %qs violates the " | |||
4249 | "C++ One Definition Rule", | |||
4250 | dmgname)) | |||
4251 | do_warning = -1; | |||
4252 | else | |||
4253 | { | |||
4254 | this_enum.warned = true; | |||
4255 | if (do_warning == -1) | |||
4256 | inform (locus, | |||
4257 | "an enum with different number of values is defined" | |||
4258 | " in another translation unit"); | |||
4259 | else if (warn_name) | |||
4260 | inform (locus, | |||
4261 | "an enum with different value name" | |||
4262 | " is defined in another translation unit"); | |||
4263 | else | |||
4264 | inform (locus, | |||
4265 | "an enum with different values" | |||
4266 | " is defined in another translation unit"); | |||
4267 | } | |||
4268 | } | |||
4269 | else | |||
4270 | data_in->location_cache.revert_location_cache (); | |||
4271 | ||||
4272 | /* Finally look up for location of the actual value that diverged. */ | |||
4273 | for (unsigned j = 0; j < nvals; j++) | |||
4274 | { | |||
4275 | location_t id_locus; | |||
4276 | ||||
4277 | data_in->location_cache.revert_location_cache (); | |||
4278 | stream_input_location (&id_locus, &bp, data_in)streamer_hooks.input_location (&id_locus, &bp, data_in ); | |||
4279 | ||||
4280 | if ((int) j
| |||
4281 | { | |||
4282 | data_in->location_cache.apply_location_cache (); | |||
4283 | ||||
4284 | if (strcmp (warn_name, this_enum.vals[j].name)) | |||
| ||||
4285 | inform (this_enum.vals[j].locus, | |||
4286 | "name %qs differs from name %qs defined" | |||
4287 | " in another translation unit", | |||
4288 | this_enum.vals[j].name, warn_name); | |||
4289 | else if (this_enum.vals[j].val.get_precision() != | |||
4290 | warn_value.get_precision()) | |||
4291 | inform (this_enum.vals[j].locus, | |||
4292 | "name %qs is defined as %u-bit while another " | |||
4293 | "translation unit defines it as %u-bit", | |||
4294 | warn_name, this_enum.vals[j].val.get_precision(), | |||
4295 | warn_value.get_precision()); | |||
4296 | /* FIXME: In case there is easy way to print wide_ints, | |||
4297 | perhaps we could do it here instead of overflow check. */ | |||
4298 | else if (wi::fits_shwi_p (this_enum.vals[j].val) | |||
4299 | && wi::fits_shwi_p (warn_value)) | |||
4300 | inform (this_enum.vals[j].locus, | |||
4301 | "name %qs is defined to %wd while another " | |||
4302 | "translation unit defines it as %wd", | |||
4303 | warn_name, this_enum.vals[j].val.to_shwi (), | |||
4304 | warn_value.to_shwi ()); | |||
4305 | else | |||
4306 | inform (this_enum.vals[j].locus, | |||
4307 | "name %qs is defined to different value " | |||
4308 | "in another translation unit", | |||
4309 | warn_name); | |||
4310 | ||||
4311 | inform (id_locus, | |||
4312 | "mismatching definition"); | |||
4313 | } | |||
4314 | else | |||
4315 | data_in->location_cache.revert_location_cache (); | |||
4316 | } | |||
4317 | if (warn_name) | |||
4318 | free (warn_name); | |||
4319 | obstack_free (&odr_enum_obstack, name)__extension__ ({ struct obstack *__o = (&odr_enum_obstack ); void *__obj = (void *) (name); if (__obj > (void *) __o ->chunk && __obj < (void *) __o->chunk_limit ) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o, __obj); }); | |||
4320 | } | |||
4321 | } | |||
4322 | lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL__null, data, | |||
4323 | len); | |||
4324 | lto_data_in_delete (data_in); | |||
4325 | } | |||
4326 | ||||
4327 | /* Read all ODR type sections. */ | |||
4328 | ||||
4329 | static void | |||
4330 | ipa_odr_summary_read (void) | |||
4331 | { | |||
4332 | struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data (); | |||
4333 | struct lto_file_decl_data *file_data; | |||
4334 | unsigned int j = 0; | |||
4335 | ||||
4336 | while ((file_data = file_data_vec[j++])) | |||
| ||||
4337 | { | |||
4338 | size_t len; | |||
4339 | const char *data | |||
4340 | = lto_get_summary_section_data (file_data, LTO_section_odr_types, | |||
4341 | &len); | |||
4342 | if (data) | |||
4343 | ipa_odr_read_section (file_data, data, len); | |||
4344 | } | |||
4345 | /* Enum info is used only to produce warnings. Only case we will need it | |||
4346 | again is streaming for incremental LTO. */ | |||
4347 | if (flag_incremental_linkglobal_options.x_flag_incremental_link != INCREMENTAL_LINK_LTO) | |||
4348 | { | |||
4349 | delete odr_enum_map; | |||
4350 | obstack_free (&odr_enum_obstack, NULL)__extension__ ({ struct obstack *__o = (&odr_enum_obstack ); void *__obj = (void *) (__null); if (__obj > (void *) __o ->chunk && __obj < (void *) __o->chunk_limit ) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o, __obj); }); | |||
4351 | odr_enum_map = NULL__null; | |||
4352 | } | |||
4353 | } | |||
4354 | ||||
4355 | namespace { | |||
4356 | ||||
4357 | const pass_data pass_data_ipa_odr = | |||
4358 | { | |||
4359 | IPA_PASS, /* type */ | |||
4360 | "odr", /* name */ | |||
4361 | OPTGROUP_NONE, /* optinfo_flags */ | |||
4362 | TV_IPA_ODR, /* tv_id */ | |||
4363 | 0, /* properties_required */ | |||
4364 | 0, /* properties_provided */ | |||
4365 | 0, /* properties_destroyed */ | |||
4366 | 0, /* todo_flags_start */ | |||
4367 | 0, /* todo_flags_finish */ | |||
4368 | }; | |||
4369 | ||||
4370 | class pass_ipa_odr : public ipa_opt_pass_d | |||
4371 | { | |||
4372 | public: | |||
4373 | pass_ipa_odr (gcc::context *ctxt) | |||
4374 | : ipa_opt_pass_d (pass_data_ipa_odr, ctxt, | |||
4375 | NULL__null, /* generate_summary */ | |||
4376 | ipa_odr_summary_write, /* write_summary */ | |||
4377 | ipa_odr_summary_read, /* read_summary */ | |||
4378 | NULL__null, /* write_optimization_summary */ | |||
4379 | NULL__null, /* read_optimization_summary */ | |||
4380 | NULL__null, /* stmt_fixup */ | |||
4381 | 0, /* function_transform_todo_flags_start */ | |||
4382 | NULL__null, /* function_transform */ | |||
4383 | NULL__null) /* variable_transform */ | |||
4384 | {} | |||
4385 | ||||
4386 | /* opt_pass methods: */ | |||
4387 | bool gate (function *) final override | |||
4388 | { | |||
4389 | return (in_lto_pglobal_options.x_in_lto_p || flag_ltoglobal_options.x_flag_lto); | |||
4390 | } | |||
4391 | ||||
4392 | unsigned int execute (function *) final override | |||
4393 | { | |||
4394 | return 0; | |||
4395 | } | |||
4396 | ||||
4397 | }; // class pass_ipa_odr | |||
4398 | ||||
4399 | } // anon namespace | |||
4400 | ||||
4401 | ipa_opt_pass_d * | |||
4402 | make_pass_ipa_odr (gcc::context *ctxt) | |||
4403 | { | |||
4404 | return new pass_ipa_odr (ctxt); | |||
4405 | } | |||
4406 | ||||
4407 | ||||
4408 | #include "gt-ipa-devirt.h" |