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