Bug Summary

File:build/gcc/lto-streamer-in.cc
Warning:line 1635, column 33
The right operand of '+' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-suse-linux -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name lto-streamer-in.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/15.0.7 -D TARGET_MACHINE="x86_64-pc-linux-gnu" -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/backward -internal-isystem /usr/lib64/clang/15.0.7/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2023-03-27-141847-20772-1/report-vtHlxY.plist -x c++ /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc
1/* Read the GIMPLE representation from a file stream.
2
3 Copyright (C) 2009-2023 Free Software Foundation, Inc.
4 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
5 Re-implemented by Diego Novillo <dnovillo@google.com>
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 3, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
26#include "backend.h"
27#include "target.h"
28#include "rtl.h"
29#include "tree.h"
30#include "gimple.h"
31#include "cfghooks.h"
32#include "tree-pass.h"
33#include "ssa.h"
34#include "gimple-streamer.h"
35#include "toplev.h"
36#include "gimple-iterator.h"
37#include "tree-cfg.h"
38#include "tree-into-ssa.h"
39#include "tree-dfa.h"
40#include "tree-ssa.h"
41#include "except.h"
42#include "cgraph.h"
43#include "cfgloop.h"
44#include "debug.h"
45#include "alloc-pool.h"
46#include "toplev.h"
47
48/* Allocator used to hold string slot entries for line map streaming. */
49static struct object_allocator<struct string_slot> *string_slot_allocator;
50
51/* The table to hold the file names. */
52static hash_table<string_slot_hasher> *file_name_hash_table;
53
54/* The table to hold the relative pathname prefixes. */
55
56/* This obstack holds file names used in locators. Line map datastructures
57 points here and thus it needs to be kept allocated as long as linemaps
58 exists. */
59static struct obstack file_name_obstack;
60
61/* Map a pair of nul terminated strings where the first one can be
62 pointer compared, but the second can't, to another string. */
63struct string_pair_map
64{
65 const char *str1;
66 const char *str2;
67 const char *str3;
68 hashval_t hash;
69 bool prefix;
70};
71
72/* Allocator used to hold string pair map entries for line map streaming. */
73static struct object_allocator<struct string_pair_map>
74 *string_pair_map_allocator;
75
76struct string_pair_map_hasher : nofree_ptr_hash <string_pair_map>
77{
78 static inline hashval_t hash (const string_pair_map *);
79 static inline bool equal (const string_pair_map *, const string_pair_map *);
80};
81
82inline hashval_t
83string_pair_map_hasher::hash (const string_pair_map *spm)
84{
85 return spm->hash;
86}
87
88inline bool
89string_pair_map_hasher::equal (const string_pair_map *spm1,
90 const string_pair_map *spm2)
91{
92 return (spm1->hash == spm2->hash
93 && spm1->str1 == spm2->str1
94 && spm1->prefix == spm2->prefix
95 && strcmp (spm1->str2, spm2->str2) == 0);
96}
97
98/* The table to hold the pairs of pathnames and corresponding
99 resulting pathname. Used for both mapping of get_src_pwd ()
100 and recorded source working directory to relative path prefix
101 from current working directory to the recorded one, and for
102 mapping of that relative path prefix and some relative path
103 to those concatenated. */
104static hash_table<string_pair_map_hasher> *path_name_pair_hash_table;
105
106
107/* Check that tag ACTUAL has one of the given values. NUM_TAGS is the
108 number of valid tag values to check. */
109
110void
111lto_tag_check_set (enum LTO_tags actual, int ntags, ...)
112{
113 va_list ap;
114 int i;
115
116 va_start (ap, ntags)__builtin_va_start(ap, ntags);
117 for (i = 0; i < ntags; i++)
118 if ((unsigned) actual == va_arg (ap, unsigned)__builtin_va_arg(ap, unsigned))
119 {
120 va_end (ap)__builtin_va_end(ap);
121 return;
122 }
123
124 va_end (ap)__builtin_va_end(ap);
125 internal_error ("bytecode stream: unexpected tag %s", lto_tag_name (actual));
126}
127
128
129/* Read LENGTH bytes from STREAM to ADDR. */
130
131void
132lto_input_data_block (class lto_input_block *ib, void *addr, size_t length)
133{
134 size_t i;
135 unsigned char *const buffer = (unsigned char *) addr;
136
137 for (i = 0; i < length; i++)
138 buffer[i] = streamer_read_uchar (ib);
139}
140
141/* Compute the relative path to get to DATA_WD (absolute directory name)
142 from CWD (another absolute directory name). E.g. for
143 DATA_WD of "/tmp/foo/bar" and CWD of "/tmp/baz/qux" return
144 "../../foo/bar". Returned string should be freed by the caller.
145 Return NULL if absolute file name needs to be used. */
146
147static char *
148relative_path_prefix (const char *data_wd, const char *cwd)
149{
150 const char *d = data_wd;
151 const char *c = cwd;
152#ifdef HAVE_DOS_BASED_FILE_SYSTEM
153 if (d[1] == ':')
154 {
155 if (!IS_DIR_SEPARATOR (d[2])(((d[2]) == '/') || (((d[2]) == '\\') && (0))))
156 return NULLnullptr;
157 if (c[0] == d[0] && c[1] == ':' && IS_DIR_SEPARATOR (c[2])(((c[2]) == '/') || (((c[2]) == '\\') && (0))))
158 {
159 c += 3;
160 d += 3;
161 }
162 else
163 return NULLnullptr;
164 }
165 else if (c[1] == ':')
166 return NULLnullptr;
167#endif
168 do
169 {
170 while (IS_DIR_SEPARATOR (*d)(((*d) == '/') || (((*d) == '\\') && (0))))
171 d++;
172 while (IS_DIR_SEPARATOR (*c)(((*c) == '/') || (((*c) == '\\') && (0))))
173 c++;
174 size_t i;
175 for (i = 0; c[i] && !IS_DIR_SEPARATOR (c[i])(((c[i]) == '/') || (((c[i]) == '\\') && (0))) && c[i] == d[i]; i++)
176 ;
177 if ((c[i] == '\0' || IS_DIR_SEPARATOR (c[i])(((c[i]) == '/') || (((c[i]) == '\\') && (0))))
178 && (d[i] == '\0' || IS_DIR_SEPARATOR (d[i])(((d[i]) == '/') || (((d[i]) == '\\') && (0)))))
179 {
180 c += i;
181 d += i;
182 if (*c == '\0' || *d == '\0')
183 break;
184 }
185 else
186 break;
187 }
188 while (1);
189 size_t num_up = 0;
190 do
191 {
192 while (IS_DIR_SEPARATOR (*c)(((*c) == '/') || (((*c) == '\\') && (0))))
193 c++;
194 if (*c == '\0')
195 break;
196 num_up++;
197 while (*c && !IS_DIR_SEPARATOR (*c)(((*c) == '/') || (((*c) == '\\') && (0))))
198 c++;
199 }
200 while (1);
201 while (IS_DIR_SEPARATOR (*d)(((*d) == '/') || (((*d) == '\\') && (0))))
202 d++;
203 size_t len = strlen (d);
204 if (len == 0 && num_up == 0)
205 return xstrdup (".");
206 char *ret = XNEWVEC (char, num_up * 3 + len + 1)((char *) xmalloc (sizeof (char) * (num_up * 3 + len + 1)));
207 char *p = ret;
208 for (; num_up; num_up--)
209 {
210 const char dir_up[3] = { '.', '.', DIR_SEPARATOR'/' };
211 memcpy (p, dir_up, 3);
212 p += 3;
213 }
214 memcpy (p, d, len + 1);
215 return ret;
216}
217
218/* Look up DATA_WD in hash table of relative prefixes. If found,
219 return relative path from CWD to DATA_WD from the hash table,
220 otherwise create it. */
221
222static const char *
223canon_relative_path_prefix (const char *data_wd, const char *cwd)
224{
225 if (!IS_ABSOLUTE_PATH (data_wd)(((((data_wd)[0]) == '/') || ((((data_wd)[0]) == '\\') &&
(0))) || ((data_wd)[0] && ((data_wd)[1] == ':') &&
(0)))
|| !IS_ABSOLUTE_PATH (cwd)(((((cwd)[0]) == '/') || ((((cwd)[0]) == '\\') && (0)
)) || ((cwd)[0] && ((cwd)[1] == ':') && (0)))
)
226 return NULLnullptr;
227
228 if (!path_name_pair_hash_table)
229 {
230 path_name_pair_hash_table
231 = new hash_table<string_pair_map_hasher> (37);
232 string_pair_map_allocator
233 = new object_allocator <struct string_pair_map>
234 ("line map string pair map hash");
235 }
236
237 inchash::hash h;
238 h.add_ptr (cwd);
239 h.merge_hash (htab_hash_string (data_wd));
240 h.add_int (true);
241
242 string_pair_map s_slot;
243 s_slot.str1 = cwd;
244 s_slot.str2 = data_wd;
245 s_slot.str3 = NULLnullptr;
246 s_slot.hash = h.end ();
247 s_slot.prefix = true;
248
249 string_pair_map **slot
250 = path_name_pair_hash_table->find_slot (&s_slot, INSERT);
251 if (*slot == NULLnullptr)
252 {
253 /* Compute relative path from cwd directory to data_wd directory.
254 E.g. if cwd is /tmp/foo/bar and data_wd is /tmp/baz/qux ,
255 it will return ../../baz/qux . */
256 char *relative_path = relative_path_prefix (data_wd, cwd);
257 const char *relative = relative_path ? relative_path : data_wd;
258 size_t relative_len = strlen (relative);
259 gcc_assert (relative_len)((void)(!(relative_len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 259, __FUNCTION__), 0 : 0))
;
260
261 size_t data_wd_len = strlen (data_wd);
262 bool add_separator = false;
263 if (!IS_DIR_SEPARATOR (relative[relative_len - 1])(((relative[relative_len - 1]) == '/') || (((relative[relative_len
- 1]) == '\\') && (0)))
)
264 add_separator = true;
265
266 size_t len = relative_len + 1 + data_wd_len + 1 + add_separator;
267
268 char *saved_string = XOBNEWVEC (&file_name_obstack, char, len)((char *) __extension__ ({ struct obstack *__h = ((&file_name_obstack
)); __extension__ ({ struct obstack *__o = (__h); size_t __len
= ((sizeof (char) * (len))); if (__extension__ ({ struct obstack
const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1->
next_free); }) < __len) _obstack_newchunk (__o, __len); ((
void) ((__o)->next_free += (__len))); }); __extension__ ({
struct obstack *__o1 = (__h); 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; }); }))
;
269 struct string_pair_map *new_slot
270 = string_pair_map_allocator->allocate ();
271 memcpy (saved_string, data_wd, data_wd_len + 1);
272 memcpy (saved_string + data_wd_len + 1, relative, relative_len);
273 if (add_separator)
274 saved_string[len - 2] = DIR_SEPARATOR'/';
275 saved_string[len - 1] = '\0';
276 new_slot->str1 = cwd;
277 new_slot->str2 = saved_string;
278 new_slot->str3 = saved_string + data_wd_len + 1;
279 if (relative_len == 1 && relative[0] == '.')
280 new_slot->str3 = NULLnullptr;
281 new_slot->hash = s_slot.hash;
282 new_slot->prefix = true;
283 *slot = new_slot;
284 free (relative_path);
285 return new_slot->str3;
286 }
287 else
288 {
289 string_pair_map *old_slot = *slot;
290 return old_slot->str3;
291 }
292}
293
294/* Look up the pair of RELATIVE_PREFIX and STRING strings in a hash table.
295 If found, return the concatenation of those from the hash table,
296 otherwise concatenate them. */
297
298static const char *
299canon_relative_file_name (const char *relative_prefix, const char *string)
300{
301 inchash::hash h;
302 h.add_ptr (relative_prefix);
303 h.merge_hash (htab_hash_string (string));
304
305 string_pair_map s_slot;
306 s_slot.str1 = relative_prefix;
307 s_slot.str2 = string;
308 s_slot.str3 = NULLnullptr;
309 s_slot.hash = h.end ();
310 s_slot.prefix = false;
311
312 string_pair_map **slot
313 = path_name_pair_hash_table->find_slot (&s_slot, INSERT);
314 if (*slot == NULLnullptr)
315 {
316 size_t relative_prefix_len = strlen (relative_prefix);
317 size_t string_len = strlen (string);
318 size_t len = relative_prefix_len + string_len + 1;
319
320 char *saved_string = XOBNEWVEC (&file_name_obstack, char, len)((char *) __extension__ ({ struct obstack *__h = ((&file_name_obstack
)); __extension__ ({ struct obstack *__o = (__h); size_t __len
= ((sizeof (char) * (len))); if (__extension__ ({ struct obstack
const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1->
next_free); }) < __len) _obstack_newchunk (__o, __len); ((
void) ((__o)->next_free += (__len))); }); __extension__ ({
struct obstack *__o1 = (__h); 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; }); }))
;
321 struct string_pair_map *new_slot
322 = string_pair_map_allocator->allocate ();
323 memcpy (saved_string, relative_prefix, relative_prefix_len);
324 memcpy (saved_string + relative_prefix_len, string, string_len + 1);
325 new_slot->str1 = relative_prefix;
326 new_slot->str2 = saved_string + relative_prefix_len;
327 new_slot->str3 = saved_string;
328 new_slot->hash = s_slot.hash;
329 new_slot->prefix = false;
330 *slot = new_slot;
331 return new_slot->str3;
332 }
333 else
334 {
335 string_pair_map *old_slot = *slot;
336 return old_slot->str3;
337 }
338}
339
340/* Lookup STRING in file_name_hash_table. If found, return the existing
341 string, otherwise insert STRING as the canonical version.
342 If STRING is a relative pathname and RELATIVE_PREFIX is non-NULL, use
343 canon_relative_file_name instead. */
344
345static const char *
346canon_file_name (const char *relative_prefix, const char *string)
347{
348 if (relative_prefix && !IS_ABSOLUTE_PATH (string)(((((string)[0]) == '/') || ((((string)[0]) == '\\') &&
(0))) || ((string)[0] && ((string)[1] == ':') &&
(0)))
)
349 return canon_relative_file_name (relative_prefix, string);
350
351 string_slot **slot;
352 struct string_slot s_slot;
353 size_t len = strlen (string);
354
355 s_slot.s = string;
356 s_slot.len = len;
357
358 slot = file_name_hash_table->find_slot (&s_slot, INSERT);
359 if (*slot == NULLnullptr)
360 {
361 char *saved_string;
362 struct string_slot *new_slot;
363
364 saved_string = XOBNEWVEC (&file_name_obstack, char, len + 1)((char *) __extension__ ({ struct obstack *__h = ((&file_name_obstack
)); __extension__ ({ struct obstack *__o = (__h); size_t __len
= ((sizeof (char) * (len + 1))); if (__extension__ ({ struct
obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit -
__o1->next_free); }) < __len) _obstack_newchunk (__o, __len
); ((void) ((__o)->next_free += (__len))); }); __extension__
({ struct obstack *__o1 = (__h); 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; }); }))
;
365 new_slot = string_slot_allocator->allocate ();
366 memcpy (saved_string, string, len + 1);
367 new_slot->s = saved_string;
368 new_slot->len = len;
369 *slot = new_slot;
370 return saved_string;
371 }
372 else
373 {
374 struct string_slot *old_slot = *slot;
375 return old_slot->s;
376 }
377}
378
379/* Pointer to currently alive instance of lto_location_cache. */
380
381lto_location_cache *lto_location_cache::current_cache;
382
383/* Sort locations in source order. Start with file from last application. */
384
385int
386lto_location_cache::cmp_loc (const void *pa, const void *pb)
387{
388 const cached_location *a = ((const cached_location *)pa);
389 const cached_location *b = ((const cached_location *)pb);
390 const char *current_file = current_cache->current_file;
391 int current_line = current_cache->current_line;
392
393 if (a->file == current_file && b->file != current_file)
394 return -1;
395 if (a->file != current_file && b->file == current_file)
396 return 1;
397 if (a->file == current_file && b->file == current_file)
398 {
399 if (a->line == current_line && b->line != current_line)
400 return -1;
401 if (a->line != current_line && b->line == current_line)
402 return 1;
403 }
404 if (a->file != b->file)
405 return strcmp (a->file, b->file);
406 if (a->sysp != b->sysp)
407 return a->sysp ? 1 : -1;
408 if (a->line != b->line)
409 return a->line - b->line;
410 if (a->col != b->col)
411 return a->col - b->col;
412 if (a->discr != b->discr)
413 return a->discr - b->discr;
414 if ((a->block == NULL_TREE(tree) nullptr) != (b->block == NULL_TREE(tree) nullptr))
415 return a->block ? 1 : -1;
416 if (a->block)
417 {
418 if (BLOCK_NUMBER (a->block)((tree_check ((a->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 418, __FUNCTION__, (BLOCK)))->block.block_num)
< BLOCK_NUMBER (b->block)((tree_check ((b->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 418, __FUNCTION__, (BLOCK)))->block.block_num)
)
419 return -1;
420 if (BLOCK_NUMBER (a->block)((tree_check ((a->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 420, __FUNCTION__, (BLOCK)))->block.block_num)
> BLOCK_NUMBER (b->block)((tree_check ((b->block), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 420, __FUNCTION__, (BLOCK)))->block.block_num)
)
421 return 1;
422 }
423 return 0;
424}
425
426/* Apply all changes in location cache. Add locations into linemap and patch
427 trees. */
428
429bool
430lto_location_cache::apply_location_cache ()
431{
432 static const char *prev_file;
433 if (!loc_cache.length ())
434 return false;
435 if (loc_cache.length () > 1)
436 loc_cache.qsort (cmp_loc)qsort (cmp_loc);
437
438 for (unsigned int i = 0; i < loc_cache.length (); i++)
439 {
440 struct cached_location loc = loc_cache[i];
441
442 if (current_file != loc.file)
443 linemap_add (line_table, prev_file ? LC_RENAME : LC_ENTER,
444 loc.sysp, loc.file, loc.line);
445 else if (current_line != loc.line)
446 {
447 int max = loc.col;
448
449 for (unsigned int j = i + 1; j < loc_cache.length (); j++)
450 if (loc.file != loc_cache[j].file
451 || loc.line != loc_cache[j].line)
452 break;
453 else if (max < loc_cache[j].col)
454 max = loc_cache[j].col;
455 linemap_line_start (line_table, loc.line, max + 1);
456 }
457 gcc_assert (*loc.loc == BUILTINS_LOCATION + 1)((void)(!(*loc.loc == ((location_t) 1) + 1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 457, __FUNCTION__), 0 : 0))
;
458 if (current_file != loc.file
459 || current_line != loc.line
460 || current_col != loc.col)
461 {
462 current_loc = linemap_position_for_column (line_table, loc.col);
463 if (loc.block)
464 current_loc = set_block (current_loc, loc.block);
465 if (loc.discr)
466 current_loc = location_with_discriminator (current_loc, loc.discr);
467 }
468 else if (current_block != loc.block)
469 {
470 if (loc.block)
471 current_loc = set_block (current_loc, loc.block);
472 else
473 current_loc = LOCATION_LOCUS (current_loc)((IS_ADHOC_LOC (current_loc)) ? get_location_from_adhoc_loc (
line_table, current_loc) : (current_loc))
;
474 if (loc.discr)
475 current_loc = location_with_discriminator (current_loc, loc.discr);
476 }
477 else if (current_discr != loc.discr)
478 current_loc = location_with_discriminator (current_loc, loc.discr);
479 *loc.loc = current_loc;
480 current_line = loc.line;
481 prev_file = current_file = loc.file;
482 current_col = loc.col;
483 current_block = loc.block;
484 current_discr = loc.discr;
485 }
486 loc_cache.truncate (0);
487 accepted_length = 0;
488 return true;
489}
490
491/* Tree merging did not succeed; mark all changes in the cache as accepted. */
492
493void
494lto_location_cache::accept_location_cache ()
495{
496 gcc_assert (current_cache == this)((void)(!(current_cache == this) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 496, __FUNCTION__), 0 : 0))
;
497 accepted_length = loc_cache.length ();
498}
499
500/* Tree merging did succeed; throw away recent changes. */
501
502void
503lto_location_cache::revert_location_cache ()
504{
505 loc_cache.truncate (accepted_length);
506}
507
508/* Read a location bitpack from bit pack BP and either update *LOC directly
509 or add it to the location cache. If IB is non-NULL, stream in a block
510 afterwards.
511 It is neccesary to call apply_location_cache to get *LOC updated. */
512
513void
514lto_location_cache::input_location_and_block (location_t *loc,
515 struct bitpack_d *bp,
516 class lto_input_block *ib,
517 class data_in *data_in)
518{
519 static const char *stream_file;
520 static int stream_line;
521 static int stream_col;
522 static bool stream_sysp;
523 static tree stream_block;
524 static unsigned stream_discr;
525 static const char *stream_relative_path_prefix;
526
527 gcc_assert (current_cache == this)((void)(!(current_cache == this) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 527, __FUNCTION__), 0 : 0))
;
528
529 *loc = bp_unpack_int_in_range (bp, "location", 0,
530 RESERVED_LOCATION_COUNT + 1);
531
532 if (*loc < RESERVED_LOCATION_COUNT)
533 {
534 if (ib)
535 {
536 bool block_change = bp_unpack_value (bp, 1);
537 if (block_change)
538 stream_block = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
539 if (stream_block)
540 *loc = set_block (*loc, stream_block);
541 }
542 return;
543 }
544
545 bool file_change = (*loc == RESERVED_LOCATION_COUNT + 1);
546 /* Keep value RESERVED_LOCATION_COUNT in *loc as linemap lookups will
547 ICE on it. */
548 *loc = RESERVED_LOCATION_COUNT;
549 bool line_change = bp_unpack_value (bp, 1);
550 bool column_change = bp_unpack_value (bp, 1);
551 bool discr_change = bp_unpack_value (bp, 1);
552
553 if (file_change)
554 {
555 bool pwd_change = bp_unpack_value (bp, 1);
556 if (pwd_change)
557 {
558 const char *pwd = bp_unpack_string (data_in, bp);
559 const char *src_pwd = get_src_pwd ();
560 if (strcmp (pwd, src_pwd) == 0)
561 stream_relative_path_prefix = NULLnullptr;
562 else
563 stream_relative_path_prefix
564 = canon_relative_path_prefix (pwd, src_pwd);
565 }
566 stream_file = canon_file_name (stream_relative_path_prefix,
567 bp_unpack_string (data_in, bp));
568 stream_sysp = bp_unpack_value (bp, 1);
569 }
570
571 if (line_change)
572 stream_line = bp_unpack_var_len_unsigned (bp);
573
574 if (column_change)
575 stream_col = bp_unpack_var_len_unsigned (bp);
576
577 if (discr_change)
578 stream_discr = bp_unpack_var_len_unsigned (bp);
579
580 tree block = NULL_TREE(tree) nullptr;
581 if (ib)
582 {
583 bool block_change = bp_unpack_value (bp, 1);
584 if (block_change)
585 stream_block = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
586 block = stream_block;
587 }
588
589 /* This optimization saves location cache operations during gimple
590 streaming. */
591
592 if (current_file == stream_file
593 && current_line == stream_line
594 && current_col == stream_col
595 && current_sysp == stream_sysp
596 && current_discr == stream_discr)
597 {
598 if (current_block == block)
599 *loc = current_loc;
600 else if (block)
601 *loc = set_block (current_loc, block);
602 else
603 *loc = LOCATION_LOCUS (current_loc)((IS_ADHOC_LOC (current_loc)) ? get_location_from_adhoc_loc (
line_table, current_loc) : (current_loc))
;
604 return;
605 }
606
607 struct cached_location entry
608 = {stream_file, loc, stream_line, stream_col, stream_sysp, block, stream_discr};
609 loc_cache.safe_push (entry);
610}
611
612/* Read a location bitpack from bit pack BP and either update *LOC directly
613 or add it to the location cache.
614 It is neccesary to call apply_location_cache to get *LOC updated. */
615
616void
617lto_location_cache::input_location (location_t *loc, struct bitpack_d *bp,
618 class data_in *data_in)
619{
620 return input_location_and_block (loc, bp, NULLnullptr, data_in);
621}
622
623/* Read a location bitpack from input block IB and either update *LOC directly
624 or add it to the location cache.
625 It is neccesary to call apply_location_cache to get *LOC updated. */
626
627void
628lto_input_location (location_t *loc, struct bitpack_d *bp,
629 class data_in *data_in)
630{
631 data_in->location_cache.input_location (loc, bp, data_in);
632}
633
634/* Read a reference to a tree node from DATA_IN using input block IB.
635 TAG is the expected node that should be found in IB, if TAG belongs
636 to one of the indexable trees, expect to read a reference index to
637 be looked up in one of the symbol tables, otherwise read the pysical
638 representation of the tree using stream_read_tree. FN is the
639 function scope for the read tree. */
640
641tree
642lto_input_tree_ref (class lto_input_block *ib, class data_in *data_in,
643 struct function *fn, enum LTO_tags tag)
644{
645 unsigned HOST_WIDE_INTlong ix_u;
646 tree result = NULL_TREE(tree) nullptr;
647
648 if (tag == LTO_ssa_name_ref)
649 {
650 ix_u = streamer_read_uhwi (ib);
651 result = (*SSANAMES (fn)(fn)->gimple_df->ssa_names)[ix_u];
652 }
653 else
654 {
655 gcc_checking_assert (tag == LTO_global_stream_ref)((void)(!(tag == LTO_global_stream_ref) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 655, __FUNCTION__), 0 : 0))
;
656 ix_u = streamer_read_uhwi (ib);
657 result = (*data_in->file_data->current_decl_state
658 ->streams[LTO_DECL_STREAM])[ix_u];
659 }
660
661 gcc_assert (result)((void)(!(result) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 661, __FUNCTION__), 0 : 0))
;
662
663 return result;
664}
665
666/* Read VAR_DECL reference to DATA from IB. */
667
668tree
669lto_input_var_decl_ref (lto_input_block *ib, lto_file_decl_data *file_data)
670{
671 unsigned int ix_u = streamer_read_uhwi (ib);
672 tree result = (*file_data->current_decl_state
673 ->streams[LTO_DECL_STREAM])[ix_u];
674 gcc_assert (TREE_CODE (result) == VAR_DECL)((void)(!(((enum tree_code) (result)->base.code) == VAR_DECL
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 674, __FUNCTION__), 0 : 0))
;
675 return result;
676}
677
678/* Read VAR_DECL reference to DATA from IB. */
679
680tree
681lto_input_fn_decl_ref (lto_input_block *ib, lto_file_decl_data *file_data)
682{
683 unsigned int ix_u = streamer_read_uhwi (ib);
684 tree result = (*file_data->current_decl_state
685 ->streams[LTO_DECL_STREAM])[ix_u];
686 gcc_assert (TREE_CODE (result) == FUNCTION_DECL)((void)(!(((enum tree_code) (result)->base.code) == FUNCTION_DECL
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 686, __FUNCTION__), 0 : 0))
;
687 return result;
688}
689
690
691/* Read and return a double-linked list of catch handlers from input
692 block IB, using descriptors in DATA_IN. */
693
694static struct eh_catch_d *
695lto_input_eh_catch_list (class lto_input_block *ib, class data_in *data_in,
696 eh_catch *last_p)
697{
698 eh_catch first;
699 enum LTO_tags tag;
700
701 *last_p = first = NULLnullptr;
702 tag = streamer_read_record_start (ib);
703 while (tag)
704 {
705 tree list;
706 eh_catch n;
707
708 lto_tag_check_range (tag, LTO_eh_catch, LTO_eh_catch);
709
710 /* Read the catch node. */
711 n = ggc_cleared_alloc<eh_catch_d> ();
712 n->type_list = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
713 n->filter_list = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
714 n->label = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
715
716 /* Register all the types in N->FILTER_LIST. */
717 for (list = n->filter_list; list; list = TREE_CHAIN (list)((contains_struct_check ((list), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 717, __FUNCTION__))->common.chain)
)
718 add_type_for_runtime (TREE_VALUE (list)((tree_check ((list), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 718, __FUNCTION__, (TREE_LIST)))->list.value)
);
719
720 /* Chain N to the end of the list. */
721 if (*last_p)
722 (*last_p)->next_catch = n;
723 n->prev_catch = *last_p;
724 *last_p = n;
725
726 /* Set the head of the list the first time through the loop. */
727 if (first == NULLnullptr)
728 first = n;
729
730 tag = streamer_read_record_start (ib);
731 }
732
733 return first;
734}
735
736
737/* Read and return EH region IX from input block IB, using descriptors
738 in DATA_IN. */
739
740static eh_region
741input_eh_region (class lto_input_block *ib, class data_in *data_in, int ix)
742{
743 enum LTO_tags tag;
744 eh_region r;
745
746 /* Read the region header. */
747 tag = streamer_read_record_start (ib);
748 if (tag == LTO_null)
749 return NULLnullptr;
750
751 r = ggc_cleared_alloc<eh_region_d> ();
752 r->index = streamer_read_hwi (ib);
753
754 gcc_assert (r->index == ix)((void)(!(r->index == ix) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 754, __FUNCTION__), 0 : 0))
;
755
756 /* Read all the region pointers as region numbers. We'll fix up
757 the pointers once the whole array has been read. */
758 r->outer = (eh_region) (intptr_t) streamer_read_hwi (ib);
759 r->inner = (eh_region) (intptr_t) streamer_read_hwi (ib);
760 r->next_peer = (eh_region) (intptr_t) streamer_read_hwi (ib);
761
762 switch (tag)
763 {
764 case LTO_ert_cleanup:
765 r->type = ERT_CLEANUP;
766 break;
767
768 case LTO_ert_try:
769 {
770 struct eh_catch_d *last_catch;
771 r->type = ERT_TRY;
772 r->u.eh_try.first_catch = lto_input_eh_catch_list (ib, data_in,
773 &last_catch);
774 r->u.eh_try.last_catch = last_catch;
775 break;
776 }
777
778 case LTO_ert_allowed_exceptions:
779 {
780 tree l;
781
782 r->type = ERT_ALLOWED_EXCEPTIONS;
783 r->u.allowed.type_list = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
784 r->u.allowed.label = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
785 r->u.allowed.filter = streamer_read_uhwi (ib);
786
787 for (l = r->u.allowed.type_list; l ; l = TREE_CHAIN (l)((contains_struct_check ((l), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 787, __FUNCTION__))->common.chain)
)
788 add_type_for_runtime (TREE_VALUE (l)((tree_check ((l), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 788, __FUNCTION__, (TREE_LIST)))->list.value)
);
789 }
790 break;
791
792 case LTO_ert_must_not_throw:
793 {
794 r->type = ERT_MUST_NOT_THROW;
795 r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
796 bitpack_d bp = streamer_read_bitpack (ib);
797 stream_input_location (&r->u.must_not_throw.failure_loc,streamer_hooks.input_location (&r->u.must_not_throw.failure_loc
, &bp, data_in)
798 &bp, data_in)streamer_hooks.input_location (&r->u.must_not_throw.failure_loc
, &bp, data_in)
;
799 }
800 break;
801
802 default:
803 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 803, __FUNCTION__))
;
804 }
805
806 r->landing_pads = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib);
807
808 return r;
809}
810
811
812/* Read and return EH landing pad IX from input block IB, using descriptors
813 in DATA_IN. */
814
815static eh_landing_pad
816input_eh_lp (class lto_input_block *ib, class data_in *data_in, int ix)
817{
818 enum LTO_tags tag;
819 eh_landing_pad lp;
820
821 /* Read the landing pad header. */
822 tag = streamer_read_record_start (ib);
823 if (tag == LTO_null)
824 return NULLnullptr;
825
826 lto_tag_check_range (tag, LTO_eh_landing_pad, LTO_eh_landing_pad);
827
828 lp = ggc_cleared_alloc<eh_landing_pad_d> ();
829 lp->index = streamer_read_hwi (ib);
830 gcc_assert (lp->index == ix)((void)(!(lp->index == ix) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 830, __FUNCTION__), 0 : 0))
;
831 lp->next_lp = (eh_landing_pad) (intptr_t) streamer_read_hwi (ib);
832 lp->region = (eh_region) (intptr_t) streamer_read_hwi (ib);
833 lp->post_landing_pad = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
834
835 return lp;
836}
837
838
839/* After reading the EH regions, pointers to peer and children regions
840 are region numbers. This converts all these region numbers into
841 real pointers into the rematerialized regions for FN. ROOT_REGION
842 is the region number for the root EH region in FN. */
843
844static void
845fixup_eh_region_pointers (struct function *fn, HOST_WIDE_INTlong root_region)
846{
847 unsigned i;
848 vec<eh_region, va_gc> *eh_array = fn->eh->region_array;
849 vec<eh_landing_pad, va_gc> *lp_array = fn->eh->lp_array;
850 eh_region r;
851 eh_landing_pad lp;
852
853 gcc_assert (eh_array && lp_array)((void)(!(eh_array && lp_array) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 853, __FUNCTION__), 0 : 0))
;
854
855 gcc_assert (root_region >= 0)((void)(!(root_region >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 855, __FUNCTION__), 0 : 0))
;
856 fn->eh->region_tree = (*eh_array)[root_region];
857
858#define FIXUP_EH_REGION(r) (r) = (*eh_array)[(HOST_WIDE_INTlong) (intptr_t) (r)]
859#define FIXUP_EH_LP(p) (p) = (*lp_array)[(HOST_WIDE_INTlong) (intptr_t) (p)]
860
861 /* Convert all the index numbers stored in pointer fields into
862 pointers to the corresponding slots in the EH region array. */
863 FOR_EACH_VEC_ELT (*eh_array, i, r)for (i = 0; (*eh_array).iterate ((i), &(r)); ++(i))
864 {
865 /* The array may contain NULL regions. */
866 if (r == NULLnullptr)
867 continue;
868
869 gcc_assert (i == (unsigned) r->index)((void)(!(i == (unsigned) r->index) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 869, __FUNCTION__), 0 : 0))
;
870 FIXUP_EH_REGION (r->outer);
871 FIXUP_EH_REGION (r->inner);
872 FIXUP_EH_REGION (r->next_peer);
873 FIXUP_EH_LP (r->landing_pads);
874 }
875
876 /* Convert all the index numbers stored in pointer fields into
877 pointers to the corresponding slots in the EH landing pad array. */
878 FOR_EACH_VEC_ELT (*lp_array, i, lp)for (i = 0; (*lp_array).iterate ((i), &(lp)); ++(i))
879 {
880 /* The array may contain NULL landing pads. */
881 if (lp == NULLnullptr)
882 continue;
883
884 gcc_assert (i == (unsigned) lp->index)((void)(!(i == (unsigned) lp->index) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 884, __FUNCTION__), 0 : 0))
;
885 FIXUP_EH_LP (lp->next_lp);
886 FIXUP_EH_REGION (lp->region);
887 }
888
889#undef FIXUP_EH_REGION
890#undef FIXUP_EH_LP
891}
892
893
894/* Initialize EH support. */
895
896void
897lto_init_eh (void)
898{
899 static bool eh_initialized_p = false;
900
901 if (eh_initialized_p)
902 return;
903
904 /* Contrary to most other FEs, we only initialize EH support when at
905 least one of the files in the set contains exception regions in
906 it. Since this happens much later than the call to init_eh in
907 lang_dependent_init, we have to set flag_exceptions and call
908 init_eh again to initialize the EH tables. */
909 flag_exceptionsglobal_options.x_flag_exceptions = 1;
910 init_eh ();
911
912 eh_initialized_p = true;
913}
914
915
916/* Read the exception table for FN from IB using the data descriptors
917 in DATA_IN. */
918
919static void
920input_eh_regions (class lto_input_block *ib, class data_in *data_in,
921 struct function *fn)
922{
923 HOST_WIDE_INTlong i, root_region, len;
924 enum LTO_tags tag;
925
926 tag = streamer_read_record_start (ib);
927 if (tag == LTO_null)
928 return;
929
930 lto_tag_check_range (tag, LTO_eh_table, LTO_eh_table);
931
932 gcc_assert (fn->eh)((void)(!(fn->eh) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 932, __FUNCTION__), 0 : 0))
;
933
934 root_region = streamer_read_hwi (ib);
935 gcc_assert (root_region == (int) root_region)((void)(!(root_region == (int) root_region) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 935, __FUNCTION__), 0 : 0))
;
936
937 /* Read the EH region array. */
938 len = streamer_read_hwi (ib);
939 gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 939, __FUNCTION__), 0 : 0))
;
940 if (len > 0)
941 {
942 vec_safe_grow_cleared (fn->eh->region_array, len, true);
943 for (i = 0; i < len; i++)
944 {
945 eh_region r = input_eh_region (ib, data_in, i);
946 (*fn->eh->region_array)[i] = r;
947 }
948 }
949
950 /* Read the landing pads. */
951 len = streamer_read_hwi (ib);
952 gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 952, __FUNCTION__), 0 : 0))
;
953 if (len > 0)
954 {
955 vec_safe_grow_cleared (fn->eh->lp_array, len, true);
956 for (i = 0; i < len; i++)
957 {
958 eh_landing_pad lp = input_eh_lp (ib, data_in, i);
959 (*fn->eh->lp_array)[i] = lp;
960 }
961 }
962
963 /* Read the runtime type data. */
964 len = streamer_read_hwi (ib);
965 gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 965, __FUNCTION__), 0 : 0))
;
966 if (len > 0)
967 {
968 vec_safe_grow_cleared (fn->eh->ttype_data, len, true);
969 for (i = 0; i < len; i++)
970 {
971 tree ttype = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
972 (*fn->eh->ttype_data)[i] = ttype;
973 }
974 }
975
976 /* Read the table of action chains. */
977 len = streamer_read_hwi (ib);
978 gcc_assert (len == (int) len)((void)(!(len == (int) len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 978, __FUNCTION__), 0 : 0))
;
979 if (len > 0)
980 {
981 if (targetm.arm_eabi_unwinder)
982 {
983 vec_safe_grow_cleared (fn->eh->ehspec_data.arm_eabi, len, true);
984 for (i = 0; i < len; i++)
985 {
986 tree t = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
987 (*fn->eh->ehspec_data.arm_eabi)[i] = t;
988 }
989 }
990 else
991 {
992 vec_safe_grow_cleared (fn->eh->ehspec_data.other, len, true);
993 for (i = 0; i < len; i++)
994 {
995 uchar c = streamer_read_uchar (ib);
996 (*fn->eh->ehspec_data.other)[i] = c;
997 }
998 }
999 }
1000
1001 /* Reconstruct the EH region tree by fixing up the peer/children
1002 pointers. */
1003 fixup_eh_region_pointers (fn, root_region);
1004
1005 tag = streamer_read_record_start (ib);
1006 lto_tag_check_range (tag, LTO_null, LTO_null);
1007}
1008
1009
1010/* Make a new basic block with index INDEX in function FN. */
1011
1012static basic_block
1013make_new_block (struct function *fn, unsigned int index)
1014{
1015 basic_block bb = alloc_block ();
1016 bb->index = index;
1017 SET_BASIC_BLOCK_FOR_FN (fn, index, bb)((*((fn)->cfg->x_basic_block_info))[(index)] = (bb));
1018 n_basic_blocks_for_fn (fn)((fn)->cfg->x_n_basic_blocks)++;
1019 return bb;
1020}
1021
1022
1023/* Read the CFG for function FN from input block IB. */
1024
1025static void
1026input_cfg (class lto_input_block *ib, class data_in *data_in,
1027 struct function *fn)
1028{
1029 unsigned int bb_count;
1030 basic_block p_bb;
1031 unsigned int i;
1032 int index;
1033
1034 init_empty_tree_cfg_for_function (fn);
1035
1036 profile_status_for_fn (fn)((fn)->cfg->x_profile_status) = streamer_read_enum (ib, profile_status_d,(enum profile_status_d)streamer_read_hwi_in_range ((ib), "profile_status_d"
, 0, (int)(PROFILE_LAST) - 1)
1037 PROFILE_LAST)(enum profile_status_d)streamer_read_hwi_in_range ((ib), "profile_status_d"
, 0, (int)(PROFILE_LAST) - 1)
;
1038
1039 bb_count = streamer_read_uhwi (ib);
1040
1041 last_basic_block_for_fn (fn)((fn)->cfg->x_last_basic_block) = bb_count;
1042 if (bb_count > basic_block_info_for_fn (fn)((fn)->cfg->x_basic_block_info)->length ())
1043 vec_safe_grow_cleared (basic_block_info_for_fn (fn)((fn)->cfg->x_basic_block_info), bb_count, true);
1044
1045 if (bb_count > label_to_block_map_for_fn (fn)((fn)->cfg->x_label_to_block_map)->length ())
1046 vec_safe_grow_cleared (label_to_block_map_for_fn (fn)((fn)->cfg->x_label_to_block_map), bb_count, true);
1047
1048 index = streamer_read_hwi (ib);
1049 while (index != -1)
1050 {
1051 basic_block bb = BASIC_BLOCK_FOR_FN (fn, index)((*((fn)->cfg->x_basic_block_info))[(index)]);
1052 unsigned int edge_count;
1053
1054 if (bb == NULLnullptr)
1055 bb = make_new_block (fn, index);
1056
1057 edge_count = streamer_read_uhwi (ib);
1058
1059 /* Connect up the CFG. */
1060 for (i = 0; i < edge_count; i++)
1061 {
1062 bitpack_d bp = streamer_read_bitpack (ib);
1063 unsigned int dest_index = bp_unpack_var_len_unsigned (&bp);
1064 unsigned int edge_flags = bp_unpack_var_len_unsigned (&bp);
1065 basic_block dest = BASIC_BLOCK_FOR_FN (fn, dest_index)((*((fn)->cfg->x_basic_block_info))[(dest_index)]);
1066
1067 if (dest == NULLnullptr)
1068 dest = make_new_block (fn, dest_index);
1069
1070 edge e = make_edge (bb, dest, edge_flags);
1071 data_in->location_cache.input_location_and_block (&e->goto_locus,
1072 &bp, ib, data_in);
1073 e->probability = profile_probability::stream_in (ib);
1074
1075 }
1076
1077 index = streamer_read_hwi (ib);
1078 }
1079
1080 p_bb = ENTRY_BLOCK_PTR_FOR_FN (fn)((fn)->cfg->x_entry_block_ptr);
1081 index = streamer_read_hwi (ib);
1082 while (index != -1)
1083 {
1084 basic_block bb = BASIC_BLOCK_FOR_FN (fn, index)((*((fn)->cfg->x_basic_block_info))[(index)]);
1085 bb->prev_bb = p_bb;
1086 p_bb->next_bb = bb;
1087 p_bb = bb;
1088 index = streamer_read_hwi (ib);
1089 }
1090
1091 /* ??? The cfgloop interface is tied to cfun. */
1092 gcc_assert (cfun == fn)((void)(!((cfun + 0) == fn) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1092, __FUNCTION__), 0 : 0))
;
1093
1094 /* Input the loop tree. */
1095 unsigned n_loops = streamer_read_uhwi (ib);
1096 if (n_loops == 0)
1097 return;
1098
1099 struct loops *loops = ggc_cleared_alloc<struct loops> ();
1100 init_loops_structure (fn, loops, n_loops);
1101 set_loops_for_fn (fn, loops);
1102
1103 /* Input each loop and associate it with its loop header so
1104 flow_loops_find can rebuild the loop tree. */
1105 for (unsigned i = 1; i < n_loops; ++i)
1106 {
1107 int header_index = streamer_read_hwi (ib);
1108 if (header_index == -1)
1109 {
1110 loops->larray->quick_push (NULLnullptr);
1111 continue;
1112 }
1113
1114 class loop *loop = alloc_loop ();
1115 loop->header = BASIC_BLOCK_FOR_FN (fn, header_index)((*((fn)->cfg->x_basic_block_info))[(header_index)]);
1116 loop->header->loop_father = loop;
1117
1118 /* Read everything copy_loop_info copies. */
1119 loop->estimate_state = streamer_read_enum (ib, loop_estimation, EST_LAST)(enum loop_estimation)streamer_read_hwi_in_range ((ib), "loop_estimation"
, 0, (int)(EST_LAST) - 1)
;
1120 loop->any_upper_bound = streamer_read_hwi (ib);
1121 if (loop->any_upper_bound)
1122 loop->nb_iterations_upper_bound = streamer_read_widest_int (ib);
1123 loop->any_likely_upper_bound = streamer_read_hwi (ib);
1124 if (loop->any_likely_upper_bound)
1125 loop->nb_iterations_likely_upper_bound = streamer_read_widest_int (ib);
1126 loop->any_estimate = streamer_read_hwi (ib);
1127 if (loop->any_estimate)
1128 loop->nb_iterations_estimate = streamer_read_widest_int (ib);
1129
1130 /* Read OMP SIMD related info. */
1131 loop->safelen = streamer_read_hwi (ib);
1132 loop->unroll = streamer_read_hwi (ib);
1133 loop->owned_clique = streamer_read_hwi (ib);
1134 loop->dont_vectorize = streamer_read_hwi (ib);
1135 loop->force_vectorize = streamer_read_hwi (ib);
1136 loop->finite_p = streamer_read_hwi (ib);
1137 loop->simduid = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1138
1139 place_new_loop (fn, loop);
1140
1141 /* flow_loops_find doesn't like loops not in the tree, hook them
1142 all as siblings of the tree root temporarily. */
1143 flow_loop_tree_node_add (loops->tree_root, loop);
1144 }
1145
1146 /* Rebuild the loop tree. */
1147 flow_loops_find (loops);
1148}
1149
1150
1151/* Read the SSA names array for function FN from DATA_IN using input
1152 block IB. */
1153
1154static void
1155input_ssa_names (class lto_input_block *ib, class data_in *data_in,
1156 struct function *fn)
1157{
1158 unsigned int i, size;
1159
1160 size = streamer_read_uhwi (ib);
1161 init_tree_ssa (fn, size);
1162 cfun(cfun + 0)->gimple_df->in_ssa_p = true;
1163 init_ssa_operands (fn);
1164
1165 i = streamer_read_uhwi (ib);
1166 while (i)
1167 {
1168 tree ssa_name, name;
1169 bool is_default_def;
1170
1171 /* Skip over the elements that had been freed. */
1172 while (SSANAMES (fn)(fn)->gimple_df->ssa_names->length () < i)
1173 SSANAMES (fn)(fn)->gimple_df->ssa_names->quick_push (NULL_TREE(tree) nullptr);
1174
1175 is_default_def = (streamer_read_uchar (ib) != 0);
1176 name = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1177 ssa_name = make_ssa_name_fn (fn, name, NULLnullptr);
1178
1179 if (is_default_def)
1180 {
1181 set_ssa_default_def (cfun(cfun + 0), SSA_NAME_VAR (ssa_name)((tree_check ((ssa_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1181, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree)
nullptr || ((enum tree_code) ((ssa_name)->ssa_name.var)->
base.code) == IDENTIFIER_NODE ? (tree) nullptr : (ssa_name)->
ssa_name.var)
, ssa_name);
1182 SSA_NAME_DEF_STMT (ssa_name)(tree_check ((ssa_name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1182, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
= gimple_build_nop ();
1183 }
1184
1185 i = streamer_read_uhwi (ib);
1186 }
1187}
1188
1189
1190/* Go through all NODE edges and fixup call_stmt pointers
1191 so they point to STMTS. */
1192
1193static void
1194fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple **stmts,
1195 struct function *fn)
1196{
1197#define STMT_UID_NOT_IN_RANGE(uid)(gimple_stmt_max_uid (fn) < uid || uid == 0) \
1198 (gimple_stmt_max_uid (fn) < uid || uid == 0)
1199
1200 struct cgraph_edge *cedge;
1201 struct ipa_ref *ref = NULLnullptr;
1202 unsigned int i;
1203
1204 for (cedge = node->callees; cedge; cedge = cedge->next_callee)
1205 {
1206 if (STMT_UID_NOT_IN_RANGE (cedge->lto_stmt_uid)(gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid || cedge
->lto_stmt_uid == 0)
)
1207 fatal_error (input_location,
1208 "Cgraph edge statement index out of range");
1209 cedge->call_stmt = as_a <gcall *> (stmts[cedge->lto_stmt_uid - 1]);
1210 cedge->lto_stmt_uid = 0;
1211 if (!cedge->call_stmt)
1212 fatal_error (input_location,
1213 "Cgraph edge statement index not found");
1214 }
1215 for (cedge = node->indirect_calls; cedge; cedge = cedge->next_callee)
1216 {
1217 if (STMT_UID_NOT_IN_RANGE (cedge->lto_stmt_uid)(gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid || cedge
->lto_stmt_uid == 0)
)
1218 fatal_error (input_location,
1219 "Cgraph edge statement index out of range");
1220 cedge->call_stmt = as_a <gcall *> (stmts[cedge->lto_stmt_uid - 1]);
1221 cedge->lto_stmt_uid = 0;
1222 if (!cedge->call_stmt)
1223 fatal_error (input_location, "Cgraph edge statement index not found");
1224 }
1225 for (i = 0; node->iterate_reference (i, ref); i++)
1226 if (ref->lto_stmt_uid)
1227 {
1228 if (STMT_UID_NOT_IN_RANGE (ref->lto_stmt_uid)(gimple_stmt_max_uid (fn) < ref->lto_stmt_uid || ref->
lto_stmt_uid == 0)
)
1229 fatal_error (input_location,
1230 "Reference statement index out of range");
1231 ref->stmt = stmts[ref->lto_stmt_uid - 1];
1232 ref->lto_stmt_uid = 0;
1233 if (!ref->stmt)
1234 fatal_error (input_location, "Reference statement index not found");
1235 }
1236}
1237
1238
1239/* Fixup call_stmt pointers in NODE and all clones. */
1240
1241static void
1242fixup_call_stmt_edges (struct cgraph_node *orig, gimple **stmts)
1243{
1244 struct cgraph_node *node;
1245 struct function *fn;
1246
1247 while (orig->clone_of)
1248 orig = orig->clone_of;
1249 fn = DECL_STRUCT_FUNCTION (orig->decl)((tree_check ((orig->decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1249, __FUNCTION__, (FUNCTION_DECL)))->function_decl.f)
;
1250
1251 if (!orig->thunk)
1252 fixup_call_stmt_edges_1 (orig, stmts, fn);
1253 if (orig->clones)
1254 for (node = orig->clones; node != orig;)
1255 {
1256 if (!node->thunk)
1257 fixup_call_stmt_edges_1 (node, stmts, fn);
1258 if (node->clones)
1259 node = node->clones;
1260 else if (node->next_sibling_clone)
1261 node = node->next_sibling_clone;
1262 else
1263 {
1264 while (node != orig && !node->next_sibling_clone)
1265 node = node->clone_of;
1266 if (node != orig)
1267 node = node->next_sibling_clone;
1268 }
1269 }
1270}
1271
1272
1273/* Input the base body of struct function FN from DATA_IN
1274 using input block IB. */
1275
1276static void
1277input_struct_function_base (struct function *fn, class data_in *data_in,
1278 class lto_input_block *ib)
1279{
1280 struct bitpack_d bp;
1281 int len;
1282
1283 /* Read the static chain and non-local goto save area. */
1284 fn->static_chain_decl = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1285 fn->nonlocal_goto_save_area = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1286
1287 /* Read all the local symbols. */
1288 len = streamer_read_hwi (ib);
1289 if (len > 0)
1290 {
1291 int i;
1292 vec_safe_grow_cleared (fn->local_decls, len, true);
1293 for (i = 0; i < len; i++)
1294 {
1295 tree t = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1296 (*fn->local_decls)[i] = t;
1297 }
1298 }
1299
1300 /* Input the current IL state of the function. */
1301 fn->curr_properties = streamer_read_uhwi (ib);
1302
1303 /* Read all the attributes for FN. */
1304 bp = streamer_read_bitpack (ib);
1305 fn->is_thunk = bp_unpack_value (&bp, 1);
1306 fn->has_local_explicit_reg_vars = bp_unpack_value (&bp, 1);
1307 fn->returns_pcc_struct = bp_unpack_value (&bp, 1);
1308 fn->returns_struct = bp_unpack_value (&bp, 1);
1309 fn->can_throw_non_call_exceptions = bp_unpack_value (&bp, 1);
1310 fn->can_delete_dead_exceptions = bp_unpack_value (&bp, 1);
1311 fn->always_inline_functions_inlined = bp_unpack_value (&bp, 1);
1312 fn->after_inlining = bp_unpack_value (&bp, 1);
1313 fn->stdarg = bp_unpack_value (&bp, 1);
1314 fn->has_nonlocal_label = bp_unpack_value (&bp, 1);
1315 fn->has_forced_label_in_static = bp_unpack_value (&bp, 1);
1316 fn->calls_alloca = bp_unpack_value (&bp, 1);
1317 fn->calls_setjmp = bp_unpack_value (&bp, 1);
1318 fn->calls_eh_return = bp_unpack_value (&bp, 1);
1319 fn->has_force_vectorize_loops = bp_unpack_value (&bp, 1);
1320 fn->has_simduid_loops = bp_unpack_value (&bp, 1);
1321 fn->assume_function = bp_unpack_value (&bp, 1);
1322 fn->va_list_fpr_size = bp_unpack_value (&bp, 8);
1323 fn->va_list_gpr_size = bp_unpack_value (&bp, 8);
1324 fn->last_clique = bp_unpack_value (&bp, sizeof (short) * 8);
1325
1326 /* Input the function start and end loci. */
1327 stream_input_location (&fn->function_start_locus, &bp, data_in)streamer_hooks.input_location (&fn->function_start_locus
, &bp, data_in)
;
1328 stream_input_location (&fn->function_end_locus, &bp, data_in)streamer_hooks.input_location (&fn->function_end_locus
, &bp, data_in)
;
1329
1330 /* Restore the instance discriminators if present. */
1331 int instance_number = bp_unpack_value (&bp, 1);
1332 if (instance_number)
1333 {
1334 instance_number = bp_unpack_value (&bp, sizeof (int) * CHAR_BIT8);
1335 maybe_create_decl_to_instance_map ()->put (fn->decl, instance_number);
1336 }
1337}
1338
1339/* Read a chain of tree nodes from input block IB. DATA_IN contains
1340 tables and descriptors for the file being read. */
1341
1342static tree
1343streamer_read_chain (class lto_input_block *ib, class data_in *data_in)
1344{
1345 tree first, prev, curr;
1346
1347 /* The chain is written as NULL terminated list of trees. */
1348 first = prev = NULL_TREE(tree) nullptr;
1349 do
1350 {
1351 curr = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1352 if (prev)
1353 TREE_CHAIN (prev)((contains_struct_check ((prev), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1353, __FUNCTION__))->common.chain)
= curr;
1354 else
1355 first = curr;
1356
1357 prev = curr;
1358 }
1359 while (curr);
1360
1361 return first;
1362}
1363
1364/* Read the body of function FN_DECL from DATA_IN using input block IB. */
1365
1366static void
1367input_function (tree fn_decl, class data_in *data_in,
1368 class lto_input_block *ib, class lto_input_block *ib_cfg,
1369 cgraph_node *node)
1370{
1371 struct function *fn;
1372 enum LTO_tags tag;
1373 gimple **stmts;
1374 basic_block bb;
1375
1376 tag = streamer_read_record_start (ib);
1377 lto_tag_check (tag, LTO_function);
1378
1379 /* Read decls for parameters and args. */
1380 DECL_RESULT (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1380, __FUNCTION__, (FUNCTION_DECL)))->decl_non_common.result
)
= stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1381 DECL_ARGUMENTS (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1381, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments
)
= streamer_read_chain (ib, data_in);
1382
1383 /* Read debug args if available. */
1384 unsigned n_debugargs = streamer_read_uhwi (ib);
1385 if (n_debugargs)
1386 {
1387 vec<tree, va_gc> **debugargs = decl_debug_args_insert (fn_decl);
1388 vec_safe_grow (*debugargs, n_debugargs, true);
1389 for (unsigned i = 0; i < n_debugargs; ++i)
1390 (**debugargs)[i] = stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1391 }
1392
1393 /* Read the tree of lexical scopes for the function. */
1394 DECL_INITIAL (fn_decl)((contains_struct_check ((fn_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1394, __FUNCTION__))->decl_common.initial)
= stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1395 unsigned block_leaf_count = streamer_read_uhwi (ib);
1396 while (block_leaf_count--)
1397 stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1398
1399 if (!streamer_read_uhwi (ib))
1400 return;
1401
1402 push_struct_function (fn_decl);
1403 fn = DECL_STRUCT_FUNCTION (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1403, __FUNCTION__, (FUNCTION_DECL)))->function_decl.f)
;
1404
1405 gimple_register_cfg_hooks ();
1406
1407 input_struct_function_base (fn, data_in, ib);
1408 input_cfg (ib_cfg, data_in, fn);
1409
1410 /* Read all the SSA names. */
1411 input_ssa_names (ib, data_in, fn);
1412
1413 /* Read the exception handling regions in the function. */
1414 input_eh_regions (ib, data_in, fn);
1415
1416 gcc_assert (DECL_INITIAL (fn_decl))((void)(!(((contains_struct_check ((fn_decl), (TS_DECL_COMMON
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1416, __FUNCTION__))->decl_common.initial)) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1416, __FUNCTION__), 0 : 0))
;
1417 DECL_SAVED_TREE (fn_decl)((tree_check ((fn_decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1417, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree
)
= NULL_TREE(tree) nullptr;
1418
1419 /* Read all the basic blocks. */
1420 tag = streamer_read_record_start (ib);
1421 while (tag)
1422 {
1423 input_bb (ib, tag, data_in, fn,
1424 node->count_materialization_scale);
1425 tag = streamer_read_record_start (ib);
1426 }
1427
1428 /* Finalize gimple_location/gimple_block of stmts and phis. */
1429 data_in->location_cache.apply_location_cache ();
1430
1431 /* Fix up the call statements that are mentioned in the callgraph
1432 edges. */
1433 set_gimple_stmt_max_uid (cfun(cfun + 0), 0);
1434 FOR_ALL_BB_FN (bb, cfun)for (bb = (((cfun + 0))->cfg->x_entry_block_ptr); bb; bb
= bb->next_bb)
1435 {
1436 gimple_stmt_iterator gsi;
1437 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1438 {
1439 gimple *stmt = gsi_stmt (gsi);
1440 gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun(cfun + 0)));
1441 }
1442 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1443 {
1444 gimple *stmt = gsi_stmt (gsi);
1445 gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun(cfun + 0)));
1446 }
1447 }
1448 stmts = (gimple **) xcalloc (gimple_stmt_max_uid (fn), sizeof (gimple *));
1449 FOR_ALL_BB_FN (bb, cfun)for (bb = (((cfun + 0))->cfg->x_entry_block_ptr); bb; bb
= bb->next_bb)
1450 {
1451 gimple_stmt_iterator bsi = gsi_start_phis (bb);
1452 while (!gsi_end_p (bsi))
1453 {
1454 gimple *stmt = gsi_stmt (bsi);
1455 gsi_next (&bsi);
1456 stmts[gimple_uid (stmt)] = stmt;
1457 }
1458 bsi = gsi_start_bb (bb);
1459 while (!gsi_end_p (bsi))
1460 {
1461 gimple *stmt = gsi_stmt (bsi);
1462 bool remove = false;
1463 /* If we're recompiling LTO objects with debug stmts but
1464 we're not supposed to have debug stmts, remove them now.
1465 We can't remove them earlier because this would cause uid
1466 mismatches in fixups, but we can do it at this point, as
1467 long as debug stmts don't require fixups.
1468 Similarly remove all IFN_*SAN_* internal calls */
1469 if (!flag_wpaglobal_options.x_flag_wpa)
1470 {
1471 if (is_gimple_debug (stmt)
1472 && (gimple_debug_nonbind_marker_p (stmt)
1473 ? !MAY_HAVE_DEBUG_MARKER_STMTSglobal_options.x_debug_nonbind_markers_p
1474 : !MAY_HAVE_DEBUG_BIND_STMTSglobal_options.x_flag_var_tracking_assignments))
1475 remove = true;
1476 /* In case the linemap overflows locations can be dropped
1477 to zero. Thus do not keep nonsensical inline entry markers
1478 we'd later ICE on. */
1479 tree block;
1480 if (gimple_debug_inline_entry_p (stmt)
1481 && (((block = gimple_block (stmt))
1482 && !inlined_function_outer_scope_p (block))
1483 || !debug_inline_pointsglobal_options.x_debug_inline_points))
1484 remove = true;
1485 if (is_gimple_call (stmt)
1486 && gimple_call_internal_p (stmt))
1487 {
1488 bool replace = false;
1489 switch (gimple_call_internal_fn (stmt))
1490 {
1491 case IFN_UBSAN_NULL:
1492 if ((flag_sanitizeglobal_options.x_flag_sanitize
1493 & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) == 0)
1494 replace = true;
1495 break;
1496 case IFN_UBSAN_BOUNDS:
1497 if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_BOUNDS) == 0)
1498 replace = true;
1499 break;
1500 case IFN_UBSAN_VPTR:
1501 if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_VPTR) == 0)
1502 replace = true;
1503 break;
1504 case IFN_UBSAN_OBJECT_SIZE:
1505 if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_OBJECT_SIZE) == 0)
1506 replace = true;
1507 break;
1508 case IFN_UBSAN_PTR:
1509 if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_POINTER_OVERFLOW) == 0)
1510 replace = true;
1511 break;
1512 case IFN_ASAN_MARK:
1513 if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_ADDRESS) == 0)
1514 replace = true;
1515 break;
1516 case IFN_TSAN_FUNC_EXIT:
1517 if ((flag_sanitizeglobal_options.x_flag_sanitize & SANITIZE_THREAD) == 0)
1518 replace = true;
1519 break;
1520 default:
1521 break;
1522 }
1523 if (replace)
1524 {
1525 gimple_call_set_internal_fn (as_a <gcall *> (stmt),
1526 IFN_NOP);
1527 update_stmt (stmt);
1528 }
1529 }
1530 }
1531 if (remove)
1532 {
1533 gimple_stmt_iterator gsi = bsi;
1534 gsi_next (&bsi);
1535 unlink_stmt_vdef (stmt);
1536 release_defs (stmt);
1537 gsi_remove (&gsi, true);
1538 }
1539 else
1540 {
1541 gsi_next (&bsi);
1542 stmts[gimple_uid (stmt)] = stmt;
1543
1544 /* Remember that the input function has begin stmt
1545 markers, so that we know to expect them when emitting
1546 debug info. */
1547 if (!cfun(cfun + 0)->debug_nonbind_markers
1548 && gimple_debug_nonbind_marker_p (stmt))
1549 cfun(cfun + 0)->debug_nonbind_markers = true;
1550 }
1551 }
1552 }
1553
1554 /* Set the gimple body to the statement sequence in the entry
1555 basic block. FIXME lto, this is fairly hacky. The existence
1556 of a gimple body is used by the cgraph routines, but we should
1557 really use the presence of the CFG. */
1558 {
1559 edge_iterator ei = ei_start (ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)ei_start_1 (&((((cfun + 0))->cfg->x_entry_block_ptr
)->succs))
;
1560 gimple_set_body (fn_decl, bb_seq (ei_edge (ei)->dest));
1561 }
1562
1563 update_max_bb_count ();
1564 fixup_call_stmt_edges (node, stmts);
1565 execute_all_ipa_stmt_fixups (node, stmts);
1566
1567 free_dominance_info (CDI_DOMINATORS);
1568 free_dominance_info (CDI_POST_DOMINATORS);
1569 free (stmts);
1570 pop_cfun ();
1571}
1572
1573/* Read the body of function FN_DECL from DATA_IN using input block IB. */
1574
1575static void
1576input_constructor (tree var, class data_in *data_in,
1577 class lto_input_block *ib)
1578{
1579 DECL_INITIAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1579, __FUNCTION__))->decl_common.initial)
= stream_read_tree (ib, data_in)streamer_hooks.read_tree (ib, data_in);
1580}
1581
1582
1583/* Read the body from DATA for function NODE and fill it in.
1584 FILE_DATA are the global decls and types. SECTION_TYPE is either
1585 LTO_section_function_body or LTO_section_static_initializer. If
1586 section type is LTO_section_function_body, FN must be the decl for
1587 that function. */
1588
1589static void
1590lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symtab_node *node,
1591 const char *data, enum lto_section_type section_type)
1592{
1593 const struct lto_function_header *header;
1594 class data_in *data_in;
1595 int cfg_offset;
2
'cfg_offset' declared without an initial value
1596 int main_offset;
1597 int string_offset;
1598 tree fn_decl = node->decl;
1599
1600 header = (const struct lto_function_header *) data;
1601 if (TREE_CODE (node->decl)((enum tree_code) (node->decl)->base.code) == FUNCTION_DECL)
3
Assuming field 'code' is not equal to FUNCTION_DECL
4
Taking false branch
1602 {
1603 cfg_offset = sizeof (struct lto_function_header);
1604 main_offset = cfg_offset + header->cfg_size;
1605 string_offset = main_offset + header->main_size;
1606 }
1607 else
1608 {
1609 main_offset = sizeof (struct lto_function_header);
1610 string_offset = main_offset + header->main_size;
1611 }
1612
1613 data_in = lto_data_in_create (file_data, data + string_offset,
1614 header->string_size, vNULL);
1615
1616 if (section_type
4.1
'section_type' is equal to LTO_section_function_body
== LTO_section_function_body)
5
Taking true branch
1617 {
1618 struct lto_in_decl_state *decl_state;
1619 unsigned from;
1620
1621 gcc_checking_assert (node)((void)(!(node) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1621, __FUNCTION__), 0 : 0))
;
6
'?' condition is false
1622
1623 /* Use the function's decl state. */
1624 decl_state = lto_get_function_in_decl_state (file_data, fn_decl);
1625 gcc_assert (decl_state)((void)(!(decl_state) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1625, __FUNCTION__), 0 : 0))
;
7
Assuming 'decl_state' is non-null
8
'?' condition is false
1626 file_data->current_decl_state = decl_state;
1627
1628
1629 /* Set up the struct function. */
1630 from = data_in->reader_cache->nodes.length ();
1631 lto_input_block ib_main (data + main_offset, header->main_size,
1632 file_data->mode_table);
1633 if (TREE_CODE (node->decl)((enum tree_code) (node->decl)->base.code) == FUNCTION_DECL)
9
Assuming field 'code' is equal to FUNCTION_DECL
10
Taking true branch
1634 {
1635 lto_input_block ib_cfg (data + cfg_offset, header->cfg_size,
11
The right operand of '+' is a garbage value
1636 file_data->mode_table);
1637 input_function (fn_decl, data_in, &ib_main, &ib_cfg,
1638 dyn_cast <cgraph_node *>(node));
1639 }
1640 else
1641 input_constructor (fn_decl, data_in, &ib_main);
1642 data_in->location_cache.apply_location_cache ();
1643 /* And fixup types we streamed locally. */
1644 {
1645 struct streamer_tree_cache_d *cache = data_in->reader_cache;
1646 unsigned len = cache->nodes.length ();
1647 unsigned i;
1648 for (i = len; i-- > from;)
1649 {
1650 tree t = streamer_tree_cache_get_tree (cache, i);
1651 if (t == NULL_TREE(tree) nullptr)
1652 continue;
1653
1654 if (TYPE_P (t)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (t)->base.code))] == tcc_type)
)
1655 {
1656 gcc_assert (TYPE_CANONICAL (t) == NULL_TREE)((void)(!(((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1656, __FUNCTION__))->type_common.canonical) == (tree) nullptr
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1656, __FUNCTION__), 0 : 0))
;
1657 if (type_with_alias_set_p (t)
1658 && canonical_type_used_p (t))
1659 TYPE_CANONICAL (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1659, __FUNCTION__))->type_common.canonical)
= TYPE_MAIN_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1659, __FUNCTION__))->type_common.main_variant)
;
1660 if (TYPE_MAIN_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1660, __FUNCTION__))->type_common.main_variant)
!= t)
1661 {
1662 gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE)((void)(!(((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1662, __FUNCTION__))->type_common.next_variant) == (tree
) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1662, __FUNCTION__), 0 : 0))
;
1663 TYPE_NEXT_VARIANT (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1663, __FUNCTION__))->type_common.next_variant)
1664 = TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t))((tree_class_check ((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1664, __FUNCTION__))->type_common.main_variant)), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1664, __FUNCTION__))->type_common.next_variant)
;
1665 TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (t))((tree_class_check ((((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1665, __FUNCTION__))->type_common.main_variant)), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1665, __FUNCTION__))->type_common.next_variant)
= t;
1666 }
1667 }
1668 }
1669 }
1670
1671 /* Restore decl state */
1672 file_data->current_decl_state = file_data->global_decl_state;
1673 }
1674
1675 lto_data_in_delete (data_in);
1676}
1677
1678
1679/* Read the body of NODE using DATA. FILE_DATA holds the global
1680 decls and types. */
1681
1682void
1683lto_input_function_body (struct lto_file_decl_data *file_data,
1684 struct cgraph_node *node, const char *data)
1685{
1686 lto_read_body_or_constructor (file_data, node, data, LTO_section_function_body);
1687}
1688
1689/* Read the body of NODE using DATA. FILE_DATA holds the global
1690 decls and types. */
1691
1692void
1693lto_input_variable_constructor (struct lto_file_decl_data *file_data,
1694 struct varpool_node *node, const char *data)
1695{
1696 lto_read_body_or_constructor (file_data, node, data, LTO_section_function_body);
1
Calling 'lto_read_body_or_constructor'
1697}
1698
1699
1700/* Queue of acummulated decl -> DIE mappings. Similar to locations those
1701 are only applied to prevailing tree nodes during tree merging. */
1702vec<dref_entry> dref_queue;
1703
1704/* Read the physical representation of a tree node EXPR from
1705 input block IB using the per-file context in DATA_IN. */
1706
1707static void
1708lto_read_tree_1 (class lto_input_block *ib, class data_in *data_in, tree expr)
1709{
1710 /* Read all the bitfield values in EXPR. Note that for LTO, we
1711 only write language-independent bitfields, so no more unpacking is
1712 needed. */
1713 streamer_read_tree_bitfields (ib, data_in, expr);
1714
1715 /* Read all the pointer fields in EXPR. */
1716 streamer_read_tree_body (ib, data_in, expr);
1717
1718 /* Read any LTO-specific data not read by the tree streamer. Do not use
1719 stream_read_tree here since that flushes the dref_queue in mids of
1720 SCC reading. */
1721 if (DECL_P (expr)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (expr)->base.code))] == tcc_declaration)
1722 && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != FUNCTION_DECL
1723 && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != TRANSLATION_UNIT_DECL)
1724 DECL_INITIAL (expr)((contains_struct_check ((expr), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1724, __FUNCTION__))->decl_common.initial)
1725 = lto_input_tree_1 (ib, data_in, streamer_read_record_start (ib), 0);
1726
1727 /* Stream references to early generated DIEs. Keep in sync with the
1728 trees handled in dwarf2out_register_external_die. */
1729 if ((DECL_P (expr)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (expr)->base.code))] == tcc_declaration)
1730 && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != FIELD_DECL
1731 && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != DEBUG_EXPR_DECL
1732 && TREE_CODE (expr)((enum tree_code) (expr)->base.code) != TYPE_DECL)
1733 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == BLOCK)
1734 {
1735 const char *str = streamer_read_string (data_in, ib);
1736 if (str)
1737 {
1738 unsigned HOST_WIDE_INTlong off = streamer_read_uhwi (ib);
1739 dref_entry e = { expr, str, off };
1740 dref_queue.safe_push (e);
1741 }
1742 }
1743}
1744
1745/* Read the physical representation of a tree node with tag TAG from
1746 input block IB using the per-file context in DATA_IN. */
1747
1748static tree
1749lto_read_tree (class lto_input_block *ib, class data_in *data_in,
1750 enum LTO_tags tag, hashval_t hash)
1751{
1752 /* Instantiate a new tree node. */
1753 tree result = streamer_alloc_tree (ib, data_in, tag);
1754
1755 /* Enter RESULT in the reader cache. This will make RESULT
1756 available so that circular references in the rest of the tree
1757 structure can be resolved in subsequent calls to stream_read_tree. */
1758 streamer_tree_cache_append (data_in->reader_cache, result, hash);
1759
1760 lto_read_tree_1 (ib, data_in, result);
1761
1762 return result;
1763}
1764
1765
1766/* Populate the reader cache with trees materialized from the SCC
1767 following in the IB, DATA_IN stream.
1768 If SHARED_SCC is true we input LTO_tree_scc. */
1769
1770hashval_t
1771lto_input_scc (class lto_input_block *ib, class data_in *data_in,
1772 unsigned *len, unsigned *entry_len, bool shared_scc)
1773{
1774 unsigned size = streamer_read_uhwi (ib);
1775 hashval_t scc_hash = 0;
1776 unsigned scc_entry_len = 1;
1777
1778 if (shared_scc)
1779 {
1780 if (size & 1)
1781 scc_entry_len = streamer_read_uhwi (ib);
1782 size /= 2;
1783 scc_hash = streamer_read_uhwi (ib);
1784 }
1785
1786 if (size == 1)
1787 {
1788 enum LTO_tags tag = streamer_read_record_start (ib);
1789 lto_input_tree_1 (ib, data_in, tag, scc_hash);
1790 }
1791 else
1792 {
1793 unsigned int first = data_in->reader_cache->nodes.length ();
1794 tree result;
1795
1796 /* Materialize size trees by reading their headers. */
1797 for (unsigned i = 0; i < size; ++i)
1798 {
1799 enum LTO_tags tag = streamer_read_record_start (ib);
1800 if (tag == LTO_null
1801 || tag == LTO_global_stream_ref
1802 || tag == LTO_tree_pickle_reference
1803 || tag == LTO_integer_cst
1804 || tag == LTO_tree_scc
1805 || tag == LTO_trees)
1806 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1806, __FUNCTION__))
;
1807
1808 result = streamer_alloc_tree (ib, data_in, tag);
1809 streamer_tree_cache_append (data_in->reader_cache, result, 0);
1810 }
1811
1812 /* Read the tree bitpacks and references. */
1813 for (unsigned i = 0; i < size; ++i)
1814 {
1815 result = streamer_tree_cache_get_tree (data_in->reader_cache,
1816 first + i);
1817 lto_read_tree_1 (ib, data_in, result);
1818 }
1819 }
1820
1821 *len = size;
1822 *entry_len = scc_entry_len;
1823 return scc_hash;
1824}
1825
1826/* Read reference to tree from IB and DATA_IN.
1827 This is used for streaming tree bodies where we know that
1828 the tree is already in cache or is indexable and
1829 must be matched with stream_write_tree_ref. */
1830
1831tree
1832stream_read_tree_ref (lto_input_block *ib, data_in *data_in)
1833{
1834 int ix = streamer_read_hwi (ib);
1835 if (!ix)
1836 return NULL_TREE(tree) nullptr;
1837 if (ix > 0)
1838 return streamer_tree_cache_get_tree (data_in->reader_cache, ix - 1);
1839
1840 ix = -ix - 1;
1841 int id = ix & 1;
1842 ix /= 2;
1843
1844 tree ret;
1845 if (!id)
1846 ret = (*data_in->file_data->current_decl_state
1847 ->streams[LTO_DECL_STREAM])[ix];
1848 else
1849 ret = (*SSANAMES (cfun)((cfun + 0))->gimple_df->ssa_names)[ix];
1850 return ret;
1851}
1852
1853/* Read a tree from input block IB using the per-file context in
1854 DATA_IN. This context is used, for example, to resolve references
1855 to previously read nodes. */
1856
1857tree
1858lto_input_tree_1 (class lto_input_block *ib, class data_in *data_in,
1859 enum LTO_tags tag, hashval_t hash)
1860{
1861 tree result;
1862
1863 gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS)((void)(!((unsigned) tag < (unsigned) LTO_NUM_TAGS) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1863, __FUNCTION__), 0 : 0))
;
1864
1865 if (tag == LTO_null)
1866 result = NULL_TREE(tree) nullptr;
1867 else if (tag == LTO_global_stream_ref || tag == LTO_ssa_name_ref)
1868 {
1869 /* If TAG is a reference to an indexable tree, the next value
1870 in IB is the index into the table where we expect to find
1871 that tree. */
1872 result = lto_input_tree_ref (ib, data_in, cfun(cfun + 0), tag);
1873 }
1874 else if (tag == LTO_tree_pickle_reference)
1875 {
1876 /* If TAG is a reference to a previously read tree, look it up in
1877 the reader cache. */
1878 result = streamer_get_pickled_tree (ib, data_in);
1879 }
1880 else if (tag == LTO_integer_cst)
1881 {
1882 /* For shared integer constants in singletons we can use the
1883 existing tree integer constant merging code. */
1884 tree type = stream_read_tree_ref (ib, data_in);
1885 unsigned HOST_WIDE_INTlong len = streamer_read_uhwi (ib);
1886 unsigned HOST_WIDE_INTlong i;
1887 HOST_WIDE_INTlong a[WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64)];
1888
1889 for (i = 0; i < len; i++)
1890 a[i] = streamer_read_hwi (ib);
1891 gcc_assert (TYPE_PRECISION (type) <= MAX_BITSIZE_MODE_ANY_INT)((void)(!(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1891, __FUNCTION__))->type_common.precision) <= (64*(
8))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1891, __FUNCTION__), 0 : 0))
;
1892 result = wide_int_to_tree (type, wide_int::from_array
1893 (a, len, TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1893, __FUNCTION__))->type_common.precision)
));
1894 streamer_tree_cache_append (data_in->reader_cache, result, hash);
1895 }
1896 else if (tag == LTO_tree_scc || tag == LTO_trees)
1897 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1897, __FUNCTION__))
;
1898 else
1899 {
1900 /* Otherwise, materialize a new node from IB. */
1901 result = lto_read_tree (ib, data_in, tag, hash);
1902 }
1903
1904 return result;
1905}
1906
1907tree
1908lto_input_tree (class lto_input_block *ib, class data_in *data_in)
1909{
1910 enum LTO_tags tag;
1911
1912 /* Input pickled trees needed to stream in the reference. */
1913 while ((tag = streamer_read_record_start (ib)) == LTO_trees)
1914 {
1915 unsigned len, entry_len;
1916 lto_input_scc (ib, data_in, &len, &entry_len, false);
1917
1918 /* Register DECLs with the debuginfo machinery. */
1919 while (!dref_queue.is_empty ())
1920 {
1921 dref_entry e = dref_queue.pop ();
1922 debug_hooks->register_external_die (e.decl, e.sym, e.off);
1923 }
1924 }
1925 tree t = lto_input_tree_1 (ib, data_in, tag, 0);
1926
1927 if (!dref_queue.is_empty ())
1928 {
1929 dref_entry e = dref_queue.pop ();
1930 debug_hooks->register_external_die (e.decl, e.sym, e.off);
1931 gcc_checking_assert (dref_queue.is_empty ())((void)(!(dref_queue.is_empty ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 1931, __FUNCTION__), 0 : 0))
;
1932 }
1933 return t;
1934}
1935
1936
1937/* Input toplevel asms. */
1938
1939void
1940lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
1941{
1942 size_t len;
1943 const char *data
1944 = lto_get_summary_section_data (file_data, LTO_section_asm, &len);
1945 const struct lto_simple_header_with_strings *header
1946 = (const struct lto_simple_header_with_strings *) data;
1947 int string_offset;
1948 class data_in *data_in;
1949 tree str;
1950
1951 if (! data)
1952 return;
1953
1954 string_offset = sizeof (*header) + header->main_size;
1955
1956 lto_input_block ib (data + sizeof (*header), header->main_size,
1957 file_data->mode_table);
1958
1959 data_in = lto_data_in_create (file_data, data + string_offset,
1960 header->string_size, vNULL);
1961
1962 while ((str = streamer_read_string_cst (data_in, &ib)))
1963 {
1964 asm_node *node = symtab->finalize_toplevel_asm (str);
1965 node->order = streamer_read_hwi (&ib) + order_base;
1966 if (node->order >= symtab->order)
1967 symtab->order = node->order + 1;
1968 }
1969
1970 lto_data_in_delete (data_in);
1971
1972 lto_free_section_data (file_data, LTO_section_asm, NULLnullptr, data, len);
1973}
1974
1975
1976/* Input mode table. */
1977
1978void
1979lto_input_mode_table (struct lto_file_decl_data *file_data)
1980{
1981 size_t len;
1982 const char *data
1983 = lto_get_summary_section_data (file_data, LTO_section_mode_table, &len);
1984 if (! data)
1985 internal_error ("cannot read LTO mode table from %s",
1986 file_data->file_name);
1987
1988 unsigned char *table = ggc_cleared_vec_alloc<unsigned char> (1 << 8);
1989 file_data->mode_table = table;
1990 const struct lto_simple_header_with_strings *header
1991 = (const struct lto_simple_header_with_strings *) data;
1992 int string_offset;
1993 class data_in *data_in;
1994 string_offset = sizeof (*header) + header->main_size;
1995
1996 lto_input_block ib (data + sizeof (*header), header->main_size, NULLnullptr);
1997 data_in = lto_data_in_create (file_data, data + string_offset,
1998 header->string_size, vNULL);
1999 bitpack_d bp = streamer_read_bitpack (&ib);
2000
2001 table[VOIDmode((void) 0, E_VOIDmode)] = VOIDmode((void) 0, E_VOIDmode);
2002 table[BLKmode((void) 0, E_BLKmode)] = BLKmode((void) 0, E_BLKmode);
2003 unsigned int m;
2004 while ((m = bp_unpack_value (&bp, 8)) != VOIDmode((void) 0, E_VOIDmode))
2005 {
2006 enum mode_class mclass
2007 = bp_unpack_enum (&bp, mode_class, MAX_MODE_CLASS)(enum mode_class)bp_unpack_int_in_range ((&bp), "mode_class"
, 0, (int)(MAX_MODE_CLASS) - 1)
;
2008 poly_uint16 size = bp_unpack_poly_value (&bp, 16);
2009 poly_uint16 prec = bp_unpack_poly_value (&bp, 16);
2010 machine_mode inner = (machine_mode) bp_unpack_value (&bp, 8);
2011 poly_uint16 nunits = bp_unpack_poly_value (&bp, 16);
2012 unsigned int ibit = 0, fbit = 0;
2013 unsigned int real_fmt_len = 0;
2014 const char *real_fmt_name = NULLnullptr;
2015 switch (mclass)
2016 {
2017 case MODE_FRACT:
2018 case MODE_UFRACT:
2019 case MODE_ACCUM:
2020 case MODE_UACCUM:
2021 ibit = bp_unpack_value (&bp, 8);
2022 fbit = bp_unpack_value (&bp, 8);
2023 break;
2024 case MODE_FLOAT:
2025 case MODE_DECIMAL_FLOAT:
2026 real_fmt_name = bp_unpack_indexed_string (data_in, &bp,
2027 &real_fmt_len);
2028 break;
2029 default:
2030 break;
2031 }
2032 /* First search just the GET_CLASS_NARROWEST_MODE to wider modes,
2033 if not found, fallback to all modes. */
2034 int pass;
2035 for (pass = 0; pass < 2; pass++)
2036 for (machine_mode mr = pass ? VOIDmode((void) 0, E_VOIDmode)
2037 : GET_CLASS_NARROWEST_MODE (mclass)((machine_mode) class_narrowest_mode[mclass]);
2038 pass ? mr < MAX_MACHINE_MODE : mr != VOIDmode((void) 0, E_VOIDmode);
2039 pass ? mr = (machine_mode) (mr + 1)
2040 : mr = GET_MODE_WIDER_MODE (mr).else_void ())
2041 if (GET_MODE_CLASS (mr)((enum mode_class) mode_class[mr]) != mclass
2042 || maybe_ne (GET_MODE_SIZE (mr), size)
2043 || maybe_ne (GET_MODE_PRECISION (mr), prec)
2044 || (inner == m
2045 ? GET_MODE_INNER (mr)(mode_to_inner (mr)) != mr
2046 : GET_MODE_INNER (mr)(mode_to_inner (mr)) != table[(int) inner])
2047 || GET_MODE_IBIT (mr)mode_ibit[mr] != ibit
2048 || GET_MODE_FBIT (mr)mode_fbit[mr] != fbit
2049 || maybe_ne (GET_MODE_NUNITS (mr), nunits))
2050 continue;
2051 else if ((mclass == MODE_FLOAT || mclass == MODE_DECIMAL_FLOAT)
2052 && strcmp (REAL_MODE_FORMAT (mr)(real_format_for_mode[(((enum mode_class) mode_class[mr]) == MODE_DECIMAL_FLOAT
) ? (((mr) - MIN_MODE_DECIMAL_FLOAT) + (MAX_MODE_FLOAT - MIN_MODE_FLOAT
+ 1)) : ((enum mode_class) mode_class[mr]) == MODE_FLOAT ? (
(mr) - MIN_MODE_FLOAT) : ((fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/lto-streamer-in.cc"
, 2052, __FUNCTION__)), 0)])
->name, real_fmt_name) != 0)
2053 continue;
2054 else
2055 {
2056 table[m] = mr;
2057 pass = 2;
2058 break;
2059 }
2060 unsigned int mname_len;
2061 const char *mname = bp_unpack_indexed_string (data_in, &bp, &mname_len);
2062 if (pass == 2)
2063 {
2064 switch (mclass)
2065 {
2066 case MODE_VECTOR_BOOL:
2067 case MODE_VECTOR_INT:
2068 case MODE_VECTOR_FLOAT:
2069 case MODE_VECTOR_FRACT:
2070 case MODE_VECTOR_UFRACT:
2071 case MODE_VECTOR_ACCUM:
2072 case MODE_VECTOR_UACCUM:
2073 /* For unsupported vector modes just use BLKmode,
2074 if the scalar mode is supported. */
2075 if (table[(int) inner] != VOIDmode((void) 0, E_VOIDmode))
2076 {
2077 table[m] = BLKmode((void) 0, E_BLKmode);
2078 break;
2079 }
2080 /* FALLTHRU */
2081 default:
2082 /* This is only used for offloading-target compilations and
2083 is a user-facing error. Give a better error message for
2084 the common modes; see also mode-classes.def. */
2085 if (mclass == MODE_FLOAT)
2086 fatal_error (UNKNOWN_LOCATION((location_t) 0),
2087 "%s - %u-bit-precision floating-point numbers "
2088 "unsupported (mode %qs)", TARGET_MACHINE"x86_64-pc-linux-gnu",
2089 prec.to_constant (), mname);
2090 else if (mclass == MODE_DECIMAL_FLOAT)
2091 fatal_error (UNKNOWN_LOCATION((location_t) 0),
2092 "%s - %u-bit-precision decimal floating-point "
2093 "numbers unsupported (mode %qs)", TARGET_MACHINE"x86_64-pc-linux-gnu",
2094 prec.to_constant (), mname);
2095 else if (mclass == MODE_COMPLEX_FLOAT)
2096 fatal_error (UNKNOWN_LOCATION((location_t) 0),
2097 "%s - %u-bit-precision complex floating-point "
2098 "numbers unsupported (mode %qs)", TARGET_MACHINE"x86_64-pc-linux-gnu",
2099 prec.to_constant (), mname);
2100 else if (mclass == MODE_INT)
2101 fatal_error (UNKNOWN_LOCATION((location_t) 0),
2102 "%s - %u-bit integer numbers unsupported (mode "
2103 "%qs)", TARGET_MACHINE"x86_64-pc-linux-gnu", prec.to_constant (), mname);
2104 else
2105 fatal_error (UNKNOWN_LOCATION((location_t) 0), "%s - unsupported mode %qs",
2106 TARGET_MACHINE"x86_64-pc-linux-gnu", mname);
2107 break;
2108 }
2109 }
2110 }
2111 lto_data_in_delete (data_in);
2112
2113 lto_free_section_data (file_data, LTO_section_mode_table, NULLnullptr, data, len);
2114}
2115
2116
2117/* Initialization for the LTO reader. */
2118
2119void
2120lto_reader_init (void)
2121{
2122 lto_streamer_init ();
2123 file_name_hash_table
2124 = new hash_table<string_slot_hasher> (37);
2125 string_slot_allocator = new object_allocator <struct string_slot>
2126 ("line map file name hash");
2127 gcc_obstack_init (&file_name_obstack)_obstack_begin (((&file_name_obstack)), (memory_block_pool
::block_size), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free
))
;
2128}
2129
2130/* Free hash table used to stream in location file names. */
2131
2132void
2133lto_free_file_name_hash (void)
2134{
2135 delete file_name_hash_table;
2136 file_name_hash_table = NULLnullptr;
2137 delete string_slot_allocator;
2138 string_slot_allocator = NULLnullptr;
2139 delete path_name_pair_hash_table;
2140 path_name_pair_hash_table = NULLnullptr;
2141 delete string_pair_map_allocator;
2142 string_pair_map_allocator = NULLnullptr;
2143 /* file_name_obstack must stay allocated since it is referred to by
2144 line map table. */
2145}
2146
2147
2148/* Create a new data_in object for FILE_DATA. STRINGS is the string
2149 table to use with LEN strings. RESOLUTIONS is the vector of linker
2150 resolutions (NULL if not using a linker plugin). */
2151
2152class data_in *
2153lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings,
2154 unsigned len,
2155 vec<ld_plugin_symbol_resolution_t> resolutions)
2156{
2157 class data_in *data_in = new (class data_in);
2158 data_in->file_data = file_data;
2159 data_in->strings = strings;
2160 data_in->strings_len = len;
2161 data_in->globals_resolution = resolutions;
2162 data_in->reader_cache = streamer_tree_cache_create (false, false, true);
2163 return data_in;
2164}
2165
2166
2167/* Remove DATA_IN. */
2168
2169void
2170lto_data_in_delete (class data_in *data_in)
2171{
2172 data_in->globals_resolution.release ();
2173 streamer_tree_cache_delete (data_in->reader_cache);
2174 delete data_in;
2175}