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