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       base = TREE_OPERAND (base, 0);
509 
510       if (refoff != HOST_WIDE_INT_MIN
511       	  && TREE_CODE (expr) == COMPONENT_REF)
512       	{
513 	  /* Bump up the offset of the referenced subobject to reflect
514 	     the offset to the enclosing object.  For example, so that
515 	     in
516 	       struct S { char a, b[3]; } s[2];
517 	       strcpy (s[1].b, "1234");
518 	     REFOFF is set to s[1].b - (char*)s.  */
519 	  offset_int off = tree_to_shwi (memrefoff);
520 	  refoff += off;
521       	}
522 
523       if (!integer_zerop (memrefoff))
524 	/* A non-zero offset into an array of struct with flexible array
525 	   members implies that the array is empty because there is no
526 	   way to initialize such a member when it belongs to an array.
527 	   This must be some sort of a bug.  */
528 	refsize = 0;
529     }
530 
531   if (TREE_CODE (ref) == COMPONENT_REF)
532     if (tree size = component_ref_size (ref))
533       if (TREE_CODE (size) == INTEGER_CST)
534 	refsize = wi::to_offset (size);
535 
536   if (TREE_CODE (base) == SSA_NAME)
537     set_base_and_offset (base);
538 }
539 
540 /* Return error_mark_node if the signed offset exceeds the bounds
541    of the address space (PTRDIFF_MAX).  Otherwise, return either BASE
542    or REF when the offset exceeds the bounds of the BASE or REF object,
543    and set OOBOFF to the past-the-end offset formed by the reference,
544    including its size.  OOBOFF is initially setto the range of offsets,
545    and OOBOFF[2] to the offset of the first write access (nonzero for
546    the strcat family).  When STRICT is nonzero use REF size, when
547    available, otherwise use BASE size.  When STRICT is greater than 1,
548    use the size of the last array member as the bound, otherwise treat
549    such a member as a flexible array member.  Return NULL when the offset
550    is in bounds.  */
551 
552 tree
offset_out_of_bounds(int strict,offset_int ooboff[3])553 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[3]) const
554 {
555   if (!ptr)
556     return NULL_TREE;
557 
558   /* The offset of the first write access or zero.  */
559   offset_int wroff = ooboff[2];
560 
561   /* A temporary, possibly adjusted, copy of the offset range.  */
562   offset_int offrng[2] = { ooboff[0], ooboff[1] };
563 
564   if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
565     {
566       /* Check for offset in an anti-range with a negative lower bound.
567 	 For such a range, consider only the non-negative subrange.  */
568       if (offrng[1] < offrng[0] && offrng[1] < 0)
569   	offrng[1] = maxobjsize;
570     }
571 
572   /* Conservative offset of the last byte of the referenced object.  */
573   offset_int endoff;
574 
575   /* The bounds need not be ordered.  Set HIB to use as the index
576      of the larger of the bounds and LOB as the opposite.  */
577   bool hib = wi::les_p (offrng[0], offrng[1]);
578   bool lob = !hib;
579 
580   /* Set to the size remaining in the object after subtracting
581      REFOFF.  It may become negative as a result of negative indices
582      into the enclosing object, such as in:
583        extern struct S { char a[4], b[3], c[1]; } *p;
584        strcpy (p[-3].b, "123");  */
585   offset_int size = basesize;
586   tree obj = base;
587 
588   const bool decl_p = DECL_P (obj);
589 
590   if (basesize < 0)
591     {
592       endoff = offrng[lob] + (sizrange[0] - wroff);
593 
594       /* For a reference through a pointer to an object of unknown size
595 	 all initial offsets are considered valid, positive as well as
596 	 negative, since the pointer itself can point past the beginning
597 	 of the object.  However, the sum of the lower bound of the offset
598 	 and that of the size must be less than or equal than PTRDIFF_MAX.  */
599       if (endoff > maxobjsize)
600 	return error_mark_node;
601 
602       /* When the referenced subobject is known, the end offset must be
603 	 within its bounds.  Otherwise there is nothing to do.  */
604       if (strict
605 	  && !decl_p
606 	  && ref
607 	  && refsize >= 0
608 	  && TREE_CODE (ref) == COMPONENT_REF)
609 	{
610 	  /* If REFOFF is negative, SIZE will become negative here.  */
611 	  size = refoff + refsize;
612 	  obj = ref;
613 	}
614       else
615 	return NULL_TREE;
616     }
617 
618   /* A reference to an object of known size must be within the bounds
619      of either the base object or the subobject (see above for when
620      a subobject can be used).  */
621   if ((decl_p && offrng[hib] < 0) || offrng[lob] > size)
622     return obj;
623 
624   /* The extent of the reference must also be within the bounds of
625      the base object (if known) or the subobject or the maximum object
626      size otherwise.  */
627   endoff = offrng[lob] + sizrange[0];
628   if (endoff > maxobjsize)
629     return error_mark_node;
630 
631   if (strict
632       && decl_p
633       && ref
634       && refsize >= 0
635       && TREE_CODE (ref) == COMPONENT_REF)
636     {
637       /* If the reference is to a member subobject of a declared object,
638 	 the offset must be within the bounds of the subobject.  */
639       size = refoff + refsize;
640       obj = ref;
641     }
642 
643   if (endoff <= size)
644     return NULL_TREE;
645 
646   /* Set the out-of-bounds offset range to be one greater than
647      that delimited by the reference including its size.  */
648   ooboff[lob] = size;
649 
650   if (endoff > ooboff[lob])
651     ooboff[hib] = endoff - 1;
652   else
653     ooboff[hib] = offrng[lob] + sizrange[1];
654 
655   return obj;
656 }
657 
658 /* Create an association between the memory references DST and SRC
659    for access by a call EXPR to a memory or string built-in funtion.  */
660 
builtin_access(gimple * call,builtin_memref & dst,builtin_memref & src)661 builtin_access::builtin_access (gimple *call, builtin_memref &dst,
662 				builtin_memref &src)
663 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
664   dstoff (), srcoff (), dstsiz (), srcsiz ()
665 {
666   dstoff[0] = dst.offrange[0];
667   dstoff[1] = dst.offrange[1];
668 
669   /* Zero out since the offset_int ctors invoked above are no-op.  */
670   srcoff[0] = srcoff[1] = 0;
671   dstsiz[0] = dstsiz[1] = 0;
672   srcsiz[0] = srcsiz[1] = 0;
673 
674   /* Object Size Type to use to determine the size of the destination
675      and source objects.  Overridden below for raw memory functions.  */
676   int ostype = 1;
677 
678   /* True when the size of one reference depends on the offset of
679      itself or the other.  */
680   bool depends_p = true;
681 
682   /* True when the size of the destination reference DSTREF has been
683      determined from SRCREF and so needs to be adjusted by the latter's
684      offset.  Only meaningful for bounded string functions like strncpy.  */
685   bool dstadjust_p = false;
686 
687   /* The size argument number (depends on the built-in).  */
688   unsigned sizeargno = 2;
689 
690   tree func = gimple_call_fndecl (call);
691   switch (DECL_FUNCTION_CODE (func))
692     {
693     case BUILT_IN_MEMCPY:
694     case BUILT_IN_MEMCPY_CHK:
695     case BUILT_IN_MEMPCPY:
696     case BUILT_IN_MEMPCPY_CHK:
697       ostype = 0;
698       depends_p = false;
699       detect_overlap = &builtin_access::generic_overlap;
700       break;
701 
702     case BUILT_IN_MEMMOVE:
703     case BUILT_IN_MEMMOVE_CHK:
704       /* For memmove there is never any overlap to check for.  */
705       ostype = 0;
706       depends_p = false;
707       detect_overlap = &builtin_access::no_overlap;
708       break;
709 
710     case BUILT_IN_MEMSET:
711     case BUILT_IN_MEMSET_CHK:
712       /* For memset there is never any overlap to check for.  */
713       ostype = 0;
714       depends_p = false;
715       detect_overlap = &builtin_access::no_overlap;
716       break;
717 
718     case BUILT_IN_STPNCPY:
719     case BUILT_IN_STPNCPY_CHK:
720     case BUILT_IN_STRNCPY:
721     case BUILT_IN_STRNCPY_CHK:
722       dstref->strbounded_p = true;
723       detect_overlap = &builtin_access::strcpy_overlap;
724       break;
725 
726     case BUILT_IN_STPCPY:
727     case BUILT_IN_STPCPY_CHK:
728     case BUILT_IN_STRCPY:
729     case BUILT_IN_STRCPY_CHK:
730       detect_overlap = &builtin_access::strcpy_overlap;
731       break;
732 
733     case BUILT_IN_STRCAT:
734     case BUILT_IN_STRCAT_CHK:
735       detect_overlap = &builtin_access::strcat_overlap;
736       break;
737 
738     case BUILT_IN_STRNCAT:
739     case BUILT_IN_STRNCAT_CHK:
740       dstref->strbounded_p = true;
741       srcref->strbounded_p = true;
742       detect_overlap = &builtin_access::strcat_overlap;
743       break;
744 
745     default:
746       /* Handle other string functions here whose access may need
747 	 to be validated for in-bounds offsets and non-overlapping
748 	 copies.  */
749       return;
750     }
751 
752   const offset_int maxobjsize = dst.maxobjsize;
753 
754   /* Try to determine the size of the base object.  compute_objsize
755      expects a pointer so create one if BASE is a non-pointer object.  */
756   tree addr;
757   if (dst.basesize < 0)
758     {
759       addr = dst.base;
760       if (!POINTER_TYPE_P (TREE_TYPE (addr)))
761 	addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
762 
763       if (tree dstsize = compute_objsize (addr, ostype))
764 	dst.basesize = wi::to_offset (dstsize);
765       else if (POINTER_TYPE_P (TREE_TYPE (addr)))
766 	dst.basesize = HOST_WIDE_INT_MIN;
767       else
768 	dst.basesize = maxobjsize;
769     }
770 
771   if (src.base && src.basesize < 0)
772     {
773       addr = src.base;
774       if (!POINTER_TYPE_P (TREE_TYPE (addr)))
775 	addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
776 
777       if (tree srcsize = compute_objsize (addr, ostype))
778 	src.basesize = wi::to_offset (srcsize);
779       else if (POINTER_TYPE_P (TREE_TYPE (addr)))
780 	src.basesize = HOST_WIDE_INT_MIN;
781       else
782 	src.basesize = maxobjsize;
783     }
784 
785   /* Make adjustments for references to the same object by string
786      built-in functions to reflect the constraints imposed by
787      the function.  */
788 
789   /* For bounded string functions determine the range of the bound
790      on the access.  For others, the range stays unbounded.  */
791   offset_int bounds[2] = { maxobjsize, maxobjsize };
792   if (dstref->strbounded_p)
793     {
794       unsigned nargs = gimple_call_num_args (call);
795       if (nargs <= sizeargno)
796 	return;
797 
798       tree size = gimple_call_arg (call, sizeargno);
799       tree range[2];
800       if (get_size_range (size, range, true))
801 	{
802 	  bounds[0] = wi::to_offset (range[0]);
803 	  bounds[1] = wi::to_offset (range[1]);
804 	}
805 
806       /* If both references' size ranges are indeterminate use the last
807 	 (size) argument from the function call as a substitute.  This
808 	 may only be necessary for strncpy (but not for memcpy where
809 	 the size range would have been already determined this way).  */
810       if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
811 	  && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
812 	{
813 	  dstref->sizrange[0] = bounds[0];
814 	  dstref->sizrange[1] = bounds[1];
815 	}
816     }
817 
818   bool dstsize_set = false;
819   /* The size range of one reference involving the same base object
820      can be determined from the size range of the other reference.
821      This makes it possible to compute accurate offsets for warnings
822      involving functions like strcpy where the length of just one of
823      the two arguments is known (determined by tree-ssa-strlen).  */
824   if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
825     {
826       /* When the destination size is unknown set it to the size of
827 	 the source.  */
828       dstref->sizrange[0] = srcref->sizrange[0];
829       dstref->sizrange[1] = srcref->sizrange[1];
830       dstsize_set = true;
831     }
832   else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
833     {
834       /* When the size of the source access is unknown set it to the size
835 	 of the destination first and adjust it later if necessary.  */
836       srcref->sizrange[0] = dstref->sizrange[0];
837       srcref->sizrange[1] = dstref->sizrange[1];
838 
839       if (depends_p)
840 	{
841 	  if (dstref->strbounded_p)
842 	    {
843 	      /* Read access by strncpy is constrained by the third
844 		 argument but except for a zero bound is at least one.  */
845 	      srcref->sizrange[0] = bounds[1] > 0 ? 1 : 0;
846 	      offset_int bound = wi::umin (srcref->basesize, bounds[1]);
847 	      if (bound < srcref->sizrange[1])
848 		srcref->sizrange[1] = bound;
849 	    }
850 	  /* For string functions, adjust the size range of the source
851 	     reference by the inverse boundaries of the offset (because
852 	     the higher the offset into the string the shorter its
853 	     length).  */
854 	  if (srcref->offrange[1] >= 0
855 	      && srcref->offrange[1] < srcref->sizrange[0])
856 	    srcref->sizrange[0] -= srcref->offrange[1];
857 	  else
858 	    srcref->sizrange[0] = 1;
859 
860 	  if (srcref->offrange[0] > 0)
861 	    {
862 	      if (srcref->offrange[0] < srcref->sizrange[1])
863 		srcref->sizrange[1] -= srcref->offrange[0];
864 	      else
865 		srcref->sizrange[1] = 0;
866 	    }
867 
868 	  dstadjust_p = true;
869 	}
870     }
871 
872   if (detect_overlap == &builtin_access::generic_overlap)
873     {
874       if (dstref->strbounded_p)
875 	{
876 	  dstref->sizrange[0] = bounds[0];
877 	  dstref->sizrange[1] = bounds[1];
878 
879 	  if (dstref->sizrange[0] < srcref->sizrange[0])
880 	    srcref->sizrange[0] = dstref->sizrange[0];
881 
882 	  if (dstref->sizrange[1] < srcref->sizrange[1])
883 	    srcref->sizrange[1] = dstref->sizrange[1];
884 	}
885     }
886   else if (detect_overlap == &builtin_access::strcpy_overlap)
887     {
888       if (!dstref->strbounded_p)
889 	{
890 	  /* For strcpy, adjust the destination size range to match that
891 	     of the source computed above.  */
892 	  if (depends_p && dstadjust_p)
893 	    {
894 	      dstref->sizrange[0] = srcref->sizrange[0];
895 	      dstref->sizrange[1] = srcref->sizrange[1];
896 	    }
897 	}
898     }
899   else if (!dstsize_set && detect_overlap == &builtin_access::strcat_overlap)
900     {
901       dstref->sizrange[0] += srcref->sizrange[0] - 1;
902       dstref->sizrange[1] += srcref->sizrange[1] - 1;
903     }
904 
905   if (dstref->strbounded_p)
906     {
907       /* For strncpy, adjust the destination size range to match that
908 	 of the source computed above.  */
909       dstref->sizrange[0] = bounds[0];
910       dstref->sizrange[1] = bounds[1];
911 
912       if (bounds[0] < srcref->sizrange[0])
913 	srcref->sizrange[0] = bounds[0];
914 
915       if (bounds[1] < srcref->sizrange[1])
916 	srcref->sizrange[1] = bounds[1];
917     }
918 }
919 
920 offset_int
overlap_size(const offset_int a[2],const offset_int b[2],offset_int * off)921 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
922 			      offset_int *off)
923 {
924   const offset_int *p = a;
925   const offset_int *q = b;
926 
927   /* Point P at the bigger of the two ranges and Q at the smaller.  */
928   if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
929     {
930       p = b;
931       q = a;
932     }
933 
934   if (p[0] < q[0])
935     {
936       if (p[1] < q[0])
937 	return 0;
938 
939       *off = q[0];
940       return wi::smin (p[1], q[1]) - q[0];
941     }
942 
943   if (q[1] < p[0])
944     return 0;
945 
946   off[0] = p[0];
947   return q[1] - p[0];
948 }
949 
950 /* Return true if the bounded mempry (memcpy amd similar) or string function
951    access (strncpy and similar) ACS overlaps.  */
952 
953 bool
generic_overlap()954 builtin_access::generic_overlap ()
955 {
956   builtin_access &acs = *this;
957   const builtin_memref *dstref = acs.dstref;
958   const builtin_memref *srcref = acs.srcref;
959 
960   gcc_assert (dstref->base == srcref->base);
961 
962   const offset_int maxobjsize = acs.dstref->maxobjsize;
963 
964   offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
965 
966   /* Adjust the larger bounds of the offsets (which may be the first
967      element if the lower bound is larger than the upper bound) to
968      make them valid for the smallest access (if possible) but no smaller
969      than the smaller bounds.  */
970   gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
971 
972   if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
973     acs.dstoff[1] = maxsize - acs.dstsiz[0];
974   if (acs.dstoff[1] < acs.dstoff[0])
975     acs.dstoff[1] = acs.dstoff[0];
976 
977   gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
978 
979   if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
980     acs.srcoff[1] = maxsize - acs.srcsiz[0];
981   if (acs.srcoff[1] < acs.srcoff[0])
982     acs.srcoff[1] = acs.srcoff[0];
983 
984   /* Determine the minimum and maximum space for the access given
985      the offsets.  */
986   offset_int space[2];
987   space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
988   space[1] = space[0];
989 
990   offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
991   if (acs.srcsiz[0] > 0)
992     {
993       if (d < space[0])
994 	space[0] = d;
995 
996       if (space[1] < d)
997 	space[1] = d;
998     }
999   else
1000     space[1] = acs.dstsiz[1];
1001 
1002   d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1003   if (d < space[0])
1004     space[0] = d;
1005 
1006   if (space[1] < d)
1007     space[1] = d;
1008 
1009   /* Treat raw memory functions both of whose references are bounded
1010      as special and permit uncertain overlaps to go undetected.  For
1011      all kinds of constant offset and constant size accesses, if
1012      overlap isn't certain it is not possible.  */
1013   bool overlap_possible = space[0] < acs.dstsiz[1];
1014   if (!overlap_possible)
1015     return false;
1016 
1017   bool overlap_certain = space[1] < acs.dstsiz[0];
1018 
1019   /* True when the size of one reference depends on the offset of
1020      the other.  */
1021   bool depends_p = detect_overlap != &builtin_access::generic_overlap;
1022 
1023   if (!overlap_certain)
1024     {
1025       if (!dstref->strbounded_p && !depends_p)
1026 	/* Memcpy only considers certain overlap.  */
1027 	return false;
1028 
1029       /* There's no way to distinguish an access to the same member
1030 	 of a structure from one to two distinct members of the same
1031 	 structure.  Give up to avoid excessive false positives.  */
1032       tree basetype = TREE_TYPE (dstref->base);
1033 
1034       if (POINTER_TYPE_P (basetype))
1035 	basetype = TREE_TYPE (basetype);
1036       else
1037 	while (TREE_CODE (basetype) == ARRAY_TYPE)
1038 	  basetype = TREE_TYPE (basetype);
1039 
1040       if (RECORD_OR_UNION_TYPE_P (basetype))
1041 	return false;
1042     }
1043 
1044   /* True for stpcpy and strcpy.  */
1045   bool stxcpy_p = (!dstref->strbounded_p
1046 		   && detect_overlap == &builtin_access::strcpy_overlap);
1047 
1048   if (dstref->refoff >= 0
1049       && srcref->refoff >= 0
1050       && dstref->refoff != srcref->refoff
1051       && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
1052     return false;
1053 
1054   offset_int siz[2] = { maxobjsize + 1, 0 };
1055 
1056   ovloff[0] = HOST_WIDE_INT_MAX;
1057   ovloff[1] = HOST_WIDE_INT_MIN;
1058 
1059   if (stxcpy_p)
1060     {
1061       /* Iterate over the extreme locations (on the horizontal axis formed
1062 	 by their offsets) and sizes of two regions and find their smallest
1063 	 and largest overlap and the corresponding offsets.  */
1064       for (unsigned i = 0; i != 2; ++i)
1065 	{
1066 	  const offset_int a[2] = {
1067 	    acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
1068 	  };
1069 
1070 	  const offset_int b[2] = {
1071 	    acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
1072 	  };
1073 
1074 	  offset_int off;
1075 	  offset_int sz = overlap_size (a, b, &off);
1076 	  if (sz < siz[0])
1077 	    siz[0] = sz;
1078 
1079 	  if (siz[1] <= sz)
1080 	    siz[1] = sz;
1081 
1082 	  if (sz != 0)
1083 	    {
1084 	      if (wi::lts_p (off, ovloff[0]))
1085 		ovloff[0] = off.to_shwi ();
1086 	      if (wi::lts_p (ovloff[1], off))
1087 		ovloff[1] = off.to_shwi ();
1088 	    }
1089 	}
1090     }
1091   else
1092     {
1093       /* Iterate over the extreme locations (on the horizontal axis
1094 	 formed by their offsets) and sizes of the two regions and
1095 	 find their smallest and largest overlap and the corresponding
1096 	 offsets.  */
1097 
1098       for (unsigned io = 0; io != 2; ++io)
1099 	for (unsigned is = 0; is != 2; ++is)
1100 	  {
1101 	    const offset_int a[2] = {
1102 	      acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1103 	    };
1104 
1105 	    for (unsigned jo = 0; jo != 2; ++jo)
1106 	      for (unsigned js = 0; js != 2; ++js)
1107 		{
1108 		  const offset_int b[2] = {
1109 		    acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1110 		  };
1111 
1112 		  offset_int off;
1113 		  offset_int sz = overlap_size (a, b, &off);
1114 		  if (sz < siz[0])
1115 		    siz[0] = sz;
1116 
1117 		  if (siz[1] <= sz)
1118 		    siz[1] = sz;
1119 
1120 		  if (sz != 0)
1121 		    {
1122 		      if (wi::lts_p (off, ovloff[0]))
1123 			ovloff[0] = off.to_shwi ();
1124 		      if (wi::lts_p (ovloff[1], off))
1125 			ovloff[1] = off.to_shwi ();
1126 		    }
1127 		}
1128 	  }
1129     }
1130 
1131   ovlsiz[0] = siz[0].to_shwi ();
1132   ovlsiz[1] = siz[1].to_shwi ();
1133 
1134   /* Adjust the overlap offset range to reflect the overlap size range.  */
1135   if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1136     ovloff[1] = ovloff[0] + ovlsiz[1] - 1;
1137 
1138   return true;
1139 }
1140 
1141 /* Return true if the strcat-like access overlaps.  */
1142 
1143 bool
strcat_overlap()1144 builtin_access::strcat_overlap ()
1145 {
1146   builtin_access &acs = *this;
1147   const builtin_memref *dstref = acs.dstref;
1148   const builtin_memref *srcref = acs.srcref;
1149 
1150   gcc_assert (dstref->base == srcref->base);
1151 
1152   const offset_int maxobjsize = acs.dstref->maxobjsize;
1153 
1154   gcc_assert (dstref->base && dstref->base == srcref->base);
1155 
1156   /* Adjust for strcat-like accesses.  */
1157 
1158   /* As a special case for strcat, set the DSTREF offsets to the length
1159      of the destination string since the function starts writing over
1160      its terminating nul, and set the destination size to 1 for the length
1161      of the nul.  */
1162   acs.dstoff[0] += dstsiz[0] - srcref->sizrange[0];
1163   acs.dstoff[1] += dstsiz[1] - srcref->sizrange[1];
1164 
1165   bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1166 
1167   /* The lower bound is zero when the size is unknown because then
1168      overlap is not certain.  */
1169   acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1170   acs.dstsiz[1] = 1;
1171 
1172   offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1173 
1174   /* For references to the same base object, determine if there's a pair
1175      of valid offsets into the two references such that access between
1176      them doesn't overlap.  Adjust both upper bounds to be valid for
1177      the smaller size (i.e., at most MAXSIZE - SIZE).  */
1178 
1179   if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1180     acs.dstoff[1] = maxsize - acs.dstsiz[0];
1181 
1182   if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1183     acs.srcoff[1] = maxsize - acs.srcsiz[0];
1184 
1185   /* Check to see if there's enough space for both accesses without
1186      overlap.  Determine the optimistic (maximum) amount of available
1187      space.  */
1188   offset_int space;
1189   if (acs.dstoff[0] <= acs.srcoff[0])
1190     {
1191       if (acs.dstoff[1] < acs.srcoff[1])
1192 	space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1193       else
1194 	space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1195     }
1196   else
1197     space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1198 
1199   /* Overlap is certain if the distance between the farthest offsets
1200      of the opposite accesses is less than the sum of the lower bounds
1201      of the sizes of the two accesses.  */
1202   bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1203 
1204   /* For a constant-offset, constant size access, consider the largest
1205      distance between the offset bounds and the lower bound of the access
1206      size.  If the overlap isn't certain return success.  */
1207   if (!overlap_certain
1208       && acs.dstoff[0] == acs.dstoff[1]
1209       && acs.srcoff[0] == acs.srcoff[1]
1210       && acs.dstsiz[0] == acs.dstsiz[1]
1211       && acs.srcsiz[0] == acs.srcsiz[1])
1212     return false;
1213 
1214   /* Overlap is not certain but may be possible.  */
1215 
1216   offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1217 
1218   /* Determine the conservative (minimum) amount of space.  */
1219   space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1220   offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1221   if (d < space)
1222     space = d;
1223   d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1224   if (d < space)
1225     space = d;
1226 
1227   /* For a strict test (used for strcpy and similar with unknown or
1228      variable bounds or sizes), consider the smallest distance between
1229      the offset bounds and either the upper bound of the access size
1230      if known, or the lower bound otherwise.  */
1231   if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1232     return false;
1233 
1234   /* When strcat overlap is certain it is always a single byte:
1235      the terminating NUL, regardless of offsets and sizes.  When
1236      overlap is only possible its range is [0, 1].  */
1237   acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1238   acs.ovlsiz[1] = 1;
1239 
1240   offset_int endoff
1241     = dstref->offrange[0] + (dstref->sizrange[0] - srcref->sizrange[0]);
1242   if (endoff <= srcref->offrange[0])
1243     acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1244   else
1245     acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1246 
1247   acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1248 			      srcref->sizrange[0]).to_shwi ();
1249   if (dstref->offrange[0] == dstref->offrange[1])
1250     {
1251       if (srcref->offrange[0] == srcref->offrange[1])
1252 	acs.ovloff[1] = acs.ovloff[0];
1253       else
1254 	acs.ovloff[1]
1255 	  = wi::smin (maxobjsize,
1256 		      srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1257     }
1258   else
1259     acs.ovloff[1]
1260       = wi::smin (maxobjsize,
1261 		  dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1262 
1263   if (acs.sizrange[0] == 0)
1264     acs.sizrange[0] = 1;
1265   acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1266   return true;
1267 }
1268 
1269 /* Return true if the strcpy-like access overlaps.  */
1270 
1271 bool
strcpy_overlap()1272 builtin_access::strcpy_overlap ()
1273 {
1274   return generic_overlap ();
1275 }
1276 
1277 
1278 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1279    one another or that, in order not to overlap, would imply that the size
1280    of the referenced object(s) exceeds the maximum size of an object.  Set
1281    Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1282    they may overlap in a way that's not apparent from the available data),
1283    return false.  */
1284 
1285 bool
overlap()1286 builtin_access::overlap ()
1287 {
1288   builtin_access &acs = *this;
1289 
1290   const offset_int maxobjsize = dstref->maxobjsize;
1291 
1292   acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1293 			      srcref->sizrange[0]).to_shwi ();
1294   acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1295 			      srcref->sizrange[1]).to_shwi ();
1296 
1297   /* Check to see if the two references refer to regions that are
1298      too large not to overlap in the address space (whose maximum
1299      size is PTRDIFF_MAX).  */
1300   offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1301   if (maxobjsize < size)
1302     {
1303       acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1304       acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1305       return true;
1306     }
1307 
1308   /* If both base objects aren't known return the maximum possible
1309      offset that would make them not overlap.  */
1310   if (!dstref->base || !srcref->base)
1311     return false;
1312 
1313   /* If the base object is an array adjust the bounds of the offset
1314      to be non-negative and within the bounds of the array if possible.  */
1315   if (dstref->base
1316       && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1317     {
1318       if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1319 	acs.dstoff[0] = 0;
1320 
1321       if (acs.dstoff[1] < acs.dstoff[0])
1322 	{
1323 	  if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1324 	    acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1325 	  else
1326 	    acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1327 	}
1328     }
1329 
1330   acs.srcoff[0] = srcref->offrange[0];
1331   acs.srcoff[1] = srcref->offrange[1];
1332 
1333   if (srcref->base
1334       && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1335     {
1336       if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1337 	acs.srcoff[0] = 0;
1338 
1339       if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1340 	acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1341       else if (acs.srcoff[1] < acs.srcoff[0])
1342 	acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1343     }
1344 
1345   /* When the upper bound of the offset is less than the lower bound
1346      the former is the result of a negative offset being represented
1347      as a large positive value or vice versa.  The resulting range is
1348      a union of two subranges: [MIN, UB] and [LB, MAX].  Since such
1349      a union is not representable using the current data structure
1350      replace it with the full range of offsets.  */
1351   if (acs.dstoff[1] < acs.dstoff[0])
1352     {
1353       acs.dstoff[0] = -maxobjsize - 1;
1354       acs.dstoff[1] = maxobjsize;
1355     }
1356 
1357   /* Validate the offset and size of each reference on its own first.
1358      This is independent of whether or not the base objects are the
1359      same.  Normally, this would have already been detected and
1360      diagnosed by -Warray-bounds, unless it has been disabled.  */
1361   offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1362   if (maxobjsize < maxoff)
1363     {
1364       acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1365       acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1366       return true;
1367     }
1368 
1369   /* Repeat the same as above but for the source offsets.  */
1370   if (acs.srcoff[1] < acs.srcoff[0])
1371     {
1372       acs.srcoff[0] = -maxobjsize - 1;
1373       acs.srcoff[1] = maxobjsize;
1374     }
1375 
1376   maxoff = acs.srcoff[0] + srcref->sizrange[0];
1377   if (maxobjsize < maxoff)
1378     {
1379       acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1380       acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1381 		       - maxobjsize).to_shwi ();
1382       acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1383       return true;
1384     }
1385 
1386   if (dstref->base != srcref->base)
1387     return false;
1388 
1389   acs.dstsiz[0] = dstref->sizrange[0];
1390   acs.dstsiz[1] = dstref->sizrange[1];
1391 
1392   acs.srcsiz[0] = srcref->sizrange[0];
1393   acs.srcsiz[1] = srcref->sizrange[1];
1394 
1395   /* Call the appropriate function to determine the overlap.  */
1396   if ((this->*detect_overlap) ())
1397     {
1398       if (!sizrange[1])
1399 	{
1400 	  /* Unless the access size range has already been set, do so here.  */
1401 	  sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1402 	  sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1403 	}
1404       return true;
1405     }
1406 
1407   return false;
1408 }
1409 
1410 /* Attempt to detect and diagnose an overlapping copy in a call expression
1411    EXPR involving an access ACS to a built-in memory or string function.
1412    Return true when one has been detected, false otherwise.  */
1413 
1414 static bool
maybe_diag_overlap(location_t loc,gimple * call,builtin_access & acs)1415 maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
1416 {
1417   if (!acs.overlap ())
1418     return false;
1419 
1420   if (gimple_no_warning_p (call))
1421     return true;
1422 
1423   /* For convenience.  */
1424   const builtin_memref &dstref = *acs.dstref;
1425   const builtin_memref &srcref = *acs.srcref;
1426 
1427   /* Determine the range of offsets and sizes of the overlap if it
1428      exists and issue diagnostics.  */
1429   HOST_WIDE_INT *ovloff = acs.ovloff;
1430   HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1431   HOST_WIDE_INT *sizrange = acs.sizrange;
1432 
1433   tree func = gimple_call_fndecl (call);
1434 
1435   /* To avoid a combinatorial explosion of diagnostics format the offsets
1436      or their ranges as strings and use them in the warning calls below.  */
1437   char offstr[3][64];
1438 
1439   if (dstref.offrange[0] == dstref.offrange[1]
1440       || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1441     sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1442 	     dstref.offrange[0].to_shwi ());
1443   else
1444     sprintf (offstr[0],
1445 	     "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1446 	     dstref.offrange[0].to_shwi (),
1447 	     dstref.offrange[1].to_shwi ());
1448 
1449   if (srcref.offrange[0] == srcref.offrange[1]
1450       || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1451     sprintf (offstr[1],
1452 	     HOST_WIDE_INT_PRINT_DEC,
1453 	     srcref.offrange[0].to_shwi ());
1454   else
1455     sprintf (offstr[1],
1456 	     "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1457 	     srcref.offrange[0].to_shwi (),
1458 	     srcref.offrange[1].to_shwi ());
1459 
1460   if (ovloff[0] == ovloff[1] || !ovloff[1])
1461     sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1462   else
1463     sprintf (offstr[2],
1464 	     "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1465 	     ovloff[0], ovloff[1]);
1466 
1467   const offset_int maxobjsize = dstref.maxobjsize;
1468   bool must_overlap = ovlsiz[0] > 0;
1469 
1470   if (ovlsiz[1] == 0)
1471     ovlsiz[1] = ovlsiz[0];
1472 
1473   if (must_overlap)
1474     {
1475       /* Issue definitive "overlaps" diagnostic in this block.  */
1476 
1477       if (sizrange[0] == sizrange[1])
1478 	{
1479 	  if (ovlsiz[0] == ovlsiz[1])
1480 	    warning_at (loc, OPT_Wrestrict,
1481 			sizrange[0] == 1
1482 			? (ovlsiz[0] == 1
1483 			   ? G_("%G%qD accessing %wu byte at offsets %s "
1484 				"and %s overlaps %wu byte at offset %s")
1485 			   :  G_("%G%qD accessing %wu byte at offsets %s "
1486 				 "and %s overlaps %wu bytes at offset "
1487 				 "%s"))
1488 			: (ovlsiz[0] == 1
1489 			   ? G_("%G%qD accessing %wu bytes at offsets %s "
1490 				"and %s overlaps %wu byte at offset %s")
1491 			   : G_("%G%qD accessing %wu bytes at offsets %s "
1492 				"and %s overlaps %wu bytes at offset "
1493 				"%s")),
1494 			call, func, sizrange[0],
1495 			offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1496 	  else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1497 	    warning_n (loc, OPT_Wrestrict, sizrange[0],
1498 		       "%G%qD accessing %wu byte at offsets %s "
1499 		       "and %s overlaps between %wu and %wu bytes "
1500 		       "at offset %s",
1501 		       "%G%qD accessing %wu bytes at offsets %s "
1502 		       "and %s overlaps between %wu and %wu bytes "
1503 		       "at offset %s",
1504 		       call, func, sizrange[0], offstr[0], offstr[1],
1505 		       ovlsiz[0], ovlsiz[1], offstr[2]);
1506 	  else
1507 	    warning_n (loc, OPT_Wrestrict, sizrange[0],
1508 		       "%G%qD accessing %wu byte at offsets %s and "
1509 		       "%s overlaps %wu or more bytes at offset %s",
1510 		       "%G%qD accessing %wu bytes at offsets %s and "
1511 		       "%s overlaps %wu or more bytes at offset %s",
1512 		       call, func, sizrange[0],
1513 		       offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1514 	  return true;
1515 	}
1516 
1517       if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1518 	{
1519 	  if (ovlsiz[0] == ovlsiz[1])
1520 	    warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1521 		       "%G%qD accessing between %wu and %wu bytes "
1522 		       "at offsets %s and %s overlaps %wu byte at "
1523 		       "offset %s",
1524 		       "%G%qD accessing between %wu and %wu bytes "
1525 		       "at offsets %s and %s overlaps %wu bytes "
1526 		       "at offset %s",
1527 		       call, func, sizrange[0], sizrange[1],
1528 		       offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1529 	  else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1530 	    warning_at (loc, OPT_Wrestrict,
1531 			"%G%qD accessing between %wu and %wu bytes at "
1532 			"offsets %s and %s overlaps between %wu and %wu "
1533 			"bytes at offset %s",
1534 			call, func, sizrange[0], sizrange[1],
1535 			offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1536 			offstr[2]);
1537 	  else
1538 	    warning_at (loc, OPT_Wrestrict,
1539 			"%G%qD accessing between %wu and %wu bytes at "
1540 			"offsets %s and %s overlaps %wu or more bytes "
1541 			"at offset %s",
1542 			call, func, sizrange[0], sizrange[1],
1543 			offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1544 	  return true;
1545 	}
1546 
1547       if (ovlsiz[0] != ovlsiz[1])
1548 	ovlsiz[1] = maxobjsize.to_shwi ();
1549 
1550       if (ovlsiz[0] == ovlsiz[1])
1551 	warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1552 		   "%G%qD accessing %wu or more bytes at offsets "
1553 		   "%s and %s overlaps %wu byte at offset %s",
1554 		   "%G%qD accessing %wu or more bytes at offsets "
1555 		   "%s and %s overlaps %wu bytes at offset %s",
1556 		   call, func, sizrange[0], offstr[0], offstr[1],
1557 		   ovlsiz[0], offstr[2]);
1558       else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1559 	warning_at (loc, OPT_Wrestrict,
1560 		    "%G%qD accessing %wu or more bytes at offsets %s "
1561 		    "and %s overlaps between %wu and %wu bytes "
1562 		    "at offset %s",
1563 		    call, func, sizrange[0], offstr[0], offstr[1],
1564 		    ovlsiz[0], ovlsiz[1], offstr[2]);
1565       else
1566 	warning_at (loc, OPT_Wrestrict,
1567 		    "%G%qD accessing %wu or more bytes at offsets %s "
1568 		    "and %s overlaps %wu or more bytes at offset %s",
1569 		    call, func, sizrange[0], offstr[0], offstr[1],
1570 		    ovlsiz[0], offstr[2]);
1571       return true;
1572     }
1573 
1574   /* Use more concise wording when one of the offsets is unbounded
1575      to avoid confusing the user with large and mostly meaningless
1576      numbers.  */
1577   bool open_range;
1578   if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1579     open_range = ((dstref.offrange[0] == 0
1580 		   && dstref.offrange[1] == maxobjsize)
1581 		  || (srcref.offrange[0] == 0
1582 		      && srcref.offrange[1] == maxobjsize));
1583   else
1584     open_range = ((dstref.offrange[0] == -maxobjsize - 1
1585 		   && dstref.offrange[1] == maxobjsize)
1586 		  || (srcref.offrange[0] == -maxobjsize - 1
1587 		      && srcref.offrange[1] == maxobjsize));
1588 
1589   if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1590     {
1591       if (ovlsiz[1] == 1)
1592 	{
1593 	  if (open_range)
1594 	    warning_n (loc, OPT_Wrestrict, sizrange[1],
1595 		       "%G%qD accessing %wu byte may overlap "
1596 		       "%wu byte",
1597 		       "%G%qD accessing %wu bytes may overlap "
1598 		       "%wu byte",
1599 		       call, func, sizrange[1], ovlsiz[1]);
1600 	  else
1601 	    warning_n (loc, OPT_Wrestrict, sizrange[1],
1602 		       "%G%qD accessing %wu byte at offsets %s "
1603 		       "and %s may overlap %wu byte at offset %s",
1604 		       "%G%qD accessing %wu bytes at offsets %s "
1605 		       "and %s may overlap %wu byte at offset %s",
1606 		       call, func, sizrange[1], offstr[0], offstr[1],
1607 		       ovlsiz[1], offstr[2]);
1608 	  return true;
1609 	}
1610 
1611       if (open_range)
1612 	warning_n (loc, OPT_Wrestrict, sizrange[1],
1613 		   "%G%qD accessing %wu byte may overlap "
1614 		   "up to %wu bytes",
1615 		   "%G%qD accessing %wu bytes may overlap "
1616 		   "up to %wu bytes",
1617 		   call, func, sizrange[1], ovlsiz[1]);
1618       else
1619 	warning_n (loc, OPT_Wrestrict, sizrange[1],
1620 		   "%G%qD accessing %wu byte at offsets %s and "
1621 		   "%s may overlap up to %wu bytes at offset %s",
1622 		   "%G%qD accessing %wu bytes at offsets %s and "
1623 		   "%s may overlap up to %wu bytes at offset %s",
1624 		   call, func, sizrange[1], offstr[0], offstr[1],
1625 		   ovlsiz[1], offstr[2]);
1626       return true;
1627     }
1628 
1629   if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1630     {
1631       if (open_range)
1632 	warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1633 		   "%G%qD accessing between %wu and %wu bytes "
1634 		   "may overlap %wu byte",
1635 		   "%G%qD accessing between %wu and %wu bytes "
1636 		   "may overlap up to %wu bytes",
1637 		   call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1638       else
1639 	warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1640 		   "%G%qD accessing between %wu and %wu bytes "
1641 		   "at offsets %s and %s may overlap %wu byte "
1642 		   "at offset %s",
1643 		   "%G%qD accessing between %wu and %wu bytes "
1644 		   "at offsets %s and %s may overlap up to %wu "
1645 		   "bytes at offset %s",
1646 		   call, func, sizrange[0], sizrange[1],
1647 		   offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1648       return true;
1649     }
1650 
1651   warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1652 	     "%G%qD accessing %wu or more bytes at offsets %s "
1653 	     "and %s may overlap %wu byte at offset %s",
1654 	     "%G%qD accessing %wu or more bytes at offsets %s "
1655 	     "and %s may overlap up to %wu bytes at offset %s",
1656 	     call, func, sizrange[0], offstr[0], offstr[1],
1657 	     ovlsiz[1], offstr[2]);
1658 
1659   return true;
1660 }
1661 
1662 /* Validate REF size and offsets in an expression passed as an argument
1663    to a CALL to a built-in function FUNC to make sure they are within
1664    the bounds of the referenced object if its size is known, or
1665    PTRDIFF_MAX otherwise.  DO_WARN is true when a diagnostic should
1666    be issued, false otherwise.
1667    Both initial values of the offsets and their final value computed
1668    by the function by incrementing the initial value by the size are
1669    validated.  Return true if the offsets are not valid and a diagnostic
1670    has been issued, or would have been issued if DO_WARN had been true.  */
1671 
1672 static bool
maybe_diag_access_bounds(gimple * call,tree func,int strict,const builtin_memref & ref,offset_int wroff,bool do_warn)1673 maybe_diag_access_bounds (gimple *call, tree func, int strict,
1674 			  const builtin_memref &ref, offset_int wroff,
1675 			  bool do_warn)
1676 {
1677   location_t loc = gimple_or_expr_nonartificial_location (call, ref.ptr);
1678   const offset_int maxobjsize = ref.maxobjsize;
1679 
1680   /* Check for excessive size first and regardless of warning options
1681      since the result is used to make codegen decisions.  */
1682   if (ref.sizrange[0] > maxobjsize)
1683     {
1684       /* Return true without issuing a warning.  */
1685       if (!do_warn)
1686 	return true;
1687 
1688       if (ref.ref && TREE_NO_WARNING (ref.ref))
1689 	return false;
1690 
1691       if (warn_stringop_overflow)
1692 	{
1693 	  if (ref.sizrange[0] == ref.sizrange[1])
1694 	    return warning_at (loc, OPT_Wstringop_overflow_,
1695 			       "%G%qD specified bound %wu "
1696 			       "exceeds maximum object size %wu",
1697 			       call, func, ref.sizrange[0].to_uhwi (),
1698 			       maxobjsize.to_uhwi ());
1699 
1700 	  return warning_at (loc, OPT_Wstringop_overflow_,
1701 			     "%G%qD specified bound between %wu and %wu "
1702 			     "exceeds maximum object size %wu",
1703 			     call, func, ref.sizrange[0].to_uhwi (),
1704 			     ref.sizrange[1].to_uhwi (),
1705 			     maxobjsize.to_uhwi ());
1706 	}
1707     }
1708 
1709   /* Check for out-bounds pointers regardless of warning options since
1710      the result is used to make codegen decisions.  An excessive WROFF
1711      can only come up as a result of an invalid strncat bound and is
1712      diagnosed separately using a more meaningful warning.  */
1713   if (maxobjsize < wroff)
1714     wroff = 0;
1715   offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff };
1716   tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1717   if (!oobref)
1718     return false;
1719 
1720   /* Return true without issuing a warning.  */
1721   if (!do_warn)
1722     return true;
1723 
1724   if (!warn_array_bounds)
1725     return false;
1726 
1727   if (TREE_NO_WARNING (ref.ptr)
1728       || (ref.ref && TREE_NO_WARNING (ref.ref)))
1729     return false;
1730 
1731   char rangestr[2][64];
1732   if (ooboff[0] == ooboff[1]
1733       || (ooboff[0] != ref.offrange[0]
1734 	  && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1735     sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1736   else
1737     sprintf (rangestr[0], "[%lli, %lli]",
1738 	     (long long) ooboff[0].to_shwi (),
1739 	     (long long) ooboff[1].to_shwi ());
1740 
1741   bool warned = false;
1742 
1743   if (oobref == error_mark_node)
1744     {
1745       if (ref.sizrange[0] == ref.sizrange[1])
1746 	sprintf (rangestr[1], "%llu",
1747 		 (unsigned long long) ref.sizrange[0].to_shwi ());
1748       else
1749 	sprintf (rangestr[1], "[%lli, %lli]",
1750 		 (unsigned long long) ref.sizrange[0].to_uhwi (),
1751 		 (unsigned long long) ref.sizrange[1].to_uhwi ());
1752 
1753       tree type;
1754 
1755       if (DECL_P (ref.base)
1756 	  && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1757 	{
1758 	  auto_diagnostic_group d;
1759 	  if (warning_at (loc, OPT_Warray_bounds,
1760 			  "%G%qD pointer overflow between offset %s "
1761 			  "and size %s accessing array %qD with type %qT",
1762 			  call, func, rangestr[0], rangestr[1], ref.base, type))
1763 	    {
1764 	      inform (DECL_SOURCE_LOCATION (ref.base),
1765 		      "array %qD declared here", ref.base);
1766 	      warned = true;
1767 	    }
1768 	  else
1769 	    warned = warning_at (loc, OPT_Warray_bounds,
1770 				 "%G%qD pointer overflow between offset %s "
1771 				 "and size %s",
1772 				 call, func, rangestr[0], rangestr[1]);
1773 	}
1774       else
1775 	warned = warning_at (loc, OPT_Warray_bounds,
1776 			     "%G%qD pointer overflow between offset %s "
1777 			     "and size %s",
1778 			     call, func, rangestr[0], rangestr[1]);
1779     }
1780   else if (oobref == ref.base)
1781     {
1782       /* True when the offset formed by an access to the reference
1783 	 is out of bounds, rather than the initial offset wich is
1784 	 in bounds.  This implies access past the end.  */
1785       bool form = ooboff[0] != ref.offrange[0];
1786 
1787       if (DECL_P (ref.base))
1788 	{
1789 	  auto_diagnostic_group d;
1790 	  if ((ref.basesize < maxobjsize
1791 	       && warning_at (loc, OPT_Warray_bounds,
1792 			      form
1793 			      ? G_("%G%qD forming offset %s is out of "
1794 				   "the bounds [0, %wu] of object %qD with "
1795 				   "type %qT")
1796 			      : G_("%G%qD offset %s is out of the bounds "
1797 				   "[0, %wu] of object %qD with type %qT"),
1798 			      call, func, rangestr[0], ref.basesize.to_uhwi (),
1799 			      ref.base, TREE_TYPE (ref.base)))
1800 	      || warning_at (loc, OPT_Warray_bounds,
1801 			     form
1802 			     ? G_("%G%qD forming offset %s is out of "
1803 				  "the bounds of object %qD with type %qT")
1804 			     : G_("%G%qD offset %s is out of the bounds "
1805 				  "of object %qD with type %qT"),
1806 			     call, func, rangestr[0],
1807 			     ref.base, TREE_TYPE (ref.base)))
1808 	    {
1809 	      inform (DECL_SOURCE_LOCATION (ref.base),
1810 		      "%qD declared here", ref.base);
1811 	      warned = true;
1812 	    }
1813 	}
1814       else if (ref.basesize < maxobjsize)
1815 	warned = warning_at (loc, OPT_Warray_bounds,
1816 			     form
1817 			     ? G_("%G%qD forming offset %s is out "
1818 				  "of the bounds [0, %wu]")
1819 			     : G_("%G%qD offset %s is out "
1820 				  "of the bounds [0, %wu]"),
1821 			     call, func, rangestr[0], ref.basesize.to_uhwi ());
1822       else
1823 	warned = warning_at (loc, OPT_Warray_bounds,
1824 			     form
1825 			     ? G_("%G%qD forming offset %s is out of bounds")
1826 			     : G_("%G%qD offset %s is out of bounds"),
1827 			     call, func, rangestr[0]);
1828     }
1829   else if (TREE_CODE (ref.ref) == MEM_REF)
1830     {
1831       tree refop = TREE_OPERAND (ref.ref, 0);
1832       tree type = TREE_TYPE (refop);
1833       if (POINTER_TYPE_P (type))
1834 	type = TREE_TYPE (type);
1835       type = TYPE_MAIN_VARIANT (type);
1836 
1837       if (warning_at (loc, OPT_Warray_bounds,
1838 		      "%G%qD offset %s from the object at %qE is out "
1839 		      "of the bounds of %qT",
1840 		      call, func, rangestr[0], ref.base, type))
1841 	{
1842 	  if (TREE_CODE (ref.ref) == COMPONENT_REF)
1843 	    refop = TREE_OPERAND (ref.ref, 1);
1844 	  if (DECL_P (refop))
1845 	    inform (DECL_SOURCE_LOCATION (refop),
1846 		    "subobject %qD declared here", refop);
1847 	  warned = true;
1848 	}
1849     }
1850   else
1851     {
1852       tree refop = TREE_OPERAND (ref.ref, 0);
1853       tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1854 
1855       if (warning_at (loc, OPT_Warray_bounds,
1856 		      "%G%qD offset %s from the object at %qE is out "
1857 		      "of the bounds of referenced subobject %qD with "
1858 		      "type %qT at offset %wi",
1859 		      call, func, rangestr[0], ref.base,
1860 		      TREE_OPERAND (ref.ref, 1), type,
1861 		      ref.refoff.to_shwi ()))
1862 	{
1863 	  if (TREE_CODE (ref.ref) == COMPONENT_REF)
1864 	    refop = TREE_OPERAND (ref.ref, 1);
1865 	  if (DECL_P (refop))
1866 	    inform (DECL_SOURCE_LOCATION (refop),
1867 		    "subobject %qD declared here", refop);
1868 	  warned = true;
1869 	}
1870     }
1871 
1872   return warned;
1873 }
1874 
1875 /* Check a CALL statement for restrict-violations and issue warnings
1876    if/when appropriate.  */
1877 
1878 void
check_call(gimple * call)1879 wrestrict_dom_walker::check_call (gimple *call)
1880 {
1881   /* Avoid checking the call if it has already been diagnosed for
1882      some reason.  */
1883   if (gimple_no_warning_p (call))
1884     return;
1885 
1886   tree func = gimple_call_fndecl (call);
1887   if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
1888     return;
1889 
1890   /* Argument number to extract from the call (depends on the built-in
1891      and its kind).  */
1892   unsigned dst_idx = -1;
1893   unsigned src_idx = -1;
1894   unsigned bnd_idx = -1;
1895 
1896   /* Is this CALL to a string function (as opposed to one to a raw
1897      memory function).  */
1898   bool strfun = true;
1899 
1900   switch (DECL_FUNCTION_CODE (func))
1901     {
1902     case BUILT_IN_MEMCPY:
1903     case BUILT_IN_MEMCPY_CHK:
1904     case BUILT_IN_MEMPCPY:
1905     case BUILT_IN_MEMPCPY_CHK:
1906     case BUILT_IN_MEMMOVE:
1907     case BUILT_IN_MEMMOVE_CHK:
1908       strfun = false;
1909       /* Fall through.  */
1910 
1911     case BUILT_IN_STPNCPY:
1912     case BUILT_IN_STPNCPY_CHK:
1913     case BUILT_IN_STRNCAT:
1914     case BUILT_IN_STRNCAT_CHK:
1915     case BUILT_IN_STRNCPY:
1916     case BUILT_IN_STRNCPY_CHK:
1917       dst_idx = 0;
1918       src_idx = 1;
1919       bnd_idx = 2;
1920       break;
1921 
1922     case BUILT_IN_MEMSET:
1923     case BUILT_IN_MEMSET_CHK:
1924       dst_idx = 0;
1925       bnd_idx = 2;
1926       break;
1927 
1928     case BUILT_IN_STPCPY:
1929     case BUILT_IN_STPCPY_CHK:
1930     case BUILT_IN_STRCPY:
1931     case BUILT_IN_STRCPY_CHK:
1932     case BUILT_IN_STRCAT:
1933     case BUILT_IN_STRCAT_CHK:
1934       dst_idx = 0;
1935       src_idx = 1;
1936       break;
1937 
1938     default:
1939       /* Handle other string functions here whose access may need
1940 	 to be validated for in-bounds offsets and non-overlapping
1941 	 copies.  */
1942       return;
1943     }
1944 
1945   unsigned nargs = gimple_call_num_args (call);
1946 
1947   tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1948   tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1949   tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1950 
1951   /* For string functions with an unspecified or unknown bound,
1952      assume the size of the access is one.  */
1953   if (!dstwr && strfun)
1954     dstwr = size_one_node;
1955 
1956   /* DST and SRC can be null for a call with an insufficient number
1957      of arguments to a built-in function declared without a protype.  */
1958   if (!dst || (src_idx < nargs && !src))
1959     return;
1960 
1961   /* DST, SRC, or DSTWR can also have the wrong type in a call to
1962      a function declared without a prototype.  Avoid checking such
1963      invalid calls.  */
1964   if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1965       || (src && TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE)
1966       || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1967     return;
1968 
1969   if (!check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1970     return;
1971 
1972   /* Avoid diagnosing the call again.  */
1973   gimple_set_no_warning (call, true);
1974 }
1975 
1976 } /* anonymous namespace */
1977 
1978 /* Attempt to detect and diagnose invalid offset bounds and (except for
1979    memmove) overlapping copy in a call expression EXPR from SRC to DST
1980    and DSTSIZE and SRCSIZE bytes, respectively.  Both DSTSIZE and
1981    SRCSIZE may be NULL.  DO_WARN is false to detect either problem
1982    without issue a warning.  Return the OPT_Wxxx constant corresponding
1983    to the warning if one has been detected and zero otherwise.  */
1984 
1985 int
check_bounds_or_overlap(gimple * call,tree dst,tree src,tree dstsize,tree srcsize,bool bounds_only,bool do_warn)1986 check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
1987 			 tree srcsize, bool bounds_only /* = false */,
1988 			 bool do_warn /* = true */)
1989 {
1990   tree func = gimple_call_fndecl (call);
1991 
1992   builtin_memref dstref (dst, dstsize);
1993   builtin_memref srcref (src, srcsize);
1994 
1995   /* Create a descriptor of the access.  This may adjust both DSTREF
1996      and SRCREF based on one another and the kind of the access.  */
1997   builtin_access acs (call, dstref, srcref);
1998 
1999   /* Set STRICT to the value of the -Warray-bounds=N argument for
2000      string functions or when N > 1.  */
2001   int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
2002 
2003   /* The starting offset of the destination write access.  Nonzero only
2004      for the strcat family of functions.  */
2005   offset_int wroff = acs.write_off (dstsize);
2006 
2007   /* Validate offsets to each reference before the access first to make
2008      sure they are within the bounds of the destination object if its
2009      size is known, or PTRDIFF_MAX otherwise.  */
2010   if (maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn)
2011       || maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn))
2012     {
2013       if (do_warn)
2014 	gimple_set_no_warning (call, true);
2015       return OPT_Warray_bounds;
2016     }
2017 
2018   if (!warn_restrict || bounds_only || !src)
2019     return 0;
2020 
2021   if (!bounds_only)
2022     {
2023       switch (DECL_FUNCTION_CODE (func))
2024 	{
2025 	case BUILT_IN_MEMMOVE:
2026 	case BUILT_IN_MEMMOVE_CHK:
2027 	case BUILT_IN_MEMSET:
2028 	case BUILT_IN_MEMSET_CHK:
2029 	  return 0;
2030 	default:
2031 	  break;
2032 	}
2033     }
2034 
2035   location_t loc = gimple_or_expr_nonartificial_location (call, dst);
2036   if (operand_equal_p (dst, src, 0))
2037     {
2038       /* Issue -Wrestrict unless the pointers are null (those do
2039 	 not point to objects and so do not indicate an overlap;
2040 	 such calls could be the result of sanitization and jump
2041 	 threading).  */
2042       if (!integer_zerop (dst) && !gimple_no_warning_p (call))
2043 	{
2044 	  warning_at (loc, OPT_Wrestrict,
2045 		      "%G%qD source argument is the same as destination",
2046 		      call, func);
2047 	  gimple_set_no_warning (call, true);
2048 	  return OPT_Wrestrict;
2049 	}
2050 
2051       return 0;
2052     }
2053 
2054   /* Return false when overlap has been detected.  */
2055   if (maybe_diag_overlap (loc, call, acs))
2056     {
2057       gimple_set_no_warning (call, true);
2058       return OPT_Wrestrict;
2059     }
2060 
2061   return 0;
2062 }
2063 
2064 gimple_opt_pass *
make_pass_warn_restrict(gcc::context * ctxt)2065 make_pass_warn_restrict (gcc::context *ctxt)
2066 {
2067   return new pass_wrestrict (ctxt);
2068 }
2069 
2070 DEBUG_FUNCTION void
dump_builtin_memref(FILE * fp,const builtin_memref & ref)2071 dump_builtin_memref (FILE *fp, const builtin_memref &ref)
2072 {
2073   fprintf (fp, "\n    ptr = ");
2074   print_generic_expr (fp, ref.ptr, TDF_LINENO);
2075   fprintf (fp, "\n    ref = ");
2076   if (ref.ref)
2077     print_generic_expr (fp, ref.ref, TDF_LINENO);
2078   else
2079     fputs ("null", fp);
2080   fprintf (fp, "\n    base = ");
2081   print_generic_expr (fp, ref.base, TDF_LINENO);
2082   fprintf (fp,
2083 	   "\n    basesize = %lli"
2084 	   "\n    refsize = %lli"
2085 	   "\n    refoff = %lli"
2086 	   "\n    offrange = [%lli, %lli]"
2087 	   "\n    sizrange = [%lli, %lli]"
2088 	   "\n    strbounded_p = %s\n",
2089 	   (long long)ref.basesize.to_shwi (),
2090 	   (long long)ref.refsize.to_shwi (),
2091 	   (long long)ref.refoff.to_shwi (),
2092 	   (long long)ref.offrange[0].to_shwi (),
2093 	   (long long)ref.offrange[1].to_shwi (),
2094 	   (long long)ref.sizrange[0].to_shwi (),
2095 	   (long long)ref.sizrange[1].to_shwi (),
2096 	   ref.strbounded_p ? "true" : "false");
2097 }
2098 
2099 void
dump(FILE * fp)2100 builtin_access::dump (FILE *fp) const
2101 {
2102   fprintf (fp, "  dstref:");
2103   dump_builtin_memref (fp, *dstref);
2104   fprintf (fp, "\n  srcref:");
2105   dump_builtin_memref (fp, *srcref);
2106 
2107   fprintf (fp,
2108 	   "  sizrange = [%lli, %lli]\n"
2109 	   "  ovloff = [%lli, %lli]\n"
2110 	   "  ovlsiz = [%lli, %lli]\n"
2111 	   "  dstoff = [%lli, %lli]\n"
2112 	   "  dstsiz = [%lli, %lli]\n"
2113 	   "  srcoff = [%lli, %lli]\n"
2114 	   "  srcsiz = [%lli, %lli]\n",
2115 	   (long long)sizrange[0], (long long)sizrange[1],
2116 	   (long long)ovloff[0], (long long)ovloff[1],
2117 	   (long long)ovlsiz[0], (long long)ovlsiz[1],
2118 	   (long long)dstoff[0].to_shwi (), (long long)dstoff[1].to_shwi (),
2119 	   (long long)dstsiz[0].to_shwi (), (long long)dstsiz[1].to_shwi (),
2120 	   (long long)srcoff[0].to_shwi (), (long long)srcoff[1].to_shwi (),
2121 	   (long long)srcsiz[0].to_shwi (), (long long)srcsiz[1].to_shwi ());
2122 }
2123 
2124 DEBUG_FUNCTION void
dump_builtin_access(FILE * fp,gimple * stmt,const builtin_access & acs)2125 dump_builtin_access (FILE *fp, gimple *stmt, const builtin_access &acs)
2126 {
2127   if (stmt)
2128     {
2129       fprintf (fp, "\nDumping builtin_access for ");
2130       print_gimple_expr (fp, stmt, TDF_LINENO);
2131       fputs (":\n", fp);
2132     }
2133 
2134   acs.dump (fp);
2135 }
2136 
2137 DEBUG_FUNCTION void
debug(gimple * stmt,const builtin_access & acs)2138 debug (gimple *stmt, const builtin_access &acs)
2139 {
2140   dump_builtin_access (stdout, stmt, acs);
2141 }
2142