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