gimple-ssa-warn-restrict.c revision 1.1.1.2
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
46namespace {
47
48const 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.  */
62class pass_wrestrict : public gimple_opt_pass
63{
64 public:
65  pass_wrestrict (gcc::context *ctxt)
66    : gimple_opt_pass (pass_data_wrestrict, ctxt)
67    { }
68
69  opt_pass *clone () { return new pass_wrestrict (m_ctxt); }
70
71  virtual bool gate (function *);
72  virtual unsigned int execute (function *);
73};
74
75bool
76pass_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.  */
82class wrestrict_dom_walker : public dom_walker
83{
84 public:
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
94edge
95wrestrict_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
113unsigned
114pass_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.  */
127struct 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
164private:
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.  */
175class 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.  */
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
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
231builtin_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
304void
305builtin_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
376void
377builtin_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
504tree
505builtin_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
596builtin_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
852offset_int
853builtin_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
885bool
886builtin_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
1094bool
1095builtin_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
1221bool
1222builtin_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
1235bool
1236builtin_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
1368static bool
1369maybe_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
1626static bool
1627maybe_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
1817void
1818wrestrict_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
1924int
1925check_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
1999gimple_opt_pass *
2000make_pass_warn_restrict (gcc::context *ctxt)
2001{
2002  return new pass_wrestrict (ctxt);
2003}
2004