comparison gcc/gimple-ssa-warn-restrict.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
comparison
equal deleted inserted replaced
130:e108057fa461 132:d34655255c78
1 /* Pass to detect and issue warnings for violations of the restrict
2 qualifier.
3 Copyright (C) 2017-2018 Free Software Foundation, Inc.
4 Contributed by Martin Sebor <msebor@redhat.com>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "domwalk.h"
29 #include "tree-pass.h"
30 #include "builtins.h"
31 #include "ssa.h"
32 #include "gimple-pretty-print.h"
33 #include "gimple-ssa-warn-restrict.h"
34 #include "diagnostic-core.h"
35 #include "fold-const.h"
36 #include "gimple-iterator.h"
37 #include "tree-dfa.h"
38 #include "tree-ssa.h"
39 #include "params.h"
40 #include "tree-cfg.h"
41 #include "tree-object-size.h"
42 #include "calls.h"
43 #include "cfgloop.h"
44 #include "intl.h"
45
46 namespace {
47
48 const pass_data pass_data_wrestrict = {
49 GIMPLE_PASS,
50 "wrestrict",
51 OPTGROUP_NONE,
52 TV_NONE,
53 PROP_cfg, /* Properties_required. */
54 0, /* properties_provided. */
55 0, /* properties_destroyed. */
56 0, /* properties_start */
57 0, /* properties_finish */
58 };
59
60 /* Pass to detect violations of strict aliasing requirements in calls
61 to built-in string and raw memory functions. */
62 class pass_wrestrict : public gimple_opt_pass
63 {
64 public:
65 pass_wrestrict (gcc::context *ctxt)
66 : gimple_opt_pass (pass_data_wrestrict, ctxt)
67 { }
68
69 opt_pass *clone () { return new pass_wrestrict (m_ctxt); }
70
71 virtual bool gate (function *);
72 virtual unsigned int execute (function *);
73 };
74
75 bool
76 pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED)
77 {
78 return warn_array_bounds != 0 || warn_restrict != 0;
79 }
80
81 /* Class to walk the basic blocks of a function in dominator order. */
82 class wrestrict_dom_walker : public dom_walker
83 {
84 public:
85 wrestrict_dom_walker () : dom_walker (CDI_DOMINATORS) {}
86
87 edge before_dom_children (basic_block) FINAL OVERRIDE;
88 bool handle_gimple_call (gimple_stmt_iterator *);
89
90 private:
91 void check_call (gimple *);
92 };
93
94 edge
95 wrestrict_dom_walker::before_dom_children (basic_block bb)
96 {
97 /* Iterate over statements, looking for function calls. */
98 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
99 gsi_next (&si))
100 {
101 gimple *stmt = gsi_stmt (si);
102 if (!is_gimple_call (stmt))
103 continue;
104
105 check_call (stmt);
106 }
107
108 return NULL;
109 }
110
111 /* Execute the pass for function FUN, walking in dominator order. */
112
113 unsigned
114 pass_wrestrict::execute (function *fun)
115 {
116 calculate_dominance_info (CDI_DOMINATORS);
117
118 wrestrict_dom_walker walker;
119 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
120
121 return 0;
122 }
123
124 /* Description of a memory reference by a built-in function. This
125 is similar to ao_ref but made especially suitable for -Wrestrict
126 and not for optimization. */
127 struct builtin_memref
128 {
129 /* The original pointer argument to the built-in function. */
130 tree ptr;
131 /* The referenced subobject or NULL if not available, and the base
132 object of the memory reference or NULL. */
133 tree ref;
134 tree base;
135
136 /* The size of the BASE object, PTRDIFF_MAX if indeterminate,
137 and negative until (possibly lazily) initialized. */
138 offset_int basesize;
139
140 /* The non-negative offset of the referenced subobject. Used to avoid
141 warnings for (apparently) possibly but not definitively overlapping
142 accesses to member arrays. Negative when unknown/invalid. */
143 offset_int refoff;
144
145 /* The offset range relative to the base. */
146 offset_int offrange[2];
147 /* The size range of the access to this reference. */
148 offset_int sizrange[2];
149
150 /* True for "bounded" string functions like strncat, and strncpy
151 and their variants that specify either an exact or upper bound
152 on the size of the accesses they perform. For strncat both
153 the source and destination references are bounded. For strncpy
154 only the destination reference is. */
155 bool strbounded_p;
156
157 builtin_memref (tree, tree);
158
159 tree offset_out_of_bounds (int, offset_int[2]) const;
160
161 private:
162
163 /* Ctor helper to set or extend OFFRANGE based on argument. */
164 void extend_offset_range (tree);
165
166 /* Ctor helper to determine BASE and OFFRANGE from argument. */
167 void set_base_and_offset (tree);
168 };
169
170 /* Description of a memory access by a raw memory or string built-in
171 function involving a pair of builtin_memref's. */
172 class builtin_access
173 {
174 public:
175 /* Destination and source memory reference. */
176 builtin_memref* const dstref;
177 builtin_memref* const srcref;
178 /* The size range of the access. It's the greater of the accesses
179 to the two references. */
180 HOST_WIDE_INT sizrange[2];
181
182 /* The minimum and maximum offset of an overlap of the access
183 (if it does, in fact, overlap), and the size of the overlap. */
184 HOST_WIDE_INT ovloff[2];
185 HOST_WIDE_INT ovlsiz[2];
186
187 /* True to consider valid only accesses to the smallest subobject
188 and false for raw memory functions. */
189 bool strict () const
190 {
191 return detect_overlap != &builtin_access::generic_overlap;
192 }
193
194 builtin_access (gimple *, builtin_memref &, builtin_memref &);
195
196 /* Entry point to determine overlap. */
197 bool overlap ();
198
199 private:
200 /* Implementation functions used to determine overlap. */
201 bool generic_overlap ();
202 bool strcat_overlap ();
203 bool strcpy_overlap ();
204
205 bool no_overlap ()
206 {
207 return false;
208 }
209
210 offset_int overlap_size (const offset_int [2], const offset_int[2],
211 offset_int [2]);
212
213 private:
214 /* Temporaries used to compute the final result. */
215 offset_int dstoff[2];
216 offset_int srcoff[2];
217 offset_int dstsiz[2];
218 offset_int srcsiz[2];
219
220 /* Pointer to a member function to call to determine overlap. */
221 bool (builtin_access::*detect_overlap) ();
222 };
223
224 /* Initialize a memory reference representation from a pointer EXPR and
225 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed
226 to be unknown. */
227
228 builtin_memref::builtin_memref (tree expr, tree size)
229 : ptr (expr),
230 ref (),
231 base (),
232 basesize (-1),
233 refoff (HOST_WIDE_INT_MIN),
234 offrange (),
235 sizrange (),
236 strbounded_p ()
237 {
238 /* Unfortunately, wide_int default ctor is a no-op so array members
239 of the type must be set individually. */
240 offrange[0] = offrange[1] = 0;
241 sizrange[0] = sizrange[1] = 0;
242
243 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
244
245 /* Find the BASE object or pointer referenced by EXPR and set
246 the offset range OFFRANGE in the process. */
247 set_base_and_offset (expr);
248
249 if (size)
250 {
251 tree range[2];
252 /* Determine the size range, allowing for the result to be [0, 0]
253 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */
254 get_size_range (size, range, true);
255 sizrange[0] = wi::to_offset (range[0]);
256 sizrange[1] = wi::to_offset (range[1]);
257 /* get_size_range returns SIZE_MAX for the maximum size.
258 Constrain it to the real maximum of PTRDIFF_MAX. */
259 if (sizrange[1] > maxobjsize)
260 sizrange[1] = maxobjsize;
261 }
262 else
263 sizrange[1] = maxobjsize;
264
265 if (!DECL_P (base))
266 return;
267
268 /* If the offset could be in the range of the referenced object
269 constrain its bounds so neither exceeds those of the object. */
270 if (offrange[0] < 0 && offrange[1] > 0)
271 offrange[0] = 0;
272
273 offset_int maxoff = maxobjsize;
274 tree basetype = TREE_TYPE (base);
275 if (TREE_CODE (basetype) == ARRAY_TYPE
276 && ref
277 && array_at_struct_end_p (ref))
278 ; /* Use the maximum possible offset for last member arrays. */
279 else if (tree basesize = TYPE_SIZE_UNIT (basetype))
280 if (TREE_CODE (basesize) == INTEGER_CST)
281 /* Size could be non-constant for a variable-length type such
282 as a struct with a VLA member (a GCC extension). */
283 maxoff = wi::to_offset (basesize);
284
285 if (offrange[0] >= 0)
286 {
287 if (offrange[1] < 0)
288 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
289 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
290 offrange[1] = maxoff;
291 }
292 }
293
294 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
295
296 void
297 builtin_memref::extend_offset_range (tree offset)
298 {
299 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
300
301 if (TREE_CODE (offset) == INTEGER_CST)
302 {
303 offset_int off = int_cst_value (offset);
304 if (off != 0)
305 {
306 offrange[0] += off;
307 offrange[1] += off;
308 }
309 return;
310 }
311
312 if (TREE_CODE (offset) == SSA_NAME)
313 {
314 wide_int min, max;
315 value_range_kind rng = get_range_info (offset, &min, &max);
316 if (rng == VR_RANGE)
317 {
318 offrange[0] += offset_int::from (min, SIGNED);
319 offrange[1] += offset_int::from (max, SIGNED);
320 }
321 else if (rng == VR_ANTI_RANGE)
322 {
323 offrange[0] += offset_int::from (max + 1, SIGNED);
324 offrange[1] += offset_int::from (min - 1, SIGNED);
325 }
326 else
327 {
328 gimple *stmt = SSA_NAME_DEF_STMT (offset);
329 tree type;
330 if (is_gimple_assign (stmt)
331 && gimple_assign_rhs_code (stmt) == NOP_EXPR
332 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
333 && INTEGRAL_TYPE_P (type))
334 {
335 /* Use the bounds of the type of the NOP_EXPR operand
336 even if it's signed. The result doesn't trigger
337 warnings but makes their output more readable. */
338 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
339 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
340 }
341 else
342 offrange[1] += maxobjsize;
343 }
344 return;
345 }
346
347 offrange[1] += maxobjsize;
348 }
349
350 /* Determines the base object or pointer of the reference EXPR
351 and the offset range from the beginning of the base. */
352
353 void
354 builtin_memref::set_base_and_offset (tree expr)
355 {
356 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
357
358 if (TREE_CODE (expr) == SSA_NAME)
359 {
360 /* Try to tease the offset out of the pointer. */
361 gimple *stmt = SSA_NAME_DEF_STMT (expr);
362 if (!base
363 && gimple_assign_single_p (stmt)
364 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
365 expr = gimple_assign_rhs1 (stmt);
366 else if (is_gimple_assign (stmt))
367 {
368 tree_code code = gimple_assign_rhs_code (stmt);
369 if (code == NOP_EXPR)
370 {
371 tree rhs = gimple_assign_rhs1 (stmt);
372 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
373 expr = gimple_assign_rhs1 (stmt);
374 else
375 {
376 base = expr;
377 return;
378 }
379 }
380 else if (code == POINTER_PLUS_EXPR)
381 {
382 expr = gimple_assign_rhs1 (stmt);
383
384 tree offset = gimple_assign_rhs2 (stmt);
385 extend_offset_range (offset);
386 }
387 else
388 {
389 base = expr;
390 return;
391 }
392 }
393 else
394 {
395 base = expr;
396 return;
397 }
398 }
399
400 if (TREE_CODE (expr) == ADDR_EXPR)
401 expr = TREE_OPERAND (expr, 0);
402
403 /* Stash the reference for offset validation. */
404 ref = expr;
405
406 poly_int64 bitsize, bitpos;
407 tree var_off;
408 machine_mode mode;
409 int sign, reverse, vol;
410
411 /* Determine the base object or pointer of the reference and
412 the constant bit offset from the beginning of the base.
413 If the offset has a non-constant component, it will be in
414 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
415 unused here. */
416 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
417 &mode, &sign, &reverse, &vol);
418
419 /* get_inner_reference is not expected to return null. */
420 gcc_assert (base != NULL);
421
422 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
423
424 /* Convert the poly_int64 offset to offset_int. The offset
425 should be constant but be prepared for it not to be just in
426 case. */
427 offset_int cstoff;
428 if (bytepos.is_constant (&cstoff))
429 {
430 offrange[0] += cstoff;
431 offrange[1] += cstoff;
432
433 /* Besides the reference saved above, also stash the offset
434 for validation. */
435 if (TREE_CODE (expr) == COMPONENT_REF)
436 refoff = cstoff;
437 }
438 else
439 offrange[1] += maxobjsize;
440
441 if (var_off)
442 {
443 if (TREE_CODE (var_off) == INTEGER_CST)
444 {
445 cstoff = wi::to_offset (var_off);
446 offrange[0] += cstoff;
447 offrange[1] += cstoff;
448 }
449 else
450 offrange[1] += maxobjsize;
451 }
452
453 if (TREE_CODE (base) == MEM_REF)
454 {
455 tree memrefoff = TREE_OPERAND (base, 1);
456 extend_offset_range (memrefoff);
457 base = TREE_OPERAND (base, 0);
458 }
459
460 if (TREE_CODE (base) == SSA_NAME)
461 set_base_and_offset (base);
462 }
463
464 /* Return error_mark_node if the signed offset exceeds the bounds
465 of the address space (PTRDIFF_MAX). Otherwise, return either
466 BASE or REF when the offset exceeds the bounds of the BASE or
467 REF object, and set OOBOFF to the past-the-end offset formed
468 by the reference, including its size. When STRICT is non-zero
469 use REF size, when available, otherwise use BASE size. When
470 STRICT is greater than 1, use the size of the last array member
471 as the bound, otherwise treat such a member as a flexible array
472 member. Return NULL when the offset is in bounds. */
473
474 tree
475 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const
476 {
477 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
478
479 /* A temporary, possibly adjusted, copy of the offset range. */
480 offset_int offrng[2] = { offrange[0], offrange[1] };
481
482 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
483 {
484 /* Check for offset in an anti-range with a negative lower bound.
485 For such a range, consider only the non-negative subrange. */
486 if (offrng[1] < offrng[0] && offrng[1] < 0)
487 offrng[1] = maxobjsize;
488 }
489
490 /* Conservative offset of the last byte of the referenced object. */
491 offset_int endoff;
492
493 /* The bounds need not be ordered. Set HIB to use as the index
494 of the larger of the bounds and LOB as the opposite. */
495 bool hib = wi::les_p (offrng[0], offrng[1]);
496 bool lob = !hib;
497
498 if (basesize < 0)
499 {
500 endoff = offrng[lob] + sizrange[0];
501
502 /* For a reference through a pointer to an object of unknown size
503 all initial offsets are considered valid, positive as well as
504 negative, since the pointer itself can point past the beginning
505 of the object. However, the sum of the lower bound of the offset
506 and that of the size must be less than or equal than PTRDIFF_MAX. */
507 if (endoff > maxobjsize)
508 return error_mark_node;
509
510 return NULL_TREE;
511 }
512
513 /* A reference to an object of known size must be within the bounds
514 of the base object. */
515 if (offrng[hib] < 0 || offrng[lob] > basesize)
516 return base;
517
518 /* The extent of the reference must also be within the bounds of
519 the base object (if known) or the maximum object size otherwise. */
520 endoff = wi::smax (offrng[lob], 0) + sizrange[0];
521 if (endoff > maxobjsize)
522 return error_mark_node;
523
524 offset_int size = basesize;
525 tree obj = base;
526
527 if (strict
528 && DECL_P (obj)
529 && ref
530 && refoff >= 0
531 && TREE_CODE (ref) == COMPONENT_REF
532 && (strict > 1
533 || !array_at_struct_end_p (ref)))
534 {
535 /* If the reference is to a member subobject, the offset must
536 be within the bounds of the subobject. */
537 tree field = TREE_OPERAND (ref, 1);
538 tree type = TREE_TYPE (field);
539 if (tree sz = TYPE_SIZE_UNIT (type))
540 if (TREE_CODE (sz) == INTEGER_CST)
541 {
542 size = refoff + wi::to_offset (sz);
543 obj = ref;
544 }
545 }
546
547 if (endoff <= size)
548 return NULL_TREE;
549
550 /* Set the out-of-bounds offset range to be one greater than
551 that delimited by the reference including its size. */
552 ooboff[lob] = size + 1;
553
554 if (endoff > ooboff[lob])
555 ooboff[hib] = endoff;
556 else
557 ooboff[hib] = wi::smax (offrng[lob], 0) + sizrange[1];
558
559 return obj;
560 }
561
562 /* Create an association between the memory references DST and SRC
563 for access by a call EXPR to a memory or string built-in funtion. */
564
565 builtin_access::builtin_access (gimple *call, builtin_memref &dst,
566 builtin_memref &src)
567 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
568 dstoff (), srcoff (), dstsiz (), srcsiz ()
569 {
570 /* Zero out since the offset_int ctors invoked above are no-op. */
571 dstoff[0] = dstoff[1] = 0;
572 srcoff[0] = srcoff[1] = 0;
573 dstsiz[0] = dstsiz[1] = 0;
574 srcsiz[0] = srcsiz[1] = 0;
575
576 /* Object Size Type to use to determine the size of the destination
577 and source objects. Overridden below for raw memory functions. */
578 int ostype = 1;
579
580 /* True when the size of one reference depends on the offset of
581 itself or the other. */
582 bool depends_p = true;
583
584 /* True when the size of the destination reference DSTREF has been
585 determined from SRCREF and so needs to be adjusted by the latter's
586 offset. Only meaningful for bounded string functions like strncpy. */
587 bool dstadjust_p = false;
588
589 /* The size argument number (depends on the built-in). */
590 unsigned sizeargno = 2;
591
592 tree func = gimple_call_fndecl (call);
593 switch (DECL_FUNCTION_CODE (func))
594 {
595 case BUILT_IN_MEMCPY:
596 case BUILT_IN_MEMCPY_CHK:
597 case BUILT_IN_MEMPCPY:
598 case BUILT_IN_MEMPCPY_CHK:
599 ostype = 0;
600 depends_p = false;
601 detect_overlap = &builtin_access::generic_overlap;
602 break;
603
604 case BUILT_IN_MEMMOVE:
605 case BUILT_IN_MEMMOVE_CHK:
606 /* For memmove there is never any overlap to check for. */
607 ostype = 0;
608 depends_p = false;
609 detect_overlap = &builtin_access::no_overlap;
610 break;
611
612 case BUILT_IN_STPNCPY:
613 case BUILT_IN_STPNCPY_CHK:
614 case BUILT_IN_STRNCPY:
615 case BUILT_IN_STRNCPY_CHK:
616 dstref->strbounded_p = true;
617 detect_overlap = &builtin_access::strcpy_overlap;
618 break;
619
620 case BUILT_IN_STPCPY:
621 case BUILT_IN_STPCPY_CHK:
622 case BUILT_IN_STRCPY:
623 case BUILT_IN_STRCPY_CHK:
624 detect_overlap = &builtin_access::strcpy_overlap;
625 break;
626
627 case BUILT_IN_STRCAT:
628 case BUILT_IN_STRCAT_CHK:
629 detect_overlap = &builtin_access::strcat_overlap;
630 break;
631
632 case BUILT_IN_STRNCAT:
633 case BUILT_IN_STRNCAT_CHK:
634 dstref->strbounded_p = true;
635 srcref->strbounded_p = true;
636 detect_overlap = &builtin_access::strcat_overlap;
637 break;
638
639 default:
640 /* Handle other string functions here whose access may need
641 to be validated for in-bounds offsets and non-overlapping
642 copies. */
643 return;
644 }
645
646 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
647
648 /* Try to determine the size of the base object. compute_objsize
649 expects a pointer so create one if BASE is a non-pointer object. */
650 tree addr;
651 if (dst.basesize < 0)
652 {
653 addr = dst.base;
654 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
655 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
656
657 if (tree dstsize = compute_objsize (addr, ostype))
658 dst.basesize = wi::to_offset (dstsize);
659 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
660 dst.basesize = HOST_WIDE_INT_MIN;
661 else
662 dst.basesize = maxobjsize;
663 }
664
665 if (src.basesize < 0)
666 {
667 addr = src.base;
668 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
669 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
670
671 if (tree srcsize = compute_objsize (addr, ostype))
672 src.basesize = wi::to_offset (srcsize);
673 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
674 src.basesize = HOST_WIDE_INT_MIN;
675 else
676 src.basesize = maxobjsize;
677 }
678
679 /* If there is no dependency between the references or the base
680 objects of the two references aren't the same there's nothing
681 else to do. */
682 if (depends_p && dstref->base != srcref->base)
683 return;
684
685 /* ...otherwise, make adjustments for references to the same object
686 by string built-in functions to reflect the constraints imposed
687 by the function. */
688
689 /* For bounded string functions determine the range of the bound
690 on the access. For others, the range stays unbounded. */
691 offset_int bounds[2] = { maxobjsize, maxobjsize };
692 if (dstref->strbounded_p)
693 {
694 tree size = gimple_call_arg (call, sizeargno);
695 tree range[2];
696 if (get_size_range (size, range, true))
697 {
698 bounds[0] = wi::to_offset (range[0]);
699 bounds[1] = wi::to_offset (range[1]);
700 }
701
702 /* If both references' size ranges are indeterminate use the last
703 (size) argument from the function call as a substitute. This
704 may only be necessary for strncpy (but not for memcpy where
705 the size range would have been already determined this way). */
706 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
707 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
708 {
709 dstref->sizrange[0] = bounds[0];
710 dstref->sizrange[1] = bounds[1];
711 }
712 }
713
714 /* The size range of one reference involving the same base object
715 can be determined from the size range of the other reference.
716 This makes it possible to compute accurate offsets for warnings
717 involving functions like strcpy where the length of just one of
718 the two arguments is known (determined by tree-ssa-strlen). */
719 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
720 {
721 /* When the destination size is unknown set it to the size of
722 the source. */
723 dstref->sizrange[0] = srcref->sizrange[0];
724 dstref->sizrange[1] = srcref->sizrange[1];
725 }
726 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
727 {
728 /* When the source size is unknown set it to the size of
729 the destination. */
730 srcref->sizrange[0] = dstref->sizrange[0];
731 srcref->sizrange[1] = dstref->sizrange[1];
732
733 if (depends_p)
734 {
735 if (dstref->strbounded_p)
736 {
737 /* Read access by strncpy is bounded. */
738 if (bounds[0] < srcref->sizrange[0])
739 srcref->sizrange[0] = bounds[0];
740 if (bounds[1] < srcref->sizrange[1])
741 srcref->sizrange[1] = bounds[1];
742 }
743
744 /* For string functions, adjust the size range of the source
745 reference by the inverse boundaries of the offset (because
746 the higher the offset into the string the shorter its
747 length). */
748 if (srcref->offrange[1] >= 0
749 && srcref->offrange[1] < srcref->sizrange[0])
750 srcref->sizrange[0] -= srcref->offrange[1];
751 else
752 srcref->sizrange[0] = 0;
753
754 if (srcref->offrange[0] > 0)
755 {
756 if (srcref->offrange[0] < srcref->sizrange[1])
757 srcref->sizrange[1] -= srcref->offrange[0];
758 else
759 srcref->sizrange[1] = 0;
760 }
761
762 dstadjust_p = true;
763 }
764 }
765
766 if (detect_overlap == &builtin_access::generic_overlap)
767 {
768 if (dstref->strbounded_p)
769 {
770 dstref->sizrange[0] = bounds[0];
771 dstref->sizrange[1] = bounds[1];
772
773 if (dstref->sizrange[0] < srcref->sizrange[0])
774 srcref->sizrange[0] = dstref->sizrange[0];
775
776 if (dstref->sizrange[1] < srcref->sizrange[1])
777 srcref->sizrange[1] = dstref->sizrange[1];
778 }
779 }
780 else if (detect_overlap == &builtin_access::strcpy_overlap)
781 {
782 if (!dstref->strbounded_p)
783 {
784 /* For strcpy, adjust the destination size range to match that
785 of the source computed above. */
786 if (depends_p && dstadjust_p)
787 {
788 dstref->sizrange[0] = srcref->sizrange[0];
789 dstref->sizrange[1] = srcref->sizrange[1];
790 }
791 }
792 }
793
794 if (dstref->strbounded_p)
795 {
796 /* For strncpy, adjust the destination size range to match that
797 of the source computed above. */
798 dstref->sizrange[0] = bounds[0];
799 dstref->sizrange[1] = bounds[1];
800
801 if (bounds[0] < srcref->sizrange[0])
802 srcref->sizrange[0] = bounds[0];
803
804 if (bounds[1] < srcref->sizrange[1])
805 srcref->sizrange[1] = bounds[1];
806 }
807 }
808
809 offset_int
810 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
811 offset_int *off)
812 {
813 const offset_int *p = a;
814 const offset_int *q = b;
815
816 /* Point P at the bigger of the two ranges and Q at the smaller. */
817 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
818 {
819 p = b;
820 q = a;
821 }
822
823 if (p[0] < q[0])
824 {
825 if (p[1] < q[0])
826 return 0;
827
828 *off = q[0];
829 return wi::smin (p[1], q[1]) - q[0];
830 }
831
832 if (q[1] < p[0])
833 return 0;
834
835 off[0] = p[0];
836 return q[1] - p[0];
837 }
838
839 /* Return true if the bounded mempry (memcpy amd similar) or string function
840 access (strncpy and similar) ACS overlaps. */
841
842 bool
843 builtin_access::generic_overlap ()
844 {
845 builtin_access &acs = *this;
846 const builtin_memref *dstref = acs.dstref;
847 const builtin_memref *srcref = acs.srcref;
848
849 gcc_assert (dstref->base == srcref->base);
850
851 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
852
853 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
854 gcc_assert (maxsize <= maxobjsize);
855
856 /* Adjust the larger bounds of the offsets (which may be the first
857 element if the lower bound is larger than the upper bound) to
858 make them valid for the smallest access (if possible) but no smaller
859 than the smaller bounds. */
860 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
861
862 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
863 acs.dstoff[1] = maxsize - acs.dstsiz[0];
864 if (acs.dstoff[1] < acs.dstoff[0])
865 acs.dstoff[1] = acs.dstoff[0];
866
867 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
868
869 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
870 acs.srcoff[1] = maxsize - acs.srcsiz[0];
871 if (acs.srcoff[1] < acs.srcoff[0])
872 acs.srcoff[1] = acs.srcoff[0];
873
874 /* Determine the minimum and maximum space for the access given
875 the offsets. */
876 offset_int space[2];
877 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
878 space[1] = space[0];
879
880 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
881 if (acs.srcsiz[0] > 0)
882 {
883 if (d < space[0])
884 space[0] = d;
885
886 if (space[1] < d)
887 space[1] = d;
888 }
889 else
890 space[1] = acs.dstsiz[1];
891
892 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
893 if (d < space[0])
894 space[0] = d;
895
896 if (space[1] < d)
897 space[1] = d;
898
899 /* Treat raw memory functions both of whose references are bounded
900 as special and permit uncertain overlaps to go undetected. For
901 all kinds of constant offset and constant size accesses, if
902 overlap isn't certain it is not possible. */
903 bool overlap_possible = space[0] < acs.dstsiz[1];
904 if (!overlap_possible)
905 return false;
906
907 bool overlap_certain = space[1] < acs.dstsiz[0];
908
909 /* True when the size of one reference depends on the offset of
910 the other. */
911 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
912
913 if (!overlap_certain)
914 {
915 if (!dstref->strbounded_p && !depends_p)
916 /* Memcpy only considers certain overlap. */
917 return false;
918
919 /* There's no way to distinguish an access to the same member
920 of a structure from one to two distinct members of the same
921 structure. Give up to avoid excessive false positives. */
922 tree basetype = TREE_TYPE (dstref->base);
923
924 if (POINTER_TYPE_P (basetype))
925 basetype = TREE_TYPE (basetype);
926 else
927 while (TREE_CODE (basetype) == ARRAY_TYPE)
928 basetype = TREE_TYPE (basetype);
929
930 if (RECORD_OR_UNION_TYPE_P (basetype))
931 return false;
932 }
933
934 /* True for stpcpy and strcpy. */
935 bool stxcpy_p = (!dstref->strbounded_p
936 && detect_overlap == &builtin_access::strcpy_overlap);
937
938 if (dstref->refoff >= 0
939 && srcref->refoff >= 0
940 && dstref->refoff != srcref->refoff
941 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
942 return false;
943
944 offset_int siz[2] = { maxobjsize + 1, 0 };
945
946 ovloff[0] = HOST_WIDE_INT_MAX;
947 ovloff[1] = HOST_WIDE_INT_MIN;
948
949 /* Adjustment to the lower bound of the offset of the overlap to
950 account for a subset of unbounded string calls where the size
951 of the destination string depends on the length of the source
952 which in turn depends on the offset into it. */
953 bool sub1;
954
955 if (stxcpy_p)
956 {
957 sub1 = acs.dstoff[0] <= acs.srcoff[0];
958
959 /* Iterate over the extreme locations (on the horizontal axis formed
960 by their offsets) and sizes of two regions and find their smallest
961 and largest overlap and the corresponding offsets. */
962 for (unsigned i = 0; i != 2; ++i)
963 {
964 const offset_int a[2] = {
965 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
966 };
967
968 const offset_int b[2] = {
969 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
970 };
971
972 offset_int off;
973 offset_int sz = overlap_size (a, b, &off);
974 if (sz < siz[0])
975 siz[0] = sz;
976
977 if (siz[1] <= sz)
978 siz[1] = sz;
979
980 if (sz != 0)
981 {
982 if (wi::lts_p (off, ovloff[0]))
983 ovloff[0] = off.to_shwi ();
984 if (wi::lts_p (ovloff[1], off))
985 ovloff[1] = off.to_shwi ();
986 }
987 }
988 }
989 else
990 {
991 sub1 = !depends_p;
992
993 /* Iterate over the extreme locations (on the horizontal axis
994 formed by their offsets) and sizes of two regions and find
995 their smallest and largest overlap and the corresponding
996 offsets. */
997
998 for (unsigned io = 0; io != 2; ++io)
999 for (unsigned is = 0; is != 2; ++is)
1000 {
1001 const offset_int a[2] = {
1002 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1003 };
1004
1005 for (unsigned jo = 0; jo != 2; ++jo)
1006 for (unsigned js = 0; js != 2; ++js)
1007 {
1008 if (depends_p)
1009 {
1010 /* For st{p,r}ncpy the size of the source sequence
1011 depends on the offset into it. */
1012 if (js)
1013 break;
1014 js = !jo;
1015 }
1016
1017 const offset_int b[2] = {
1018 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1019 };
1020
1021 offset_int off;
1022 offset_int sz = overlap_size (a, b, &off);
1023 if (sz < siz[0])
1024 siz[0] = sz;
1025
1026 if (siz[1] <= sz)
1027 siz[1] = sz;
1028
1029 if (sz != 0)
1030 {
1031 if (wi::lts_p (off, ovloff[0]))
1032 ovloff[0] = off.to_shwi ();
1033 if (wi::lts_p (ovloff[1], off))
1034 ovloff[1] = off.to_shwi ();
1035 }
1036 }
1037 }
1038 }
1039
1040 ovlsiz[0] = siz[0].to_shwi ();
1041 ovlsiz[1] = siz[1].to_shwi ();
1042
1043 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1044 ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
1045
1046 return true;
1047 }
1048
1049 /* Return true if the strcat-like access overlaps. */
1050
1051 bool
1052 builtin_access::strcat_overlap ()
1053 {
1054 builtin_access &acs = *this;
1055 const builtin_memref *dstref = acs.dstref;
1056 const builtin_memref *srcref = acs.srcref;
1057
1058 gcc_assert (dstref->base == srcref->base);
1059
1060 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1061
1062 gcc_assert (dstref->base && dstref->base == srcref->base);
1063
1064 /* Adjust for strcat-like accesses. */
1065
1066 /* As a special case for strcat, set the DSTREF offsets to the length
1067 of the source string since the function starts writing at the first
1068 nul, and set the size to 1 for the length of the nul. */
1069 acs.dstoff[0] += acs.dstsiz[0];
1070 acs.dstoff[1] += acs.dstsiz[1];
1071
1072 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1073
1074 /* The lower bound is zero when the size is unknown because then
1075 overlap is not certain. */
1076 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1077 acs.dstsiz[1] = 1;
1078
1079 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1080 gcc_assert (maxsize <= maxobjsize);
1081
1082 /* For references to the same base object, determine if there's a pair
1083 of valid offsets into the two references such that access between
1084 them doesn't overlap. Adjust both upper bounds to be valid for
1085 the smaller size (i.e., at most MAXSIZE - SIZE). */
1086
1087 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1088 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1089
1090 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1091 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1092
1093 /* Check to see if there's enough space for both accesses without
1094 overlap. Determine the optimistic (maximum) amount of available
1095 space. */
1096 offset_int space;
1097 if (acs.dstoff[0] <= acs.srcoff[0])
1098 {
1099 if (acs.dstoff[1] < acs.srcoff[1])
1100 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1101 else
1102 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1103 }
1104 else
1105 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1106
1107 /* Overlap is certain if the distance between the farthest offsets
1108 of the opposite accesses is less than the sum of the lower bounds
1109 of the sizes of the two accesses. */
1110 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1111
1112 /* For a constant-offset, constant size access, consider the largest
1113 distance between the offset bounds and the lower bound of the access
1114 size. If the overlap isn't certain return success. */
1115 if (!overlap_certain
1116 && acs.dstoff[0] == acs.dstoff[1]
1117 && acs.srcoff[0] == acs.srcoff[1]
1118 && acs.dstsiz[0] == acs.dstsiz[1]
1119 && acs.srcsiz[0] == acs.srcsiz[1])
1120 return false;
1121
1122 /* Overlap is not certain but may be possible. */
1123
1124 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1125
1126 /* Determine the conservative (minimum) amount of space. */
1127 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1128 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1129 if (d < space)
1130 space = d;
1131 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1132 if (d < space)
1133 space = d;
1134
1135 /* For a strict test (used for strcpy and similar with unknown or
1136 variable bounds or sizes), consider the smallest distance between
1137 the offset bounds and either the upper bound of the access size
1138 if known, or the lower bound otherwise. */
1139 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1140 return false;
1141
1142 /* When strcat overlap is certain it is always a single byte:
1143 the terminating NUL, regardless of offsets and sizes. When
1144 overlap is only possible its range is [0, 1]. */
1145 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1146 acs.ovlsiz[1] = 1;
1147
1148 offset_int endoff = dstref->offrange[0] + dstref->sizrange[0];
1149 if (endoff <= srcref->offrange[0])
1150 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1151 else
1152 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1153
1154 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1155 srcref->sizrange[0]).to_shwi ();
1156 if (dstref->offrange[0] == dstref->offrange[1])
1157 {
1158 if (srcref->offrange[0] == srcref->offrange[1])
1159 acs.ovloff[1] = acs.ovloff[0];
1160 else
1161 acs.ovloff[1]
1162 = wi::smin (maxobjsize,
1163 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1164 }
1165 else
1166 acs.ovloff[1]
1167 = wi::smin (maxobjsize,
1168 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1169
1170 if (acs.sizrange[0] == 0)
1171 acs.sizrange[0] = 1;
1172 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1173 return true;
1174 }
1175
1176 /* Return true if the strcpy-like access overlaps. */
1177
1178 bool
1179 builtin_access::strcpy_overlap ()
1180 {
1181 return generic_overlap ();
1182 }
1183
1184
1185 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1186 one another or that, in order not to overlap, would imply that the size
1187 of the referenced object(s) exceeds the maximum size of an object. Set
1188 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1189 they may overlap in a way that's not apparent from the available data),
1190 return false. */
1191
1192 bool
1193 builtin_access::overlap ()
1194 {
1195 builtin_access &acs = *this;
1196
1197 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1198
1199 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1200 srcref->sizrange[0]).to_shwi ();
1201 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1202 srcref->sizrange[1]).to_shwi ();
1203
1204 /* Check to see if the two references refer to regions that are
1205 too large not to overlap in the address space (whose maximum
1206 size is PTRDIFF_MAX). */
1207 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1208 if (maxobjsize < size)
1209 {
1210 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1211 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1212 return true;
1213 }
1214
1215 /* If both base objects aren't known return the maximum possible
1216 offset that would make them not overlap. */
1217 if (!dstref->base || !srcref->base)
1218 return false;
1219
1220 /* Set the access offsets. */
1221 acs.dstoff[0] = dstref->offrange[0];
1222 acs.dstoff[1] = dstref->offrange[1];
1223
1224 /* If the base object is an array adjust the bounds of the offset
1225 to be non-negative and within the bounds of the array if possible. */
1226 if (dstref->base
1227 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1228 {
1229 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1230 acs.dstoff[0] = 0;
1231
1232 if (acs.dstoff[1] < acs.dstoff[0])
1233 {
1234 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1235 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1236 else
1237 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1238 }
1239 }
1240
1241 acs.srcoff[0] = srcref->offrange[0];
1242 acs.srcoff[1] = srcref->offrange[1];
1243
1244 if (srcref->base
1245 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1246 {
1247 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1248 acs.srcoff[0] = 0;
1249
1250 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1251 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1252 else if (acs.srcoff[1] < acs.srcoff[0])
1253 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1254 }
1255
1256 /* When the upper bound of the offset is less than the lower bound
1257 the former is the result of a negative offset being represented
1258 as a large positive value or vice versa. The resulting range is
1259 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1260 a union is not representable using the current data structure
1261 replace it with the full range of offsets. */
1262 if (acs.dstoff[1] < acs.dstoff[0])
1263 {
1264 acs.dstoff[0] = -maxobjsize - 1;
1265 acs.dstoff[1] = maxobjsize;
1266 }
1267
1268 /* Validate the offset and size of each reference on its own first.
1269 This is independent of whether or not the base objects are the
1270 same. Normally, this would have already been detected and
1271 diagnosed by -Warray-bounds, unless it has been disabled. */
1272 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1273 if (maxobjsize < maxoff)
1274 {
1275 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1276 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1277 return true;
1278 }
1279
1280 /* Repeat the same as above but for the source offsets. */
1281 if (acs.srcoff[1] < acs.srcoff[0])
1282 {
1283 acs.srcoff[0] = -maxobjsize - 1;
1284 acs.srcoff[1] = maxobjsize;
1285 }
1286
1287 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1288 if (maxobjsize < maxoff)
1289 {
1290 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1291 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1292 - maxobjsize).to_shwi ();
1293 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1294 return true;
1295 }
1296
1297 if (dstref->base != srcref->base)
1298 return false;
1299
1300 acs.dstsiz[0] = dstref->sizrange[0];
1301 acs.dstsiz[1] = dstref->sizrange[1];
1302
1303 acs.srcsiz[0] = srcref->sizrange[0];
1304 acs.srcsiz[1] = srcref->sizrange[1];
1305
1306 /* Call the appropriate function to determine the overlap. */
1307 if ((this->*detect_overlap) ())
1308 {
1309 if (!sizrange[1])
1310 {
1311 /* Unless the access size range has already been set, do so here. */
1312 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1313 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1314 }
1315 return true;
1316 }
1317
1318 return false;
1319 }
1320
1321 /* Attempt to detect and diagnose an overlapping copy in a call expression
1322 EXPR involving an an access ACS to a built-in memory or string function.
1323 Return true when one has been detected, false otherwise. */
1324
1325 static bool
1326 maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
1327 {
1328 if (!acs.overlap ())
1329 return false;
1330
1331 /* For convenience. */
1332 const builtin_memref &dstref = *acs.dstref;
1333 const builtin_memref &srcref = *acs.srcref;
1334
1335 /* Determine the range of offsets and sizes of the overlap if it
1336 exists and issue diagnostics. */
1337 HOST_WIDE_INT *ovloff = acs.ovloff;
1338 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1339 HOST_WIDE_INT *sizrange = acs.sizrange;
1340
1341 tree func = gimple_call_fndecl (call);
1342
1343 /* To avoid a combinatorial explosion of diagnostics format the offsets
1344 or their ranges as strings and use them in the warning calls below. */
1345 char offstr[3][64];
1346
1347 if (dstref.offrange[0] == dstref.offrange[1]
1348 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1349 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1350 dstref.offrange[0].to_shwi ());
1351 else
1352 sprintf (offstr[0],
1353 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1354 dstref.offrange[0].to_shwi (),
1355 dstref.offrange[1].to_shwi ());
1356
1357 if (srcref.offrange[0] == srcref.offrange[1]
1358 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1359 sprintf (offstr[1],
1360 HOST_WIDE_INT_PRINT_DEC,
1361 srcref.offrange[0].to_shwi ());
1362 else
1363 sprintf (offstr[1],
1364 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1365 srcref.offrange[0].to_shwi (),
1366 srcref.offrange[1].to_shwi ());
1367
1368 if (ovloff[0] == ovloff[1] || !ovloff[1])
1369 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1370 else
1371 sprintf (offstr[2],
1372 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1373 ovloff[0], ovloff[1]);
1374
1375 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1376 bool must_overlap = ovlsiz[0] > 0;
1377
1378 if (ovlsiz[1] == 0)
1379 ovlsiz[1] = ovlsiz[0];
1380
1381 if (must_overlap)
1382 {
1383 /* Issue definitive "overlaps" diagnostic in this block. */
1384
1385 if (sizrange[0] == sizrange[1])
1386 {
1387 if (ovlsiz[0] == ovlsiz[1])
1388 warning_at (loc, OPT_Wrestrict,
1389 sizrange[0] == 1
1390 ? (ovlsiz[0] == 1
1391 ? G_("%G%qD accessing %wu byte at offsets %s "
1392 "and %s overlaps %wu byte at offset %s")
1393 : G_("%G%qD accessing %wu byte at offsets %s "
1394 "and %s overlaps %wu bytes at offset "
1395 "%s"))
1396 : (ovlsiz[0] == 1
1397 ? G_("%G%qD accessing %wu bytes at offsets %s "
1398 "and %s overlaps %wu byte at offset %s")
1399 : G_("%G%qD accessing %wu bytes at offsets %s "
1400 "and %s overlaps %wu bytes at offset "
1401 "%s")),
1402 call, func, sizrange[0],
1403 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1404 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1405 warning_n (loc, OPT_Wrestrict, sizrange[0],
1406 "%G%qD accessing %wu byte at offsets %s "
1407 "and %s overlaps between %wu and %wu bytes "
1408 "at offset %s",
1409 "%G%qD accessing %wu bytes at offsets %s "
1410 "and %s overlaps between %wu and %wu bytes "
1411 "at offset %s",
1412 call, func, sizrange[0], offstr[0], offstr[1],
1413 ovlsiz[0], ovlsiz[1], offstr[2]);
1414 else
1415 warning_n (loc, OPT_Wrestrict, sizrange[0],
1416 "%G%qD accessing %wu byte at offsets %s and "
1417 "%s overlaps %wu or more bytes at offset %s",
1418 "%G%qD accessing %wu bytes at offsets %s and "
1419 "%s overlaps %wu or more bytes at offset %s",
1420 call, func, sizrange[0],
1421 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1422 return true;
1423 }
1424
1425 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1426 {
1427 if (ovlsiz[0] == ovlsiz[1])
1428 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1429 "%G%qD accessing between %wu and %wu bytes "
1430 "at offsets %s and %s overlaps %wu byte at "
1431 "offset %s",
1432 "%G%qD accessing between %wu and %wu bytes "
1433 "at offsets %s and %s overlaps %wu bytes "
1434 "at offset %s",
1435 call, func, sizrange[0], sizrange[1],
1436 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1437 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1438 warning_at (loc, OPT_Wrestrict,
1439 "%G%qD accessing between %wu and %wu bytes at "
1440 "offsets %s and %s overlaps between %wu and %wu "
1441 "bytes at offset %s",
1442 call, func, sizrange[0], sizrange[1],
1443 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1444 offstr[2]);
1445 else
1446 warning_at (loc, OPT_Wrestrict,
1447 "%G%qD accessing between %wu and %wu bytes at "
1448 "offsets %s and %s overlaps %wu or more bytes "
1449 "at offset %s",
1450 call, func, sizrange[0], sizrange[1],
1451 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1452 return true;
1453 }
1454
1455 if (ovlsiz[0] != ovlsiz[1])
1456 ovlsiz[1] = maxobjsize.to_shwi ();
1457
1458 if (ovlsiz[0] == ovlsiz[1])
1459 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1460 "%G%qD accessing %wu or more bytes at offsets "
1461 "%s and %s overlaps %wu byte at offset %s",
1462 "%G%qD accessing %wu or more bytes at offsets "
1463 "%s and %s overlaps %wu bytes at offset %s",
1464 call, func, sizrange[0], offstr[0], offstr[1],
1465 ovlsiz[0], offstr[2]);
1466 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1467 warning_at (loc, OPT_Wrestrict,
1468 "%G%qD accessing %wu or more bytes at offsets %s "
1469 "and %s overlaps between %wu and %wu bytes "
1470 "at offset %s",
1471 call, func, sizrange[0], offstr[0], offstr[1],
1472 ovlsiz[0], ovlsiz[1], offstr[2]);
1473 else
1474 warning_at (loc, OPT_Wrestrict,
1475 "%G%qD accessing %wu or more bytes at offsets %s "
1476 "and %s overlaps %wu or more bytes at offset %s",
1477 call, func, sizrange[0], offstr[0], offstr[1],
1478 ovlsiz[0], offstr[2]);
1479 return true;
1480 }
1481
1482 /* Use more concise wording when one of the offsets is unbounded
1483 to avoid confusing the user with large and mostly meaningless
1484 numbers. */
1485 bool open_range;
1486 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1487 open_range = ((dstref.offrange[0] == 0
1488 && dstref.offrange[1] == maxobjsize)
1489 || (srcref.offrange[0] == 0
1490 && srcref.offrange[1] == maxobjsize));
1491 else
1492 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1493 && dstref.offrange[1] == maxobjsize)
1494 || (srcref.offrange[0] == -maxobjsize - 1
1495 && srcref.offrange[1] == maxobjsize));
1496
1497 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1498 {
1499 if (ovlsiz[1] == 1)
1500 {
1501 if (open_range)
1502 warning_n (loc, OPT_Wrestrict, sizrange[1],
1503 "%G%qD accessing %wu byte may overlap "
1504 "%wu byte",
1505 "%G%qD accessing %wu bytes may overlap "
1506 "%wu byte",
1507 call, func, sizrange[1], ovlsiz[1]);
1508 else
1509 warning_n (loc, OPT_Wrestrict, sizrange[1],
1510 "%G%qD accessing %wu byte at offsets %s "
1511 "and %s may overlap %wu byte at offset %s",
1512 "%G%qD accessing %wu bytes at offsets %s "
1513 "and %s may overlap %wu byte at offset %s",
1514 call, func, sizrange[1], offstr[0], offstr[1],
1515 ovlsiz[1], offstr[2]);
1516 return true;
1517 }
1518
1519 if (open_range)
1520 warning_n (loc, OPT_Wrestrict, sizrange[1],
1521 "%G%qD accessing %wu byte may overlap "
1522 "up to %wu bytes",
1523 "%G%qD accessing %wu bytes may overlap "
1524 "up to %wu bytes",
1525 call, func, sizrange[1], ovlsiz[1]);
1526 else
1527 warning_n (loc, OPT_Wrestrict, sizrange[1],
1528 "%G%qD accessing %wu byte at offsets %s and "
1529 "%s may overlap up to %wu bytes at offset %s",
1530 "%G%qD accessing %wu bytes at offsets %s and "
1531 "%s may overlap up to %wu bytes at offset %s",
1532 call, func, sizrange[1], offstr[0], offstr[1],
1533 ovlsiz[1], offstr[2]);
1534 return true;
1535 }
1536
1537 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1538 {
1539 if (open_range)
1540 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1541 "%G%qD accessing between %wu and %wu bytes "
1542 "may overlap %wu byte",
1543 "%G%qD accessing between %wu and %wu bytes "
1544 "may overlap up to %wu bytes",
1545 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1546 else
1547 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1548 "%G%qD accessing between %wu and %wu bytes "
1549 "at offsets %s and %s may overlap %wu byte "
1550 "at offset %s",
1551 "%G%qD accessing between %wu and %wu bytes "
1552 "at offsets %s and %s may overlap up to %wu "
1553 "bytes at offset %s",
1554 call, func, sizrange[0], sizrange[1],
1555 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1556 return true;
1557 }
1558
1559 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1560 "%G%qD accessing %wu or more bytes at offsets %s "
1561 "and %s may overlap %wu byte at offset %s",
1562 "%G%qD accessing %wu or more bytes at offsets %s "
1563 "and %s may overlap up to %wu bytes at offset %s",
1564 call, func, sizrange[0], offstr[0], offstr[1],
1565 ovlsiz[1], offstr[2]);
1566
1567 return true;
1568 }
1569
1570 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1571 to a built-in function FUNC to make sure they are within the bounds
1572 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1573 Both initial values of the offsets and their final value computed by
1574 the function by incrementing the initial value by the size are
1575 validated. Return true if the offsets are not valid and a diagnostic
1576 has been issued. */
1577
1578 static bool
1579 maybe_diag_offset_bounds (location_t loc, gimple *call, tree func, int strict,
1580 tree expr, const builtin_memref &ref)
1581 {
1582 if (!warn_array_bounds)
1583 return false;
1584
1585 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] };
1586 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1587 if (!oobref)
1588 return false;
1589
1590 if (EXPR_HAS_LOCATION (expr))
1591 loc = EXPR_LOCATION (expr);
1592
1593 loc = expansion_point_location_if_in_system_header (loc);
1594
1595 char rangestr[2][64];
1596 if (ooboff[0] == ooboff[1]
1597 || (ooboff[0] != ref.offrange[0]
1598 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1599 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1600 else
1601 sprintf (rangestr[0], "[%lli, %lli]",
1602 (long long) ooboff[0].to_shwi (),
1603 (long long) ooboff[1].to_shwi ());
1604
1605 bool warned = false;
1606
1607 if (oobref == error_mark_node)
1608 {
1609 if (ref.sizrange[0] == ref.sizrange[1])
1610 sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ());
1611 else
1612 sprintf (rangestr[1], "[%lli, %lli]",
1613 (long long) ref.sizrange[0].to_shwi (),
1614 (long long) ref.sizrange[1].to_shwi ());
1615
1616 tree type;
1617
1618 if (DECL_P (ref.base)
1619 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1620 {
1621 auto_diagnostic_group d;
1622 if (warning_at (loc, OPT_Warray_bounds,
1623 "%G%qD pointer overflow between offset %s "
1624 "and size %s accessing array %qD with type %qT",
1625 call, func, rangestr[0], rangestr[1], ref.base, type))
1626 {
1627 inform (DECL_SOURCE_LOCATION (ref.base),
1628 "array %qD declared here", ref.base);
1629 warned = true;
1630 }
1631 else
1632 warned = warning_at (loc, OPT_Warray_bounds,
1633 "%G%qD pointer overflow between offset %s "
1634 "and size %s",
1635 call, func, rangestr[0], rangestr[1]);
1636 }
1637 else
1638 warned = warning_at (loc, OPT_Warray_bounds,
1639 "%G%qD pointer overflow between offset %s "
1640 "and size %s",
1641 call, func, rangestr[0], rangestr[1]);
1642 }
1643 else if (oobref == ref.base)
1644 {
1645 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1646
1647 /* True when the offset formed by an access to the reference
1648 is out of bounds, rather than the initial offset wich is
1649 in bounds. This implies access past the end. */
1650 bool form = ooboff[0] != ref.offrange[0];
1651
1652 if (DECL_P (ref.base))
1653 {
1654 auto_diagnostic_group d;
1655 if ((ref.basesize < maxobjsize
1656 && warning_at (loc, OPT_Warray_bounds,
1657 form
1658 ? G_("%G%qD forming offset %s is out of "
1659 "the bounds [0, %wu] of object %qD with "
1660 "type %qT")
1661 : G_("%G%qD offset %s is out of the bounds "
1662 "[0, %wu] of object %qD with type %qT"),
1663 call, func, rangestr[0], ref.basesize.to_uhwi (),
1664 ref.base, TREE_TYPE (ref.base)))
1665 || warning_at (loc, OPT_Warray_bounds,
1666 form
1667 ? G_("%G%qD forming offset %s is out of "
1668 "the bounds of object %qD with type %qT")
1669 : G_("%G%qD offset %s is out of the bounds "
1670 "of object %qD with type %qT"),
1671 call, func, rangestr[0],
1672 ref.base, TREE_TYPE (ref.base)))
1673 {
1674 inform (DECL_SOURCE_LOCATION (ref.base),
1675 "%qD declared here", ref.base);
1676 warned = true;
1677 }
1678 }
1679 else if (ref.basesize < maxobjsize)
1680 warned = warning_at (loc, OPT_Warray_bounds,
1681 form
1682 ? G_("%G%qD forming offset %s is out "
1683 "of the bounds [0, %wu]")
1684 : G_("%G%qD offset %s is out "
1685 "of the bounds [0, %wu]"),
1686 call, func, rangestr[0], ref.basesize.to_uhwi ());
1687 else
1688 warned = warning_at (loc, OPT_Warray_bounds,
1689 form
1690 ? G_("%G%qD forming offset %s is out of bounds")
1691 : G_("%G%qD offset %s is out of bounds"),
1692 call, func, rangestr[0]);
1693 }
1694 else if (TREE_CODE (ref.ref) == MEM_REF)
1695 {
1696 tree type = TREE_TYPE (TREE_OPERAND (ref.ref, 0));
1697 if (POINTER_TYPE_P (type))
1698 type = TREE_TYPE (type);
1699 type = TYPE_MAIN_VARIANT (type);
1700
1701 warned = warning_at (loc, OPT_Warray_bounds,
1702 "%G%qD offset %s from the object at %qE is out "
1703 "of the bounds of %qT",
1704 call, func, rangestr[0], ref.base, type);
1705 }
1706 else
1707 {
1708 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1709
1710 warned = warning_at (loc, OPT_Warray_bounds,
1711 "%G%qD offset %s from the object at %qE is out "
1712 "of the bounds of referenced subobject %qD with "
1713 "type %qT at offset %wu",
1714 call, func, rangestr[0], ref.base,
1715 TREE_OPERAND (ref.ref, 1), type,
1716 ref.refoff.to_uhwi ());
1717 }
1718
1719 return warned;
1720 }
1721
1722 /* Check a CALL statement for restrict-violations and issue warnings
1723 if/when appropriate. */
1724
1725 void
1726 wrestrict_dom_walker::check_call (gimple *call)
1727 {
1728 /* Avoid checking the call if it has already been diagnosed for
1729 some reason. */
1730 if (gimple_no_warning_p (call))
1731 return;
1732
1733 tree func = gimple_call_fndecl (call);
1734 if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
1735 return;
1736
1737 /* Argument number to extract from the call (depends on the built-in
1738 and its kind). */
1739 unsigned dst_idx = -1;
1740 unsigned src_idx = -1;
1741 unsigned bnd_idx = -1;
1742
1743 /* Is this CALL to a string function (as opposed to one to a raw
1744 memory function). */
1745 bool strfun = true;
1746
1747 switch (DECL_FUNCTION_CODE (func))
1748 {
1749 case BUILT_IN_MEMCPY:
1750 case BUILT_IN_MEMCPY_CHK:
1751 case BUILT_IN_MEMPCPY:
1752 case BUILT_IN_MEMPCPY_CHK:
1753 case BUILT_IN_MEMMOVE:
1754 case BUILT_IN_MEMMOVE_CHK:
1755 strfun = false;
1756 /* Fall through. */
1757
1758 case BUILT_IN_STPNCPY:
1759 case BUILT_IN_STPNCPY_CHK:
1760 case BUILT_IN_STRNCAT:
1761 case BUILT_IN_STRNCAT_CHK:
1762 case BUILT_IN_STRNCPY:
1763 case BUILT_IN_STRNCPY_CHK:
1764 dst_idx = 0;
1765 src_idx = 1;
1766 bnd_idx = 2;
1767 break;
1768
1769 case BUILT_IN_STPCPY:
1770 case BUILT_IN_STPCPY_CHK:
1771 case BUILT_IN_STRCPY:
1772 case BUILT_IN_STRCPY_CHK:
1773 case BUILT_IN_STRCAT:
1774 case BUILT_IN_STRCAT_CHK:
1775 dst_idx = 0;
1776 src_idx = 1;
1777 break;
1778
1779 default:
1780 /* Handle other string functions here whose access may need
1781 to be validated for in-bounds offsets and non-overlapping
1782 copies. */
1783 return;
1784 }
1785
1786 unsigned nargs = gimple_call_num_args (call);
1787
1788 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1789 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1790 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1791
1792 /* For string functions with an unspecified or unknown bound,
1793 assume the size of the access is one. */
1794 if (!dstwr && strfun)
1795 dstwr = size_one_node;
1796
1797 /* DST and SRC can be null for a call with an insufficient number
1798 of arguments to a built-in function declared without a protype. */
1799 if (!dst || !src)
1800 return;
1801
1802 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1803 a function declared without a prototype. Avoid checking such
1804 invalid calls. */
1805 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1806 || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
1807 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1808 return;
1809
1810 if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1811 return;
1812
1813 /* Avoid diagnosing the call again. */
1814 gimple_set_no_warning (call, true);
1815 }
1816
1817 } /* anonymous namespace */
1818
1819 /* Attempt to detect and diagnose invalid offset bounds and (except for
1820 memmove) overlapping copy in a call expression EXPR from SRC to DST
1821 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1822 SRCSIZE may be NULL. Return false when one or the other has been
1823 detected and diagnosed, true otherwise. */
1824
1825 bool
1826 check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
1827 tree srcsize, bool bounds_only /* = false */)
1828 {
1829 location_t loc = gimple_nonartificial_location (call);
1830 loc = expansion_point_location_if_in_system_header (loc);
1831
1832 tree func = gimple_call_fndecl (call);
1833
1834 builtin_memref dstref (dst, dstsize);
1835 builtin_memref srcref (src, srcsize);
1836
1837 builtin_access acs (call, dstref, srcref);
1838
1839 /* Set STRICT to the value of the -Warray-bounds=N argument for
1840 string functions or when N > 1. */
1841 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
1842
1843 /* Validate offsets first to make sure they are within the bounds
1844 of the destination object if its size is known, or PTRDIFF_MAX
1845 otherwise. */
1846 if (maybe_diag_offset_bounds (loc, call, func, strict, dst, dstref)
1847 || maybe_diag_offset_bounds (loc, call, func, strict, src, srcref))
1848 {
1849 gimple_set_no_warning (call, true);
1850 return false;
1851 }
1852
1853 bool check_overlap
1854 = (warn_restrict
1855 && (bounds_only
1856 || (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
1857 && DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
1858
1859 if (!check_overlap)
1860 return true;
1861
1862 if (operand_equal_p (dst, src, 0))
1863 {
1864 /* Issue -Wrestrict unless the pointers are null (those do
1865 not point to objects and so do not indicate an overlap;
1866 such calls could be the result of sanitization and jump
1867 threading). */
1868 if (!integer_zerop (dst) && !gimple_no_warning_p (call))
1869 {
1870 warning_at (loc, OPT_Wrestrict,
1871 "%G%qD source argument is the same as destination",
1872 call, func);
1873 gimple_set_no_warning (call, true);
1874 return false;
1875 }
1876
1877 return true;
1878 }
1879
1880 /* Return false when overlap has been detected. */
1881 if (maybe_diag_overlap (loc, call, acs))
1882 {
1883 gimple_set_no_warning (call, true);
1884 return false;
1885 }
1886
1887 return true;
1888 }
1889
1890 gimple_opt_pass *
1891 make_pass_warn_restrict (gcc::context *ctxt)
1892 {
1893 return new pass_wrestrict (ctxt);
1894 }