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