Line data Source code
1 : /* Definitions of the pointer_query and related classes.
2 :
3 : Copyright (C) 2020-2026 Free Software Foundation, Inc.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "backend.h"
25 : #include "tree.h"
26 : #include "gimple.h"
27 : #include "stringpool.h"
28 : #include "tree-vrp.h"
29 : #include "diagnostic-core.h"
30 : #include "fold-const.h"
31 : #include "tree-object-size.h"
32 : #include "tree-ssa-strlen.h"
33 : #include "langhooks.h"
34 : #include "attribs.h"
35 : #include "gimple-iterator.h"
36 : #include "gimple-fold.h"
37 : #include "gimple-ssa.h"
38 : #include "intl.h"
39 : #include "attr-fnspec.h"
40 : #include "gimple-range.h"
41 : #include "pointer-query.h"
42 : #include "tree-pretty-print.h"
43 : #include "tree-ssanames.h"
44 : #include "target.h"
45 :
46 : static bool compute_objsize_r (tree, gimple *, bool, int, access_ref *,
47 : ssa_name_limit_t &, pointer_query *);
48 :
49 : /* Wrapper around the wide_int overload of get_range that accepts
50 : offset_int instead. For middle end expressions returns the same
51 : result. For a subset of nonconstamt expressions emitted by the front
52 : end determines a more precise range than would be possible otherwise. */
53 :
54 : static bool
55 4691172 : get_offset_range (tree x, gimple *stmt, offset_int r[2], range_query *rvals)
56 : {
57 4691172 : offset_int add = 0;
58 4691172 : if (TREE_CODE (x) == PLUS_EXPR)
59 : {
60 : /* Handle constant offsets in pointer addition expressions seen
61 : n the front end IL. */
62 39 : tree op = TREE_OPERAND (x, 1);
63 39 : if (TREE_CODE (op) == INTEGER_CST)
64 : {
65 39 : op = fold_convert (signed_type_for (TREE_TYPE (op)), op);
66 39 : add = wi::to_offset (op);
67 39 : x = TREE_OPERAND (x, 0);
68 : }
69 : }
70 :
71 4691172 : if (TREE_CODE (x) == NOP_EXPR)
72 : /* Also handle conversions to sizetype seen in the front end IL. */
73 119 : x = TREE_OPERAND (x, 0);
74 :
75 4691172 : tree type = TREE_TYPE (x);
76 4691172 : if ((!INTEGRAL_TYPE_P (type)
77 : /* ??? We get along without caring about overflow by using
78 : offset_int, but that falls apart when indexes are bigger
79 : than pointer differences. */
80 1637664 : || TYPE_PRECISION (type) > TYPE_PRECISION (ptrdiff_type_node))
81 4691357 : && !POINTER_TYPE_P (type))
82 : return false;
83 :
84 4690978 : if (TREE_CODE (x) != INTEGER_CST
85 699595 : && TREE_CODE (x) != SSA_NAME)
86 : {
87 182 : if (TYPE_UNSIGNED (type)
88 182 : && TYPE_PRECISION (type) == TYPE_PRECISION (sizetype))
89 50 : type = signed_type_for (type);
90 :
91 182 : r[0] = wi::to_offset (TYPE_MIN_VALUE (type)) + add;
92 182 : r[1] = wi::to_offset (TYPE_MAX_VALUE (type)) + add;
93 182 : return x;
94 : }
95 :
96 23453980 : wide_int wr[2];
97 4690796 : if (!get_range (x, stmt, wr, rvals))
98 : return false;
99 :
100 4527123 : signop sgn = SIGNED;
101 : /* Only convert signed integers or unsigned sizetype to a signed
102 : offset and avoid converting large positive values in narrower
103 : types to negative offsets. */
104 4527123 : if (TYPE_UNSIGNED (type)
105 4527123 : && wr[0].get_precision () < TYPE_PRECISION (sizetype))
106 : sgn = UNSIGNED;
107 :
108 4527123 : r[0] = offset_int::from (wr[0], sgn);
109 4527123 : r[1] = offset_int::from (wr[1], sgn);
110 4527123 : return true;
111 14072388 : }
112 :
113 : /* Return the argument that the call STMT to a built-in function returns
114 : or null if it doesn't. On success, set OFFRNG[] to the range of offsets
115 : from the argument reflected in the value returned by the built-in if it
116 : can be determined, otherwise to 0 and HWI_M1U respectively. Set
117 : *PAST_END for functions like mempcpy that might return a past the end
118 : pointer (most functions return a dereferenceable pointer to an existing
119 : element of an array). */
120 :
121 : static tree
122 344943 : gimple_call_return_array (gimple *stmt, offset_int offrng[2], bool *past_end,
123 : ssa_name_limit_t &snlim, pointer_query *qry)
124 : {
125 : /* Clear and set below for the rare function(s) that might return
126 : a past-the-end pointer. */
127 344943 : *past_end = false;
128 :
129 344943 : {
130 : /* Check for attribute fn spec to see if the function returns one
131 : of its arguments. */
132 344943 : attr_fnspec fnspec = gimple_call_fnspec (as_a <gcall *>(stmt));
133 344943 : unsigned int argno;
134 344943 : if (fnspec.returns_arg (&argno))
135 : {
136 : /* Functions return the first argument (not a range). */
137 5799 : offrng[0] = offrng[1] = 0;
138 5799 : return gimple_call_arg (stmt, argno);
139 : }
140 : }
141 :
142 339144 : if (gimple_call_num_args (stmt) < 1)
143 : return NULL_TREE;
144 :
145 326309 : tree fn = gimple_call_fndecl (stmt);
146 326309 : if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
147 : {
148 : /* See if this is a call to placement new. */
149 257193 : if (!fn
150 239030 : || !DECL_IS_OPERATOR_NEW_P (fn)
151 266415 : || DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fn))
152 : return NULL_TREE;
153 :
154 : /* Check the mangling, keeping in mind that operator new takes
155 : a size_t which could be unsigned int or unsigned long. */
156 9222 : tree fname = DECL_ASSEMBLER_NAME (fn);
157 9222 : if (!id_equal (fname, "_ZnwjPv") // ordinary form
158 9171 : && !id_equal (fname, "_ZnwmPv") // ordinary form
159 756 : && !id_equal (fname, "_ZnajPv") // array form
160 9974 : && !id_equal (fname, "_ZnamPv")) // array form
161 : return NULL_TREE;
162 :
163 8565 : if (gimple_call_num_args (stmt) != 2)
164 : return NULL_TREE;
165 :
166 : /* Allocation functions return a pointer to the beginning. */
167 8565 : offrng[0] = offrng[1] = 0;
168 8565 : return gimple_call_arg (stmt, 1);
169 : }
170 :
171 69116 : switch (DECL_FUNCTION_CODE (fn))
172 : {
173 0 : case BUILT_IN_MEMCPY:
174 0 : case BUILT_IN_MEMCPY_CHK:
175 0 : case BUILT_IN_MEMMOVE:
176 0 : case BUILT_IN_MEMMOVE_CHK:
177 0 : case BUILT_IN_MEMSET:
178 0 : case BUILT_IN_STRCAT:
179 0 : case BUILT_IN_STRCAT_CHK:
180 0 : case BUILT_IN_STRCPY:
181 0 : case BUILT_IN_STRCPY_CHK:
182 0 : case BUILT_IN_STRNCAT:
183 0 : case BUILT_IN_STRNCAT_CHK:
184 0 : case BUILT_IN_STRNCPY:
185 0 : case BUILT_IN_STRNCPY_CHK:
186 : /* Functions return the first argument (not a range). */
187 0 : offrng[0] = offrng[1] = 0;
188 0 : return gimple_call_arg (stmt, 0);
189 :
190 211 : case BUILT_IN_MEMPCPY:
191 211 : case BUILT_IN_MEMPCPY_CHK:
192 211 : {
193 : /* The returned pointer is in a range constrained by the smaller
194 : of the upper bound of the size argument and the source object
195 : size. */
196 211 : offrng[0] = 0;
197 211 : offrng[1] = HOST_WIDE_INT_M1U;
198 211 : tree off = gimple_call_arg (stmt, 2);
199 211 : bool off_valid = get_offset_range (off, stmt, offrng, qry->rvals);
200 211 : if (!off_valid || offrng[0] != offrng[1])
201 : {
202 : /* If the offset is either indeterminate or in some range,
203 : try to constrain its upper bound to at most the size
204 : of the source object. */
205 92 : access_ref aref;
206 92 : tree src = gimple_call_arg (stmt, 1);
207 92 : if (compute_objsize_r (src, stmt, false, 1, &aref, snlim, qry)
208 92 : && aref.sizrng[1] < offrng[1])
209 36 : offrng[1] = aref.sizrng[1];
210 : }
211 :
212 : /* Mempcpy may return a past-the-end pointer. */
213 211 : *past_end = true;
214 211 : return gimple_call_arg (stmt, 0);
215 : }
216 :
217 4316 : case BUILT_IN_MEMCHR:
218 4316 : {
219 4316 : tree off = gimple_call_arg (stmt, 2);
220 4316 : if (get_offset_range (off, stmt, offrng, qry->rvals))
221 4258 : offrng[1] -= 1;
222 : else
223 58 : offrng[1] = HOST_WIDE_INT_M1U;
224 :
225 4316 : offrng[0] = 0;
226 4316 : return gimple_call_arg (stmt, 0);
227 : }
228 :
229 355 : case BUILT_IN_STRCHR:
230 355 : case BUILT_IN_STRRCHR:
231 355 : case BUILT_IN_STRSTR:
232 355 : offrng[0] = 0;
233 355 : offrng[1] = HOST_WIDE_INT_M1U;
234 355 : return gimple_call_arg (stmt, 0);
235 :
236 98 : case BUILT_IN_STPCPY:
237 98 : case BUILT_IN_STPCPY_CHK:
238 98 : {
239 98 : access_ref aref;
240 98 : tree src = gimple_call_arg (stmt, 1);
241 98 : if (compute_objsize_r (src, stmt, false, 1, &aref, snlim, qry))
242 98 : offrng[1] = aref.sizrng[1] - 1;
243 : else
244 0 : offrng[1] = HOST_WIDE_INT_M1U;
245 :
246 98 : offrng[0] = 0;
247 98 : return gimple_call_arg (stmt, 0);
248 : }
249 :
250 88 : case BUILT_IN_STPNCPY:
251 88 : case BUILT_IN_STPNCPY_CHK:
252 88 : {
253 : /* The returned pointer is in a range between the first argument
254 : and it plus the smaller of the upper bound of the size argument
255 : and the source object size. */
256 88 : offrng[1] = HOST_WIDE_INT_M1U;
257 88 : tree off = gimple_call_arg (stmt, 2);
258 88 : if (!get_offset_range (off, stmt, offrng, qry->rvals)
259 88 : || offrng[0] != offrng[1])
260 : {
261 : /* If the offset is either indeterminate or in some range,
262 : try to constrain its upper bound to at most the size
263 : of the source object. */
264 13 : access_ref aref;
265 13 : tree src = gimple_call_arg (stmt, 1);
266 13 : if (compute_objsize_r (src, stmt, false, 1, &aref, snlim, qry)
267 13 : && aref.sizrng[1] < offrng[1])
268 13 : offrng[1] = aref.sizrng[1];
269 : }
270 :
271 : /* When the source is the empty string the returned pointer is
272 : a copy of the argument. Otherwise stpcpy can also return
273 : a past-the-end pointer. */
274 88 : offrng[0] = 0;
275 88 : *past_end = true;
276 88 : return gimple_call_arg (stmt, 0);
277 : }
278 :
279 : default:
280 : break;
281 : }
282 :
283 : return NULL_TREE;
284 : }
285 :
286 : /* Return true when EXP's range can be determined and set RANGE[] to it
287 : after adjusting it if necessary to make EXP a represents a valid size
288 : of object, or a valid size argument to an allocation function declared
289 : with attribute alloc_size (whose argument may be signed), or to a string
290 : manipulation function like memset.
291 : When ALLOW_ZERO is set in FLAGS, allow returning a range of [0, 0] for
292 : a size in an anti-range [1, N] where N > PTRDIFF_MAX. A zero range is
293 : a (nearly) invalid argument to allocation functions like malloc but it
294 : is a valid argument to functions like memset.
295 : When USE_LARGEST is set in FLAGS set RANGE to the largest valid subrange
296 : in a multi-range, otherwise to the smallest valid subrange. */
297 :
298 : bool
299 1175597 : get_size_range (range_query *query, tree exp, gimple *stmt, tree range[2],
300 : int flags /* = 0 */)
301 : {
302 1175597 : if (!exp)
303 : return false;
304 :
305 1175597 : if (tree_fits_uhwi_p (exp))
306 : {
307 : /* EXP is a constant. */
308 819405 : range[0] = range[1] = exp;
309 819405 : return true;
310 : }
311 :
312 356192 : tree exptype = TREE_TYPE (exp);
313 356192 : bool integral = INTEGRAL_TYPE_P (exptype);
314 :
315 356192 : wide_int min, max;
316 356192 : enum value_range_kind range_type;
317 :
318 356192 : if (!query)
319 47067 : query = get_range_query (cfun);
320 :
321 356192 : if (integral)
322 : {
323 356170 : int_range_max vr;
324 356170 : tree tmin, tmax;
325 :
326 356170 : query->range_of_expr (vr, exp, stmt);
327 :
328 356170 : if (vr.undefined_p ())
329 9 : vr.set_varying (TREE_TYPE (exp));
330 356170 : range_type = get_legacy_range (vr, tmin, tmax);
331 356170 : min = wi::to_wide (tmin);
332 356170 : max = wi::to_wide (tmax);
333 356170 : }
334 : else
335 : range_type = VR_VARYING;
336 :
337 356170 : if (range_type == VR_VARYING)
338 : {
339 45349 : if (integral)
340 : {
341 : /* Use the full range of the type of the expression when
342 : no value range information is available. */
343 45327 : range[0] = TYPE_MIN_VALUE (exptype);
344 45327 : range[1] = TYPE_MAX_VALUE (exptype);
345 45327 : return true;
346 : }
347 :
348 22 : range[0] = NULL_TREE;
349 22 : range[1] = NULL_TREE;
350 22 : return false;
351 : }
352 :
353 310843 : unsigned expprec = TYPE_PRECISION (exptype);
354 :
355 310843 : bool signed_p = !TYPE_UNSIGNED (exptype);
356 :
357 310843 : if (range_type == VR_ANTI_RANGE)
358 : {
359 22437 : if (signed_p)
360 : {
361 81 : if (wi::les_p (max, 0))
362 : {
363 : /* EXP is not in a strictly negative range. That means
364 : it must be in some (not necessarily strictly) positive
365 : range which includes zero. Since in signed to unsigned
366 : conversions negative values end up converted to large
367 : positive values, and otherwise they are not valid sizes,
368 : the resulting range is in both cases [0, TYPE_MAX]. */
369 15 : min = wi::zero (expprec);
370 15 : max = wi::to_wide (TYPE_MAX_VALUE (exptype));
371 : }
372 66 : else if (wi::les_p (min - 1, 0))
373 : {
374 : /* EXP is not in a negative-positive range. That means EXP
375 : is either negative, or greater than max. Since negative
376 : sizes are invalid make the range [MAX + 1, TYPE_MAX]. */
377 42 : min = max + 1;
378 42 : max = wi::to_wide (TYPE_MAX_VALUE (exptype));
379 : }
380 : else
381 : {
382 24 : max = min - 1;
383 24 : min = wi::zero (expprec);
384 : }
385 : }
386 : else
387 : {
388 22356 : wide_int maxsize = wi::to_wide (max_object_size ());
389 22356 : min = wide_int::from (min, maxsize.get_precision (), UNSIGNED);
390 22356 : max = wide_int::from (max, maxsize.get_precision (), UNSIGNED);
391 22356 : if (wi::eq_p (0, min - 1))
392 : {
393 : /* EXP is unsigned and not in the range [1, MAX]. That means
394 : it's either zero or greater than MAX. Even though 0 would
395 : normally be detected by -Walloc-zero, unless ALLOW_ZERO
396 : is set, set the range to [MAX, TYPE_MAX] so that when MAX
397 : is greater than the limit the whole range is diagnosed. */
398 362 : wide_int maxsize = wi::to_wide (max_object_size ());
399 362 : if (flags & SR_ALLOW_ZERO)
400 : {
401 422 : if (wi::leu_p (maxsize, max + 1)
402 211 : || !(flags & SR_USE_LARGEST))
403 125 : min = max = wi::zero (expprec);
404 : else
405 : {
406 86 : min = max + 1;
407 86 : max = wi::to_wide (TYPE_MAX_VALUE (exptype));
408 : }
409 : }
410 : else
411 : {
412 151 : min = max + 1;
413 151 : max = wi::to_wide (TYPE_MAX_VALUE (exptype));
414 : }
415 362 : }
416 43988 : else if ((flags & SR_USE_LARGEST)
417 32001 : && wi::ltu_p (max + 1, maxsize))
418 : {
419 : /* When USE_LARGEST is set and the larger of the two subranges
420 : is a valid size, use it... */
421 36 : min = max + 1;
422 36 : max = maxsize;
423 : }
424 : else
425 : {
426 : /* ...otherwise use the smaller subrange. */
427 21958 : max = min - 1;
428 21958 : min = wi::zero (expprec);
429 : }
430 22356 : }
431 : }
432 :
433 310843 : range[0] = wide_int_to_tree (exptype, min);
434 310843 : range[1] = wide_int_to_tree (exptype, max);
435 :
436 310843 : return true;
437 356192 : }
438 :
439 : bool
440 53609 : get_size_range (tree exp, tree range[2], int flags /* = 0 */)
441 : {
442 53609 : return get_size_range (/*query=*/NULL, exp, /*stmt=*/NULL, range, flags);
443 : }
444 :
445 : /* If STMT is a call to an allocation function, returns the constant
446 : maximum size of the object allocated by the call represented as
447 : sizetype. If nonnull, sets RNG1[] to the range of the size.
448 : When nonnull, uses RVALS for range information, otherwise gets global
449 : range info.
450 : Returns null when STMT is not a call to a valid allocation function. */
451 :
452 : tree
453 495809 : gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
454 : range_query *qry /* = NULL */)
455 : {
456 495809 : if (!stmt || !is_gimple_call (stmt))
457 : return NULL_TREE;
458 :
459 495805 : tree allocfntype;
460 495805 : if (tree fndecl = gimple_call_fndecl (stmt))
461 477323 : allocfntype = TREE_TYPE (fndecl);
462 : else
463 18482 : allocfntype = gimple_call_fntype (stmt);
464 :
465 495805 : if (!allocfntype)
466 : return NULL_TREE;
467 :
468 494725 : unsigned argidx1 = UINT_MAX, argidx2 = UINT_MAX;
469 494725 : tree at = lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (allocfntype));
470 494725 : if (!at)
471 : {
472 348662 : if (!gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
473 : return NULL_TREE;
474 :
475 : argidx1 = 0;
476 : }
477 :
478 150864 : unsigned nargs = gimple_call_num_args (stmt);
479 :
480 150864 : if (argidx1 == UINT_MAX)
481 : {
482 146063 : tree atval = TREE_VALUE (at);
483 146063 : if (!atval)
484 : return NULL_TREE;
485 :
486 146063 : argidx1 = TREE_INT_CST_LOW (TREE_VALUE (atval)) - 1;
487 146063 : if (nargs <= argidx1)
488 : return NULL_TREE;
489 :
490 146063 : atval = TREE_CHAIN (atval);
491 146063 : if (atval)
492 : {
493 1071 : argidx2 = TREE_INT_CST_LOW (TREE_VALUE (atval)) - 1;
494 1071 : if (nargs <= argidx2)
495 : return NULL_TREE;
496 : }
497 : }
498 :
499 150864 : tree size = gimple_call_arg (stmt, argidx1);
500 :
501 754320 : wide_int rng1_buf[2];
502 : /* If RNG1 is not set, use the buffer. */
503 150864 : if (!rng1)
504 38 : rng1 = rng1_buf;
505 :
506 : /* Use maximum precision to avoid overflow below. */
507 150864 : const int prec = ADDR_MAX_PRECISION;
508 :
509 150864 : {
510 150864 : tree r[2];
511 : /* Determine the largest valid range size, including zero. */
512 150864 : if (!get_size_range (qry, size, stmt, r, SR_ALLOW_ZERO | SR_USE_LARGEST))
513 2 : return NULL_TREE;
514 150862 : rng1[0] = wi::to_wide (r[0], prec);
515 150862 : rng1[1] = wi::to_wide (r[1], prec);
516 : }
517 :
518 150862 : if (argidx2 > nargs && TREE_CODE (size) == INTEGER_CST)
519 55354 : return fold_convert (sizetype, size);
520 :
521 : /* To handle ranges do the math in wide_int and return the product
522 : of the upper bounds as a constant. Ignore anti-ranges. */
523 95508 : tree n = argidx2 < nargs ? gimple_call_arg (stmt, argidx2) : integer_one_node;
524 477540 : wide_int rng2[2];
525 95508 : {
526 95508 : tree r[2];
527 : /* As above, use the full non-negative range on failure. */
528 95508 : if (!get_size_range (qry, n, stmt, r, SR_ALLOW_ZERO | SR_USE_LARGEST))
529 0 : return NULL_TREE;
530 95508 : rng2[0] = wi::to_wide (r[0], prec);
531 95508 : rng2[1] = wi::to_wide (r[1], prec);
532 : }
533 :
534 : /* Compute products of both bounds for the caller but return the lesser
535 : of SIZE_MAX and the product of the upper bounds as a constant. */
536 95508 : rng1[0] = rng1[0] * rng2[0];
537 95508 : rng1[1] = rng1[1] * rng2[1];
538 :
539 95508 : const tree size_max = TYPE_MAX_VALUE (sizetype);
540 95508 : if (wi::gtu_p (rng1[1], wi::to_wide (size_max, prec)))
541 : {
542 79 : rng1[1] = wi::to_wide (size_max, prec);
543 79 : return size_max;
544 : }
545 :
546 95429 : return wide_int_to_tree (sizetype, rng1[1]);
547 739116 : }
548 :
549 : /* For an access to an object referenced to by the function parameter PTR
550 : of pointer type, and set RNG[] to the range of sizes of the object
551 : obtainedfrom the attribute access specification for the current function.
552 : Set STATIC_ARRAY if the array parameter has been declared [static].
553 : Return the function parameter on success and null otherwise. */
554 :
555 : static tree
556 836626 : gimple_parm_array_size (tree ptr, wide_int rng[2],
557 : bool *static_array /* = NULL */)
558 : {
559 : /* For a function argument try to determine the byte size of the array
560 : from the current function declaratation (e.g., attribute access or
561 : related). */
562 836626 : tree var = SSA_NAME_VAR (ptr);
563 836626 : if (TREE_CODE (var) != PARM_DECL || !POINTER_TYPE_P (TREE_TYPE (var)))
564 : return NULL_TREE;
565 :
566 789838 : const unsigned prec = TYPE_PRECISION (sizetype);
567 :
568 789838 : rdwr_map rdwr_idx;
569 789838 : attr_access *access = get_parm_access (rdwr_idx, var);
570 789838 : if (!access)
571 : return NULL_TREE;
572 :
573 2834 : if (access->sizarg != UINT_MAX)
574 : {
575 : /* TODO: Try to extract the range from the argument based on
576 : those of subsequent assertions or based on known calls to
577 : the current function. */
578 : return NULL_TREE;
579 : }
580 :
581 2814 : if (!access->minsize)
582 : return NULL_TREE;
583 :
584 : /* Only consider ordinary array bound at level 2 (or above if it's
585 : ever added). */
586 2003 : if (warn_array_parameter < 2 && !access->static_p)
587 : return NULL_TREE;
588 :
589 215 : if (static_array)
590 215 : *static_array = access->static_p;
591 :
592 215 : rng[0] = wi::zero (prec);
593 215 : rng[1] = wi::uhwi (access->minsize, prec);
594 : /* Multiply the array bound encoded in the attribute by the size
595 : of what the pointer argument to which it decays points to. */
596 215 : tree eltype = TREE_TYPE (TREE_TYPE (ptr));
597 215 : tree size = TYPE_SIZE_UNIT (eltype);
598 215 : if (!size || TREE_CODE (size) != INTEGER_CST)
599 : return NULL_TREE;
600 :
601 185 : rng[1] *= wi::to_wide (size, prec);
602 185 : return var;
603 789838 : }
604 :
605 : /* Initialize the object. */
606 :
607 20235494 : access_ref::access_ref ()
608 20235494 : : ref (), eval ([](tree x){ return x; }), deref (), ref_nullptr_p (false),
609 20235494 : trail1special (true), base0 (true), parmarray ()
610 : {
611 : /* Set to valid. */
612 20235494 : offrng[0] = offrng[1] = 0;
613 20235494 : offmax[0] = offmax[1] = 0;
614 : /* Invalidate. */
615 20235494 : sizrng[0] = sizrng[1] = -1;
616 20235494 : }
617 :
618 : /* Return the PHI node REF refers to or null if it doesn't. */
619 :
620 : gphi *
621 623050 : access_ref::phi () const
622 : {
623 623050 : if (!ref || TREE_CODE (ref) != SSA_NAME)
624 : return NULL;
625 :
626 620080 : gimple *def_stmt = SSA_NAME_DEF_STMT (ref);
627 620080 : if (!def_stmt || gimple_code (def_stmt) != GIMPLE_PHI)
628 : return NULL;
629 :
630 619148 : return as_a <gphi *> (def_stmt);
631 : }
632 :
633 : /* Determine the size and offset for ARG, append it to ALL_REFS, and
634 : merge the result with *THIS. Ignore ARG if SKIP_NULL is set and
635 : ARG refers to the null pointer. Return true on success and false
636 : on failure. */
637 :
638 : void
639 701195 : access_ref::merge_ref (vec<access_ref> *all_refs, tree arg, gimple *stmt,
640 : int ostype, bool skip_null,
641 : ssa_name_limit_t &snlim, pointer_query &qry)
642 : {
643 701195 : access_ref aref;
644 701195 : if (!compute_objsize_r (arg, stmt, false, ostype, &aref, snlim, &qry)
645 701195 : || aref.sizrng[0] < 0)
646 : {
647 : /* This may be a PHI with all null pointer arguments. Handle it
648 : conservatively by setting all properties to the most permissive
649 : values. */
650 59801 : base0 = false;
651 59801 : offrng[0] = offrng[1] = 0;
652 59801 : add_max_offset ();
653 59801 : set_max_size_range ();
654 59801 : return;
655 : }
656 :
657 641394 : if (all_refs)
658 : {
659 264 : access_ref dummy_ref;
660 264 : aref.get_ref (all_refs, &dummy_ref, ostype, &snlim, &qry);
661 : }
662 :
663 641394 : if (TREE_CODE (arg) == SSA_NAME)
664 534658 : qry.put_ref (arg, aref, ostype);
665 :
666 641394 : if (all_refs)
667 264 : all_refs->safe_push (aref);
668 :
669 641394 : aref.deref += deref;
670 :
671 641394 : bool merged_parmarray = aref.parmarray;
672 :
673 641394 : const bool nullp = skip_null && integer_zerop (arg);
674 641394 : const offset_int maxobjsize = wi::to_offset (max_object_size ());
675 641394 : offset_int minsize = sizrng[0];
676 :
677 641394 : if (sizrng[0] < 0)
678 : {
679 : /* If *THIS doesn't contain a meaningful result yet set it to AREF
680 : unless the argument is null and it's okay to ignore it. */
681 552132 : if (!nullp)
682 532416 : *this = aref;
683 :
684 : /* Set if the current argument refers to one or more objects of
685 : known size (or range of sizes), as opposed to referring to
686 : one or more unknown object(s). */
687 552132 : const bool arg_known_size = (aref.sizrng[0] != 0
688 1021125 : || aref.sizrng[1] != maxobjsize);
689 552132 : if (arg_known_size)
690 86588 : sizrng[0] = aref.sizrng[0];
691 :
692 : return;
693 : }
694 :
695 : /* Disregard null pointers in PHIs with two or more arguments.
696 : TODO: Handle this better! */
697 89262 : if (nullp)
698 : return;
699 :
700 86164 : const bool known_size = (sizrng[0] != 0 || sizrng[1] != maxobjsize);
701 :
702 168806 : if (known_size && aref.sizrng[0] < minsize)
703 27508 : minsize = aref.sizrng[0];
704 :
705 : /* Extend the size and offset of *THIS to account for AREF. The result
706 : can be cached but results in false negatives. */
707 :
708 86164 : offset_int orng[2];
709 86164 : if (sizrng[1] < aref.sizrng[1])
710 : {
711 27404 : orng[0] = offrng[0];
712 27404 : orng[1] = offrng[1];
713 27404 : *this = aref;
714 : }
715 : else
716 : {
717 58760 : orng[0] = aref.offrng[0];
718 58760 : orng[1] = aref.offrng[1];
719 : }
720 :
721 86164 : if (orng[0] < offrng[0])
722 7750 : offrng[0] = orng[0];
723 86164 : if (offrng[1] < orng[1])
724 21832 : offrng[1] = orng[1];
725 :
726 : /* Reset the PHI's BASE0 flag if any of the nonnull arguments
727 : refers to an object at an unknown offset. */
728 86164 : if (!aref.base0)
729 17968 : base0 = false;
730 :
731 86164 : sizrng[0] = minsize;
732 86164 : parmarray = merged_parmarray;
733 :
734 86164 : return;
735 : }
736 :
737 : /* Determine and return the largest object to which *THIS refers. If
738 : *THIS refers to a PHI and PREF is nonnull, fill *PREF with the details
739 : of the object determined by compute_objsize(ARG, OSTYPE) for each PHI
740 : argument ARG. */
741 :
742 : tree
743 619144 : access_ref::get_ref (vec<access_ref> *all_refs,
744 : access_ref *pref /* = NULL */,
745 : int ostype /* = 1 */,
746 : ssa_name_limit_t *psnlim /* = NULL */,
747 : pointer_query *qry /* = NULL */) const
748 : {
749 619144 : if (!ref || TREE_CODE (ref) != SSA_NAME)
750 : return NULL;
751 :
752 : /* FIXME: Calling get_ref() with a null PSNLIM is dangerous and might
753 : cause unbounded recursion. */
754 618938 : ssa_name_limit_t snlim_buf;
755 618938 : if (!psnlim)
756 82 : psnlim = &snlim_buf;
757 :
758 618938 : pointer_query empty_qry;
759 618938 : if (!qry)
760 82 : qry = &empty_qry;
761 :
762 618938 : if (gimple *def_stmt = SSA_NAME_DEF_STMT (ref))
763 : {
764 618938 : if (is_gimple_assign (def_stmt))
765 : {
766 0 : tree_code code = gimple_assign_rhs_code (def_stmt);
767 0 : if (code != MIN_EXPR && code != MAX_EXPR)
768 : return NULL_TREE;
769 :
770 0 : access_ref aref;
771 0 : tree arg1 = gimple_assign_rhs1 (def_stmt);
772 0 : aref.merge_ref (all_refs, arg1, def_stmt, ostype, false,
773 : *psnlim, *qry);
774 :
775 0 : tree arg2 = gimple_assign_rhs2 (def_stmt);
776 0 : aref.merge_ref (all_refs, arg2, def_stmt, ostype, false,
777 : *psnlim, *qry);
778 :
779 0 : if (pref && pref != this)
780 : {
781 0 : tree ref = pref->ref;
782 0 : *pref = aref;
783 0 : pref->ref = ref;
784 : }
785 :
786 0 : return aref.ref;
787 : }
788 : }
789 : else
790 : return NULL_TREE;
791 :
792 618938 : gphi *phi_stmt = this->phi ();
793 618938 : if (!phi_stmt)
794 23 : return ref;
795 :
796 618915 : if (!psnlim->visit_phi (ref))
797 : return NULL_TREE;
798 :
799 : /* The conservative result of the PHI reflecting the offset and size
800 : of the largest PHI argument, regardless of whether or not they all
801 : refer to the same object. */
802 559098 : access_ref phi_ref;
803 559098 : if (pref)
804 : {
805 : /* The identity of the object has not been determined yet but
806 : PREF->REF is set by the caller to the PHI for convenience.
807 : The size is negative/invalid and the offset is zero (it's
808 : updated only after the identity of the object has been
809 : established). */
810 559098 : gcc_assert (pref->sizrng[0] < 0);
811 559098 : gcc_assert (pref->offrng[0] == 0 && pref->offrng[1] == 0);
812 :
813 559098 : phi_ref = *pref;
814 : }
815 :
816 559098 : const offset_int maxobjsize = wi::to_offset (max_object_size ());
817 559098 : const unsigned nargs = gimple_phi_num_args (phi_stmt);
818 739455 : for (unsigned i = 0; i < nargs; ++i)
819 : {
820 701195 : access_ref phi_arg_ref;
821 701195 : bool skip_null = i || i + 1 < nargs;
822 701195 : tree arg = gimple_phi_arg_def (phi_stmt, i);
823 701195 : phi_ref.merge_ref (all_refs, arg, phi_stmt, ostype, skip_null,
824 : *psnlim, *qry);
825 :
826 701195 : if (!phi_ref.base0
827 1222033 : && phi_ref.sizrng[0] == 0
828 1222033 : && phi_ref.sizrng[1] >= maxobjsize)
829 : /* When an argument results in the most permissive result,
830 : the remaining arguments cannot constrain it. Short-circuit
831 : the evaluation. */
832 : break;
833 : }
834 :
835 559098 : if (phi_ref.sizrng[0] < 0)
836 : {
837 : /* Fail if none of the PHI's arguments resulted in updating PHI_REF
838 : (perhaps because they have all been already visited by prior
839 : recursive calls). */
840 0 : psnlim->leave_phi (ref);
841 0 : return NULL_TREE;
842 : }
843 :
844 : /* Avoid changing *THIS. */
845 559098 : if (pref && pref != this)
846 : {
847 : /* Keep the SSA_NAME of the PHI unchanged so that all PHI arguments
848 : can be referred to later if necessary. This is useful even if
849 : they all refer to the same object. */
850 559098 : tree ref = pref->ref;
851 559098 : *pref = phi_ref;
852 559098 : pref->ref = ref;
853 : }
854 :
855 559098 : psnlim->leave_phi (ref);
856 :
857 559098 : return phi_ref.ref;
858 618938 : }
859 :
860 : /* Return the maximum amount of space remaining and if non-null, set
861 : argument to the minimum. */
862 :
863 : offset_int
864 15955135 : access_ref::size_remaining (offset_int *pmin /* = NULL */) const
865 : {
866 15955135 : offset_int minbuf;
867 15955135 : if (!pmin)
868 11714205 : pmin = &minbuf;
869 :
870 15955135 : if (sizrng[0] < 0)
871 : {
872 : /* If the identity of the object hasn't been determined return
873 : the maximum size range. */
874 0 : *pmin = 0;
875 0 : return wi::to_offset (max_object_size ());
876 : }
877 :
878 : /* add_offset() ensures the offset range isn't inverted. */
879 15955135 : gcc_checking_assert (offrng[0] <= offrng[1]);
880 :
881 15955135 : if (base0)
882 : {
883 : /* The offset into referenced object is zero-based (i.e., it's
884 : not referenced by a pointer into middle of some unknown object). */
885 10350247 : if (offrng[0] < 0 && offrng[1] < 0)
886 : {
887 : /* If the offset is negative the remaining size is zero. */
888 2509 : *pmin = 0;
889 2509 : return 0;
890 : }
891 :
892 10347738 : if (sizrng[1] <= offrng[0])
893 : {
894 : /* If the starting offset is greater than or equal to the upper
895 : bound on the size of the object, the space remaining is zero.
896 : As a special case, if it's equal, set *PMIN to -1 to let
897 : the caller know the offset is valid and just past the end. */
898 77047 : *pmin = sizrng[1] == offrng[0] ? -1 : 0;
899 72463 : return 0;
900 : }
901 :
902 : /* Otherwise return the size minus the lower bound of the offset. */
903 10275275 : offset_int or0 = offrng[0] < 0 ? 0 : offrng[0];
904 :
905 10275275 : *pmin = sizrng[0] - or0;
906 10275275 : return sizrng[1] - or0;
907 : }
908 :
909 : /* The offset to the referenced object isn't zero-based (i.e., it may
910 : refer to a byte other than the first. The size of such an object
911 : is constrained only by the size of the address space (the result
912 : of max_object_size()). */
913 5604888 : if (sizrng[1] <= offrng[0])
914 : {
915 5 : *pmin = 0;
916 5 : return 0;
917 : }
918 :
919 5604883 : offset_int or0 = offrng[0] < 0 ? 0 : offrng[0];
920 :
921 5604883 : *pmin = sizrng[0] - or0;
922 5604883 : return sizrng[1] - or0;
923 : }
924 :
925 : /* Return true if the offset and object size are in range for SIZE. */
926 :
927 : bool
928 617905 : access_ref::offset_in_range (const offset_int &size) const
929 : {
930 617905 : if (size_remaining () < size)
931 : return false;
932 :
933 605912 : if (base0)
934 63294 : return offmax[0] >= 0 && offmax[1] <= sizrng[1];
935 :
936 542636 : offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
937 542636 : return offmax[0] > -maxoff && offmax[1] < maxoff;
938 : }
939 :
940 : /* Add the range [MIN, MAX] to the offset range. For known objects (with
941 : zero-based offsets) at least one of whose offset's bounds is in range,
942 : constrain the other (or both) to the bounds of the object (i.e., zero
943 : and the upper bound of its size). This improves the quality of
944 : diagnostics. */
945 :
946 8285409 : void access_ref::add_offset (const offset_int &min, const offset_int &max)
947 : {
948 8285409 : if (min <= max)
949 : {
950 : /* To add an ordinary range just add it to the bounds. */
951 8063092 : offrng[0] += min;
952 8063092 : offrng[1] += max;
953 : }
954 222317 : else if (!base0)
955 : {
956 : /* To add an inverted range to an offset to an unknown object
957 : expand it to the maximum. */
958 193253 : add_max_offset ();
959 4651366 : return;
960 : }
961 : else
962 : {
963 : /* To add an inverted range to an offset to an known object set
964 : the upper bound to the maximum representable offset value
965 : (which may be greater than MAX_OBJECT_SIZE).
966 : The lower bound is either the sum of the current offset and
967 : MIN when abs(MAX) is greater than the former, or zero otherwise.
968 : Zero because then the inverted range includes the negative of
969 : the lower bound. */
970 29064 : offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
971 29064 : offrng[1] = maxoff;
972 :
973 29064 : if (max >= 0)
974 : {
975 0 : offrng[0] = 0;
976 0 : if (offmax[0] > 0)
977 0 : offmax[0] = 0;
978 0 : return;
979 : }
980 :
981 29064 : offset_int absmax = wi::abs (max);
982 29064 : if (offrng[0] < absmax)
983 : {
984 26610 : offrng[0] += min;
985 : /* Cap the lower bound at the upper (set to MAXOFF above)
986 : to avoid inadvertently recreating an inverted range. */
987 26610 : if (offrng[1] < offrng[0])
988 2 : offrng[0] = offrng[1];
989 : }
990 : else
991 2454 : offrng[0] = 0;
992 : }
993 :
994 : /* Set the minimum and maximmum computed so far. */
995 8092156 : if (offrng[1] < 0 && offrng[1] < offmax[0])
996 30598 : offmax[0] = offrng[1];
997 8092156 : if (offrng[0] > 0 && offrng[0] > offmax[1])
998 2900255 : offmax[1] = offrng[0];
999 :
1000 8092156 : if (!base0)
1001 : return;
1002 :
1003 : /* When referencing a known object check to see if the offset computed
1004 : so far is in bounds... */
1005 3827296 : offset_int remrng[2];
1006 3827296 : remrng[1] = size_remaining (remrng);
1007 3827296 : if (remrng[1] > 0 || remrng[0] < 0)
1008 : {
1009 : /* ...if so, constrain it so that neither bound exceeds the size of
1010 : the object. Out of bounds offsets are left unchanged, and, for
1011 : better or worse, become in bounds later. They should be detected
1012 : and diagnosed at the point they first become invalid by
1013 : -Warray-bounds. */
1014 3823900 : if (offrng[0] < 0)
1015 109026 : offrng[0] = 0;
1016 3823900 : if (offrng[1] > sizrng[1])
1017 138482 : offrng[1] = sizrng[1];
1018 : }
1019 : }
1020 :
1021 : /* Issue one inform message describing each target of an access REF.
1022 : WRITE is set for a write access and clear for a read access. */
1023 :
1024 : void
1025 3580 : access_ref::inform_access (access_mode mode, int ostype /* = 1 */) const
1026 : {
1027 3580 : const access_ref &aref = *this;
1028 3580 : if (!aref.ref)
1029 3081 : return;
1030 :
1031 3439 : if (phi ())
1032 : {
1033 : /* Set MAXREF to refer to the largest object and fill ALL_REFS
1034 : with data for all objects referenced by the PHI arguments. */
1035 82 : access_ref maxref;
1036 82 : auto_vec<access_ref> all_refs;
1037 82 : if (!get_ref (&all_refs, &maxref, ostype))
1038 : return;
1039 :
1040 82 : if (all_refs.length ())
1041 : {
1042 : /* Except for MAXREF, the rest of the arguments' offsets need not
1043 : reflect one added to the PHI itself. Determine the latter from
1044 : MAXREF on which the result is based. */
1045 82 : const offset_int orng[] =
1046 : {
1047 82 : offrng[0] - maxref.offrng[0],
1048 82 : wi::smax (offrng[1] - maxref.offrng[1], offrng[0]),
1049 : };
1050 :
1051 : /* Add the final PHI's offset to that of each of the arguments
1052 : and recurse to issue an inform message for it. */
1053 692 : for (unsigned i = 0; i != all_refs.length (); ++i)
1054 : {
1055 : /* Skip any PHIs; those could lead to infinite recursion. */
1056 264 : if (all_refs[i].phi ())
1057 35 : continue;
1058 :
1059 229 : all_refs[i].add_offset (orng[0], orng[1]);
1060 229 : all_refs[i].inform_access (mode, ostype);
1061 : }
1062 82 : return;
1063 : }
1064 82 : }
1065 :
1066 : /* Convert offset range and avoid including a zero range since it
1067 : isn't necessarily meaningful. */
1068 3357 : HOST_WIDE_INT diff_min = tree_to_shwi (TYPE_MIN_VALUE (ptrdiff_type_node));
1069 3357 : HOST_WIDE_INT diff_max = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
1070 3357 : HOST_WIDE_INT minoff;
1071 3357 : HOST_WIDE_INT maxoff = diff_max;
1072 3357 : if (wi::fits_shwi_p (aref.offrng[0]))
1073 3357 : minoff = aref.offrng[0].to_shwi ();
1074 : else
1075 0 : minoff = aref.offrng[0] < 0 ? diff_min : diff_max;
1076 :
1077 3357 : if (wi::fits_shwi_p (aref.offrng[1]))
1078 3354 : maxoff = aref.offrng[1].to_shwi ();
1079 :
1080 3357 : if (maxoff <= diff_min || maxoff >= diff_max)
1081 : /* Avoid mentioning an upper bound that's equal to or in excess
1082 : of the maximum of ptrdiff_t. */
1083 124 : maxoff = minoff;
1084 :
1085 : /* Convert size range and always include it since all sizes are
1086 : meaningful. */
1087 3357 : unsigned long long minsize = 0, maxsize = 0;
1088 3357 : if (wi::fits_shwi_p (aref.sizrng[0])
1089 3357 : && wi::fits_shwi_p (aref.sizrng[1]))
1090 : {
1091 3357 : minsize = aref.sizrng[0].to_shwi ();
1092 3357 : maxsize = aref.sizrng[1].to_shwi ();
1093 : }
1094 :
1095 : /* SIZRNG doesn't necessarily have the same range as the allocation
1096 : size determined by gimple_call_alloc_size (). */
1097 3357 : char sizestr[80];
1098 3357 : if (minsize == maxsize)
1099 3102 : sprintf (sizestr, "%llu", minsize);
1100 : else
1101 255 : sprintf (sizestr, "[%llu, %llu]", minsize, maxsize);
1102 :
1103 3357 : char offstr[80];
1104 3357 : if (minoff == 0
1105 3357 : && (maxoff == 0 || aref.sizrng[1] <= maxoff))
1106 979 : offstr[0] = '\0';
1107 2378 : else if (minoff == maxoff)
1108 2113 : sprintf (offstr, "%lli", (long long) minoff);
1109 : else
1110 265 : sprintf (offstr, "[%lli, %lli]", (long long) minoff, (long long) maxoff);
1111 :
1112 3357 : location_t loc = UNKNOWN_LOCATION;
1113 :
1114 3357 : tree ref = this->ref;
1115 3357 : tree allocfn = NULL_TREE;
1116 3357 : if (TREE_CODE (ref) == SSA_NAME)
1117 : {
1118 772 : gimple *stmt = SSA_NAME_DEF_STMT (ref);
1119 772 : if (!stmt)
1120 : return;
1121 :
1122 772 : if (is_gimple_call (stmt))
1123 : {
1124 732 : loc = gimple_location (stmt);
1125 732 : if (gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
1126 : {
1127 : /* Strip the SSA_NAME suffix from the variable name and
1128 : recreate an identifier with the VLA's original name. */
1129 23 : ref = gimple_call_lhs (stmt);
1130 23 : if (SSA_NAME_IDENTIFIER (ref))
1131 : {
1132 22 : ref = SSA_NAME_IDENTIFIER (ref);
1133 22 : const char *id = IDENTIFIER_POINTER (ref);
1134 22 : size_t len = strcspn (id, ".$");
1135 22 : if (!len)
1136 0 : len = strlen (id);
1137 22 : ref = get_identifier_with_length (id, len);
1138 : }
1139 : }
1140 : else
1141 : {
1142 : /* Except for VLAs, retrieve the allocation function. */
1143 709 : allocfn = gimple_call_fndecl (stmt);
1144 709 : if (!allocfn)
1145 7 : allocfn = gimple_call_fn (stmt);
1146 709 : if (TREE_CODE (allocfn) == SSA_NAME)
1147 : {
1148 : /* For an ALLOC_CALL via a function pointer make a small
1149 : effort to determine the destination of the pointer. */
1150 4 : gimple *def = SSA_NAME_DEF_STMT (allocfn);
1151 4 : if (gimple_assign_single_p (def))
1152 : {
1153 3 : tree rhs = gimple_assign_rhs1 (def);
1154 3 : if (DECL_P (rhs))
1155 : allocfn = rhs;
1156 2 : else if (TREE_CODE (rhs) == COMPONENT_REF)
1157 1 : allocfn = TREE_OPERAND (rhs, 1);
1158 : }
1159 : }
1160 : }
1161 : }
1162 40 : else if (gimple_nop_p (stmt))
1163 : /* Handle DECL_PARM below. */
1164 5 : ref = SSA_NAME_VAR (ref);
1165 35 : else if (is_gimple_assign (stmt)
1166 35 : && (gimple_assign_rhs_code (stmt) == MIN_EXPR
1167 18 : || gimple_assign_rhs_code (stmt) == MAX_EXPR))
1168 : {
1169 : /* MIN or MAX_EXPR here implies a reference to a known object
1170 : and either an unknown or distinct one (the latter being
1171 : the result of an invalid relational expression). Determine
1172 : the identity of the former and point to it in the note.
1173 : TODO: Consider merging with PHI handling. */
1174 105 : access_ref arg_ref[2];
1175 35 : tree arg = gimple_assign_rhs1 (stmt);
1176 35 : compute_objsize (arg, /* ostype = */ 1 , &arg_ref[0]);
1177 35 : arg = gimple_assign_rhs2 (stmt);
1178 35 : compute_objsize (arg, /* ostype = */ 1 , &arg_ref[1]);
1179 :
1180 : /* Use the argument that references a known object with more
1181 : space remaining. */
1182 35 : const bool idx
1183 35 : = (!arg_ref[0].ref || !arg_ref[0].base0
1184 52 : || (arg_ref[0].base0 && arg_ref[1].base0
1185 11 : && (arg_ref[0].size_remaining ()
1186 22 : < arg_ref[1].size_remaining ())));
1187 :
1188 35 : arg_ref[idx].offrng[0] = offrng[0];
1189 35 : arg_ref[idx].offrng[1] = offrng[1];
1190 35 : arg_ref[idx].inform_access (mode);
1191 35 : return;
1192 : }
1193 : }
1194 :
1195 3322 : if (DECL_P (ref))
1196 2482 : loc = DECL_SOURCE_LOCATION (ref);
1197 840 : else if (EXPR_P (ref) && EXPR_HAS_LOCATION (ref))
1198 0 : loc = EXPR_LOCATION (ref);
1199 840 : else if (TREE_CODE (ref) != IDENTIFIER_NODE
1200 840 : && TREE_CODE (ref) != SSA_NAME)
1201 : {
1202 108 : if (TREE_CODE (ref) == INTEGER_CST && ref_nullptr_p)
1203 : {
1204 5 : if (mode == access_read_write || mode == access_write_only)
1205 1 : inform (loc, "destination object is likely at address zero");
1206 : else
1207 4 : inform (loc, "source object is likely at address zero");
1208 : }
1209 : return;
1210 : }
1211 :
1212 3214 : if (mode == access_read_write || mode == access_write_only)
1213 : {
1214 1625 : if (allocfn == NULL_TREE)
1215 : {
1216 1422 : if (*offstr)
1217 1119 : inform (loc, "at offset %s into destination object %qE of size %s",
1218 : offstr, ref, sizestr);
1219 : else
1220 303 : inform (loc, "destination object %qE of size %s", ref, sizestr);
1221 : return;
1222 : }
1223 :
1224 203 : if (*offstr)
1225 55 : inform (loc,
1226 : "at offset %s into destination object of size %s "
1227 : "allocated by %qE", offstr, sizestr, allocfn);
1228 : else
1229 148 : inform (loc, "destination object of size %s allocated by %qE",
1230 : sizestr, allocfn);
1231 : return;
1232 : }
1233 :
1234 1589 : if (mode == access_read_only)
1235 : {
1236 379 : if (allocfn == NULL_TREE)
1237 : {
1238 372 : if (*offstr)
1239 249 : inform (loc, "at offset %s into source object %qE of size %s",
1240 : offstr, ref, sizestr);
1241 : else
1242 123 : inform (loc, "source object %qE of size %s", ref, sizestr);
1243 :
1244 : return;
1245 : }
1246 :
1247 7 : if (*offstr)
1248 0 : inform (loc,
1249 : "at offset %s into source object of size %s allocated by %qE",
1250 : offstr, sizestr, allocfn);
1251 : else
1252 7 : inform (loc, "source object of size %s allocated by %qE",
1253 : sizestr, allocfn);
1254 : return;
1255 : }
1256 :
1257 1210 : if (allocfn == NULL_TREE)
1258 : {
1259 711 : if (*offstr)
1260 588 : inform (loc, "at offset %s into object %qE of size %s",
1261 : offstr, ref, sizestr);
1262 : else
1263 123 : inform (loc, "object %qE of size %s", ref, sizestr);
1264 :
1265 : return;
1266 : }
1267 :
1268 499 : if (*offstr)
1269 252 : inform (loc,
1270 : "at offset %s into object of size %s allocated by %qE",
1271 : offstr, sizestr, allocfn);
1272 : else
1273 247 : inform (loc, "object of size %s allocated by %qE",
1274 : sizestr, allocfn);
1275 : }
1276 :
1277 : /* Dump *THIS to FILE. */
1278 :
1279 : void
1280 0 : access_ref::dump (FILE *file) const
1281 : {
1282 0 : for (int i = deref; i < 0; ++i)
1283 0 : fputc ('&', file);
1284 :
1285 0 : for (int i = 0; i < deref; ++i)
1286 0 : fputc ('*', file);
1287 :
1288 0 : if (gphi *phi_stmt = phi ())
1289 : {
1290 0 : fputs ("PHI <", file);
1291 0 : unsigned nargs = gimple_phi_num_args (phi_stmt);
1292 0 : for (unsigned i = 0; i != nargs; ++i)
1293 : {
1294 0 : tree arg = gimple_phi_arg_def (phi_stmt, i);
1295 0 : print_generic_expr (file, arg);
1296 0 : if (i + 1 < nargs)
1297 0 : fputs (", ", file);
1298 : }
1299 0 : fputc ('>', file);
1300 : }
1301 : else
1302 0 : print_generic_expr (file, ref);
1303 :
1304 0 : if (offrng[0] != offrng[1])
1305 0 : fprintf (file, " + [%lli, %lli]",
1306 0 : (long long) offrng[0].to_shwi (),
1307 0 : (long long) offrng[1].to_shwi ());
1308 0 : else if (offrng[0] != 0)
1309 0 : fprintf (file, " %c %lli",
1310 0 : offrng[0] < 0 ? '-' : '+',
1311 0 : (long long) offrng[0].to_shwi ());
1312 :
1313 0 : if (base0)
1314 0 : fputs (" (base0)", file);
1315 :
1316 0 : fputs ("; size: ", file);
1317 0 : if (sizrng[0] != sizrng[1])
1318 : {
1319 0 : offset_int maxsize = wi::to_offset (max_object_size ());
1320 0 : if (sizrng[0] == 0 && sizrng[1] >= maxsize)
1321 0 : fputs ("unknown", file);
1322 : else
1323 0 : fprintf (file, "[%llu, %llu]",
1324 0 : (unsigned long long) sizrng[0].to_uhwi (),
1325 0 : (unsigned long long) sizrng[1].to_uhwi ());
1326 : }
1327 0 : else if (sizrng[0] != 0)
1328 0 : fprintf (file, "%llu",
1329 0 : (unsigned long long) sizrng[0].to_uhwi ());
1330 :
1331 0 : fputc ('\n', file);
1332 0 : }
1333 :
1334 : /* Set the access to at most MAXWRITE and MAXREAD bytes, and at least 1
1335 : when MINWRITE or MINREAD, respectively, is set. */
1336 752811 : access_data::access_data (range_query *query, gimple *stmt, access_mode mode,
1337 : tree maxwrite /* = NULL_TREE */,
1338 : bool minwrite /* = false */,
1339 : tree maxread /* = NULL_TREE */,
1340 : bool minread /* = false */)
1341 752811 : : stmt (stmt), call (), dst (), src (), mode (mode), ostype ()
1342 : {
1343 752811 : set_bound (dst_bndrng, maxwrite, minwrite, query, stmt);
1344 752811 : set_bound (src_bndrng, maxread, minread, query, stmt);
1345 752811 : }
1346 :
1347 : /* Set the access to at most MAXWRITE and MAXREAD bytes, and at least 1
1348 : when MINWRITE or MINREAD, respectively, is set. */
1349 108 : access_data::access_data (range_query *query, tree expr, access_mode mode,
1350 : tree maxwrite /* = NULL_TREE */,
1351 : bool minwrite /* = false */,
1352 : tree maxread /* = NULL_TREE */,
1353 : bool minread /* = false */)
1354 108 : : stmt (), call (expr), dst (), src (), mode (mode), ostype ()
1355 : {
1356 108 : set_bound (dst_bndrng, maxwrite, minwrite, query, stmt);
1357 108 : set_bound (src_bndrng, maxread, minread, query, stmt);
1358 108 : }
1359 :
1360 : /* Set BNDRNG to the range of BOUND for the statement STMT. */
1361 :
1362 : void
1363 1505838 : access_data::set_bound (offset_int bndrng[2], tree bound, bool minaccess,
1364 : range_query *query, gimple *stmt)
1365 : {
1366 : /* Set the default bounds of the access and adjust below. */
1367 2670765 : bndrng[0] = minaccess ? 1 : 0;
1368 1505838 : bndrng[1] = HOST_WIDE_INT_M1U;
1369 :
1370 : /* When BOUND is nonnull and a range can be extracted from it,
1371 : set the bounds of the access to reflect both it and MINACCESS.
1372 : BNDRNG[0] is the size of the minimum access. */
1373 1505838 : tree rng[2];
1374 1505838 : if (bound && get_size_range (query, bound, stmt, rng, SR_ALLOW_ZERO))
1375 : {
1376 49432 : bndrng[0] = wi::to_offset (rng[0]);
1377 49432 : bndrng[1] = wi::to_offset (rng[1]);
1378 56475 : bndrng[0] = bndrng[0] > 0 && minaccess ? 1 : 0;
1379 : }
1380 1505838 : }
1381 :
1382 : /* Set a bit for the PHI in VISITED and return true if it wasn't
1383 : already set. */
1384 :
1385 : bool
1386 758627 : ssa_name_limit_t::visit_phi (tree ssa_name)
1387 : {
1388 758627 : if (!visited)
1389 523868 : visited = BITMAP_ALLOC (NULL);
1390 :
1391 : /* Return false if SSA_NAME has already been visited. */
1392 758627 : return bitmap_set_bit (visited, SSA_NAME_VERSION (ssa_name));
1393 : }
1394 :
1395 : /* Clear a bit for the PHI in VISITED. */
1396 :
1397 : void
1398 559098 : ssa_name_limit_t::leave_phi (tree ssa_name)
1399 : {
1400 : /* Return false if SSA_NAME has already been visited. */
1401 559098 : bitmap_clear_bit (visited, SSA_NAME_VERSION (ssa_name));
1402 559098 : }
1403 :
1404 : /* Return false if the SSA_NAME chain length counter has reached
1405 : the limit, otherwise increment the counter and return true. */
1406 :
1407 : bool
1408 6908660 : ssa_name_limit_t::next ()
1409 : {
1410 : /* Return a negative value to let caller avoid recursing beyond
1411 : the specified limit. */
1412 6908660 : if (ssa_def_max == 0)
1413 : return false;
1414 :
1415 6908651 : --ssa_def_max;
1416 6908651 : return true;
1417 : }
1418 :
1419 : /* If the SSA_NAME has already been "seen" return a positive value.
1420 : Otherwise add it to VISITED. If the SSA_NAME limit has been
1421 : reached, return a negative value. Otherwise return zero. */
1422 :
1423 : int
1424 139712 : ssa_name_limit_t::next_phi (tree ssa_name)
1425 : {
1426 139712 : {
1427 139712 : gimple *def_stmt = SSA_NAME_DEF_STMT (ssa_name);
1428 : /* Return a positive value if the PHI has already been visited. */
1429 139712 : if (gimple_code (def_stmt) == GIMPLE_PHI
1430 139712 : && !visit_phi (ssa_name))
1431 : return 1;
1432 : }
1433 :
1434 : /* Return a negative value to let caller avoid recursing beyond
1435 : the specified limit. */
1436 100514 : if (ssa_def_max == 0)
1437 : return -1;
1438 :
1439 100514 : --ssa_def_max;
1440 :
1441 100514 : return 0;
1442 : }
1443 :
1444 12624399 : ssa_name_limit_t::~ssa_name_limit_t ()
1445 : {
1446 12624399 : if (visited)
1447 523868 : BITMAP_FREE (visited);
1448 12624399 : }
1449 :
1450 : /* Default ctor. Initialize object with pointers to the range_query
1451 : instance to use or null. */
1452 :
1453 14686532 : pointer_query::pointer_query (range_query *qry /* = NULL */)
1454 14686532 : : rvals (qry), hits (), misses (), failures (), depth (), max_depth (),
1455 14686532 : var_cache ()
1456 : {
1457 : /* No op. */
1458 14686532 : }
1459 :
1460 : /* Return a pointer to the cached access_ref instance for the SSA_NAME
1461 : PTR if it's there or null otherwise. */
1462 :
1463 : const access_ref *
1464 6908651 : pointer_query::get_ref (tree ptr, int ostype /* = 1 */) const
1465 : {
1466 6908651 : unsigned version = SSA_NAME_VERSION (ptr);
1467 6908651 : unsigned idx = version << 1 | (ostype & 1);
1468 6908651 : if (var_cache.indices.length () <= idx)
1469 : {
1470 3080892 : ++misses;
1471 3080892 : return NULL;
1472 : }
1473 :
1474 3827759 : unsigned cache_idx = var_cache.indices[idx];
1475 3827759 : if (var_cache.access_refs.length () <= cache_idx)
1476 : {
1477 0 : ++misses;
1478 0 : return NULL;
1479 : }
1480 :
1481 3827759 : const access_ref &cache_ref = var_cache.access_refs[cache_idx];
1482 3827759 : if (cache_ref.ref)
1483 : {
1484 1816024 : ++hits;
1485 1816024 : return &cache_ref;
1486 : }
1487 :
1488 2011735 : ++misses;
1489 2011735 : return NULL;
1490 : }
1491 :
1492 : /* Retrieve the access_ref instance for a variable from the cache if it's
1493 : there or compute it and insert it into the cache if it's nonnonull. */
1494 :
1495 : bool
1496 8785351 : pointer_query::get_ref (tree ptr, gimple *stmt, access_ref *pref,
1497 : int ostype /* = 1 */)
1498 : {
1499 8785351 : const unsigned version
1500 8785351 : = TREE_CODE (ptr) == SSA_NAME ? SSA_NAME_VERSION (ptr) : 0;
1501 :
1502 2181219 : if (version)
1503 : {
1504 2181219 : unsigned idx = version << 1 | (ostype & 1);
1505 2181219 : if (idx < var_cache.indices.length ())
1506 : {
1507 1117013 : unsigned cache_idx = var_cache.indices[idx] - 1;
1508 1117013 : if (cache_idx < var_cache.access_refs.length ()
1509 1117013 : && var_cache.access_refs[cache_idx].ref)
1510 : {
1511 0 : ++hits;
1512 0 : *pref = var_cache.access_refs[cache_idx];
1513 0 : return true;
1514 : }
1515 : }
1516 :
1517 2181219 : ++misses;
1518 : }
1519 :
1520 8785351 : if (!compute_objsize (ptr, stmt, ostype, pref, this))
1521 : {
1522 9403 : ++failures;
1523 9403 : return false;
1524 : }
1525 :
1526 : return true;
1527 : }
1528 :
1529 : /* Add a copy of the access_ref REF for the SSA_NAME to the cache if it's
1530 : nonnull. */
1531 :
1532 : void
1533 3693556 : pointer_query::put_ref (tree ptr, const access_ref &ref, int ostype /* = 1 */)
1534 : {
1535 : /* Only add populated/valid entries. */
1536 3693556 : if (!ref.ref || ref.sizrng[0] < 0)
1537 : return;
1538 :
1539 : /* Add REF to the two-level cache. */
1540 3693556 : unsigned version = SSA_NAME_VERSION (ptr);
1541 3693556 : unsigned idx = version << 1 | (ostype & 1);
1542 :
1543 : /* Grow INDICES if necessary. An index is valid if it's nonzero.
1544 : Its value minus one is the index into ACCESS_REFS. Not all
1545 : entries are valid. */
1546 3693556 : if (var_cache.indices.length () <= idx)
1547 1911556 : var_cache.indices.safe_grow_cleared (idx + 1);
1548 :
1549 3693556 : if (!var_cache.indices[idx])
1550 5687825 : var_cache.indices[idx] = var_cache.access_refs.length () + 1;
1551 :
1552 : /* Grow ACCESS_REF cache if necessary. An entry is valid if its
1553 : REF member is nonnull. All entries except for the last two
1554 : are valid. Once nonnull, the REF value must stay unchanged. */
1555 3693556 : unsigned cache_idx = var_cache.indices[idx];
1556 3693556 : if (var_cache.access_refs.length () <= cache_idx)
1557 3352990 : var_cache.access_refs.safe_grow_cleared (cache_idx + 1);
1558 :
1559 3693556 : access_ref &cache_ref = var_cache.access_refs[cache_idx];
1560 3693556 : if (cache_ref.ref)
1561 : {
1562 340566 : gcc_checking_assert (cache_ref.ref == ref.ref);
1563 : return;
1564 : }
1565 :
1566 3352990 : cache_ref = ref;
1567 : }
1568 :
1569 : /* Flush the cache if it's nonnull. */
1570 :
1571 : void
1572 8557762 : pointer_query::flush_cache ()
1573 : {
1574 8557762 : var_cache.indices.release ();
1575 8557762 : var_cache.access_refs.release ();
1576 8557762 : }
1577 :
1578 : /* Dump statistics and, optionally, cache contents to DUMP_FILE. */
1579 :
1580 : void
1581 167 : pointer_query::dump (FILE *dump_file, bool contents /* = false */)
1582 : {
1583 167 : unsigned nused = 0, nrefs = 0;
1584 167 : unsigned nidxs = var_cache.indices.length ();
1585 167 : for (unsigned i = 0; i != nidxs; ++i)
1586 : {
1587 0 : unsigned ari = var_cache.indices[i];
1588 0 : if (!ari)
1589 0 : continue;
1590 :
1591 0 : ++nused;
1592 :
1593 0 : const access_ref &aref = var_cache.access_refs[ari];
1594 0 : if (!aref.ref)
1595 0 : continue;
1596 :
1597 0 : ++nrefs;
1598 : }
1599 :
1600 167 : fprintf (dump_file, "pointer_query counters:\n"
1601 : " index cache size: %u\n"
1602 : " index entries: %u\n"
1603 : " access cache size: %u\n"
1604 : " access entries: %u\n"
1605 : " hits: %u\n"
1606 : " misses: %u\n"
1607 : " failures: %u\n"
1608 : " max_depth: %u\n",
1609 : nidxs, nused,
1610 : var_cache.access_refs.length (), nrefs,
1611 : hits, misses, failures, max_depth);
1612 :
1613 167 : if (!contents || !nidxs)
1614 : return;
1615 :
1616 0 : fputs ("\npointer_query cache contents:\n", dump_file);
1617 :
1618 0 : for (unsigned i = 0; i != nidxs; ++i)
1619 : {
1620 0 : unsigned ari = var_cache.indices[i];
1621 0 : if (!ari)
1622 0 : continue;
1623 :
1624 0 : const access_ref &aref = var_cache.access_refs[ari];
1625 0 : if (!aref.ref)
1626 0 : continue;
1627 :
1628 : /* The level-1 cache index corresponds to the SSA_NAME_VERSION
1629 : shifted left by one and ORed with the Object Size Type in
1630 : the lowest bit. Print the two separately. */
1631 0 : unsigned ver = i >> 1;
1632 0 : unsigned ost = i & 1;
1633 :
1634 0 : fprintf (dump_file, " %u.%u[%u]: ", ver, ost, ari);
1635 0 : if (tree name = ssa_name (ver))
1636 : {
1637 0 : print_generic_expr (dump_file, name);
1638 0 : fputs (" = ", dump_file);
1639 : }
1640 : else
1641 0 : fprintf (dump_file, " _%u = ", ver);
1642 :
1643 0 : aref.dump (dump_file);
1644 : }
1645 :
1646 0 : fputc ('\n', dump_file);
1647 : }
1648 :
1649 : /* A helper of compute_objsize_r() to determine the size from an assignment
1650 : statement STMT with the RHS of either MIN_EXPR or MAX_EXPR. On success
1651 : set PREF->REF to the operand with more or less space remaining,
1652 : respectively, if both refer to the same (sub)object, or to PTR if they
1653 : might not, and return true. Otherwise, if the identity of neither
1654 : operand can be determined, return false. */
1655 :
1656 : static bool
1657 1323 : handle_min_max_size (tree ptr, int ostype, access_ref *pref,
1658 : ssa_name_limit_t &snlim, pointer_query *qry)
1659 : {
1660 1323 : gimple *stmt = SSA_NAME_DEF_STMT (ptr);
1661 1323 : const tree_code code = gimple_assign_rhs_code (stmt);
1662 :
1663 : /* In a valid MAX_/MIN_EXPR both operands must refer to the same array.
1664 : Determine the size/offset of each and use the one with more or less
1665 : space remaining, respectively. If either fails, use the information
1666 : determined from the other instead, adjusted up or down as appropriate
1667 : for the expression. */
1668 1323 : access_ref aref[2] = { *pref, *pref };
1669 1323 : tree arg1 = gimple_assign_rhs1 (stmt);
1670 1323 : if (!compute_objsize_r (arg1, stmt, false, ostype, &aref[0], snlim, qry))
1671 : {
1672 7 : aref[0].base0 = false;
1673 7 : aref[0].offrng[0] = aref[0].offrng[1] = 0;
1674 7 : aref[0].add_max_offset ();
1675 7 : aref[0].set_max_size_range ();
1676 : }
1677 :
1678 1323 : tree arg2 = gimple_assign_rhs2 (stmt);
1679 1323 : if (!compute_objsize_r (arg2, stmt, false, ostype, &aref[1], snlim, qry))
1680 : {
1681 2 : aref[1].base0 = false;
1682 2 : aref[1].offrng[0] = aref[1].offrng[1] = 0;
1683 2 : aref[1].add_max_offset ();
1684 2 : aref[1].set_max_size_range ();
1685 : }
1686 :
1687 1323 : if (!aref[0].ref && !aref[1].ref)
1688 : /* Fail if the identity of neither argument could be determined. */
1689 : return false;
1690 :
1691 1323 : bool i0 = false;
1692 1323 : if (aref[0].ref && aref[0].base0)
1693 : {
1694 128 : if (aref[1].ref && aref[1].base0)
1695 : {
1696 : /* If the object referenced by both arguments has been determined
1697 : set *PREF to the one with more or less space remainng, whichever
1698 : is appropriate for CODE.
1699 : TODO: Indicate when the objects are distinct so it can be
1700 : diagnosed. */
1701 89 : i0 = code == MAX_EXPR;
1702 89 : const bool i1 = !i0;
1703 :
1704 89 : if (aref[i0].size_remaining () < aref[i1].size_remaining ())
1705 23 : *pref = aref[i1];
1706 : else
1707 66 : *pref = aref[i0];
1708 :
1709 89 : if (aref[i0].ref != aref[i1].ref)
1710 : /* If the operands don't refer to the same (sub)object set
1711 : PREF->REF to the SSA_NAME from which STMT was obtained
1712 : so that both can be identified in a diagnostic. */
1713 63 : pref->ref = ptr;
1714 :
1715 : return true;
1716 : }
1717 :
1718 : /* If only the object referenced by one of the arguments could be
1719 : determined, use it and... */
1720 39 : *pref = aref[0];
1721 39 : i0 = true;
1722 39 : }
1723 : else
1724 1195 : *pref = aref[1];
1725 :
1726 1234 : const bool i1 = !i0;
1727 : /* ...see if the offset obtained from the other pointer can be used
1728 : to tighten up the bound on the offset obtained from the first. */
1729 667 : if ((code == MAX_EXPR && aref[i1].offrng[1] < aref[i0].offrng[0])
1730 1883 : || (code == MIN_EXPR && aref[i0].offrng[0] < aref[i1].offrng[1]))
1731 : {
1732 127 : pref->offrng[0] = aref[i0].offrng[0];
1733 127 : pref->offrng[1] = aref[i0].offrng[1];
1734 : }
1735 :
1736 : /* Replace PTR->REF with the SSA_NAME to indicate the expression
1737 : might not refer to the same (sub)object. */
1738 1234 : pref->ref = ptr;
1739 1234 : return true;
1740 : }
1741 :
1742 : /* A helper of compute_objsize_r() to determine the size of a DECL.
1743 : Return true on success and (possibly in the future) false on failure. */
1744 :
1745 : static bool
1746 5079486 : handle_decl (tree decl, bool addr, access_ref *pref)
1747 : {
1748 5079486 : tree decl_type = TREE_TYPE (decl);
1749 :
1750 5079486 : pref->ref = decl;
1751 :
1752 : /* Reset the offset in case it was set by a prior call and not
1753 : cleared by the caller. The offset is only adjusted after
1754 : the identity of the object has been determined. */
1755 5079486 : pref->offrng[0] = pref->offrng[1] = 0;
1756 :
1757 5079486 : if (!addr && POINTER_TYPE_P (decl_type))
1758 : {
1759 : /* Set the maximum size if the reference is to the pointer
1760 : itself (as opposed to what it points to), and clear
1761 : BASE0 since the offset isn't necessarily zero-based. */
1762 46833 : pref->set_max_size_range ();
1763 46833 : pref->base0 = false;
1764 46833 : return true;
1765 : }
1766 :
1767 : /* Valid offsets into the object are nonnegative. */
1768 5032653 : pref->base0 = true;
1769 :
1770 5032653 : if (tree size = decl_init_size (decl, false))
1771 5007451 : if (TREE_CODE (size) == INTEGER_CST)
1772 : {
1773 5007317 : pref->sizrng[0] = wi::to_offset (size);
1774 5007317 : pref->sizrng[1] = pref->sizrng[0];
1775 5007317 : return true;
1776 : }
1777 :
1778 25336 : pref->set_max_size_range ();
1779 25336 : return true;
1780 : }
1781 :
1782 : /* A helper of compute_objsize_r() to determine the size from ARRAY_REF
1783 : AREF. ADDR is true if PTR is the operand of ADDR_EXPR. Return true
1784 : on success and false on failure. */
1785 :
1786 : static bool
1787 880962 : handle_array_ref (tree aref, gimple *stmt, bool addr, int ostype,
1788 : access_ref *pref, ssa_name_limit_t &snlim,
1789 : pointer_query *qry)
1790 : {
1791 880962 : gcc_assert (TREE_CODE (aref) == ARRAY_REF);
1792 :
1793 880962 : tree arefop = TREE_OPERAND (aref, 0);
1794 880962 : tree reftype = TREE_TYPE (arefop);
1795 880962 : if (!addr && TREE_CODE (TREE_TYPE (reftype)) == POINTER_TYPE)
1796 : /* Avoid arrays of pointers. FIXME: Handle pointers to arrays
1797 : of known bound. */
1798 : return false;
1799 :
1800 871553 : if (!compute_objsize_r (arefop, stmt, addr, ostype, pref, snlim, qry))
1801 : return false;
1802 :
1803 871553 : offset_int orng[2];
1804 871553 : tree off = pref->eval (TREE_OPERAND (aref, 1));
1805 871553 : range_query *const rvals = qry ? qry->rvals : NULL;
1806 871553 : if (!get_offset_range (off, stmt, orng, rvals))
1807 : {
1808 : /* Set ORNG to the maximum offset representable in ptrdiff_t. */
1809 45910 : orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
1810 45910 : orng[0] = -orng[1] - 1;
1811 : }
1812 :
1813 : /* Convert the array index range determined above to a byte offset. */
1814 871553 : tree lowbnd = array_ref_low_bound (aref);
1815 871553 : if (TREE_CODE (lowbnd) == INTEGER_CST && !integer_zerop (lowbnd))
1816 : {
1817 : /* Adjust the index by the low bound of the array domain (0 in C/C++,
1818 : 1 in Fortran and anything in Ada) by applying the same processing
1819 : as in get_offset_range. */
1820 17143 : const wide_int wlb = wi::to_wide (lowbnd);
1821 17143 : signop sgn = SIGNED;
1822 17143 : if (TYPE_UNSIGNED (TREE_TYPE (lowbnd))
1823 17143 : && wlb.get_precision () < TYPE_PRECISION (sizetype))
1824 : sgn = UNSIGNED;
1825 17143 : const offset_int lb = offset_int::from (wlb, sgn);
1826 17143 : orng[0] -= lb;
1827 17143 : orng[1] -= lb;
1828 17143 : }
1829 :
1830 871553 : tree eltype = TREE_TYPE (aref);
1831 871553 : tree tpsize = TYPE_SIZE_UNIT (eltype);
1832 871553 : if (!tpsize || TREE_CODE (tpsize) != INTEGER_CST)
1833 : {
1834 511 : pref->add_max_offset ();
1835 511 : return true;
1836 : }
1837 :
1838 871042 : offset_int sz = wi::to_offset (tpsize);
1839 871042 : orng[0] *= sz;
1840 871042 : orng[1] *= sz;
1841 :
1842 871042 : if (ostype && TREE_CODE (eltype) == ARRAY_TYPE)
1843 : {
1844 : /* Except for the permissive raw memory functions which use
1845 : the size of the whole object determined above, use the size
1846 : of the referenced array. Because the overall offset is from
1847 : the beginning of the complete array object add this overall
1848 : offset to the size of array. */
1849 7164 : offset_int sizrng[2] =
1850 : {
1851 7164 : pref->offrng[0] + orng[0] + sz,
1852 7164 : pref->offrng[1] + orng[1] + sz
1853 : };
1854 7164 : if (sizrng[1] < sizrng[0])
1855 2 : std::swap (sizrng[0], sizrng[1]);
1856 7164 : if (sizrng[0] >= 0 && sizrng[0] <= pref->sizrng[0])
1857 6625 : pref->sizrng[0] = sizrng[0];
1858 7164 : if (sizrng[1] >= 0 && sizrng[1] <= pref->sizrng[1])
1859 6767 : pref->sizrng[1] = sizrng[1];
1860 : }
1861 :
1862 871042 : pref->add_offset (orng[0], orng[1]);
1863 871042 : return true;
1864 : }
1865 :
1866 : /* Given a COMPONENT_REF CREF, set *PREF size to the size of the referenced
1867 : member. */
1868 :
1869 : static void
1870 56294 : set_component_ref_size (tree cref, access_ref *pref)
1871 : {
1872 56294 : const tree base = TREE_OPERAND (cref, 0);
1873 56294 : const tree base_type = TREE_TYPE (base);
1874 :
1875 : /* SAM is set for array members that might need special treatment. */
1876 56294 : special_array_member sam;
1877 56294 : tree size = component_ref_size (cref, &sam);
1878 56294 : if (sam == special_array_member::int_0)
1879 191 : pref->sizrng[0] = pref->sizrng[1] = 0;
1880 56103 : else if (!pref->trail1special && sam == special_array_member::trail_1)
1881 27 : pref->sizrng[0] = pref->sizrng[1] = 1;
1882 56076 : else if (size && TREE_CODE (size) == INTEGER_CST)
1883 53828 : pref->sizrng[0] = pref->sizrng[1] = wi::to_offset (size);
1884 : else
1885 : {
1886 : /* When the size of the member is unknown it's either a flexible
1887 : array member or a trailing special array member (either zero
1888 : length or one-element). Set the size to the maximum minus
1889 : the constant size of the base object's type. */
1890 2248 : pref->sizrng[0] = 0;
1891 2248 : pref->sizrng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
1892 2248 : if (tree base_size = TYPE_SIZE_UNIT (base_type))
1893 2248 : if (TREE_CODE (base_size) == INTEGER_CST)
1894 2207 : pref->sizrng[1] -= wi::to_offset (base_size);
1895 : }
1896 56294 : }
1897 :
1898 : /* A helper of compute_objsize_r() to determine the size from COMPONENT_REF
1899 : CREF. Return true on success and false on failure. */
1900 :
1901 : static bool
1902 3312895 : handle_component_ref (tree cref, gimple *stmt, bool addr, int ostype,
1903 : access_ref *pref, ssa_name_limit_t &snlim,
1904 : pointer_query *qry)
1905 : {
1906 3312895 : gcc_assert (TREE_CODE (cref) == COMPONENT_REF);
1907 :
1908 3312895 : const tree base = TREE_OPERAND (cref, 0);
1909 3312895 : const tree field = TREE_OPERAND (cref, 1);
1910 3312895 : access_ref base_ref = *pref;
1911 :
1912 : /* Unconditionally determine the size of the base object (it could
1913 : be smaller than the referenced member when the object is stored
1914 : in a buffer with an insufficient size). */
1915 3312895 : if (!compute_objsize_r (base, stmt, addr, 0, &base_ref, snlim, qry))
1916 : return false;
1917 :
1918 : /* Add the offset of the member to the offset into the object computed
1919 : so far. */
1920 3312895 : tree offset = byte_position (field);
1921 3312895 : if (TREE_CODE (offset) == INTEGER_CST)
1922 3312868 : base_ref.add_offset (wi::to_offset (offset));
1923 : else
1924 27 : base_ref.add_max_offset ();
1925 :
1926 3312895 : if (!base_ref.ref)
1927 : /* PREF->REF may have been already set to an SSA_NAME earlier
1928 : to provide better context for diagnostics. In that case,
1929 : leave it unchanged. */
1930 0 : base_ref.ref = base;
1931 :
1932 3312895 : const tree base_type = TREE_TYPE (base);
1933 3312895 : if (TREE_CODE (base_type) == UNION_TYPE)
1934 : /* In accesses through union types consider the entire unions
1935 : rather than just their members. */
1936 : ostype = 0;
1937 :
1938 2905409 : if (ostype == 0)
1939 : {
1940 : /* In OSTYPE zero (for raw memory functions like memcpy), use
1941 : the maximum size instead if the identity of the enclosing
1942 : object cannot be determined. */
1943 3256590 : *pref = base_ref;
1944 3256590 : return true;
1945 : }
1946 :
1947 56305 : pref->ref = field;
1948 :
1949 56305 : if (!addr && POINTER_TYPE_P (TREE_TYPE (field)))
1950 : {
1951 : /* Set maximum size if the reference is to the pointer member
1952 : itself (as opposed to what it points to). */
1953 11 : pref->set_max_size_range ();
1954 11 : return true;
1955 : }
1956 :
1957 56294 : set_component_ref_size (cref, pref);
1958 :
1959 56294 : if (base_ref.size_remaining () < pref->size_remaining ())
1960 : /* Use the base object if it's smaller than the member. */
1961 443 : *pref = base_ref;
1962 :
1963 : return true;
1964 : }
1965 :
1966 : /* A helper of compute_objsize_r() to determine the size from MEM_REF
1967 : MREF. Return true on success and false on failure. */
1968 :
1969 : static bool
1970 3053505 : handle_mem_ref (tree mref, gimple *stmt, int ostype, access_ref *pref,
1971 : ssa_name_limit_t &snlim, pointer_query *qry)
1972 : {
1973 3053505 : gcc_assert (TREE_CODE (mref) == MEM_REF);
1974 :
1975 3053505 : tree mreftype = TYPE_MAIN_VARIANT (TREE_TYPE (mref));
1976 3053505 : if (VECTOR_TYPE_P (mreftype))
1977 : {
1978 : /* Hack: Handle MEM_REFs of vector types as those to complete
1979 : objects; those may be synthesized from multiple assignments
1980 : to consecutive data members (see PR 93200 and 96963).
1981 : FIXME: Vectorized assignments should only be present after
1982 : vectorization so this hack is only necessary after it has
1983 : run and could be avoided in calls from prior passes (e.g.,
1984 : tree-ssa-strlen.cc).
1985 : FIXME: Deal with this more generally, e.g., by marking up
1986 : such MEM_REFs at the time they're created. */
1987 68041 : ostype = 0;
1988 : }
1989 :
1990 3053505 : tree mrefop = TREE_OPERAND (mref, 0);
1991 3053505 : if (!compute_objsize_r (mrefop, stmt, false, ostype, pref, snlim, qry))
1992 : return false;
1993 :
1994 3053499 : ++pref->deref;
1995 :
1996 3053499 : offset_int orng[2];
1997 3053499 : tree off = pref->eval (TREE_OPERAND (mref, 1));
1998 3053499 : range_query *const rvals = qry ? qry->rvals : NULL;
1999 3053499 : if (!get_offset_range (off, stmt, orng, rvals))
2000 : {
2001 : /* Set ORNG to the maximum offset representable in ptrdiff_t. */
2002 0 : orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
2003 0 : orng[0] = -orng[1] - 1;
2004 : }
2005 :
2006 3053499 : pref->add_offset (orng[0], orng[1]);
2007 3053499 : return true;
2008 : }
2009 :
2010 : /* A helper of compute_objsize_r() to determine the size from SSA_NAME
2011 : PTR. Return true on success and false on failure. */
2012 :
2013 : static bool
2014 6908660 : handle_ssa_name (tree ptr, bool addr, int ostype,
2015 : access_ref *pref, ssa_name_limit_t &snlim,
2016 : pointer_query *qry)
2017 : {
2018 6908660 : if (!snlim.next ())
2019 : return false;
2020 :
2021 : /* Only process an SSA_NAME if the recursion limit has not yet
2022 : been reached. */
2023 6908651 : if (qry)
2024 : {
2025 6908651 : if (++qry->depth > qry->max_depth)
2026 712793 : qry->max_depth = qry->depth;
2027 6908651 : if (const access_ref *cache_ref = qry->get_ref (ptr, ostype))
2028 : {
2029 : /* Add the number of DEREFerences accumulated so far. */
2030 1816024 : const int deref = pref->deref;
2031 1816024 : *pref = *cache_ref;
2032 1816024 : pref->deref += deref;
2033 1816024 : return true;
2034 : }
2035 : }
2036 :
2037 5092627 : gimple *stmt = SSA_NAME_DEF_STMT (ptr);
2038 5092627 : if (is_gimple_call (stmt))
2039 : {
2040 : /* If STMT is a call to an allocation function get the size
2041 : from its argument(s). If successful, also set *PREF->REF
2042 : to PTR for the caller to include in diagnostics. */
2043 2478835 : wide_int wr[2];
2044 495767 : range_query *const rvals = qry ? qry->rvals : NULL;
2045 495767 : if (gimple_call_alloc_size (stmt, wr, rvals))
2046 : {
2047 150824 : pref->ref = ptr;
2048 150824 : pref->sizrng[0] = offset_int::from (wr[0], UNSIGNED);
2049 150824 : pref->sizrng[1] = offset_int::from (wr[1], UNSIGNED);
2050 : /* Constrain both bounds to a valid size. */
2051 150824 : offset_int maxsize = wi::to_offset (max_object_size ());
2052 150824 : if (pref->sizrng[0] > maxsize)
2053 352 : pref->sizrng[0] = maxsize;
2054 150824 : if (pref->sizrng[1] > maxsize)
2055 14361 : pref->sizrng[1] = maxsize;
2056 : }
2057 : else
2058 : {
2059 : /* For functions known to return one of their pointer arguments
2060 : try to determine what the returned pointer points to, and on
2061 : success add OFFRNG which was set to the offset added by
2062 : the function (e.g., memchr) to the overall offset. */
2063 344943 : bool past_end;
2064 344943 : offset_int offrng[2];
2065 344943 : if (tree ret = gimple_call_return_array (stmt, offrng, &past_end,
2066 : snlim, qry))
2067 : {
2068 19432 : if (!compute_objsize_r (ret, stmt, addr, ostype, pref, snlim, qry))
2069 1815 : return false;
2070 :
2071 : /* Cap OFFRNG[1] to at most the remaining size of
2072 : the object. */
2073 17617 : offset_int remrng[2];
2074 17617 : remrng[1] = pref->size_remaining (remrng);
2075 17617 : if (remrng[1] != 0 && !past_end)
2076 : /* Decrement the size for functions that never return
2077 : a past-the-end pointer. */
2078 17316 : remrng[1] -= 1;
2079 :
2080 17617 : if (remrng[1] < offrng[1])
2081 408 : offrng[1] = remrng[1];
2082 17617 : pref->add_offset (offrng[0], offrng[1]);
2083 : }
2084 : else
2085 : {
2086 : /* For other calls that might return arbitrary pointers
2087 : including into the middle of objects set the size
2088 : range to maximum, clear PREF->BASE0, and also set
2089 : PREF->REF to include in diagnostics. */
2090 325511 : pref->set_max_size_range ();
2091 325511 : pref->base0 = false;
2092 325511 : pref->ref = ptr;
2093 : }
2094 : }
2095 493952 : qry->put_ref (ptr, *pref, ostype);
2096 493952 : return true;
2097 1487301 : }
2098 :
2099 4596860 : if (gimple_nop_p (stmt))
2100 : {
2101 : /* For a function argument try to determine the byte size
2102 : of the array from the current function declaratation
2103 : (e.g., attribute access or related). */
2104 4183130 : wide_int wr[2];
2105 836626 : bool static_array = false;
2106 836626 : if (tree ref = gimple_parm_array_size (ptr, wr, &static_array))
2107 : {
2108 185 : pref->parmarray = !static_array;
2109 185 : pref->sizrng[0] = offset_int::from (wr[0], UNSIGNED);
2110 185 : pref->sizrng[1] = offset_int::from (wr[1], UNSIGNED);
2111 185 : pref->ref = ref;
2112 185 : qry->put_ref (ptr, *pref, ostype);
2113 185 : return true;
2114 : }
2115 :
2116 836441 : pref->set_max_size_range ();
2117 836441 : pref->base0 = false;
2118 836441 : pref->ref = ptr;
2119 836441 : qry->put_ref (ptr, *pref, ostype);
2120 836441 : return true;
2121 2509878 : }
2122 :
2123 3760234 : if (gimple_code (stmt) == GIMPLE_PHI)
2124 : {
2125 : /* Pass PTR to get_ref() via PREF. If all PHI arguments refer
2126 : to the same object the function will replace it with it. */
2127 618798 : pref->ref = ptr;
2128 618798 : access_ref phi_ref = *pref;
2129 618798 : if (!pref->get_ref (NULL, &phi_ref, ostype, &snlim, qry))
2130 : return false;
2131 558981 : *pref = phi_ref;
2132 558981 : qry->put_ref (ptr, *pref, ostype);
2133 558981 : return true;
2134 : }
2135 :
2136 3141436 : if (!is_gimple_assign (stmt))
2137 : {
2138 : /* Clear BASE0 since the assigned pointer might point into
2139 : the middle of the object, set the maximum size range and,
2140 : if the SSA_NAME refers to a function argumnent, set
2141 : PREF->REF to it. */
2142 7799 : pref->base0 = false;
2143 7799 : pref->set_max_size_range ();
2144 7799 : pref->ref = ptr;
2145 7799 : return true;
2146 : }
2147 :
2148 3133637 : tree_code code = gimple_assign_rhs_code (stmt);
2149 :
2150 3133637 : if (code == MAX_EXPR || code == MIN_EXPR)
2151 : {
2152 1323 : if (!handle_min_max_size (ptr, ostype, pref, snlim, qry))
2153 : return false;
2154 :
2155 1323 : qry->put_ref (ptr, *pref, ostype);
2156 1323 : return true;
2157 : }
2158 :
2159 3132314 : tree rhs = gimple_assign_rhs1 (stmt);
2160 :
2161 3132314 : if (code == POINTER_PLUS_EXPR
2162 3132314 : && TREE_CODE (TREE_TYPE (rhs)) == POINTER_TYPE)
2163 : {
2164 : /* Compute the size of the object first. */
2165 806987 : if (!compute_objsize_r (rhs, stmt, addr, ostype, pref, snlim, qry))
2166 : return false;
2167 :
2168 761064 : offset_int orng[2];
2169 761064 : tree off = gimple_assign_rhs2 (stmt);
2170 761064 : range_query *const rvals = qry ? qry->rvals : NULL;
2171 761064 : if (get_offset_range (off, stmt, orng, rvals))
2172 643219 : pref->add_offset (orng[0], orng[1]);
2173 : else
2174 117845 : pref->add_max_offset ();
2175 :
2176 761064 : qry->put_ref (ptr, *pref, ostype);
2177 761064 : return true;
2178 : }
2179 :
2180 2325327 : if (code == ADDR_EXPR || code == SSA_NAME)
2181 : {
2182 508289 : if (!compute_objsize_r (rhs, stmt, addr, ostype, pref, snlim, qry))
2183 : return false;
2184 506952 : qry->put_ref (ptr, *pref, ostype);
2185 506952 : return true;
2186 : }
2187 :
2188 1817038 : if (ostype > 1 && POINTER_TYPE_P (TREE_TYPE (rhs)))
2189 : {
2190 : /* When determining the qualifiers follow the pointer but
2191 : avoid caching the result. As the pointer is added to
2192 : and/or dereferenced the computed size and offset need
2193 : not be meaningful for other queries involving the same
2194 : pointer. */
2195 0 : if (!compute_objsize_r (rhs, stmt, addr, ostype, pref, snlim, qry))
2196 : return false;
2197 :
2198 0 : rhs = pref->ref;
2199 : }
2200 :
2201 : /* (This could also be an assignment from a nonlocal pointer.) Save
2202 : PTR to mention in diagnostics but otherwise treat it as a pointer
2203 : to an unknown object. */
2204 1817038 : pref->ref = rhs;
2205 1817038 : pref->base0 = false;
2206 1817038 : pref->set_max_size_range ();
2207 1817038 : return true;
2208 : }
2209 :
2210 : /* Helper to compute the size of the object referenced by the PTR
2211 : expression which must have pointer type, using Object Size type
2212 : OSTYPE (only the least significant 2 bits are used).
2213 : On success, sets PREF->REF to the DECL of the referenced object
2214 : if it's unique, otherwise to null, PREF->OFFRNG to the range of
2215 : offsets into it, and PREF->SIZRNG to the range of sizes of
2216 : the object(s).
2217 : ADDR is true for an enclosing ADDR_EXPR.
2218 : SNLIM is used to avoid visiting the same PHI operand multiple
2219 : times, and, when nonnull, RVALS to determine range information.
2220 : Returns true on success, false when a meaningful size (or range)
2221 : cannot be determined.
2222 :
2223 : The function is intended for diagnostics and should not be used
2224 : to influence code generation or optimization. */
2225 :
2226 : static bool
2227 22024939 : compute_objsize_r (tree ptr, gimple *stmt, bool addr, int ostype,
2228 : access_ref *pref, ssa_name_limit_t &snlim,
2229 : pointer_query *qry)
2230 : {
2231 22025669 : STRIP_NOPS (ptr);
2232 :
2233 22025669 : if (DECL_P (ptr))
2234 5079486 : return handle_decl (ptr, addr, pref);
2235 :
2236 16946183 : switch (TREE_CODE (ptr))
2237 : {
2238 1793153 : case ADDR_EXPR:
2239 1793153 : {
2240 1793153 : tree ref = TREE_OPERAND (ptr, 0);
2241 1793153 : if (!compute_objsize_r (ref, stmt, true, ostype, pref, snlim, qry))
2242 : return false;
2243 :
2244 1793153 : --pref->deref;
2245 1793153 : return true;
2246 : }
2247 :
2248 4026 : case BIT_FIELD_REF:
2249 4026 : {
2250 4026 : tree ref = TREE_OPERAND (ptr, 0);
2251 4026 : if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
2252 : return false;
2253 :
2254 4026 : offset_int off = wi::to_offset (pref->eval (TREE_OPERAND (ptr, 2)));
2255 4026 : pref->add_offset (off / BITS_PER_UNIT);
2256 4026 : return true;
2257 : }
2258 :
2259 880962 : case ARRAY_REF:
2260 880962 : return handle_array_ref (ptr, stmt, addr, ostype, pref, snlim, qry);
2261 :
2262 3312895 : case COMPONENT_REF:
2263 3312895 : return handle_component_ref (ptr, stmt, addr, ostype, pref, snlim, qry);
2264 :
2265 3053505 : case MEM_REF:
2266 3053505 : return handle_mem_ref (ptr, stmt, ostype, pref, snlim, qry);
2267 :
2268 11022 : case TARGET_MEM_REF:
2269 11022 : {
2270 11022 : tree ref = TREE_OPERAND (ptr, 0);
2271 11022 : if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
2272 : return false;
2273 :
2274 : /* TODO: Handle remaining operands. Until then, add maximum offset. */
2275 11022 : pref->ref = ptr;
2276 11022 : pref->add_max_offset ();
2277 11022 : return true;
2278 : }
2279 :
2280 633551 : case INTEGER_CST:
2281 : /* Pointer constants other than null smaller than param_min_pagesize
2282 : might be the result of erroneous null pointer addition/subtraction.
2283 : Unless zero is a valid address set size to zero. For null pointers,
2284 : set size to the maximum for now since those may be the result of
2285 : jump threading. Similarly, for values >= param_min_pagesize in
2286 : order to support (type *) 0x7cdeab00. */
2287 633551 : if (integer_zerop (ptr)
2288 680949 : || wi::to_widest (ptr) >= param_min_pagesize)
2289 589778 : pref->set_max_size_range ();
2290 43773 : else if (POINTER_TYPE_P (TREE_TYPE (ptr)))
2291 : {
2292 585 : tree deref_type = TREE_TYPE (TREE_TYPE (ptr));
2293 585 : addr_space_t as = TYPE_ADDR_SPACE (deref_type);
2294 585 : if (targetm.addr_space.zero_address_valid (as))
2295 0 : pref->set_max_size_range ();
2296 : else
2297 : {
2298 585 : pref->sizrng[0] = pref->sizrng[1] = 0;
2299 585 : pref->ref_nullptr_p = true;
2300 : }
2301 : }
2302 : else
2303 43188 : pref->sizrng[0] = pref->sizrng[1] = 0;
2304 :
2305 633551 : pref->ref = ptr;
2306 633551 : return true;
2307 :
2308 258672 : case STRING_CST:
2309 258672 : pref->sizrng[0] = pref->sizrng[1] = TREE_STRING_LENGTH (ptr);
2310 258672 : pref->ref = ptr;
2311 258672 : return true;
2312 :
2313 519 : case POINTER_PLUS_EXPR:
2314 519 : {
2315 519 : tree ref = TREE_OPERAND (ptr, 0);
2316 519 : if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
2317 : return false;
2318 :
2319 : /* The below only makes sense if the offset is being applied to the
2320 : address of the object. */
2321 519 : if (pref->deref != -1)
2322 : return false;
2323 :
2324 441 : offset_int orng[2];
2325 441 : tree off = pref->eval (TREE_OPERAND (ptr, 1));
2326 441 : if (get_offset_range (off, stmt, orng, qry->rvals))
2327 432 : pref->add_offset (orng[0], orng[1]);
2328 : else
2329 9 : pref->add_max_offset ();
2330 : return true;
2331 : }
2332 :
2333 730 : case VIEW_CONVERT_EXPR:
2334 730 : ptr = TREE_OPERAND (ptr, 0);
2335 730 : return compute_objsize_r (ptr, stmt, addr, ostype, pref, snlim, qry);
2336 :
2337 6908660 : case SSA_NAME:
2338 6908660 : return handle_ssa_name (ptr, addr, ostype, pref, snlim, qry);
2339 :
2340 88488 : default:
2341 88488 : break;
2342 : }
2343 :
2344 : /* Assume all other expressions point into an unknown object
2345 : of the maximum valid size. */
2346 88488 : pref->ref = ptr;
2347 88488 : pref->base0 = false;
2348 88488 : pref->set_max_size_range ();
2349 88488 : if (TREE_CODE (ptr) == SSA_NAME)
2350 0 : qry->put_ref (ptr, *pref);
2351 : return true;
2352 : }
2353 :
2354 : /* A "public" wrapper around the above. Clients should use this overload
2355 : instead. */
2356 :
2357 : tree
2358 10939514 : compute_objsize (tree ptr, gimple *stmt, int ostype, access_ref *pref,
2359 : pointer_query *ptr_qry)
2360 : {
2361 10939514 : pointer_query qry;
2362 10939514 : if (ptr_qry)
2363 10938400 : ptr_qry->depth = 0;
2364 : else
2365 : ptr_qry = &qry;
2366 :
2367 : /* Clear and invalidate in case *PREF is being reused. */
2368 10939514 : pref->offrng[0] = pref->offrng[1] = 0;
2369 10939514 : pref->sizrng[0] = pref->sizrng[1] = -1;
2370 :
2371 10939514 : ssa_name_limit_t snlim;
2372 10939514 : if (!compute_objsize_r (ptr, stmt, false, ostype, pref, snlim, ptr_qry))
2373 : return NULL_TREE;
2374 :
2375 10930018 : offset_int maxsize = pref->size_remaining ();
2376 10930018 : if (pref->base0 && pref->offrng[0] < 0 && pref->offrng[1] >= 0)
2377 109 : pref->offrng[0] = 0;
2378 10930018 : return wide_int_to_tree (sizetype, maxsize);
2379 10939514 : }
2380 :
2381 : /* Transitional wrapper. The function should be removed once callers
2382 : transition to the pointer_query API. */
2383 :
2384 : tree
2385 658940 : compute_objsize (tree ptr, gimple *stmt, int ostype, access_ref *pref,
2386 : range_query *rvals /* = NULL */)
2387 : {
2388 658940 : pointer_query qry;
2389 658940 : qry.rvals = rvals;
2390 658940 : return compute_objsize (ptr, stmt, ostype, pref, &qry);
2391 658940 : }
2392 :
2393 : /* Legacy wrapper around the above. The function should be removed
2394 : once callers transition to one of the two above. */
2395 :
2396 : tree
2397 0 : compute_objsize (tree ptr, gimple *stmt, int ostype, tree *pdecl /* = NULL */,
2398 : tree *poff /* = NULL */, range_query *rvals /* = NULL */)
2399 : {
2400 : /* Set the initial offsets to zero and size to negative to indicate
2401 : none has been computed yet. */
2402 0 : access_ref ref;
2403 0 : tree size = compute_objsize (ptr, stmt, ostype, &ref, rvals);
2404 0 : if (!size || !ref.base0)
2405 : return NULL_TREE;
2406 :
2407 0 : if (pdecl)
2408 0 : *pdecl = ref.ref;
2409 :
2410 0 : if (poff)
2411 0 : *poff = wide_int_to_tree (ptrdiff_type_node, ref.offrng[ref.offrng[0] < 0]);
2412 :
2413 : return size;
2414 : }
2415 :
2416 : /* Determine the offset *FLDOFF of the first byte of a struct member
2417 : of TYPE (possibly recursively) into which the byte offset OFF points,
2418 : starting after the field START_AFTER if it's non-null. On success,
2419 : if nonnull, set *FLDOFF to the offset of the first byte, and return
2420 : the field decl. If nonnull, set *NEXTOFF to the offset of the next
2421 : field (which reflects any padding between the returned field and
2422 : the next). Otherwise, if no such member can be found, return null. */
2423 :
2424 : tree
2425 1540 : field_at_offset (tree type, tree start_after, HOST_WIDE_INT off,
2426 : HOST_WIDE_INT *fldoff /* = nullptr */,
2427 : HOST_WIDE_INT *nextoff /* = nullptr */)
2428 : {
2429 1540 : tree first_fld = TYPE_FIELDS (type);
2430 :
2431 1540 : HOST_WIDE_INT offbuf = 0, nextbuf = 0;
2432 1540 : if (!fldoff)
2433 9 : fldoff = &offbuf;
2434 1540 : if (!nextoff)
2435 692 : nextoff = &nextbuf;
2436 :
2437 1540 : *nextoff = 0;
2438 :
2439 : /* The field to return. */
2440 1540 : tree last_fld = NULL_TREE;
2441 : /* The next field to advance to. */
2442 1540 : tree next_fld = NULL_TREE;
2443 :
2444 : /* NEXT_FLD's cached offset. */
2445 1540 : HOST_WIDE_INT next_pos = -1;
2446 :
2447 1800 : for (tree fld = first_fld; fld; fld = next_fld)
2448 : {
2449 : next_fld = fld;
2450 1781 : do
2451 : /* Advance to the next relevant data member. */
2452 1781 : next_fld = TREE_CHAIN (next_fld);
2453 : while (next_fld
2454 3442 : && (TREE_CODE (next_fld) != FIELD_DECL
2455 1661 : || DECL_ARTIFICIAL (next_fld)));
2456 :
2457 1781 : if (TREE_CODE (fld) != FIELD_DECL || DECL_ARTIFICIAL (fld))
2458 0 : continue;
2459 :
2460 1781 : if (fld == start_after)
2461 0 : continue;
2462 :
2463 1781 : tree fldtype = TREE_TYPE (fld);
2464 : /* The offset of FLD within its immediately enclosing structure. */
2465 1781 : HOST_WIDE_INT fldpos = next_pos < 0 ? int_byte_position (fld) : next_pos;
2466 :
2467 1781 : tree typesize = TYPE_SIZE_UNIT (fldtype);
2468 1781 : if (typesize && TREE_CODE (typesize) != INTEGER_CST)
2469 : /* Bail if FLD is a variable length member. */
2470 : return NULL_TREE;
2471 :
2472 : /* If the size is not available the field is a flexible array
2473 : member. Treat this case as success. */
2474 3552 : HOST_WIDE_INT fldsize = (tree_fits_uhwi_p (typesize)
2475 1781 : ? tree_to_uhwi (typesize)
2476 : : off);
2477 :
2478 : /* If OFF is beyond the end of the current field continue. */
2479 1781 : HOST_WIDE_INT fldend = fldpos + fldsize;
2480 1781 : if (fldend < off)
2481 236 : continue;
2482 :
2483 1545 : if (next_fld)
2484 : {
2485 : /* If OFF is equal to the offset of the next field continue
2486 : to it and skip the array/struct business below. */
2487 1439 : tree pos = byte_position (next_fld);
2488 1439 : if (!tree_fits_shwi_p (pos))
2489 : /* Bail if NEXT_FLD is a variable length member. */
2490 : return NULL_TREE;
2491 1439 : next_pos = tree_to_shwi (pos);
2492 1439 : *nextoff = *fldoff + next_pos;
2493 1439 : if (*nextoff == off && TREE_CODE (type) != UNION_TYPE)
2494 19 : continue;
2495 : }
2496 : else
2497 106 : *nextoff = HOST_WIDE_INT_MAX;
2498 :
2499 : /* OFF refers somewhere into the current field or just past its end,
2500 : which could mean it refers to the next field. */
2501 1526 : if (TREE_CODE (fldtype) == ARRAY_TYPE)
2502 : {
2503 : /* Will be set to the offset of the first byte of the array
2504 : element (which may be an array) of FLDTYPE into which
2505 : OFF - FLDPOS points (which may be past ELTOFF). */
2506 549 : HOST_WIDE_INT eltoff = 0;
2507 549 : if (tree ft = array_elt_at_offset (fldtype, off - fldpos, &eltoff))
2508 549 : fldtype = ft;
2509 : else
2510 0 : continue;
2511 :
2512 : /* Advance the position to include the array element above.
2513 : If OFF - FLPOS refers to a member of FLDTYPE, the member
2514 : will be determined below. */
2515 549 : fldpos += eltoff;
2516 : }
2517 :
2518 1526 : *fldoff += fldpos;
2519 :
2520 1526 : if (TREE_CODE (fldtype) == RECORD_TYPE)
2521 : /* Drill down into the current field if it's a struct. */
2522 848 : fld = field_at_offset (fldtype, start_after, off - fldpos,
2523 : fldoff, nextoff);
2524 :
2525 1526 : last_fld = fld;
2526 :
2527 : /* Unless the offset is just past the end of the field return it.
2528 : Otherwise save it and return it only if the offset of the next
2529 : next field is greater (i.e., there is padding between the two)
2530 : or if there is no next field. */
2531 1526 : if (off < fldend)
2532 : break;
2533 : }
2534 :
2535 1540 : if (*nextoff == HOST_WIDE_INT_MAX && next_fld)
2536 35 : *nextoff = next_pos;
2537 :
2538 : return last_fld;
2539 : }
2540 :
2541 : /* Determine the offset *ELTOFF of the first byte of the array element
2542 : of array ARTYPE into which the byte offset OFF points. On success
2543 : set *ELTOFF to the offset of the first byte and return type.
2544 : Otherwise, if no such element can be found, return null. */
2545 :
2546 : tree
2547 581 : array_elt_at_offset (tree artype, HOST_WIDE_INT off,
2548 : HOST_WIDE_INT *eltoff /* = nullptr */,
2549 : HOST_WIDE_INT *subar_size /* = nullptr */)
2550 : {
2551 581 : gcc_assert (TREE_CODE (artype) == ARRAY_TYPE);
2552 :
2553 581 : HOST_WIDE_INT dummy;
2554 581 : if (!eltoff)
2555 0 : eltoff = &dummy;
2556 581 : if (!subar_size)
2557 549 : subar_size = &dummy;
2558 :
2559 581 : tree eltype = artype;
2560 613 : while (TREE_CODE (TREE_TYPE (eltype)) == ARRAY_TYPE)
2561 32 : eltype = TREE_TYPE (eltype);
2562 :
2563 581 : tree subartype = eltype;
2564 581 : if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (eltype))
2565 565 : || TYPE_MODE (TREE_TYPE (eltype)) != TYPE_MODE (char_type_node))
2566 16 : eltype = TREE_TYPE (eltype);
2567 :
2568 581 : *subar_size = int_size_in_bytes (subartype);
2569 :
2570 581 : if (eltype == artype)
2571 : {
2572 533 : *eltoff = 0;
2573 533 : return artype;
2574 : }
2575 :
2576 48 : HOST_WIDE_INT artype_size = int_size_in_bytes (artype);
2577 48 : HOST_WIDE_INT eltype_size = int_size_in_bytes (eltype);
2578 :
2579 48 : if (off < artype_size)// * eltype_size)
2580 : {
2581 32 : *eltoff = (off / eltype_size) * eltype_size;
2582 32 : return TREE_CODE (eltype) == ARRAY_TYPE ? TREE_TYPE (eltype) : eltype;
2583 : }
2584 :
2585 : return NULL_TREE;
2586 : }
2587 :
2588 : /* Wrapper around build_array_type_nelts that makes sure the array
2589 : can be created at all and handles zero sized arrays specially. */
2590 :
2591 : tree
2592 12084 : build_printable_array_type (tree eltype, unsigned HOST_WIDE_INT nelts)
2593 : {
2594 : /* Cannot build an array type of functions or methods without
2595 : an error diagnostic. */
2596 12084 : if (FUNC_OR_METHOD_TYPE_P (eltype))
2597 : {
2598 1 : tree arrtype = make_node (ARRAY_TYPE);
2599 1 : TREE_TYPE (arrtype) = eltype;
2600 1 : TYPE_SIZE (arrtype) = bitsize_zero_node;
2601 1 : TYPE_SIZE_UNIT (arrtype) = size_zero_node;
2602 1 : return arrtype;
2603 : }
2604 :
2605 12083 : if (TYPE_SIZE_UNIT (eltype)
2606 11809 : && TREE_CODE (TYPE_SIZE_UNIT (eltype)) == INTEGER_CST
2607 11793 : && !integer_zerop (TYPE_SIZE_UNIT (eltype))
2608 11703 : && TYPE_ALIGN_UNIT (eltype) > 1
2609 27573 : && wi::zext (wi::to_wide (TYPE_SIZE_UNIT (eltype)),
2610 27573 : ffs_hwi (TYPE_ALIGN_UNIT (eltype)) - 1) != 0)
2611 3 : eltype = TYPE_MAIN_VARIANT (eltype);
2612 :
2613 : /* Consider excessive NELTS an array of unknown bound. */
2614 12083 : tree idxtype = NULL_TREE;
2615 12083 : if (nelts < HOST_WIDE_INT_MAX)
2616 : {
2617 12050 : if (nelts)
2618 11750 : return build_array_type_nelts (eltype, nelts);
2619 300 : idxtype = build_range_type (sizetype, size_zero_node, NULL_TREE);
2620 : }
2621 :
2622 333 : tree arrtype = build_array_type (eltype, idxtype);
2623 333 : arrtype = build_distinct_type_copy (TYPE_MAIN_VARIANT (arrtype));
2624 333 : TYPE_SIZE (arrtype) = bitsize_zero_node;
2625 333 : TYPE_SIZE_UNIT (arrtype) = size_zero_node;
2626 333 : return arrtype;
2627 : }
|