xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/gimple-ssa-warn-restrict.c (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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