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