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