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