1 /* String length optimization
2    Copyright (C) 2011-2021 Free Software Foundation, Inc.
3    Contributed by Jakub Jelinek <jakub@redhat.com>
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "alloc-pool.h"
29 #include "tree-pass.h"
30 #include "ssa.h"
31 #include "cgraph.h"
32 #include "gimple-pretty-print.h"
33 #include "gimple-ssa-warn-access.h"
34 #include "gimple-ssa-warn-restrict.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "gimple-fold.h"
38 #include "tree-eh.h"
39 #include "gimplify.h"
40 #include "gimple-iterator.h"
41 #include "gimplify-me.h"
42 #include "expr.h"
43 #include "tree-cfg.h"
44 #include "tree-dfa.h"
45 #include "domwalk.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-ssa-propagate.h"
48 #include "tree-ssa-strlen.h"
49 #include "tree-hash-traits.h"
50 #include "builtins.h"
51 #include "pointer-query.h"
52 #include "target.h"
53 #include "diagnostic-core.h"
54 #include "diagnostic.h"
55 #include "intl.h"
56 #include "attribs.h"
57 #include "calls.h"
58 #include "cfgloop.h"
59 #include "tree-ssa-loop.h"
60 #include "tree-scalar-evolution.h"
61 #include "vr-values.h"
62 #include "gimple-range.h"
63 #include "tree-ssa.h"
64 
65 /* A vector indexed by SSA_NAME_VERSION.  0 means unknown, positive value
66    is an index into strinfo vector, negative value stands for
67    string length of a string literal (~strlen).  */
68 static vec<int> ssa_ver_to_stridx;
69 
70 /* Number of currently active string indexes plus one.  */
71 static int max_stridx;
72 
73 /* Set to true to optimize, false when just checking.  */
74 static bool strlen_optimize;
75 
76 /* String information record.  */
77 struct strinfo
78 {
79   /* Number of leading characters that are known to be nonzero.  This is
80      also the length of the string if FULL_STRING_P.
81 
82      The values in a list of related string pointers must be consistent;
83      that is, if strinfo B comes X bytes after strinfo A, it must be
84      the case that A->nonzero_chars == X + B->nonzero_chars.  */
85   tree nonzero_chars;
86   /* Any of the corresponding pointers for querying alias oracle.  */
87   tree ptr;
88   /* STMT is used for two things:
89 
90      - To record the statement that should be used for delayed length
91        computations.  We maintain the invariant that all related strinfos
92        have delayed lengths or none do.
93 
94      - To record the malloc or calloc call that produced this result
95        to optimize away malloc/memset sequences.  STMT is reset after
96        a calloc-allocated object has been stored a non-zero value into.  */
97   gimple *stmt;
98   /* Set to the dynamic allocation statement for the object (alloca,
99      calloc, malloc, or VLA).  Unlike STMT, once set for a strinfo
100      object, ALLOC doesn't change.  */
101   gimple *alloc;
102   /* Pointer to '\0' if known, if NULL, it can be computed as
103      ptr + length.  */
104   tree endptr;
105   /* Reference count.  Any changes to strinfo entry possibly shared
106      with dominating basic blocks need unshare_strinfo first, except
107      for dont_invalidate which affects only the immediately next
108      maybe_invalidate.  */
109   int refcount;
110   /* Copy of index.  get_strinfo (si->idx) should return si;  */
111   int idx;
112   /* These 3 fields are for chaining related string pointers together.
113      E.g. for
114      bl = strlen (b); dl = strlen (d); strcpy (a, b); c = a + bl;
115      strcpy (c, d); e = c + dl;
116      strinfo(a) -> strinfo(c) -> strinfo(e)
117      All have ->first field equal to strinfo(a)->idx and are doubly
118      chained through prev/next fields.  The later strinfos are required
119      to point into the same string with zero or more bytes after
120      the previous pointer and all bytes in between the two pointers
121      must be non-zero.  Functions like strcpy or memcpy are supposed
122      to adjust all previous strinfo lengths, but not following strinfo
123      lengths (those are uncertain, usually invalidated during
124      maybe_invalidate, except when the alias oracle knows better).
125      Functions like strcat on the other side adjust the whole
126      related strinfo chain.
127      They are updated lazily, so to use the chain the same first fields
128      and si->prev->next == si->idx needs to be verified.  */
129   int first;
130   int next;
131   int prev;
132   /* A flag whether the string is known to be written in the current
133      function.  */
134   bool writable;
135   /* A flag for the next maybe_invalidate that this strinfo shouldn't
136      be invalidated.  Always cleared by maybe_invalidate.  */
137   bool dont_invalidate;
138   /* True if the string is known to be nul-terminated after NONZERO_CHARS
139      characters.  False is useful when detecting strings that are built
140      up via successive memcpys.  */
141   bool full_string_p;
142 };
143 
144 /* Pool for allocating strinfo_struct entries.  */
145 static object_allocator<strinfo> strinfo_pool ("strinfo pool");
146 
147 /* Vector mapping positive string indexes to strinfo, for the
148    current basic block.  The first pointer in the vector is special,
149    it is either NULL, meaning the vector isn't shared, or it is
150    a basic block pointer to the owner basic_block if shared.
151    If some other bb wants to modify the vector, the vector needs
152    to be unshared first, and only the owner bb is supposed to free it.  */
153 static vec<strinfo *, va_heap, vl_embed> *stridx_to_strinfo;
154 
155 /* One OFFSET->IDX mapping.  */
156 struct stridxlist
157 {
158   struct stridxlist *next;
159   HOST_WIDE_INT offset;
160   int idx;
161 };
162 
163 /* Hash table entry, mapping a DECL to a chain of OFFSET->IDX mappings.  */
164 struct decl_stridxlist_map
165 {
166   struct tree_map_base base;
167   struct stridxlist list;
168 };
169 
170 /* Hash table for mapping decls to a chained list of offset -> idx
171    mappings.  */
172 typedef hash_map<tree_decl_hash, stridxlist> decl_to_stridxlist_htab_t;
173 static decl_to_stridxlist_htab_t *decl_to_stridxlist_htab;
174 
175 /* Hash table mapping strlen (or strnlen with constant bound and return
176    smaller than bound) calls to stridx instances describing
177    the calls' arguments.  Non-null only when warn_stringop_truncation
178    is non-zero.  */
179 typedef std::pair<int, location_t> stridx_strlenloc;
180 static hash_map<tree, stridx_strlenloc> *strlen_to_stridx;
181 
182 /* Obstack for struct stridxlist and struct decl_stridxlist_map.  */
183 static struct obstack stridx_obstack;
184 
185 /* Last memcpy statement if it could be adjusted if the trailing
186    '\0' written is immediately overwritten, or
187    *x = '\0' store that could be removed if it is immediately overwritten.  */
188 struct laststmt_struct
189 {
190   gimple *stmt;
191   tree len;
192   int stridx;
193 } laststmt;
194 
195 static int get_stridx_plus_constant (strinfo *, unsigned HOST_WIDE_INT, tree);
196 static bool get_range_strlen_dynamic (tree, gimple *s, c_strlen_data *,
197 				      bitmap, range_query *, unsigned *);
198 
199 /* Sets MINMAX to either the constant value or the range VAL is in
200    and returns either the constant value or VAL on success or null
201    when the range couldn't be determined.  Uses RVALS or CFUN for
202    range info, whichever is nonnull.  */
203 
204 tree
get_range(tree val,gimple * stmt,wide_int minmax[2],range_query * rvals)205 get_range (tree val, gimple *stmt, wide_int minmax[2],
206 	   range_query *rvals /* = NULL */)
207 {
208   if (!rvals)
209     {
210       if (!cfun)
211 	/* When called from front ends for global initializers CFUN
212 	   may be null.  */
213 	return NULL_TREE;
214 
215       rvals = get_range_query (cfun);
216     }
217 
218   value_range vr;
219   if (!rvals->range_of_expr (vr, val, stmt))
220     return NULL_TREE;
221 
222   value_range_kind rng = vr.kind ();
223   if (rng == VR_RANGE)
224     {
225       /* Only handle straight ranges.  */
226       minmax[0] = wi::to_wide (vr.min ());
227       minmax[1] = wi::to_wide (vr.max ());
228       return val;
229     }
230 
231   return NULL_TREE;
232 }
233 
234 class strlen_pass : public dom_walker
235 {
236 public:
strlen_pass(cdi_direction direction)237   strlen_pass (cdi_direction direction)
238     : dom_walker (direction),
239       ptr_qry (&m_ranger, &var_cache),
240       var_cache (),
241       m_cleanup_cfg (false)
242   {
243   }
244 
245   ~strlen_pass ();
246 
247   virtual edge before_dom_children (basic_block);
248   virtual void after_dom_children (basic_block);
249 
250   bool check_and_optimize_stmt (bool *cleanup_eh);
251   bool check_and_optimize_call (bool *zero_write);
252   bool handle_assign (tree lhs, bool *zero_write);
253   bool handle_store (bool *zero_write);
254   void handle_pointer_plus ();
255   void handle_builtin_strlen ();
256   void handle_builtin_strchr ();
257   void handle_builtin_strcpy (built_in_function);
258   void handle_integral_assign (bool *cleanup_eh);
259   void handle_builtin_stxncpy_strncat (bool append_p);
260   void handle_builtin_memcpy (built_in_function bcode);
261   void handle_builtin_strcat (built_in_function bcode);
262   void handle_builtin_strncat (built_in_function);
263   bool handle_builtin_memset (bool *zero_write);
264   bool handle_builtin_memcmp ();
265   bool handle_builtin_string_cmp ();
266   void handle_alloc_call (built_in_function);
267   void maybe_warn_overflow (gimple *stmt, bool call_lhs, tree len,
268 			    strinfo *si = NULL, bool plus_one = false,
269 			    bool rawmem = false);
270   void maybe_warn_overflow (gimple *stmt, bool call_lhs,
271 			    unsigned HOST_WIDE_INT len,
272 			    strinfo *si = NULL,
273 			    bool plus_one = false, bool rawmem = false);
274   void adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat);
275   tree strxcmp_eqz_result (gimple *stmt, tree arg1, int idx1,
276 			   tree arg2, int idx2,
277 			   unsigned HOST_WIDE_INT bound,
278 			   unsigned HOST_WIDE_INT len[2],
279 			   unsigned HOST_WIDE_INT *psize);
280   bool count_nonzero_bytes (tree expr_or_type,
281 			    gimple *stmt,
282 			    unsigned lenrange[3], bool *nulterm,
283 			    bool *allnul, bool *allnonnul);
284   bool count_nonzero_bytes (tree exp,
285 			    gimple *stmt,
286 			    unsigned HOST_WIDE_INT offset,
287 			    unsigned HOST_WIDE_INT nbytes,
288 			    unsigned lenrange[3], bool *nulterm,
289 			    bool *allnul, bool *allnonnul,
290 			    ssa_name_limit_t &snlim);
291   bool count_nonzero_bytes_addr (tree exp,
292 				 gimple *stmt,
293 				 unsigned HOST_WIDE_INT offset,
294 				 unsigned HOST_WIDE_INT nbytes,
295 				 unsigned lenrange[3], bool *nulterm,
296 				 bool *allnul, bool *allnonnul,
297 				 ssa_name_limit_t &snlim);
298   bool get_len_or_size (gimple *stmt, tree arg, int idx,
299 			unsigned HOST_WIDE_INT lenrng[2],
300 			unsigned HOST_WIDE_INT *size, bool *nulterm);
301 
302   gimple_ranger m_ranger;
303 
304   /* A pointer_query object and its cache to store information about
305      pointers and their targets in.  */
306   pointer_query ptr_qry;
307   pointer_query::cache_type var_cache;
308 
309   gimple_stmt_iterator m_gsi;
310 
311   /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
312      execute function.  */
313   bool m_cleanup_cfg;
314 };
315 
316 /* Return:
317 
318    *  +1  if SI is known to start with more than OFF nonzero characters.
319 
320    *   0  if SI is known to start with exactly OFF nonzero characters.
321 
322    *  -1  if SI either does not start with OFF nonzero characters
323 	  or the relationship between the number of leading nonzero
324 	  characters in SI and OFF is unknown.  */
325 
326 static int
compare_nonzero_chars(strinfo * si,unsigned HOST_WIDE_INT off)327 compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off)
328 {
329   if (si->nonzero_chars
330       && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
331     return compare_tree_int (si->nonzero_chars, off);
332   else
333     return -1;
334 }
335 
336 /* Same as above but suitable also for strings with non-constant lengths.
337    Uses RVALS to determine length range.  */
338 
339 static int
compare_nonzero_chars(strinfo * si,gimple * stmt,unsigned HOST_WIDE_INT off,range_query * rvals)340 compare_nonzero_chars (strinfo *si, gimple *stmt,
341 		       unsigned HOST_WIDE_INT off,
342 		       range_query *rvals)
343 {
344   if (!si->nonzero_chars)
345     return -1;
346 
347   if (TREE_CODE (si->nonzero_chars) == INTEGER_CST)
348     return compare_tree_int (si->nonzero_chars, off);
349 
350   if (!rvals || TREE_CODE (si->nonzero_chars) != SSA_NAME)
351     return -1;
352 
353   value_range vr;
354   if (!rvals->range_of_expr (vr, si->nonzero_chars, stmt))
355     return -1;
356   value_range_kind rng = vr.kind ();
357   if (rng != VR_RANGE)
358     return -1;
359 
360   /* If the offset is less than the minimum length or if the bounds
361      of the length range are equal return the result of the comparison
362      same as in the constant case.  Otherwise return a conservative
363      result.  */
364   int cmpmin = compare_tree_int (vr.min (), off);
365   if (cmpmin > 0 || tree_int_cst_equal (vr.min (), vr.max ()))
366     return cmpmin;
367 
368   return -1;
369 }
370 
371 /* Return true if SI is known to be a zero-length string.  */
372 
373 static inline bool
zero_length_string_p(strinfo * si)374 zero_length_string_p (strinfo *si)
375 {
376   return si->full_string_p && integer_zerop (si->nonzero_chars);
377 }
378 
379 /* Return strinfo vector entry IDX.  */
380 
381 static inline strinfo *
get_strinfo(int idx)382 get_strinfo (int idx)
383 {
384   if (vec_safe_length (stridx_to_strinfo) <= (unsigned int) idx)
385     return NULL;
386   return (*stridx_to_strinfo)[idx];
387 }
388 
389 /* Get the next strinfo in the chain after SI, or null if none.  */
390 
391 static inline strinfo *
get_next_strinfo(strinfo * si)392 get_next_strinfo (strinfo *si)
393 {
394   if (si->next == 0)
395     return NULL;
396   strinfo *nextsi = get_strinfo (si->next);
397   if (nextsi == NULL || nextsi->first != si->first || nextsi->prev != si->idx)
398     return NULL;
399   return nextsi;
400 }
401 
402 /* Helper function for get_stridx.  Return the strinfo index of the address
403    of EXP, which is available in PTR if nonnull.  If OFFSET_OUT, it is
404    OK to return the index for some X <= &EXP and store &EXP - X in
405    *OFFSET_OUT.  When RVALS is nonnull uses it to determine range
406    information.  */
407 
408 static int
409 get_addr_stridx (tree exp, gimple *stmt,
410 		 tree ptr, unsigned HOST_WIDE_INT *offset_out,
411 		 range_query *rvals = NULL)
412 {
413   HOST_WIDE_INT off;
414   struct stridxlist *list, *last = NULL;
415   tree base;
416 
417   if (!decl_to_stridxlist_htab)
418     return 0;
419 
420   poly_int64 poff;
421   base = get_addr_base_and_unit_offset (exp, &poff);
422   if (base == NULL || !DECL_P (base) || !poff.is_constant (&off))
423     return 0;
424 
425   list = decl_to_stridxlist_htab->get (base);
426   if (list == NULL)
427     return 0;
428 
429   do
430     {
431       if (list->offset == off)
432 	{
433 	  if (offset_out)
434 	    *offset_out = 0;
435 	  return list->idx;
436 	}
437       if (list->offset > off)
438 	return 0;
439       last = list;
440       list = list->next;
441     }
442   while (list);
443 
444   if ((offset_out || ptr) && last && last->idx > 0)
445     {
446       unsigned HOST_WIDE_INT rel_off
447 	= (unsigned HOST_WIDE_INT) off - last->offset;
448       strinfo *si = get_strinfo (last->idx);
449       if (si && compare_nonzero_chars (si, stmt, rel_off, rvals) >= 0)
450 	{
451 	  if (offset_out)
452 	    {
453 	      *offset_out = rel_off;
454 	      return last->idx;
455 	    }
456 	  else
457 	    return get_stridx_plus_constant (si, rel_off, ptr);
458 	}
459     }
460   return 0;
461 }
462 
463 /* Returns string index for EXP.  When EXP is an SSA_NAME that refers
464    to a known strinfo with an offset and OFFRNG is non-null, sets
465    both elements of the OFFRNG array to the range of the offset and
466    returns the index of the known strinfo.  In this case the result
467    must not be used in for functions that modify the string.
468    When nonnull, uses RVALS to determine range information.  */
469 
470 static int
471 get_stridx (tree exp, gimple *stmt,
472 	    wide_int offrng[2] = NULL, range_query *rvals = NULL)
473 {
474   if (offrng)
475     offrng[0] = offrng[1] = wi::zero (TYPE_PRECISION (ptrdiff_type_node));
476 
477   if (TREE_CODE (exp) == SSA_NAME)
478     {
479       if (ssa_ver_to_stridx[SSA_NAME_VERSION (exp)])
480 	return ssa_ver_to_stridx[SSA_NAME_VERSION (exp)];
481 
482       tree e = exp;
483       int last_idx = 0;
484       HOST_WIDE_INT offset = 0;
485       /* Follow a chain of at most 5 assignments.  */
486       for (int i = 0; i < 5; i++)
487 	{
488 	  gimple *def_stmt = SSA_NAME_DEF_STMT (e);
489 	  if (!is_gimple_assign (def_stmt))
490 	    return last_idx;
491 
492 	  tree_code rhs_code = gimple_assign_rhs_code (def_stmt);
493 	  tree ptr, off;
494 
495 	  if (rhs_code == ADDR_EXPR)
496 	    {
497 	      /* Handle indices/offsets into VLAs which are implemented
498 	         as pointers to arrays.  */
499 	      ptr = gimple_assign_rhs1 (def_stmt);
500 	      ptr = TREE_OPERAND (ptr, 0);
501 
502 	      /* Handle also VLAs of types larger than char.  */
503 	      if (tree eltsize = TYPE_SIZE_UNIT (TREE_TYPE (ptr)))
504 		{
505 		  if (TREE_CODE (ptr) == ARRAY_REF)
506 		    {
507 		      off = TREE_OPERAND (ptr, 1);
508 		      ptr = TREE_OPERAND (ptr, 0);
509 		      if (!integer_onep (eltsize))
510 			{
511 			  /* Scale the array index by the size of the element
512 			     type in the rare case that it's greater than
513 			     the typical 1 for char, making sure both operands
514 			     have the same type.  */
515 			  eltsize = fold_convert (ssizetype, eltsize);
516 			  off = fold_convert (ssizetype, off);
517 			  off = fold_build2 (MULT_EXPR, ssizetype, off, eltsize);
518 			}
519 		    }
520 		  else
521 		    off = integer_zero_node;
522 		}
523 	      else
524 		return 0;
525 
526 	      if (TREE_CODE (ptr) != MEM_REF)
527 	        return 0;
528 
529 	      /* Add the MEM_REF byte offset.  */
530 	      tree mem_off = TREE_OPERAND (ptr, 1);
531 	      off = fold_build2 (PLUS_EXPR, TREE_TYPE (off), off, mem_off);
532 	      ptr = TREE_OPERAND (ptr, 0);
533 	    }
534 	  else if (rhs_code == POINTER_PLUS_EXPR)
535 	    {
536 	      ptr = gimple_assign_rhs1 (def_stmt);
537 	      off = gimple_assign_rhs2 (def_stmt);
538 	    }
539 	  else
540 	    return 0;
541 
542 	  if (TREE_CODE (ptr) != SSA_NAME)
543 	    return 0;
544 
545 	  if (!tree_fits_shwi_p (off))
546 	    {
547 	      if (int idx = ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)])
548 		if (offrng)
549 		  {
550 		    /* Only when requested by setting OFFRNG to non-null,
551 		       return the index corresponding to the SSA_NAME.
552 		       Do this irrespective of the whether the offset
553 		       is known.  */
554 		    if (get_range (off, def_stmt, offrng, rvals))
555 		      {
556 			/* When the offset range is known, increment it
557 			   it by the constant offset computed in prior
558 			   iterations and store it in the OFFRNG array.  */
559  			offrng[0] += offset;
560 			offrng[1] += offset;
561 		      }
562 		    else
563 		      {
564 			/* When the offset range cannot be determined
565 			   store [0, SIZE_MAX] and let the caller decide
566 			   if the offset matters.  */
567 			offrng[1] = wi::to_wide (TYPE_MAX_VALUE (sizetype));
568 			offrng[0] = wi::zero (offrng[1].get_precision ());
569 		      }
570 		    return idx;
571 		  }
572 	      return 0;
573 	    }
574 
575 	  HOST_WIDE_INT this_off = tree_to_shwi (off);
576 	  if (offrng)
577 	    {
578 	      offrng[0] += wi::shwi (this_off, offrng->get_precision ());
579 	      offrng[1] += offrng[0];
580 	    }
581 
582 	  if (this_off < 0)
583 	    return last_idx;
584 
585 	  offset = (unsigned HOST_WIDE_INT) offset + this_off;
586 	  if (offset < 0)
587 	    return last_idx;
588 
589 	  if (int idx = ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)])
590 	    {
591 	      strinfo *si = get_strinfo (idx);
592 	      if (si)
593 		{
594 		  if (compare_nonzero_chars (si, offset) >= 0)
595 		    return get_stridx_plus_constant (si, offset, exp);
596 
597 		  if (offrng)
598 		    last_idx = idx;
599 		}
600 	    }
601 	  e = ptr;
602 	}
603 
604       return last_idx;
605     }
606 
607   if (TREE_CODE (exp) == ADDR_EXPR)
608     {
609       int idx = get_addr_stridx (TREE_OPERAND (exp, 0), stmt, exp, NULL);
610       if (idx != 0)
611 	return idx;
612     }
613 
614   const char *p = c_getstr (exp);
615   if (p)
616     return ~(int) strlen (p);
617 
618   return 0;
619 }
620 
621 /* Return true if strinfo vector is shared with the immediate dominator.  */
622 
623 static inline bool
strinfo_shared(void)624 strinfo_shared (void)
625 {
626   return vec_safe_length (stridx_to_strinfo)
627 	 && (*stridx_to_strinfo)[0] != NULL;
628 }
629 
630 /* Unshare strinfo vector that is shared with the immediate dominator.  */
631 
632 static void
unshare_strinfo_vec(void)633 unshare_strinfo_vec (void)
634 {
635   strinfo *si;
636   unsigned int i = 0;
637 
638   gcc_assert (strinfo_shared ());
639   stridx_to_strinfo = vec_safe_copy (stridx_to_strinfo);
640   for (i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
641     if (si != NULL)
642       si->refcount++;
643   (*stridx_to_strinfo)[0] = NULL;
644 }
645 
646 /* Attempt to create a string index for exp, ADDR_EXPR's operand.
647    Return a pointer to the location where the string index can
648    be stored (if 0) or is stored, or NULL if this can't be tracked.  */
649 
650 static int *
addr_stridxptr(tree exp)651 addr_stridxptr (tree exp)
652 {
653   HOST_WIDE_INT off;
654 
655   poly_int64 poff;
656   tree base = get_addr_base_and_unit_offset (exp, &poff);
657   if (base == NULL_TREE || !DECL_P (base) || !poff.is_constant (&off))
658     return NULL;
659 
660   if (!decl_to_stridxlist_htab)
661     {
662       decl_to_stridxlist_htab
663        	= new hash_map<tree_decl_hash, stridxlist> (64);
664       gcc_obstack_init (&stridx_obstack);
665     }
666 
667   bool existed;
668   stridxlist *list = &decl_to_stridxlist_htab->get_or_insert (base, &existed);
669   if (existed)
670     {
671       int i;
672       stridxlist *before = NULL;
673       for (i = 0; i < 32; i++)
674 	{
675 	  if (list->offset == off)
676 	    return &list->idx;
677 	  if (list->offset > off && before == NULL)
678 	    before = list;
679 	  if (list->next == NULL)
680 	    break;
681 	  list = list->next;
682 	}
683       if (i == 32)
684 	return NULL;
685       if (before)
686 	{
687 	  list = before;
688 	  before = XOBNEW (&stridx_obstack, struct stridxlist);
689 	  *before = *list;
690 	  list->next = before;
691 	  list->offset = off;
692 	  list->idx = 0;
693 	  return &list->idx;
694 	}
695       list->next = XOBNEW (&stridx_obstack, struct stridxlist);
696       list = list->next;
697     }
698 
699   list->next = NULL;
700   list->offset = off;
701   list->idx = 0;
702   return &list->idx;
703 }
704 
705 /* Create a new string index, or return 0 if reached limit.  */
706 
707 static int
new_stridx(tree exp)708 new_stridx (tree exp)
709 {
710   int idx;
711   if (max_stridx >= param_max_tracked_strlens)
712     return 0;
713   if (TREE_CODE (exp) == SSA_NAME)
714     {
715       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp))
716 	return 0;
717       idx = max_stridx++;
718       ssa_ver_to_stridx[SSA_NAME_VERSION (exp)] = idx;
719       return idx;
720     }
721   if (TREE_CODE (exp) == ADDR_EXPR)
722     {
723       int *pidx = addr_stridxptr (TREE_OPERAND (exp, 0));
724       if (pidx != NULL)
725 	{
726 	  gcc_assert (*pidx == 0);
727 	  *pidx = max_stridx++;
728 	  return *pidx;
729 	}
730     }
731   return 0;
732 }
733 
734 /* Like new_stridx, but for ADDR_EXPR's operand instead.  */
735 
736 static int
new_addr_stridx(tree exp)737 new_addr_stridx (tree exp)
738 {
739   int *pidx;
740   if (max_stridx >= param_max_tracked_strlens)
741     return 0;
742   pidx = addr_stridxptr (exp);
743   if (pidx != NULL)
744     {
745       gcc_assert (*pidx == 0);
746       *pidx = max_stridx++;
747       return *pidx;
748     }
749   return 0;
750 }
751 
752 /* Create a new strinfo.  */
753 
754 static strinfo *
new_strinfo(tree ptr,int idx,tree nonzero_chars,bool full_string_p)755 new_strinfo (tree ptr, int idx, tree nonzero_chars, bool full_string_p)
756 {
757   strinfo *si = strinfo_pool.allocate ();
758   si->nonzero_chars = nonzero_chars;
759   STRIP_USELESS_TYPE_CONVERSION (ptr);
760   si->ptr = ptr;
761   si->stmt = NULL;
762   si->alloc = NULL;
763   si->endptr = NULL_TREE;
764   si->refcount = 1;
765   si->idx = idx;
766   si->first = 0;
767   si->prev = 0;
768   si->next = 0;
769   si->writable = false;
770   si->dont_invalidate = false;
771   si->full_string_p = full_string_p;
772   return si;
773 }
774 
775 /* Decrease strinfo refcount and free it if not referenced anymore.  */
776 
777 static inline void
free_strinfo(strinfo * si)778 free_strinfo (strinfo *si)
779 {
780   if (si && --si->refcount == 0)
781     strinfo_pool.remove (si);
782 }
783 
784 /* Set strinfo in the vector entry IDX to SI.  */
785 
786 static inline void
set_strinfo(int idx,strinfo * si)787 set_strinfo (int idx, strinfo *si)
788 {
789   if (vec_safe_length (stridx_to_strinfo) && (*stridx_to_strinfo)[0])
790     unshare_strinfo_vec ();
791   if (vec_safe_length (stridx_to_strinfo) <= (unsigned int) idx)
792     vec_safe_grow_cleared (stridx_to_strinfo, idx + 1, true);
793   (*stridx_to_strinfo)[idx] = si;
794 }
795 
796 /* Return the first strinfo in the related strinfo chain
797    if all strinfos in between belong to the chain, otherwise NULL.  */
798 
799 static strinfo *
verify_related_strinfos(strinfo * origsi)800 verify_related_strinfos (strinfo *origsi)
801 {
802   strinfo *si = origsi, *psi;
803 
804   if (origsi->first == 0)
805     return NULL;
806   for (; si->prev; si = psi)
807     {
808       if (si->first != origsi->first)
809 	return NULL;
810       psi = get_strinfo (si->prev);
811       if (psi == NULL)
812 	return NULL;
813       if (psi->next != si->idx)
814 	return NULL;
815     }
816   if (si->idx != si->first)
817     return NULL;
818   return si;
819 }
820 
821 /* Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
822    Use LOC for folding.  */
823 
824 static void
set_endptr_and_length(location_t loc,strinfo * si,tree endptr)825 set_endptr_and_length (location_t loc, strinfo *si, tree endptr)
826 {
827   si->endptr = endptr;
828   si->stmt = NULL;
829   tree start_as_size = fold_convert_loc (loc, size_type_node, si->ptr);
830   tree end_as_size = fold_convert_loc (loc, size_type_node, endptr);
831   si->nonzero_chars = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
832 				       end_as_size, start_as_size);
833   si->full_string_p = true;
834 }
835 
836 /* Return the string length, or NULL if it can't be computed.
837    The length may but need not be constant.  Instead, it might be
838    the result of a strlen() call.  */
839 
840 static tree
get_string_length(strinfo * si)841 get_string_length (strinfo *si)
842 {
843   /* If the length has already been computed return it if it's exact
844      (i.e., the string is nul-terminated at NONZERO_CHARS), or return
845      null if it isn't.  */
846   if (si->nonzero_chars)
847     return si->full_string_p ? si->nonzero_chars : NULL;
848 
849   /* If the string is the result of one of the built-in calls below
850      attempt to compute the length from the call statement.  */
851   if (si->stmt)
852     {
853       gimple *stmt = si->stmt, *lenstmt;
854       tree callee, lhs, fn, tem;
855       location_t loc;
856       gimple_stmt_iterator gsi;
857 
858       gcc_assert (is_gimple_call (stmt));
859       callee = gimple_call_fndecl (stmt);
860       gcc_assert (callee && fndecl_built_in_p (callee, BUILT_IN_NORMAL));
861       lhs = gimple_call_lhs (stmt);
862       /* unshare_strinfo is intentionally not called here.  The (delayed)
863 	 transformation of strcpy or strcat into stpcpy is done at the place
864 	 of the former strcpy/strcat call and so can affect all the strinfos
865 	 with the same stmt.  If they were unshared before and transformation
866 	 has been already done, the handling of BUILT_IN_STPCPY{,_CHK} should
867 	 just compute the right length.  */
868       switch (DECL_FUNCTION_CODE (callee))
869 	{
870 	case BUILT_IN_STRCAT:
871 	case BUILT_IN_STRCAT_CHK:
872 	  gsi = gsi_for_stmt (stmt);
873 	  fn = builtin_decl_implicit (BUILT_IN_STRLEN);
874 	  gcc_assert (lhs == NULL_TREE);
875 	  tem = unshare_expr (gimple_call_arg (stmt, 0));
876 	  lenstmt = gimple_build_call (fn, 1, tem);
877 	  lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), lenstmt);
878 	  gimple_call_set_lhs (lenstmt, lhs);
879 	  gimple_set_vuse (lenstmt, gimple_vuse (stmt));
880 	  gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT);
881 	  tem = gimple_call_arg (stmt, 0);
882           if (!ptrofftype_p (TREE_TYPE (lhs)))
883             {
884               lhs = convert_to_ptrofftype (lhs);
885               lhs = force_gimple_operand_gsi (&gsi, lhs, true, NULL_TREE,
886                                               true, GSI_SAME_STMT);
887             }
888 	  lenstmt = gimple_build_assign
889 			(make_ssa_name (TREE_TYPE (gimple_call_arg (stmt, 0))),
890 			 POINTER_PLUS_EXPR,tem, lhs);
891 	  gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT);
892 	  gimple_call_set_arg (stmt, 0, gimple_assign_lhs (lenstmt));
893 	  lhs = NULL_TREE;
894 	  /* FALLTHRU */
895 	case BUILT_IN_STRCPY:
896 	case BUILT_IN_STRCPY_CHK:
897 	  gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY));
898 	  if (gimple_call_num_args (stmt) == 2)
899 	    fn = builtin_decl_implicit (BUILT_IN_STPCPY);
900 	  else
901 	    fn = builtin_decl_explicit (BUILT_IN_STPCPY_CHK);
902 	  gcc_assert (lhs == NULL_TREE);
903 	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
904 	    {
905 	      fprintf (dump_file, "Optimizing: ");
906 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
907 	    }
908 	  gimple_call_set_fndecl (stmt, fn);
909 	  lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), stmt);
910 	  gimple_call_set_lhs (stmt, lhs);
911 	  update_stmt (stmt);
912 	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
913 	    {
914 	      fprintf (dump_file, "into: ");
915 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
916 	    }
917 	  /* FALLTHRU */
918 	case BUILT_IN_STPCPY:
919 	case BUILT_IN_STPCPY_CHK:
920 	  gcc_assert (lhs != NULL_TREE);
921 	  loc = gimple_location (stmt);
922 	  set_endptr_and_length (loc, si, lhs);
923 	  for (strinfo *chainsi = verify_related_strinfos (si);
924 	       chainsi != NULL;
925 	       chainsi = get_next_strinfo (chainsi))
926 	    if (chainsi->nonzero_chars == NULL)
927 	      set_endptr_and_length (loc, chainsi, lhs);
928 	  break;
929 	case BUILT_IN_ALLOCA:
930 	case BUILT_IN_ALLOCA_WITH_ALIGN:
931 	case BUILT_IN_MALLOC:
932 	  break;
933 	/* BUILT_IN_CALLOC always has si->nonzero_chars set.  */
934 	default:
935 	  gcc_unreachable ();
936 	  break;
937 	}
938     }
939 
940   return si->nonzero_chars;
941 }
942 
943 /* Dump strlen data to FP for statement STMT.  When non-null, RVALS
944    points to the valuation engine used to calculate ranges, and is
945    used to dump strlen range for non-constant results.  */
946 
947 DEBUG_FUNCTION void
dump_strlen_info(FILE * fp,gimple * stmt,range_query * rvals)948 dump_strlen_info (FILE *fp, gimple *stmt, range_query *rvals)
949 {
950   if (stmt)
951     {
952       fprintf (fp, "\nDumping strlen pass data after ");
953       print_gimple_expr (fp, stmt, TDF_LINENO);
954       fputc ('\n', fp);
955     }
956   else
957     fprintf (fp, "\nDumping strlen pass data\n");
958 
959   fprintf (fp, "max_stridx = %i\n", max_stridx);
960   fprintf (fp, "ssa_ver_to_stridx has %u elements\n",
961 	   ssa_ver_to_stridx.length ());
962   fprintf (fp, "stridx_to_strinfo");
963   if (stridx_to_strinfo)
964     {
965       fprintf (fp, " has %u elements\n", stridx_to_strinfo->length ());
966       for (unsigned i = 0; i != stridx_to_strinfo->length (); ++i)
967 	{
968 	  if (strinfo *si = (*stridx_to_strinfo)[i])
969 	    {
970 	      if (!si->idx)
971 		continue;
972 	      fprintf (fp, "  idx = %i", si->idx);
973 	      if (si->ptr)
974 		{
975 		  fprintf (fp, ", ptr = ");
976 		  print_generic_expr (fp, si->ptr);
977 		}
978 
979 	      if (si->nonzero_chars)
980 		{
981 		  fprintf (fp, ", nonzero_chars = ");
982 		  print_generic_expr (fp, si->nonzero_chars);
983 		  if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
984 		    {
985 		      value_range_kind rng = VR_UNDEFINED;
986 		      wide_int min, max;
987 		      if (rvals)
988 			{
989 			  value_range vr;
990 			  rvals->range_of_expr (vr, si->nonzero_chars,
991 						si->stmt);
992 			  rng = vr.kind ();
993 			  if (range_int_cst_p (&vr))
994 			    {
995 			      min = wi::to_wide (vr.min ());
996 			      max = wi::to_wide (vr.max ());
997 			    }
998 			  else
999 			    rng = VR_UNDEFINED;
1000 			}
1001 		      else
1002 			{
1003 			  value_range vr;
1004 			  get_range_query (cfun)
1005 			    ->range_of_expr (vr, si->nonzero_chars);
1006 			  rng = vr.kind ();
1007 			  if (!vr.undefined_p ())
1008 			    {
1009 			      min = wi::to_wide (vr.min ());
1010 			      max = wi::to_wide (vr.max ());
1011 			    }
1012 			}
1013 
1014 		      if (rng == VR_RANGE || rng == VR_ANTI_RANGE)
1015 			{
1016 			  fprintf (fp, " %s[%llu, %llu]",
1017 				   rng == VR_RANGE ? "" : "~",
1018 				   (long long) min.to_uhwi (),
1019 				   (long long) max.to_uhwi ());
1020 			}
1021 		    }
1022 		}
1023 
1024 	      fprintf (fp, ", refcount = %i", si->refcount);
1025 	      if (si->stmt)
1026 		{
1027 		  fprintf (fp, ", stmt = ");
1028 		  print_gimple_expr (fp, si->stmt, 0);
1029 		}
1030 	      if (si->alloc)
1031 		{
1032 		  fprintf (fp, ", alloc = ");
1033 		  print_gimple_expr (fp, si->alloc, 0);
1034 		}
1035 	      if (si->writable)
1036 		fprintf (fp, ", writable");
1037 	      if (si->dont_invalidate)
1038 		fprintf (fp, ", dont_invalidate");
1039 	      if (si->full_string_p)
1040 		fprintf (fp, ", full_string_p");
1041 	      if (strinfo *next = get_next_strinfo (si))
1042 		{
1043 		  fprintf (fp, ", {");
1044 		  do
1045 		    fprintf (fp, "%i%s", next->idx, next->first ? ", " : "");
1046 		  while ((next = get_next_strinfo (next)));
1047 		  fprintf (fp, "}");
1048 		}
1049 	      fputs ("\n", fp);
1050 	    }
1051 	}
1052     }
1053   else
1054     fprintf (fp, " = null\n");
1055 
1056   fprintf (fp, "decl_to_stridxlist_htab");
1057   if (decl_to_stridxlist_htab)
1058     {
1059       fputs ("\n", fp);
1060       typedef decl_to_stridxlist_htab_t::iterator iter_t;
1061       for (iter_t it = decl_to_stridxlist_htab->begin ();
1062 	   it != decl_to_stridxlist_htab->end (); ++it)
1063 	{
1064 	  tree decl = (*it).first;
1065 	  stridxlist *list = &(*it).second;
1066 	  fprintf (fp, "  decl = ");
1067 	  print_generic_expr (fp, decl);
1068 	  if (list)
1069 	    {
1070 	      fprintf (fp, ", offsets = {");
1071 	      for (; list; list = list->next)
1072 		fprintf (fp, "%lli%s", (long long) list->offset,
1073 			 list->next ? ", " : "");
1074 	      fputs ("}", fp);
1075 	    }
1076 	  fputs ("\n", fp);
1077 	}
1078     }
1079   else
1080     fprintf (fp, " = null\n");
1081 
1082   if (laststmt.stmt)
1083     {
1084       fprintf (fp, "laststmt = ");
1085       print_gimple_expr (fp, laststmt.stmt, 0);
1086       fprintf (fp, ", len = ");
1087       print_generic_expr (fp, laststmt.len);
1088       fprintf (fp, ", stridx = %i\n", laststmt.stridx);
1089     }
1090 }
1091 
1092 /* Helper of get_range_strlen_dynamic().  See below.  */
1093 
1094 static bool
get_range_strlen_phi(tree src,gphi * phi,c_strlen_data * pdata,bitmap visited,range_query * rvals,unsigned * pssa_def_max)1095 get_range_strlen_phi (tree src, gphi *phi,
1096 		      c_strlen_data *pdata, bitmap visited,
1097 		      range_query *rvals, unsigned *pssa_def_max)
1098 {
1099   if (!bitmap_set_bit (visited, SSA_NAME_VERSION (src)))
1100     return true;
1101 
1102   if (*pssa_def_max == 0)
1103     return false;
1104 
1105   --*pssa_def_max;
1106 
1107   /* Iterate over the PHI arguments and determine the minimum and maximum
1108      length/size of each and incorporate them into the overall result.  */
1109   for (unsigned i = 0; i != gimple_phi_num_args (phi); ++i)
1110     {
1111       tree arg = gimple_phi_arg_def (phi, i);
1112       if (arg == gimple_phi_result (phi))
1113 	continue;
1114 
1115       c_strlen_data argdata = { };
1116       if (!get_range_strlen_dynamic (arg, phi, &argdata, visited, rvals,
1117 				     pssa_def_max))
1118 	{
1119 	  pdata->maxlen = build_all_ones_cst (size_type_node);
1120 	  continue;
1121 	}
1122 
1123       /* Set the DECL of an unterminated array this argument refers to
1124 	 if one hasn't been found yet.  */
1125       if (!pdata->decl && argdata.decl)
1126 	pdata->decl = argdata.decl;
1127 
1128       if (!argdata.minlen
1129 	  || (integer_zerop (argdata.minlen)
1130 	      && (!argdata.maxbound
1131 		  || integer_all_onesp (argdata.maxbound))
1132 	      && integer_all_onesp (argdata.maxlen)))
1133 	{
1134 	  /* Set the upper bound of the length to unbounded.  */
1135 	  pdata->maxlen = build_all_ones_cst (size_type_node);
1136 	  continue;
1137 	}
1138 
1139       /* Adjust the minimum and maximum length determined so far and
1140 	 the upper bound on the array size.  */
1141       if (!pdata->minlen
1142 	  || tree_int_cst_lt (argdata.minlen, pdata->minlen))
1143 	pdata->minlen = argdata.minlen;
1144 
1145       if (!pdata->maxlen
1146 	  || (argdata.maxlen
1147 	      && TREE_CODE (argdata.maxlen) == INTEGER_CST
1148 	      && tree_int_cst_lt (pdata->maxlen, argdata.maxlen)))
1149 	pdata->maxlen = argdata.maxlen;
1150 
1151       if (!pdata->maxbound
1152 	  || TREE_CODE (pdata->maxbound) != INTEGER_CST
1153 	  || (argdata.maxbound
1154 	      && tree_int_cst_lt (pdata->maxbound, argdata.maxbound)
1155 	      && !integer_all_onesp (argdata.maxbound)))
1156 	pdata->maxbound = argdata.maxbound;
1157     }
1158 
1159   return true;
1160 }
1161 
1162 /* Attempt to determine the length of the string SRC.  On success, store
1163    the length in *PDATA and return true.  Otherwise, return false.
1164    VISITED is a bitmap of visited PHI nodes.  RVALS points to the valuation
1165    engine used to calculate ranges.  PSSA_DEF_MAX to an SSA_NAME
1166    assignment limit used to prevent runaway recursion.  */
1167 
1168 static bool
get_range_strlen_dynamic(tree src,gimple * stmt,c_strlen_data * pdata,bitmap visited,range_query * rvals,unsigned * pssa_def_max)1169 get_range_strlen_dynamic (tree src, gimple *stmt,
1170 			  c_strlen_data *pdata, bitmap visited,
1171 			  range_query *rvals, unsigned *pssa_def_max)
1172 {
1173   int idx = get_stridx (src, stmt);
1174   if (!idx)
1175     {
1176       if (TREE_CODE (src) == SSA_NAME)
1177 	{
1178 	  gimple *def_stmt = SSA_NAME_DEF_STMT (src);
1179 	  if (gphi *phi = dyn_cast<gphi *>(def_stmt))
1180 	    return get_range_strlen_phi (src, phi, pdata, visited, rvals,
1181 					 pssa_def_max);
1182 	}
1183 
1184       /* Return success regardless of the result and handle *PDATA
1185 	 in the caller.  */
1186       get_range_strlen (src, pdata, 1);
1187       return true;
1188     }
1189 
1190   if (idx < 0)
1191     {
1192       /* SRC is a string of constant length.  */
1193       pdata->minlen = build_int_cst (size_type_node, ~idx);
1194       pdata->maxlen = pdata->minlen;
1195       pdata->maxbound = pdata->maxlen;
1196       return true;
1197     }
1198 
1199   if (strinfo *si = get_strinfo (idx))
1200     {
1201       pdata->minlen = get_string_length (si);
1202       if (!pdata->minlen && si->nonzero_chars)
1203 	{
1204 	  if (TREE_CODE (si->nonzero_chars) == INTEGER_CST)
1205 	    pdata->minlen = si->nonzero_chars;
1206 	  else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
1207 	    {
1208 	      value_range vr;
1209 	      rvals->range_of_expr (vr, si->nonzero_chars, si->stmt);
1210 	      if (range_int_cst_p (&vr))
1211 		{
1212 		  pdata->minlen = vr.min ();
1213 		  pdata->maxlen = vr.max ();
1214 		}
1215 	      else
1216 		pdata->minlen = build_zero_cst (size_type_node);
1217 	    }
1218 	  else
1219 	    pdata->minlen = build_zero_cst (size_type_node);
1220 
1221 	  tree base = si->ptr;
1222 	  if (TREE_CODE (base) == ADDR_EXPR)
1223 	    base = TREE_OPERAND (base, 0);
1224 
1225 	  HOST_WIDE_INT off;
1226 	  poly_int64 poff;
1227 	  base = get_addr_base_and_unit_offset (base, &poff);
1228 	  if (base
1229 	      && DECL_P (base)
1230 	      && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE
1231 	      && TYPE_SIZE_UNIT (TREE_TYPE (base))
1232 	      && poff.is_constant (&off))
1233 	    {
1234 	      tree basetype = TREE_TYPE (base);
1235 	      tree size = TYPE_SIZE_UNIT (basetype);
1236 	      if (TREE_CODE (size) == INTEGER_CST)
1237 		{
1238 		  ++off;   /* Increment for the terminating nul.  */
1239 		  tree toffset = build_int_cst (size_type_node, off);
1240 		  pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size,
1241 					       toffset);
1242 		  pdata->maxbound = pdata->maxlen;
1243 		}
1244 	      else
1245 		pdata->maxlen = build_all_ones_cst (size_type_node);
1246 	    }
1247 	  else
1248 	    pdata->maxlen = build_all_ones_cst (size_type_node);
1249 	}
1250       else if (pdata->minlen && TREE_CODE (pdata->minlen) == SSA_NAME)
1251 	{
1252 	  value_range vr;
1253 	  rvals->range_of_expr (vr, si->nonzero_chars, stmt);
1254 	  if (range_int_cst_p (&vr))
1255 	    {
1256 	      pdata->minlen = vr.min ();
1257 	      pdata->maxlen = vr.max ();
1258 	      pdata->maxbound = pdata->maxlen;
1259 	    }
1260 	  else
1261 	    {
1262 	      pdata->minlen = build_zero_cst (size_type_node);
1263 	      pdata->maxlen = build_all_ones_cst (size_type_node);
1264 	    }
1265 	}
1266       else if (pdata->minlen && TREE_CODE (pdata->minlen) == INTEGER_CST)
1267 	{
1268 	  pdata->maxlen = pdata->minlen;
1269 	  pdata->maxbound = pdata->minlen;
1270 	}
1271       else
1272 	{
1273 	  /* For PDATA->MINLEN that's a non-constant expression such
1274 	     as PLUS_EXPR whose value range is unknown, set the bounds
1275 	     to zero and SIZE_MAX.  */
1276 	  pdata->minlen = build_zero_cst (size_type_node);
1277 	  pdata->maxlen = build_all_ones_cst (size_type_node);
1278 	}
1279 
1280       return true;
1281     }
1282 
1283   return false;
1284 }
1285 
1286 /* Analogous to get_range_strlen but for dynamically created strings,
1287    i.e., those created by calls to strcpy as opposed to just string
1288    constants.
1289    Try to obtain the range of the lengths of the string(s) referenced
1290    by SRC, or the size of the largest array SRC refers to if the range
1291    of lengths cannot be determined, and store all in *PDATA.  RVALS
1292    points to the valuation engine used to calculate ranges.  */
1293 
1294 void
get_range_strlen_dynamic(tree src,gimple * stmt,c_strlen_data * pdata,range_query * rvals)1295 get_range_strlen_dynamic (tree src, gimple *stmt, c_strlen_data *pdata,
1296 			  range_query *rvals)
1297 {
1298   auto_bitmap visited;
1299   tree maxbound = pdata->maxbound;
1300 
1301   unsigned limit = param_ssa_name_def_chain_limit;
1302   if (!get_range_strlen_dynamic (src, stmt, pdata, visited, rvals, &limit))
1303     {
1304       /* On failure extend the length range to an impossible maximum
1305 	 (a valid MAXLEN must be less than PTRDIFF_MAX - 1).  Other
1306 	 members can stay unchanged regardless.  */
1307       pdata->minlen = ssize_int (0);
1308       pdata->maxlen = build_all_ones_cst (size_type_node);
1309     }
1310   else if (!pdata->minlen)
1311     pdata->minlen = ssize_int (0);
1312 
1313   /* If it's unchanged from it initial non-null value, set the conservative
1314      MAXBOUND to SIZE_MAX.  Otherwise leave it null (if it is null).  */
1315   if (maxbound && pdata->maxbound == maxbound)
1316     pdata->maxbound = build_all_ones_cst (size_type_node);
1317 }
1318 
1319 /* Invalidate string length information for strings whose length might
1320    change due to stores in STMT, except those marked DONT_INVALIDATE.
1321    For string-modifying statements, ZERO_WRITE is set when the statement
1322    wrote only zeros.
1323    Returns true if any STRIDX_TO_STRINFO entries were considered
1324    for invalidation.  */
1325 
1326 static bool
1327 maybe_invalidate (gimple *stmt, bool zero_write = false)
1328 {
1329   if (dump_file && (dump_flags & TDF_DETAILS))
1330     {
1331       fprintf (dump_file, "%s called for ", __func__);
1332       print_gimple_stmt (dump_file, stmt, TDF_LINENO);
1333     }
1334 
1335   strinfo *si;
1336   bool nonempty = false;
1337 
1338   for (unsigned i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
1339     {
1340       if (si == NULL || !POINTER_TYPE_P (TREE_TYPE (si->ptr)))
1341 	continue;
1342 
1343       nonempty = true;
1344 
1345       /* Unconditionally reset DONT_INVALIDATE.  */
1346       bool dont_invalidate = si->dont_invalidate;
1347       si->dont_invalidate = false;
1348 
1349       if (dont_invalidate)
1350 	continue;
1351 
1352       ao_ref r;
1353       tree size = si->nonzero_chars;
1354       ao_ref_init_from_ptr_and_size (&r, si->ptr, size);
1355       /* Include the terminating nul in the size of the string
1356 	 to consider when determining possible clobber.  But do not
1357 	 add it to 'size' since we don't know whether it would
1358 	 actually fit the allocated area.  */
1359       if (known_size_p (r.size))
1360 	{
1361 	  if (known_le (r.size, HOST_WIDE_INT_MAX - BITS_PER_UNIT))
1362 	    r.max_size += BITS_PER_UNIT;
1363 	  else
1364 	    r.max_size = -1;
1365 	}
1366       if (stmt_may_clobber_ref_p_1 (stmt, &r))
1367 	{
1368 	  if (dump_file && (dump_flags & TDF_DETAILS))
1369 	    {
1370 	      fputs ("  statement may clobber object ", dump_file);
1371 	      print_generic_expr (dump_file, si->ptr);
1372 	      if (size && tree_fits_uhwi_p (size))
1373 		fprintf (dump_file, " " HOST_WIDE_INT_PRINT_UNSIGNED
1374 			 " bytes in size", tree_to_uhwi (size));
1375 	      fputc ('\n', dump_file);
1376 	    }
1377 
1378 	  set_strinfo (i, NULL);
1379 	  free_strinfo (si);
1380 	  continue;
1381 	}
1382 
1383       if (size
1384 	  && !zero_write
1385 	  && si->stmt
1386 	  && is_gimple_call (si->stmt)
1387 	  && (DECL_FUNCTION_CODE (gimple_call_fndecl (si->stmt))
1388 	      == BUILT_IN_CALLOC))
1389 	{
1390 	  /* If the clobber test above considered the length of
1391 	     the string (including the nul), then for (potentially)
1392 	     non-zero writes that might modify storage allocated by
1393 	     calloc consider the whole object and if it might be
1394 	     clobbered by the statement reset the statement.  */
1395 	  ao_ref_init_from_ptr_and_size (&r, si->ptr, NULL_TREE);
1396 	  if (stmt_may_clobber_ref_p_1 (stmt, &r))
1397 	    si->stmt = NULL;
1398 	}
1399     }
1400 
1401   if (dump_file && (dump_flags & TDF_DETAILS))
1402     fprintf (dump_file, "%s returns %i\n", __func__, nonempty);
1403 
1404   return nonempty;
1405 }
1406 
1407 /* Unshare strinfo record SI, if it has refcount > 1 or
1408    if stridx_to_strinfo vector is shared with some other
1409    bbs.  */
1410 
1411 static strinfo *
unshare_strinfo(strinfo * si)1412 unshare_strinfo (strinfo *si)
1413 {
1414   strinfo *nsi;
1415 
1416   if (si->refcount == 1 && !strinfo_shared ())
1417     return si;
1418 
1419   nsi = new_strinfo (si->ptr, si->idx, si->nonzero_chars, si->full_string_p);
1420   nsi->stmt = si->stmt;
1421   nsi->alloc = si->alloc;
1422   nsi->endptr = si->endptr;
1423   nsi->first = si->first;
1424   nsi->prev = si->prev;
1425   nsi->next = si->next;
1426   nsi->writable = si->writable;
1427   set_strinfo (si->idx, nsi);
1428   free_strinfo (si);
1429   return nsi;
1430 }
1431 
1432 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1433    strinfo if there is any.  Return it's idx, or 0 if no strinfo has
1434    been created.  */
1435 
1436 static int
get_stridx_plus_constant(strinfo * basesi,unsigned HOST_WIDE_INT off,tree ptr)1437 get_stridx_plus_constant (strinfo *basesi, unsigned HOST_WIDE_INT off,
1438 			  tree ptr)
1439 {
1440   if (TREE_CODE (ptr) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr))
1441     return 0;
1442 
1443   if (compare_nonzero_chars (basesi, off) < 0
1444       || !tree_fits_uhwi_p (basesi->nonzero_chars))
1445     return 0;
1446 
1447   unsigned HOST_WIDE_INT nonzero_chars
1448     = tree_to_uhwi (basesi->nonzero_chars) - off;
1449   strinfo *si = basesi, *chainsi;
1450   if (si->first || si->prev || si->next)
1451     si = verify_related_strinfos (basesi);
1452   if (si == NULL
1453       || si->nonzero_chars == NULL_TREE
1454       || TREE_CODE (si->nonzero_chars) != INTEGER_CST)
1455     return 0;
1456 
1457   if (TREE_CODE (ptr) == SSA_NAME
1458       && ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
1459     ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
1460 
1461   gcc_checking_assert (compare_tree_int (si->nonzero_chars, off) != -1);
1462   for (chainsi = si; chainsi->next; chainsi = si)
1463     {
1464       si = get_next_strinfo (chainsi);
1465       if (si == NULL
1466 	  || si->nonzero_chars == NULL_TREE
1467 	  || TREE_CODE (si->nonzero_chars) != INTEGER_CST)
1468 	break;
1469       int r = compare_tree_int (si->nonzero_chars, nonzero_chars);
1470       if (r != 1)
1471 	{
1472 	  if (r == 0)
1473 	    {
1474 	      if (TREE_CODE (ptr) == SSA_NAME)
1475 		ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = si->idx;
1476 	      else
1477 		{
1478 		  int *pidx = addr_stridxptr (TREE_OPERAND (ptr, 0));
1479 		  if (pidx != NULL && *pidx == 0)
1480 		    *pidx = si->idx;
1481 		}
1482 	      return si->idx;
1483 	    }
1484 	  break;
1485 	}
1486     }
1487 
1488   int idx = new_stridx (ptr);
1489   if (idx == 0)
1490     return 0;
1491   si = new_strinfo (ptr, idx, build_int_cst (size_type_node, nonzero_chars),
1492 		    basesi->full_string_p);
1493   set_strinfo (idx, si);
1494   if (strinfo *nextsi = get_strinfo (chainsi->next))
1495     {
1496       nextsi = unshare_strinfo (nextsi);
1497       si->next = nextsi->idx;
1498       nextsi->prev = idx;
1499     }
1500   chainsi = unshare_strinfo (chainsi);
1501   if (chainsi->first == 0)
1502     chainsi->first = chainsi->idx;
1503   chainsi->next = idx;
1504   if (chainsi->endptr == NULL_TREE && zero_length_string_p (si))
1505     chainsi->endptr = ptr;
1506   si->endptr = chainsi->endptr;
1507   si->prev = chainsi->idx;
1508   si->first = chainsi->first;
1509   si->writable = chainsi->writable;
1510   return si->idx;
1511 }
1512 
1513 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1514    to a zero-length string and if possible chain it to a related strinfo
1515    chain whose part is or might be CHAINSI.  */
1516 
1517 static strinfo *
zero_length_string(tree ptr,strinfo * chainsi)1518 zero_length_string (tree ptr, strinfo *chainsi)
1519 {
1520   strinfo *si;
1521   int idx;
1522   if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
1523     ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
1524   gcc_checking_assert (TREE_CODE (ptr) == SSA_NAME
1525 		       && ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] == 0);
1526 
1527   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr))
1528     return NULL;
1529   if (chainsi != NULL)
1530     {
1531       si = verify_related_strinfos (chainsi);
1532       if (si)
1533 	{
1534 	  do
1535 	    {
1536 	      /* We shouldn't mix delayed and non-delayed lengths.  */
1537 	      gcc_assert (si->full_string_p);
1538 	      if (si->endptr == NULL_TREE)
1539 		{
1540 		  si = unshare_strinfo (si);
1541 		  si->endptr = ptr;
1542 		}
1543 	      chainsi = si;
1544 	      si = get_next_strinfo (si);
1545 	    }
1546 	  while (si != NULL);
1547 	  if (zero_length_string_p (chainsi))
1548 	    {
1549 	      if (chainsi->next)
1550 		{
1551 		  chainsi = unshare_strinfo (chainsi);
1552 		  chainsi->next = 0;
1553 		}
1554 	      ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = chainsi->idx;
1555 	      return chainsi;
1556 	    }
1557 	}
1558       else
1559 	{
1560 	  /* We shouldn't mix delayed and non-delayed lengths.  */
1561 	  gcc_assert (chainsi->full_string_p);
1562 	  if (chainsi->first || chainsi->prev || chainsi->next)
1563 	    {
1564 	      chainsi = unshare_strinfo (chainsi);
1565 	      chainsi->first = 0;
1566 	      chainsi->prev = 0;
1567 	      chainsi->next = 0;
1568 	    }
1569 	}
1570     }
1571   idx = new_stridx (ptr);
1572   if (idx == 0)
1573     return NULL;
1574   si = new_strinfo (ptr, idx, build_int_cst (size_type_node, 0), true);
1575   set_strinfo (idx, si);
1576   si->endptr = ptr;
1577   if (chainsi != NULL)
1578     {
1579       chainsi = unshare_strinfo (chainsi);
1580       if (chainsi->first == 0)
1581 	chainsi->first = chainsi->idx;
1582       chainsi->next = idx;
1583       if (chainsi->endptr == NULL_TREE)
1584 	chainsi->endptr = ptr;
1585       si->prev = chainsi->idx;
1586       si->first = chainsi->first;
1587       si->writable = chainsi->writable;
1588     }
1589   return si;
1590 }
1591 
1592 /* For strinfo ORIGSI whose length has been just updated, adjust other
1593    related strinfos so that they match the new ORIGSI.  This involves:
1594 
1595    - adding ADJ to the nonzero_chars fields
1596    - copying full_string_p from the new ORIGSI.  */
1597 
1598 static void
adjust_related_strinfos(location_t loc,strinfo * origsi,tree adj)1599 adjust_related_strinfos (location_t loc, strinfo *origsi, tree adj)
1600 {
1601   strinfo *si = verify_related_strinfos (origsi);
1602 
1603   if (si == NULL)
1604     return;
1605 
1606   while (1)
1607     {
1608       strinfo *nsi;
1609 
1610       if (si != origsi)
1611 	{
1612 	  tree tem;
1613 
1614 	  si = unshare_strinfo (si);
1615 	  /* We shouldn't see delayed lengths here; the caller must
1616 	     have calculated the old length in order to calculate
1617 	     the adjustment.  */
1618 	  gcc_assert (si->nonzero_chars);
1619 	  tem = fold_convert_loc (loc, TREE_TYPE (si->nonzero_chars), adj);
1620 	  si->nonzero_chars = fold_build2_loc (loc, PLUS_EXPR,
1621 					       TREE_TYPE (si->nonzero_chars),
1622 					       si->nonzero_chars, tem);
1623 	  si->full_string_p = origsi->full_string_p;
1624 
1625 	  si->endptr = NULL_TREE;
1626 	  si->dont_invalidate = true;
1627 	}
1628       nsi = get_next_strinfo (si);
1629       if (nsi == NULL)
1630 	return;
1631       si = nsi;
1632     }
1633 }
1634 
1635 /* Find if there are other SSA_NAME pointers equal to PTR
1636    for which we don't track their string lengths yet.  If so, use
1637    IDX for them.  */
1638 
1639 static void
find_equal_ptrs(tree ptr,int idx)1640 find_equal_ptrs (tree ptr, int idx)
1641 {
1642   if (TREE_CODE (ptr) != SSA_NAME)
1643     return;
1644   while (1)
1645     {
1646       gimple *stmt = SSA_NAME_DEF_STMT (ptr);
1647       if (!is_gimple_assign (stmt))
1648 	return;
1649       ptr = gimple_assign_rhs1 (stmt);
1650       switch (gimple_assign_rhs_code (stmt))
1651 	{
1652 	case SSA_NAME:
1653 	  break;
1654 	CASE_CONVERT:
1655 	  if (!POINTER_TYPE_P (TREE_TYPE (ptr)))
1656 	    return;
1657 	  if (TREE_CODE (ptr) == SSA_NAME)
1658 	    break;
1659 	  if (TREE_CODE (ptr) != ADDR_EXPR)
1660 	    return;
1661 	  /* FALLTHRU */
1662 	case ADDR_EXPR:
1663 	  {
1664 	    int *pidx = addr_stridxptr (TREE_OPERAND (ptr, 0));
1665 	    if (pidx != NULL && *pidx == 0)
1666 	      *pidx = idx;
1667 	    return;
1668 	  }
1669 	default:
1670 	  return;
1671 	}
1672 
1673       /* We might find an endptr created in this pass.  Grow the
1674 	 vector in that case.  */
1675       if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
1676 	ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
1677 
1678       if (ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] != 0)
1679 	return;
1680       ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = idx;
1681     }
1682 }
1683 
1684 /* Return true if STMT is a call to a builtin function with the right
1685    arguments and attributes that should be considered for optimization
1686    by this pass.  */
1687 
1688 static bool
valid_builtin_call(gimple * stmt)1689 valid_builtin_call (gimple *stmt)
1690 {
1691   if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
1692     return false;
1693 
1694   tree callee = gimple_call_fndecl (stmt);
1695   tree decl = builtin_decl_explicit (DECL_FUNCTION_CODE (callee));
1696   if (decl
1697       && decl != callee
1698       && !gimple_builtin_call_types_compatible_p (stmt, decl))
1699     return false;
1700 
1701   switch (DECL_FUNCTION_CODE (callee))
1702     {
1703     case BUILT_IN_MEMCMP:
1704     case BUILT_IN_MEMCMP_EQ:
1705     case BUILT_IN_STRCMP:
1706     case BUILT_IN_STRNCMP:
1707     case BUILT_IN_STRCHR:
1708     case BUILT_IN_STRLEN:
1709     case BUILT_IN_STRNLEN:
1710       /* The above functions should be pure.  Punt if they aren't.  */
1711       if (gimple_vdef (stmt) || gimple_vuse (stmt) == NULL_TREE)
1712 	return false;
1713       break;
1714 
1715     case BUILT_IN_ALLOCA:
1716     case BUILT_IN_ALLOCA_WITH_ALIGN:
1717     case BUILT_IN_CALLOC:
1718     case BUILT_IN_MALLOC:
1719     case BUILT_IN_MEMCPY:
1720     case BUILT_IN_MEMCPY_CHK:
1721     case BUILT_IN_MEMPCPY:
1722     case BUILT_IN_MEMPCPY_CHK:
1723     case BUILT_IN_MEMSET:
1724     case BUILT_IN_STPCPY:
1725     case BUILT_IN_STPCPY_CHK:
1726     case BUILT_IN_STPNCPY:
1727     case BUILT_IN_STPNCPY_CHK:
1728     case BUILT_IN_STRCAT:
1729     case BUILT_IN_STRCAT_CHK:
1730     case BUILT_IN_STRCPY:
1731     case BUILT_IN_STRCPY_CHK:
1732     case BUILT_IN_STRNCAT:
1733     case BUILT_IN_STRNCAT_CHK:
1734     case BUILT_IN_STRNCPY:
1735     case BUILT_IN_STRNCPY_CHK:
1736       /* The above functions should be neither const nor pure.  Punt if they
1737 	 aren't.  */
1738       if (gimple_vdef (stmt) == NULL_TREE || gimple_vuse (stmt) == NULL_TREE)
1739 	return false;
1740       break;
1741 
1742     default:
1743       break;
1744     }
1745 
1746   return true;
1747 }
1748 
1749 /* If the last .MEM setter statement before STMT is
1750    memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1751    and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1752    just memcpy (x, y, strlen (y)).  SI must be the zero length
1753    strinfo.  */
1754 
1755 void
adjust_last_stmt(strinfo * si,gimple * stmt,bool is_strcat)1756 strlen_pass::adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat)
1757 {
1758   tree vuse, callee, len;
1759   struct laststmt_struct last = laststmt;
1760   strinfo *lastsi, *firstsi;
1761   unsigned len_arg_no = 2;
1762 
1763   laststmt.stmt = NULL;
1764   laststmt.len = NULL_TREE;
1765   laststmt.stridx = 0;
1766 
1767   if (last.stmt == NULL)
1768     return;
1769 
1770   vuse = gimple_vuse (stmt);
1771   if (vuse == NULL_TREE
1772       || SSA_NAME_DEF_STMT (vuse) != last.stmt
1773       || !has_single_use (vuse))
1774     return;
1775 
1776   gcc_assert (last.stridx > 0);
1777   lastsi = get_strinfo (last.stridx);
1778   if (lastsi == NULL)
1779     return;
1780 
1781   if (lastsi != si)
1782     {
1783       if (lastsi->first == 0 || lastsi->first != si->first)
1784 	return;
1785 
1786       firstsi = verify_related_strinfos (si);
1787       if (firstsi == NULL)
1788 	return;
1789       while (firstsi != lastsi)
1790 	{
1791 	  firstsi = get_next_strinfo (firstsi);
1792 	  if (firstsi == NULL)
1793 	    return;
1794 	}
1795     }
1796 
1797   if (!is_strcat && !zero_length_string_p (si))
1798     return;
1799 
1800   if (is_gimple_assign (last.stmt))
1801     {
1802       gimple_stmt_iterator gsi;
1803 
1804       if (!integer_zerop (gimple_assign_rhs1 (last.stmt)))
1805 	return;
1806       if (stmt_could_throw_p (cfun, last.stmt))
1807 	return;
1808       gsi = gsi_for_stmt (last.stmt);
1809       unlink_stmt_vdef (last.stmt);
1810       release_defs (last.stmt);
1811       gsi_remove (&gsi, true);
1812       return;
1813     }
1814 
1815   if (!valid_builtin_call (last.stmt))
1816     return;
1817 
1818   callee = gimple_call_fndecl (last.stmt);
1819   switch (DECL_FUNCTION_CODE (callee))
1820     {
1821     case BUILT_IN_MEMCPY:
1822     case BUILT_IN_MEMCPY_CHK:
1823       break;
1824     default:
1825       return;
1826     }
1827 
1828   len = gimple_call_arg (last.stmt, len_arg_no);
1829   if (tree_fits_uhwi_p (len))
1830     {
1831       if (!tree_fits_uhwi_p (last.len)
1832 	  || integer_zerop (len)
1833 	  || tree_to_uhwi (len) != tree_to_uhwi (last.len) + 1)
1834 	return;
1835       /* Don't adjust the length if it is divisible by 4, it is more efficient
1836 	 to store the extra '\0' in that case.  */
1837       if ((tree_to_uhwi (len) & 3) == 0)
1838 	return;
1839 
1840       /* Don't fold away an out of bounds access, as this defeats proper
1841 	 warnings.  */
1842       tree dst = gimple_call_arg (last.stmt, 0);
1843 
1844       access_ref aref;
1845       tree size = compute_objsize (dst, stmt, 1, &aref, &ptr_qry);
1846       if (size && tree_int_cst_lt (size, len))
1847 	return;
1848     }
1849   else if (TREE_CODE (len) == SSA_NAME)
1850     {
1851       gimple *def_stmt = SSA_NAME_DEF_STMT (len);
1852       if (!is_gimple_assign (def_stmt)
1853 	  || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
1854 	  || gimple_assign_rhs1 (def_stmt) != last.len
1855 	  || !integer_onep (gimple_assign_rhs2 (def_stmt)))
1856 	return;
1857     }
1858   else
1859     return;
1860 
1861   gimple_call_set_arg (last.stmt, len_arg_no, last.len);
1862   update_stmt (last.stmt);
1863 }
1864 
1865 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1866    call, or when BOUND is non-null, of a strnlen() call, set LHS
1867    range info to [0, min (MAX, BOUND)] when the range includes more
1868    than one value and return LHS.  Otherwise, when the range
1869    [MIN, MAX] is such that MIN == MAX, return the tree representation
1870    of (MIN). The latter allows callers to fold suitable strnlen() calls
1871    to constants.  */
1872 
1873 tree
set_strlen_range(tree lhs,wide_int min,wide_int max,tree bound)1874 set_strlen_range (tree lhs, wide_int min, wide_int max,
1875 		  tree bound /* = NULL_TREE */)
1876 {
1877   if (TREE_CODE (lhs) != SSA_NAME
1878       || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
1879     return NULL_TREE;
1880 
1881   if (bound)
1882     {
1883       /* For strnlen, adjust MIN and MAX as necessary.  If the bound
1884 	 is less than the size of the array set MAX to it.  It it's
1885 	 greater than MAX and MAX is non-zero bump MAX down to account
1886 	 for the necessary terminating nul.  Otherwise leave it alone.  */
1887       if (TREE_CODE (bound) == INTEGER_CST)
1888 	{
1889 	  wide_int wibnd = wi::to_wide (bound);
1890 	  int cmp = wi::cmpu (wibnd, max);
1891 	  if (cmp < 0)
1892 	    max = wibnd;
1893 	  else if (cmp && wi::ne_p (max, min))
1894 	    --max;
1895 	}
1896       else if (TREE_CODE (bound) == SSA_NAME)
1897 	{
1898 	  value_range r;
1899 	  get_range_query (cfun)->range_of_expr (r, bound);
1900 	  if (!r.undefined_p ())
1901 	    {
1902 	      /* For a bound in a known range, adjust the range determined
1903 		 above as necessary.  For a bound in some anti-range or
1904 		 in an unknown range, use the range determined by callers.  */
1905 	      if (wi::ltu_p (r.lower_bound (), min))
1906 		min = r.lower_bound ();
1907 	      if (wi::ltu_p (r.upper_bound (), max))
1908 		max = r.upper_bound ();
1909 	    }
1910 	}
1911     }
1912 
1913   if (min == max)
1914     return wide_int_to_tree (size_type_node, min);
1915 
1916   set_range_info (lhs, VR_RANGE, min, max);
1917   return lhs;
1918 }
1919 
1920 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1921    SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1922    a character array A[N] with unknown length bounded by N, and for
1923    strnlen(), by min (N, BOUND).  */
1924 
1925 static tree
maybe_set_strlen_range(tree lhs,tree src,tree bound)1926 maybe_set_strlen_range (tree lhs, tree src, tree bound)
1927 {
1928   if (TREE_CODE (lhs) != SSA_NAME
1929       || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
1930     return NULL_TREE;
1931 
1932   if (TREE_CODE (src) == SSA_NAME)
1933     {
1934       gimple *def = SSA_NAME_DEF_STMT (src);
1935       if (is_gimple_assign (def)
1936 	  && gimple_assign_rhs_code (def) == ADDR_EXPR)
1937 	src = gimple_assign_rhs1 (def);
1938     }
1939 
1940   /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1941      NUL so that the difference between a pointer to just past it and
1942      one to its beginning is positive.  */
1943   wide_int max = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2;
1944 
1945   if (TREE_CODE (src) == ADDR_EXPR)
1946     {
1947       /* The last array member of a struct can be bigger than its size
1948 	 suggests if it's treated as a poor-man's flexible array member.  */
1949       src = TREE_OPERAND (src, 0);
1950       if (TREE_CODE (src) != MEM_REF
1951 	  && !array_at_struct_end_p (src))
1952 	{
1953 	  tree type = TREE_TYPE (src);
1954 	  tree size = TYPE_SIZE_UNIT (type);
1955 	  if (size
1956 	      && TREE_CODE (size) == INTEGER_CST
1957 	      && !integer_zerop (size))
1958 	    {
1959 	      /* Even though such uses of strlen would be undefined,
1960 		 avoid relying on arrays of arrays in case some genius
1961 		 decides to call strlen on an unterminated array element
1962 		 that's followed by a terminated one.  Likewise, avoid
1963 		 assuming that a struct array member is necessarily
1964 		 nul-terminated (the nul may be in the member that
1965 		 follows).  In those cases, assume that the length
1966 		 of the string stored in such an array is bounded
1967 		 by the size of the enclosing object if one can be
1968 		 determined.  */
1969 	      tree base = get_base_address (src);
1970 	      if (VAR_P (base))
1971 		{
1972 		  if (tree size = DECL_SIZE_UNIT (base))
1973 		    if (size
1974 			&& TREE_CODE (size) == INTEGER_CST
1975 			&& TREE_CODE (TREE_TYPE (base)) != POINTER_TYPE)
1976 		      max = wi::to_wide (size);
1977 		}
1978 	    }
1979 
1980 	  /* For strlen() the upper bound above is equal to
1981 	     the longest string that can be stored in the array
1982 	     (i.e., it accounts for the terminating nul.  For
1983 	     strnlen() bump up the maximum by one since the array
1984 	     need not be nul-terminated.  */
1985 	  if (!bound && max != 0)
1986 	    --max;
1987 	}
1988     }
1989 
1990   wide_int min = wi::zero (max.get_precision ());
1991   return set_strlen_range (lhs, min, max, bound);
1992 }
1993 
1994 /* Diagnose buffer overflow by a STMT writing LEN + PLUS_ONE bytes,
1995    either into a region allocated for the object SI when non-null,
1996    or into an object designated by the LHS of STMT otherwise.
1997    For a call STMT, when CALL_LHS is set use its left hand side
1998    as the destination, otherwise use argument zero.
1999    When nonnull uses RVALS to determine range information.
2000    RAWMEM may be set by memcpy and other raw memory functions
2001    to allow accesses across subobject boundaries.  */
2002 
2003 void
maybe_warn_overflow(gimple * stmt,bool call_lhs,tree len,strinfo * si,bool plus_one,bool rawmem)2004 strlen_pass::maybe_warn_overflow (gimple *stmt, bool call_lhs, tree len,
2005 				  strinfo *si, bool plus_one, bool rawmem)
2006 {
2007   if (!len || warning_suppressed_p (stmt, OPT_Wstringop_overflow_))
2008     return;
2009 
2010   /* The DECL of the function performing the write if it is done
2011      by one.  */
2012   tree writefn = NULL_TREE;
2013   /* The destination expression involved in the store or call STMT.  */
2014   tree dest = NULL_TREE;
2015 
2016   if (is_gimple_assign (stmt))
2017     dest = gimple_assign_lhs (stmt);
2018   else if (is_gimple_call (stmt))
2019     {
2020       if (call_lhs)
2021 	dest = gimple_call_lhs (stmt);
2022       else
2023 	{
2024 	  gcc_assert (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL));
2025 	  dest = gimple_call_arg (stmt, 0);
2026 	}
2027 
2028       if (!dest)
2029 	return;
2030       writefn = gimple_call_fndecl (stmt);
2031     }
2032   else
2033     return;
2034 
2035   if (warning_suppressed_p (dest, OPT_Wstringop_overflow_))
2036     return;
2037 
2038   const int ostype = rawmem ? 0 : 1;
2039 
2040   /* Use maximum precision to avoid overflow in the addition below.
2041      Make sure all operands have the same precision to keep wide_int
2042      from ICE'ing.  */
2043 
2044   access_ref aref;
2045   /* The size of the destination region (which is smaller than
2046      the destination object for stores at a non-zero offset).  */
2047   tree destsize = compute_objsize (dest, stmt, ostype, &aref, &ptr_qry);
2048 
2049   if (!destsize)
2050     {
2051       aref.sizrng[0] = 0;
2052       aref.sizrng[1] = wi::to_offset (max_object_size ());
2053     }
2054 
2055   /* Return early if the DESTSIZE size expression is the same as LEN
2056      and the offset into the destination is zero.  This might happen
2057      in the case of a pair of malloc and memset calls to allocate
2058      an object and clear it as if by calloc.  */
2059   if (destsize == len && !plus_one
2060       && aref.offrng[0] == 0 && aref.offrng[0] == aref.offrng[1])
2061     return;
2062 
2063   wide_int rng[2];
2064   if (!get_range (len, stmt, rng, ptr_qry.rvals))
2065     return;
2066 
2067   widest_int lenrng[2] =
2068     { widest_int::from (rng[0], SIGNED), widest_int::from (rng[1], SIGNED) };
2069 
2070   if (plus_one)
2071     {
2072       lenrng[0] += 1;
2073       lenrng[1] += 1;
2074     }
2075 
2076   /* The size of the remaining space in the destination computed
2077      as the size of the latter minus the offset into it.  */
2078   widest_int spcrng[2];
2079   {
2080     offset_int remrng[2];
2081     remrng[1] = aref.size_remaining (remrng);
2082     spcrng[0] = remrng[0] == -1 ? 0 : widest_int::from (remrng[0], UNSIGNED);
2083     spcrng[1] = widest_int::from (remrng[1], UNSIGNED);
2084   }
2085 
2086   if (wi::leu_p (lenrng[0], spcrng[0])
2087       && wi::leu_p (lenrng[1], spcrng[1]))
2088     return;
2089 
2090   location_t loc = gimple_or_expr_nonartificial_location (stmt, dest);
2091   bool warned = false;
2092   if (wi::leu_p (lenrng[0], spcrng[1]))
2093     {
2094       if (len != destsize
2095 	  && (!si || rawmem || !is_strlen_related_p (si->ptr, len)))
2096 	return;
2097 
2098       warned = (writefn
2099 		? warning_at (loc, OPT_Wstringop_overflow_,
2100 			      "%qD writing one too many bytes into a region "
2101 			      "of a size that depends on %<strlen%>",
2102 			      writefn)
2103 		: warning_at (loc, OPT_Wstringop_overflow_,
2104 			      "writing one too many bytes into a region "
2105 			      "of a size that depends on %<strlen%>"));
2106     }
2107   else if (lenrng[0] == lenrng[1])
2108     {
2109       if (spcrng[0] == spcrng[1])
2110 	warned = (writefn
2111 		  ? warning_n (loc, OPT_Wstringop_overflow_,
2112 			       lenrng[0].to_uhwi (),
2113 			       "%qD writing %wu byte into a region "
2114 			       "of size %wu",
2115 			       "%qD writing %wu bytes into a region "
2116 			       "of size %wu",
2117 			       writefn, lenrng[0].to_uhwi (),
2118 			       spcrng[0].to_uhwi ())
2119 		  : warning_n (loc, OPT_Wstringop_overflow_,
2120 			       lenrng[0].to_uhwi (),
2121 			       "writing %wu byte into a region "
2122 			       "of size %wu",
2123 			       "writing %wu bytes into a region "
2124 			       "of size %wu",
2125 			       lenrng[0].to_uhwi (),
2126 			       spcrng[0].to_uhwi ()));
2127       else
2128 	warned = (writefn
2129 		  ? warning_n (loc, OPT_Wstringop_overflow_,
2130 			       lenrng[0].to_uhwi (),
2131 			       "%qD writing %wu byte into a region "
2132 			       "of size between %wu and %wu",
2133 			       "%qD writing %wu bytes into a region "
2134 			       "of size between %wu and %wu",
2135 			       writefn, lenrng[0].to_uhwi (),
2136 			       spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
2137 		  : warning_n (loc, OPT_Wstringop_overflow_,
2138 			       lenrng[0].to_uhwi (),
2139 			       "writing %wu byte into a region "
2140 			       "of size between %wu and %wu",
2141 			       "writing %wu bytes into a region "
2142 			       "of size between %wu and %wu",
2143 			       lenrng[0].to_uhwi (),
2144 			       spcrng[0].to_uhwi (), spcrng[1].to_uhwi ()));
2145     }
2146   else if (spcrng[0] == spcrng[1])
2147     warned = (writefn
2148 	      ? warning_at (loc, OPT_Wstringop_overflow_,
2149 			    "%qD writing between %wu and %wu bytes "
2150 			    "into a region of size %wu",
2151 			    writefn, lenrng[0].to_uhwi (),
2152 			    lenrng[1].to_uhwi (),
2153 			    spcrng[0].to_uhwi ())
2154 	      : warning_at (loc, OPT_Wstringop_overflow_,
2155 			    "writing between %wu and %wu bytes "
2156 			    "into a region of size %wu",
2157 			    lenrng[0].to_uhwi (),
2158 			    lenrng[1].to_uhwi (),
2159 			    spcrng[0].to_uhwi ()));
2160   else
2161     warned = (writefn
2162 	      ? warning_at (loc, OPT_Wstringop_overflow_,
2163 			    "%qD writing between %wu and %wu bytes "
2164 			    "into a region of size between %wu and %wu",
2165 			    writefn, lenrng[0].to_uhwi (),
2166 			    lenrng[1].to_uhwi (),
2167 			    spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
2168 	      : warning_at (loc, OPT_Wstringop_overflow_,
2169 			    "writing between %wu and %wu bytes "
2170 			    "into a region of size between %wu and %wu",
2171 			    lenrng[0].to_uhwi (),
2172 			    lenrng[1].to_uhwi (),
2173 			    spcrng[0].to_uhwi (), spcrng[1].to_uhwi ()));
2174 
2175   if (!warned)
2176     return;
2177 
2178   suppress_warning (stmt, OPT_Wstringop_overflow_);
2179 
2180   aref.inform_access (access_write_only);
2181 }
2182 
2183 /* Convenience wrapper for the above.  */
2184 
2185 void
maybe_warn_overflow(gimple * stmt,bool call_lhs,unsigned HOST_WIDE_INT len,strinfo * si,bool plus_one,bool rawmem)2186 strlen_pass::maybe_warn_overflow (gimple *stmt, bool call_lhs,
2187 				  unsigned HOST_WIDE_INT len,
2188 				  strinfo *si, bool plus_one, bool rawmem)
2189 {
2190   tree tlen = build_int_cst (size_type_node, len);
2191   maybe_warn_overflow (stmt, call_lhs, tlen, si, plus_one, rawmem);
2192 }
2193 
2194 /* Handle a strlen call.  If strlen of the argument is known, replace
2195    the strlen call with the known value, otherwise remember that strlen
2196    of the argument is stored in the lhs SSA_NAME.  */
2197 
2198 void
handle_builtin_strlen()2199 strlen_pass::handle_builtin_strlen ()
2200 {
2201   gimple *stmt = gsi_stmt (m_gsi);
2202   tree lhs = gimple_call_lhs (stmt);
2203 
2204   if (lhs == NULL_TREE)
2205     return;
2206 
2207   location_t loc = gimple_location (stmt);
2208   tree callee = gimple_call_fndecl (stmt);
2209   tree src = gimple_call_arg (stmt, 0);
2210   tree bound = (DECL_FUNCTION_CODE (callee) == BUILT_IN_STRNLEN
2211 		? gimple_call_arg (stmt, 1) : NULL_TREE);
2212   int idx = get_stridx (src, stmt);
2213   if (idx || (bound && integer_zerop (bound)))
2214     {
2215       strinfo *si = NULL;
2216       tree rhs;
2217 
2218       if (idx < 0)
2219 	rhs = build_int_cst (TREE_TYPE (lhs), ~idx);
2220       else if (idx == 0)
2221 	rhs = bound;
2222       else
2223 	{
2224 	  rhs = NULL_TREE;
2225 	  si = get_strinfo (idx);
2226 	  if (si != NULL)
2227 	    {
2228 	      rhs = get_string_length (si);
2229 	      /* For strnlen, if bound is constant, even if si is not known
2230 		 to be zero terminated, if we know at least bound bytes are
2231 		 not zero, the return value will be bound.  */
2232 	      if (rhs == NULL_TREE
2233 		  && bound != NULL_TREE
2234 		  && TREE_CODE (bound) == INTEGER_CST
2235 		  && si->nonzero_chars != NULL_TREE
2236 		  && TREE_CODE (si->nonzero_chars) == INTEGER_CST
2237 		  && tree_int_cst_le (bound, si->nonzero_chars))
2238 		rhs = bound;
2239 	    }
2240 	}
2241       if (rhs != NULL_TREE)
2242 	{
2243 	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2244 	    {
2245 	      fprintf (dump_file, "Optimizing: ");
2246 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2247 	    }
2248 	  rhs = unshare_expr (rhs);
2249 	  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
2250 	    rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
2251 
2252 	  if (bound)
2253 	    rhs = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (rhs), rhs, bound);
2254 
2255 	  gimplify_and_update_call_from_tree (&m_gsi, rhs);
2256 	  stmt = gsi_stmt (m_gsi);
2257 	  update_stmt (stmt);
2258 	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2259 	    {
2260 	      fprintf (dump_file, "into: ");
2261 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2262 	    }
2263 
2264 	  if (si != NULL
2265 	      /* Don't update anything for strnlen.  */
2266 	      && bound == NULL_TREE
2267 	      && TREE_CODE (si->nonzero_chars) != SSA_NAME
2268 	      && TREE_CODE (si->nonzero_chars) != INTEGER_CST
2269 	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
2270 	    {
2271 	      si = unshare_strinfo (si);
2272 	      si->nonzero_chars = lhs;
2273 	      gcc_assert (si->full_string_p);
2274 	    }
2275 
2276 	  if (strlen_to_stridx
2277 	      && (bound == NULL_TREE
2278 		  /* For strnlen record this only if the call is proven
2279 		     to return the same value as strlen would.  */
2280 		  || (TREE_CODE (bound) == INTEGER_CST
2281 		      && TREE_CODE (rhs) == INTEGER_CST
2282 		      && tree_int_cst_lt (rhs, bound))))
2283 	    strlen_to_stridx->put (lhs, stridx_strlenloc (idx, loc));
2284 
2285 	  return;
2286 	}
2287     }
2288   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
2289     return;
2290 
2291   if (idx == 0)
2292     idx = new_stridx (src);
2293   else
2294     {
2295       strinfo *si = get_strinfo (idx);
2296       if (si != NULL)
2297 	{
2298 	  if (!si->full_string_p && !si->stmt)
2299 	    {
2300 	      /* Until now we only had a lower bound on the string length.
2301 		 Install LHS as the actual length.  */
2302 	      si = unshare_strinfo (si);
2303 	      tree old = si->nonzero_chars;
2304 	      si->nonzero_chars = lhs;
2305 	      si->full_string_p = true;
2306 	      if (old && TREE_CODE (old) == INTEGER_CST)
2307 		{
2308 		  old = fold_convert_loc (loc, TREE_TYPE (lhs), old);
2309 		  tree adj = fold_build2_loc (loc, MINUS_EXPR,
2310 					      TREE_TYPE (lhs), lhs, old);
2311 		  adjust_related_strinfos (loc, si, adj);
2312 		  /* Use the constant minimum length as the lower bound
2313 		     of the non-constant length.  */
2314 		  wide_int min = wi::to_wide (old);
2315 		  wide_int max
2316 		    = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2;
2317 		  set_strlen_range (lhs, min, max);
2318 		}
2319 	      else
2320 		{
2321 		  si->first = 0;
2322 		  si->prev = 0;
2323 		  si->next = 0;
2324 		}
2325 	    }
2326 	  return;
2327 	}
2328     }
2329   if (idx)
2330     {
2331       if (!bound)
2332 	{
2333 	  /* Only store the new length information for calls to strlen(),
2334 	     not for those to strnlen().  */
2335 	  strinfo *si = new_strinfo (src, idx, lhs, true);
2336 	  set_strinfo (idx, si);
2337 	  find_equal_ptrs (src, idx);
2338 	}
2339 
2340       /* For SRC that is an array of N elements, set LHS's range
2341 	 to [0, min (N, BOUND)].  A constant return value means
2342 	 the range would have consisted of a single value.  In
2343 	 that case, fold the result into the returned constant.  */
2344       if (tree ret = maybe_set_strlen_range (lhs, src, bound))
2345 	if (TREE_CODE (ret) == INTEGER_CST)
2346 	  {
2347 	    if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2348 	      {
2349 		fprintf (dump_file, "Optimizing: ");
2350 		print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2351 	      }
2352 	    if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (ret)))
2353 	      ret = fold_convert_loc (loc, TREE_TYPE (lhs), ret);
2354 	    gimplify_and_update_call_from_tree (&m_gsi, ret);
2355 	    stmt = gsi_stmt (m_gsi);
2356 	    update_stmt (stmt);
2357 	    if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2358 	      {
2359 		fprintf (dump_file, "into: ");
2360 		print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2361 	      }
2362 	  }
2363 
2364       if (strlen_to_stridx && !bound)
2365 	strlen_to_stridx->put (lhs, stridx_strlenloc (idx, loc));
2366     }
2367 }
2368 
2369 /* Handle a strchr call.  If strlen of the first argument is known, replace
2370    the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
2371    that lhs of the call is endptr and strlen of the argument is endptr - x.  */
2372 
2373 void
handle_builtin_strchr()2374 strlen_pass::handle_builtin_strchr ()
2375 {
2376   gimple *stmt = gsi_stmt (m_gsi);
2377   tree lhs = gimple_call_lhs (stmt);
2378 
2379   if (lhs == NULL_TREE)
2380     return;
2381 
2382   if (!integer_zerop (gimple_call_arg (stmt, 1)))
2383     return;
2384 
2385   tree src = gimple_call_arg (stmt, 0);
2386 
2387   /* Avoid folding if the first argument is not a nul-terminated array.
2388      Defer warning until later.  */
2389   if (!check_nul_terminated_array (NULL_TREE, src))
2390     return;
2391 
2392   int idx = get_stridx (src, stmt);
2393   if (idx)
2394     {
2395       strinfo *si = NULL;
2396       tree rhs;
2397 
2398       if (idx < 0)
2399 	rhs = build_int_cst (size_type_node, ~idx);
2400       else
2401 	{
2402 	  rhs = NULL_TREE;
2403 	  si = get_strinfo (idx);
2404 	  if (si != NULL)
2405 	    rhs = get_string_length (si);
2406 	}
2407       if (rhs != NULL_TREE)
2408 	{
2409 	  location_t loc = gimple_location (stmt);
2410 
2411 	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2412 	    {
2413 	      fprintf (dump_file, "Optimizing: ");
2414 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2415 	    }
2416 	  if (si != NULL && si->endptr != NULL_TREE)
2417 	    {
2418 	      rhs = unshare_expr (si->endptr);
2419 	      if (!useless_type_conversion_p (TREE_TYPE (lhs),
2420 					      TREE_TYPE (rhs)))
2421 		rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
2422 	    }
2423 	  else
2424 	    {
2425 	      rhs = fold_convert_loc (loc, sizetype, unshare_expr (rhs));
2426 	      rhs = fold_build2_loc (loc, POINTER_PLUS_EXPR,
2427 				     TREE_TYPE (src), src, rhs);
2428 	      if (!useless_type_conversion_p (TREE_TYPE (lhs),
2429 					      TREE_TYPE (rhs)))
2430 		rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
2431 	    }
2432 	  gimplify_and_update_call_from_tree (&m_gsi, rhs);
2433 	  stmt = gsi_stmt (m_gsi);
2434 	  update_stmt (stmt);
2435 	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2436 	    {
2437 	      fprintf (dump_file, "into: ");
2438 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2439 	    }
2440 	  if (si != NULL
2441 	      && si->endptr == NULL_TREE
2442 	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
2443 	    {
2444 	      si = unshare_strinfo (si);
2445 	      si->endptr = lhs;
2446 	    }
2447 	  zero_length_string (lhs, si);
2448 	  return;
2449 	}
2450     }
2451   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
2452     return;
2453   if (TREE_CODE (src) != SSA_NAME || !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src))
2454     {
2455       if (idx == 0)
2456 	idx = new_stridx (src);
2457       else if (get_strinfo (idx) != NULL)
2458 	{
2459 	  zero_length_string (lhs, NULL);
2460 	  return;
2461 	}
2462       if (idx)
2463 	{
2464 	  location_t loc = gimple_location (stmt);
2465 	  tree lhsu = fold_convert_loc (loc, size_type_node, lhs);
2466 	  tree srcu = fold_convert_loc (loc, size_type_node, src);
2467 	  tree length = fold_build2_loc (loc, MINUS_EXPR,
2468 					 size_type_node, lhsu, srcu);
2469 	  strinfo *si = new_strinfo (src, idx, length, true);
2470 	  si->endptr = lhs;
2471 	  set_strinfo (idx, si);
2472 	  find_equal_ptrs (src, idx);
2473 	  zero_length_string (lhs, si);
2474 	}
2475     }
2476   else
2477     zero_length_string (lhs, NULL);
2478 }
2479 
2480 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
2481    If strlen of the second argument is known, strlen of the first argument
2482    is the same after this call.  Furthermore, attempt to convert it to
2483    memcpy.  Uses RVALS to determine range information.  */
2484 
2485 void
handle_builtin_strcpy(built_in_function bcode)2486 strlen_pass::handle_builtin_strcpy (built_in_function bcode)
2487 {
2488   int idx, didx;
2489   tree src, dst, srclen, len, lhs, type, fn, oldlen;
2490   bool success;
2491   gimple *stmt = gsi_stmt (m_gsi);
2492   strinfo *si, *dsi, *olddsi, *zsi;
2493   location_t loc;
2494 
2495   src = gimple_call_arg (stmt, 1);
2496   dst = gimple_call_arg (stmt, 0);
2497   lhs = gimple_call_lhs (stmt);
2498   idx = get_stridx (src, stmt);
2499   si = NULL;
2500   if (idx > 0)
2501     si = get_strinfo (idx);
2502 
2503   didx = get_stridx (dst, stmt);
2504   olddsi = NULL;
2505   oldlen = NULL_TREE;
2506   if (didx > 0)
2507     olddsi = get_strinfo (didx);
2508   else if (didx < 0)
2509     return;
2510 
2511   if (olddsi != NULL)
2512     adjust_last_stmt (olddsi, stmt, false);
2513 
2514   srclen = NULL_TREE;
2515   if (si != NULL)
2516     srclen = get_string_length (si);
2517   else if (idx < 0)
2518     srclen = build_int_cst (size_type_node, ~idx);
2519 
2520   maybe_warn_overflow (stmt, false, srclen, olddsi, true);
2521 
2522   if (olddsi != NULL)
2523     adjust_last_stmt (olddsi, stmt, false);
2524 
2525   loc = gimple_location (stmt);
2526   if (srclen == NULL_TREE)
2527     switch (bcode)
2528       {
2529       case BUILT_IN_STRCPY:
2530       case BUILT_IN_STRCPY_CHK:
2531 	if (lhs != NULL_TREE || !builtin_decl_implicit_p (BUILT_IN_STPCPY))
2532 	  return;
2533 	break;
2534       case BUILT_IN_STPCPY:
2535       case BUILT_IN_STPCPY_CHK:
2536 	if (lhs == NULL_TREE)
2537 	  return;
2538 	else
2539 	  {
2540 	    tree lhsuint = fold_convert_loc (loc, size_type_node, lhs);
2541 	    srclen = fold_convert_loc (loc, size_type_node, dst);
2542 	    srclen = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
2543 				      lhsuint, srclen);
2544 	  }
2545 	break;
2546       default:
2547 	gcc_unreachable ();
2548       }
2549 
2550   if (didx == 0)
2551     {
2552       didx = new_stridx (dst);
2553       if (didx == 0)
2554 	return;
2555     }
2556   if (olddsi != NULL)
2557     {
2558       oldlen = olddsi->nonzero_chars;
2559       dsi = unshare_strinfo (olddsi);
2560       dsi->nonzero_chars = srclen;
2561       dsi->full_string_p = (srclen != NULL_TREE);
2562       /* Break the chain, so adjust_related_strinfo on later pointers in
2563 	 the chain won't adjust this one anymore.  */
2564       dsi->next = 0;
2565       dsi->stmt = NULL;
2566       dsi->endptr = NULL_TREE;
2567     }
2568   else
2569     {
2570       dsi = new_strinfo (dst, didx, srclen, srclen != NULL_TREE);
2571       set_strinfo (didx, dsi);
2572       find_equal_ptrs (dst, didx);
2573     }
2574   dsi->writable = true;
2575   dsi->dont_invalidate = true;
2576 
2577   if (dsi->nonzero_chars == NULL_TREE)
2578     {
2579       strinfo *chainsi;
2580 
2581       /* If string length of src is unknown, use delayed length
2582 	 computation.  If string length of dst will be needed, it
2583 	 can be computed by transforming this strcpy call into
2584 	 stpcpy and subtracting dst from the return value.  */
2585 
2586       /* Look for earlier strings whose length could be determined if
2587 	 this strcpy is turned into an stpcpy.  */
2588 
2589       if (dsi->prev != 0 && (chainsi = verify_related_strinfos (dsi)) != NULL)
2590 	{
2591 	  for (; chainsi && chainsi != dsi; chainsi = get_strinfo (chainsi->next))
2592 	    {
2593 	      /* When setting a stmt for delayed length computation
2594 		 prevent all strinfos through dsi from being
2595 		 invalidated.  */
2596 	      chainsi = unshare_strinfo (chainsi);
2597 	      chainsi->stmt = stmt;
2598 	      chainsi->nonzero_chars = NULL_TREE;
2599 	      chainsi->full_string_p = false;
2600 	      chainsi->endptr = NULL_TREE;
2601 	      chainsi->dont_invalidate = true;
2602 	    }
2603 	}
2604       dsi->stmt = stmt;
2605 
2606       /* Try to detect overlap before returning.  This catches cases
2607 	 like strcpy (d, d + n) where n is non-constant whose range
2608 	 is such that (n <= strlen (d) holds).
2609 
2610 	 OLDDSI->NONZERO_chars may have been reset by this point with
2611 	 oldlen holding it original value.  */
2612       if (olddsi && oldlen)
2613 	{
2614 	  /* Add 1 for the terminating NUL.  */
2615 	  tree type = TREE_TYPE (oldlen);
2616 	  oldlen = fold_build2 (PLUS_EXPR, type, oldlen,
2617 				build_int_cst (type, 1));
2618 	  check_bounds_or_overlap (stmt, olddsi->ptr, src, oldlen, NULL_TREE);
2619 	}
2620 
2621       return;
2622     }
2623 
2624   if (olddsi != NULL)
2625     {
2626       tree adj = NULL_TREE;
2627       if (oldlen == NULL_TREE)
2628 	;
2629       else if (integer_zerop (oldlen))
2630 	adj = srclen;
2631       else if (TREE_CODE (oldlen) == INTEGER_CST
2632 	       || TREE_CODE (srclen) == INTEGER_CST)
2633 	adj = fold_build2_loc (loc, MINUS_EXPR,
2634 			       TREE_TYPE (srclen), srclen,
2635 			       fold_convert_loc (loc, TREE_TYPE (srclen),
2636 						 oldlen));
2637       if (adj != NULL_TREE)
2638 	adjust_related_strinfos (loc, dsi, adj);
2639       else
2640 	dsi->prev = 0;
2641     }
2642   /* strcpy src may not overlap dst, so src doesn't need to be
2643      invalidated either.  */
2644   if (si != NULL)
2645     si->dont_invalidate = true;
2646 
2647   fn = NULL_TREE;
2648   zsi = NULL;
2649   switch (bcode)
2650     {
2651     case BUILT_IN_STRCPY:
2652       fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2653       if (lhs)
2654 	ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
2655       break;
2656     case BUILT_IN_STRCPY_CHK:
2657       fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
2658       if (lhs)
2659 	ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
2660       break;
2661     case BUILT_IN_STPCPY:
2662       /* This would need adjustment of the lhs (subtract one),
2663 	 or detection that the trailing '\0' doesn't need to be
2664 	 written, if it will be immediately overwritten.
2665       fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);  */
2666       if (lhs)
2667 	{
2668 	  dsi->endptr = lhs;
2669 	  zsi = zero_length_string (lhs, dsi);
2670 	}
2671       break;
2672     case BUILT_IN_STPCPY_CHK:
2673       /* This would need adjustment of the lhs (subtract one),
2674 	 or detection that the trailing '\0' doesn't need to be
2675 	 written, if it will be immediately overwritten.
2676       fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK);  */
2677       if (lhs)
2678 	{
2679 	  dsi->endptr = lhs;
2680 	  zsi = zero_length_string (lhs, dsi);
2681 	}
2682       break;
2683     default:
2684       gcc_unreachable ();
2685     }
2686   if (zsi != NULL)
2687     zsi->dont_invalidate = true;
2688 
2689   if (fn)
2690     {
2691       tree args = TYPE_ARG_TYPES (TREE_TYPE (fn));
2692       type = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
2693     }
2694   else
2695     type = size_type_node;
2696 
2697   len = fold_convert_loc (loc, type, unshare_expr (srclen));
2698   len = fold_build2_loc (loc, PLUS_EXPR, type, len, build_int_cst (type, 1));
2699 
2700   /* Disable warning for the transformed statement?  */
2701   opt_code no_warning_opt = no_warning;
2702 
2703   if (const strinfo *chksi = si ? olddsi ? olddsi : dsi : NULL)
2704     {
2705       no_warning_opt = check_bounds_or_overlap (stmt, chksi->ptr, si->ptr,
2706 						NULL_TREE, len);
2707       if (no_warning_opt)
2708 	suppress_warning (stmt, no_warning_opt);
2709     }
2710 
2711   if (fn == NULL_TREE)
2712     return;
2713 
2714   len = force_gimple_operand_gsi (&m_gsi, len, true, NULL_TREE, true,
2715 				  GSI_SAME_STMT);
2716   if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2717     {
2718       fprintf (dump_file, "Optimizing: ");
2719       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2720     }
2721   if (gimple_call_num_args (stmt) == 2)
2722     success = update_gimple_call (&m_gsi, fn, 3, dst, src, len);
2723   else
2724     success = update_gimple_call (&m_gsi, fn, 4, dst, src, len,
2725 				  gimple_call_arg (stmt, 2));
2726   if (success)
2727     {
2728       stmt = gsi_stmt (m_gsi);
2729       update_stmt (stmt);
2730       if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2731 	{
2732 	  fprintf (dump_file, "into: ");
2733 	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2734 	}
2735       /* Allow adjust_last_stmt to decrease this memcpy's size.  */
2736       laststmt.stmt = stmt;
2737       laststmt.len = srclen;
2738       laststmt.stridx = dsi->idx;
2739     }
2740   else if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2741     fprintf (dump_file, "not possible.\n");
2742 
2743   if (no_warning_opt)
2744     suppress_warning (stmt, no_warning_opt);
2745 }
2746 
2747 /* Check the size argument to the built-in forms of stpncpy and strncpy
2748    for out-of-bounds offsets or overlapping access, and to see if the
2749    size argument is derived from a call to strlen() on the source argument,
2750    and if so, issue an appropriate warning.  */
2751 
2752 void
handle_builtin_strncat(built_in_function)2753 strlen_pass::handle_builtin_strncat (built_in_function)
2754 {
2755   /* Same as stxncpy().  */
2756   handle_builtin_stxncpy_strncat (true);
2757 }
2758 
2759 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2760    way.  LEN can either be an integer expression, or a pointer (to char).
2761    When it is the latter (such as in recursive calls to self) it is
2762    assumed to be the argument in some call to strlen() whose relationship
2763    to SRC is being ascertained.  */
2764 
2765 bool
is_strlen_related_p(tree src,tree len)2766 is_strlen_related_p (tree src, tree len)
2767 {
2768   if (TREE_CODE (TREE_TYPE (len)) == POINTER_TYPE
2769       && operand_equal_p (src, len, 0))
2770     return true;
2771 
2772   if (TREE_CODE (len) != SSA_NAME)
2773     return false;
2774 
2775   if (TREE_CODE (src) == SSA_NAME)
2776     {
2777       gimple *srcdef = SSA_NAME_DEF_STMT (src);
2778       if (is_gimple_assign (srcdef))
2779 	{
2780 	  /* Handle bitwise AND used in conversions from wider size_t
2781 	     to narrower unsigned types.  */
2782 	  tree_code code = gimple_assign_rhs_code (srcdef);
2783 	  if (code == BIT_AND_EXPR
2784 	      || code == NOP_EXPR)
2785 	    return is_strlen_related_p (gimple_assign_rhs1 (srcdef), len);
2786 
2787 	  return false;
2788 	}
2789 
2790       if (gimple_call_builtin_p (srcdef, BUILT_IN_NORMAL))
2791 	{
2792 	  /* If SRC is the result of a call to an allocation function
2793 	     or strlen, use the function's argument instead.  */
2794 	  tree func = gimple_call_fndecl (srcdef);
2795 	  built_in_function code = DECL_FUNCTION_CODE (func);
2796 	  if (code == BUILT_IN_ALLOCA
2797 	      || code == BUILT_IN_ALLOCA_WITH_ALIGN
2798 	      || code == BUILT_IN_MALLOC
2799 	      || code == BUILT_IN_STRLEN)
2800 	    return is_strlen_related_p (gimple_call_arg (srcdef, 0), len);
2801 
2802 	  /* FIXME: Handle other functions with attribute alloc_size.  */
2803 	  return false;
2804 	}
2805     }
2806 
2807   gimple *lendef = SSA_NAME_DEF_STMT (len);
2808   if (!lendef)
2809     return false;
2810 
2811   if (is_gimple_call (lendef))
2812     {
2813       tree func = gimple_call_fndecl (lendef);
2814       if (!valid_builtin_call (lendef)
2815 	  || DECL_FUNCTION_CODE (func) != BUILT_IN_STRLEN)
2816 	return false;
2817 
2818       tree arg = gimple_call_arg (lendef, 0);
2819       return is_strlen_related_p (src, arg);
2820     }
2821 
2822   if (!is_gimple_assign (lendef))
2823     return false;
2824 
2825   tree_code code = gimple_assign_rhs_code (lendef);
2826   tree rhs1 = gimple_assign_rhs1 (lendef);
2827   tree rhstype = TREE_TYPE (rhs1);
2828 
2829   if ((TREE_CODE (rhstype) == POINTER_TYPE && code == POINTER_PLUS_EXPR)
2830       || (INTEGRAL_TYPE_P (rhstype)
2831 	  && (code == BIT_AND_EXPR
2832 	      || code == NOP_EXPR)))
2833     {
2834       /* Pointer plus (an integer), and truncation are considered among
2835 	 the (potentially) related expressions to strlen.  */
2836       return is_strlen_related_p (src, rhs1);
2837     }
2838 
2839   if (tree rhs2 = gimple_assign_rhs2 (lendef))
2840     {
2841       /* Integer subtraction is considered strlen-related when both
2842 	 arguments are integers and second one is strlen-related.  */
2843       rhstype = TREE_TYPE (rhs2);
2844       if (INTEGRAL_TYPE_P (rhstype) && code == MINUS_EXPR)
2845 	return is_strlen_related_p (src, rhs2);
2846     }
2847 
2848   return false;
2849 }
2850 
2851 /* Called by handle_builtin_stxncpy_strncat and by
2852    gimple_fold_builtin_strncpy in gimple-fold.c.
2853    Check to see if the specified bound is a) equal to the size of
2854    the destination DST and if so, b) if it's immediately followed by
2855    DST[CNT - 1] = '\0'.  If a) holds and b) does not, warn.  Otherwise,
2856    do nothing.  Return true if diagnostic has been issued.
2857 
2858    The purpose is to diagnose calls to strncpy and stpncpy that do
2859    not nul-terminate the copy while allowing for the idiom where
2860    such a call is immediately followed by setting the last element
2861    to nul, as in:
2862      char a[32];
2863      strncpy (a, s, sizeof a);
2864      a[sizeof a - 1] = '\0';
2865 */
2866 
2867 bool
maybe_diag_stxncpy_trunc(gimple_stmt_iterator gsi,tree src,tree cnt,pointer_query * ptr_qry)2868 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
2869 			  pointer_query *ptr_qry /* = NULL */)
2870 {
2871   gimple *stmt = gsi_stmt (gsi);
2872   if (warning_suppressed_p (stmt, OPT_Wstringop_truncation))
2873     return false;
2874 
2875   wide_int cntrange[2];
2876   value_range r;
2877   if (!get_range_query (cfun)->range_of_expr (r, cnt)
2878       || r.varying_p ()
2879       || r.undefined_p ())
2880     return false;
2881 
2882   cntrange[0] = wi::to_wide (r.min ());
2883   cntrange[1] = wi::to_wide (r.max ());
2884   if (r.kind () == VR_ANTI_RANGE)
2885     {
2886       wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));
2887 
2888       if (wi::ltu_p (cntrange[1], maxobjsize))
2889 	{
2890 	  cntrange[0] = cntrange[1] + 1;
2891 	  cntrange[1] = maxobjsize;
2892 	}
2893       else
2894 	{
2895 	  cntrange[1] = cntrange[0] - 1;
2896 	  cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt)));
2897 	}
2898     }
2899 
2900   /* Negative value is the constant string length.  If it's less than
2901      the lower bound there is no truncation.  Avoid calling get_stridx()
2902      when ssa_ver_to_stridx is empty.  That implies the caller isn't
2903      running under the control of this pass and ssa_ver_to_stridx hasn't
2904      been created yet.  */
2905   int sidx = ssa_ver_to_stridx.length () ? get_stridx (src, stmt) : 0;
2906   if (sidx < 0 && wi::gtu_p (cntrange[0], ~sidx))
2907     return false;
2908 
2909   tree dst = gimple_call_arg (stmt, 0);
2910   tree dstdecl = dst;
2911   if (TREE_CODE (dstdecl) == ADDR_EXPR)
2912     dstdecl = TREE_OPERAND (dstdecl, 0);
2913 
2914   tree ref = NULL_TREE;
2915 
2916   if (!sidx)
2917     {
2918       /* If the source is a non-string return early to avoid warning
2919 	 for possible truncation (if the truncation is certain SIDX
2920 	 is non-zero).  */
2921       tree srcdecl = gimple_call_arg (stmt, 1);
2922       if (TREE_CODE (srcdecl) == ADDR_EXPR)
2923 	srcdecl = TREE_OPERAND (srcdecl, 0);
2924       if (get_attr_nonstring_decl (srcdecl, &ref))
2925 	return false;
2926     }
2927 
2928   /* Likewise, if the destination refers to an array/pointer declared
2929      nonstring return early.  */
2930   if (get_attr_nonstring_decl (dstdecl, &ref))
2931     return false;
2932 
2933   /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2934      avoid the truncation warning.  */
2935   gsi_next_nondebug (&gsi);
2936   gimple *next_stmt = gsi_stmt (gsi);
2937   if (!next_stmt)
2938     {
2939       /* When there is no statement in the same basic block check
2940 	 the immediate successor block.  */
2941       if (basic_block bb = gimple_bb (stmt))
2942 	{
2943 	  if (single_succ_p (bb))
2944 	    {
2945 	      /* For simplicity, ignore blocks with multiple outgoing
2946 		 edges for now and only consider successor blocks along
2947 		 normal edges.  */
2948 	      edge e = EDGE_SUCC (bb, 0);
2949 	      if (!(e->flags & EDGE_ABNORMAL))
2950 		{
2951 		  gsi = gsi_start_bb (e->dest);
2952 		  next_stmt = gsi_stmt (gsi);
2953 		  if (next_stmt && is_gimple_debug (next_stmt))
2954 		    {
2955 		      gsi_next_nondebug (&gsi);
2956 		      next_stmt = gsi_stmt (gsi);
2957 		    }
2958 		}
2959 	    }
2960 	}
2961     }
2962 
2963   if (next_stmt && is_gimple_assign (next_stmt))
2964     {
2965       tree lhs = gimple_assign_lhs (next_stmt);
2966       tree_code code = TREE_CODE (lhs);
2967       if (code == ARRAY_REF || code == MEM_REF)
2968 	lhs = TREE_OPERAND (lhs, 0);
2969 
2970       tree func = gimple_call_fndecl (stmt);
2971       if (DECL_FUNCTION_CODE (func) == BUILT_IN_STPNCPY)
2972 	{
2973 	  tree ret = gimple_call_lhs (stmt);
2974 	  if (ret && operand_equal_p (ret, lhs, 0))
2975 	    return false;
2976 	}
2977 
2978       /* Determine the base address and offset of the reference,
2979 	 ignoring the innermost array index.  */
2980       if (TREE_CODE (ref) == ARRAY_REF)
2981 	ref = TREE_OPERAND (ref, 0);
2982 
2983       poly_int64 dstoff;
2984       tree dstbase = get_addr_base_and_unit_offset (ref, &dstoff);
2985 
2986       poly_int64 lhsoff;
2987       tree lhsbase = get_addr_base_and_unit_offset (lhs, &lhsoff);
2988       if (lhsbase
2989 	  && dstbase
2990 	  && known_eq (dstoff, lhsoff)
2991 	  && operand_equal_p (dstbase, lhsbase, 0))
2992 	return false;
2993     }
2994 
2995   int prec = TYPE_PRECISION (TREE_TYPE (cnt));
2996   wide_int lenrange[2];
2997   if (strinfo *sisrc = sidx > 0 ? get_strinfo (sidx) : NULL)
2998     {
2999       lenrange[0] = (sisrc->nonzero_chars
3000 		     && TREE_CODE (sisrc->nonzero_chars) == INTEGER_CST
3001 		     ? wi::to_wide (sisrc->nonzero_chars)
3002 		     : wi::zero (prec));
3003       lenrange[1] = lenrange[0];
3004     }
3005   else if (sidx < 0)
3006     lenrange[0] = lenrange[1] = wi::shwi (~sidx, prec);
3007   else
3008     {
3009       c_strlen_data lendata = { };
3010       /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
3011 	 to have it set to the length of the longest string in a PHI.  */
3012       lendata.maxbound = src;
3013       get_range_strlen (src, &lendata, /* eltsize = */1);
3014       if (TREE_CODE (lendata.minlen) == INTEGER_CST
3015 	  && TREE_CODE (lendata.maxbound) == INTEGER_CST)
3016 	{
3017 	  /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
3018 	     which stores the length of the shortest known string.  */
3019 	  if (integer_all_onesp (lendata.maxlen))
3020 	    lenrange[0] = wi::shwi (0, prec);
3021 	  else
3022 	    lenrange[0] = wi::to_wide (lendata.minlen, prec);
3023 	  lenrange[1] = wi::to_wide (lendata.maxbound, prec);
3024 	}
3025       else
3026 	{
3027 	  lenrange[0] = wi::shwi (0, prec);
3028 	  lenrange[1] = wi::shwi (-1, prec);
3029 	}
3030     }
3031 
3032   location_t callloc = gimple_or_expr_nonartificial_location (stmt, dst);
3033   tree func = gimple_call_fndecl (stmt);
3034 
3035   if (lenrange[0] != 0 || !wi::neg_p (lenrange[1]))
3036     {
3037       /* If the longest source string is shorter than the lower bound
3038 	 of the specified count the copy is definitely nul-terminated.  */
3039       if (wi::ltu_p (lenrange[1], cntrange[0]))
3040 	return false;
3041 
3042       if (wi::neg_p (lenrange[1]))
3043 	{
3044 	  /* The length of one of the strings is unknown but at least
3045 	     one has non-zero length and that length is stored in
3046 	     LENRANGE[1].  Swap the bounds to force a "may be truncated"
3047 	     warning below.  */
3048 	  lenrange[1] = lenrange[0];
3049 	  lenrange[0] = wi::shwi (0, prec);
3050 	}
3051 
3052       /* Set to true for strncat whose bound is derived from the length
3053 	 of the destination (the expected usage pattern).  */
3054       bool cat_dstlen_bounded = false;
3055       if (DECL_FUNCTION_CODE (func) == BUILT_IN_STRNCAT)
3056 	cat_dstlen_bounded = is_strlen_related_p (dst, cnt);
3057 
3058       if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1])
3059 	return warning_n (callloc, OPT_Wstringop_truncation,
3060 			  cntrange[0].to_uhwi (),
3061 			  "%qD output truncated before terminating "
3062 			  "nul copying %E byte from a string of the "
3063 			  "same length",
3064 			  "%qD output truncated before terminating nul "
3065 			  "copying %E bytes from a string of the same "
3066 			  "length",
3067 			  func, cnt);
3068       else if (!cat_dstlen_bounded)
3069 	{
3070 	  if (wi::geu_p (lenrange[0], cntrange[1]))
3071 	    {
3072 	      /* The shortest string is longer than the upper bound of
3073 		 the count so the truncation is certain.  */
3074 	      if (cntrange[0] == cntrange[1])
3075 		return warning_n (callloc, OPT_Wstringop_truncation,
3076 				  cntrange[0].to_uhwi (),
3077 				  "%qD output truncated copying %E byte "
3078 				  "from a string of length %wu",
3079 				  "%qD output truncated copying %E bytes "
3080 				  "from a string of length %wu",
3081 				  func, cnt, lenrange[0].to_uhwi ());
3082 
3083 	      return warning_at (callloc, OPT_Wstringop_truncation,
3084 				 "%qD output truncated copying between %wu "
3085 				 "and %wu bytes from a string of length %wu",
3086 				 func, cntrange[0].to_uhwi (),
3087 				 cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
3088 	    }
3089 	  else if (wi::geu_p (lenrange[1], cntrange[1]))
3090 	    {
3091 	      /* The longest string is longer than the upper bound of
3092 		 the count so the truncation is possible.  */
3093 	      if (cntrange[0] == cntrange[1])
3094 		return warning_n (callloc, OPT_Wstringop_truncation,
3095 				  cntrange[0].to_uhwi (),
3096 				  "%qD output may be truncated copying %E "
3097 				  "byte from a string of length %wu",
3098 				  "%qD output may be truncated copying %E "
3099 				  "bytes from a string of length %wu",
3100 				  func, cnt, lenrange[1].to_uhwi ());
3101 
3102 	      return warning_at (callloc, OPT_Wstringop_truncation,
3103 				 "%qD output may be truncated copying between "
3104 				 "%wu and %wu bytes from a string of length %wu",
3105 				 func, cntrange[0].to_uhwi (),
3106 				 cntrange[1].to_uhwi (), lenrange[1].to_uhwi ());
3107 	    }
3108 	}
3109 
3110       if (!cat_dstlen_bounded
3111 	  && cntrange[0] != cntrange[1]
3112 	  && wi::leu_p (cntrange[0], lenrange[0])
3113 	  && wi::leu_p (cntrange[1], lenrange[0] + 1))
3114 	{
3115 	  /* If the source (including the terminating nul) is longer than
3116 	     the lower bound of the specified count but shorter than the
3117 	     upper bound the copy may (but need not) be truncated.  */
3118 	  return warning_at (callloc, OPT_Wstringop_truncation,
3119 			     "%qD output may be truncated copying between "
3120 			     "%wu and %wu bytes from a string of length %wu",
3121 			     func, cntrange[0].to_uhwi (),
3122 			     cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
3123 	}
3124     }
3125 
3126   access_ref aref;
3127   if (tree dstsize = compute_objsize (dst, stmt, 1, &aref, ptr_qry))
3128     {
3129       /* The source length is unknown.  Try to determine the destination
3130 	 size and see if it matches the specified bound.  If not, bail.
3131 	 Otherwise go on to see if it should be diagnosed for possible
3132 	 truncation.  */
3133       if (!dstsize)
3134 	return false;
3135 
3136       if (wi::to_wide (dstsize) != cntrange[1])
3137 	return false;
3138 
3139       /* Avoid warning for strncpy(a, b, N) calls where the following
3140 	 equalities hold:
3141 	   N == sizeof a && N == sizeof b */
3142       if (tree srcsize = compute_objsize (src, stmt, 1, &aref, ptr_qry))
3143 	if (wi::to_wide (srcsize) == cntrange[1])
3144 	  return false;
3145 
3146       if (cntrange[0] == cntrange[1])
3147 	return warning_at (callloc, OPT_Wstringop_truncation,
3148 			   "%qD specified bound %E equals destination size",
3149 			   func, cnt);
3150     }
3151 
3152   return false;
3153 }
3154 
3155 /* Check the arguments to the built-in forms of stpncpy, strncpy, and
3156    strncat, for out-of-bounds offsets or overlapping access, and to see
3157    if the size is derived from calling strlen() on the source argument,
3158    and if so, issue the appropriate warning.
3159    APPEND_P is true for strncat.  */
3160 
3161 void
handle_builtin_stxncpy_strncat(bool append_p)3162 strlen_pass::handle_builtin_stxncpy_strncat (bool append_p)
3163 {
3164   if (!strlen_to_stridx)
3165     return;
3166 
3167   gimple *stmt = gsi_stmt (m_gsi);
3168 
3169   tree dst = gimple_call_arg (stmt, 0);
3170   tree src = gimple_call_arg (stmt, 1);
3171   tree len = gimple_call_arg (stmt, 2);
3172   /* An upper bound of the size of the destination.  */
3173   tree dstsize = NULL_TREE;
3174   /* The length of the destination and source strings (plus 1 for those
3175      whose FULL_STRING_P is set, i.e., whose length is exact rather than
3176      a lower bound).  */
3177   tree dstlenp1 = NULL_TREE, srclenp1 = NULL_TREE;;
3178 
3179   int didx = get_stridx (dst, stmt);
3180   if (strinfo *sidst = didx > 0 ? get_strinfo (didx) : NULL)
3181     {
3182       /* Compute the size of the destination string including the nul
3183 	 if it is known to be nul-terminated.  */
3184       if (sidst->nonzero_chars)
3185 	{
3186 	  if (sidst->full_string_p)
3187 	    {
3188 	      /* String is known to be nul-terminated.  */
3189 	      tree type = TREE_TYPE (sidst->nonzero_chars);
3190 	      dstlenp1 = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
3191 				     build_int_cst (type, 1));
3192 	    }
3193 	  else
3194 	    dstlenp1 = sidst->nonzero_chars;
3195 	}
3196       else if (TREE_CODE (sidst->ptr) == SSA_NAME)
3197 	{
3198 	  gimple *def_stmt = SSA_NAME_DEF_STMT (sidst->ptr);
3199 	  dstsize = gimple_call_alloc_size (def_stmt);
3200 	}
3201 
3202       dst = sidst->ptr;
3203     }
3204 
3205   int sidx = get_stridx (src, stmt);
3206   strinfo *sisrc = sidx > 0 ? get_strinfo (sidx) : NULL;
3207   if (sisrc)
3208     {
3209       /* strncat() and strncpy() can modify the source string by writing
3210 	 over the terminating nul so SISRC->DONT_INVALIDATE must be left
3211 	 clear.  */
3212 
3213       /* Compute the size of the source string including the terminating
3214 	 nul if its known to be nul-terminated.  */
3215       if (sisrc->nonzero_chars)
3216 	{
3217 	  if (sisrc->full_string_p)
3218 	    {
3219 	      tree type = TREE_TYPE (sisrc->nonzero_chars);
3220 	      srclenp1 = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
3221 				     build_int_cst (type, 1));
3222 	    }
3223 	  else
3224 	    srclenp1 = sisrc->nonzero_chars;
3225 	}
3226 
3227 	src = sisrc->ptr;
3228     }
3229   else
3230     srclenp1 = NULL_TREE;
3231 
3232   opt_code opt = check_bounds_or_overlap (stmt, dst, src, dstlenp1, srclenp1);
3233   if (opt != no_warning)
3234     {
3235       suppress_warning (stmt, opt);
3236       return;
3237     }
3238 
3239   /* If the length argument was computed from strlen(S) for some string
3240      S retrieve the strinfo index for the string (PSS->FIRST) along with
3241      the location of the strlen() call (PSS->SECOND).  */
3242   stridx_strlenloc *pss = strlen_to_stridx->get (len);
3243   if (!pss || pss->first <= 0)
3244     {
3245       if (maybe_diag_stxncpy_trunc (m_gsi, src, len))
3246 	suppress_warning (stmt, OPT_Wstringop_truncation);
3247 
3248       return;
3249     }
3250 
3251   /* Retrieve the strinfo data for the string S that LEN was computed
3252      from as some function F of strlen (S) (i.e., LEN need not be equal
3253      to strlen(S)).  */
3254   strinfo *silen = get_strinfo (pss->first);
3255 
3256   location_t callloc = gimple_or_expr_nonartificial_location (stmt, dst);
3257 
3258   tree func = gimple_call_fndecl (stmt);
3259 
3260   bool warned = false;
3261 
3262   /* When -Wstringop-truncation is set, try to determine truncation
3263      before diagnosing possible overflow.  Truncation is implied by
3264      the LEN argument being equal to strlen(SRC), regardless of
3265      whether its value is known.  Otherwise, when appending, or
3266      when copying into a destination of known size, issue the more
3267      generic -Wstringop-overflow which triggers for LEN arguments
3268      that in any meaningful way depend on strlen(SRC).  */
3269   if (!append_p
3270       && sisrc == silen
3271       && is_strlen_related_p (src, len)
3272       && warning_at (callloc, OPT_Wstringop_truncation,
3273 		     "%qD output truncated before terminating nul "
3274 		     "copying as many bytes from a string as its length",
3275 		     func))
3276     warned = true;
3277   else if ((append_p || !dstsize || len == dstlenp1)
3278 	   && silen && is_strlen_related_p (src, silen->ptr))
3279     {
3280       /* Issue -Wstringop-overflow when appending or when writing into
3281 	 a destination of a known size.  Otherwise, when copying into
3282 	 a destination of an unknown size, it's truncation.  */
3283       opt_code opt = (append_p || dstsize
3284 		      ? OPT_Wstringop_overflow_ : OPT_Wstringop_truncation);
3285       warned = warning_at (callloc, opt,
3286 			   "%qD specified bound depends on the length "
3287 			   "of the source argument",
3288 			   func);
3289     }
3290   if (warned)
3291     {
3292       location_t strlenloc = pss->second;
3293       if (strlenloc != UNKNOWN_LOCATION && strlenloc != callloc)
3294 	inform (strlenloc, "length computed here");
3295     }
3296 }
3297 
3298 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
3299    If strlen of the second argument is known and length of the third argument
3300    is that plus one, strlen of the first argument is the same after this
3301    call.  Uses RVALS to determine range information.  */
3302 
3303 void
handle_builtin_memcpy(built_in_function bcode)3304 strlen_pass::handle_builtin_memcpy (built_in_function bcode)
3305 {
3306   tree lhs, oldlen, newlen;
3307   gimple *stmt = gsi_stmt (m_gsi);
3308   strinfo *si, *dsi;
3309 
3310   tree len = gimple_call_arg (stmt, 2);
3311   tree src = gimple_call_arg (stmt, 1);
3312   tree dst = gimple_call_arg (stmt, 0);
3313 
3314   int didx = get_stridx (dst, stmt);
3315   strinfo *olddsi = NULL;
3316   if (didx > 0)
3317     olddsi = get_strinfo (didx);
3318   else if (didx < 0)
3319     return;
3320 
3321   if (olddsi != NULL
3322       && !integer_zerop (len))
3323     {
3324       maybe_warn_overflow (stmt, false, len, olddsi, false, true);
3325       adjust_last_stmt (olddsi, stmt, false);
3326     }
3327 
3328   int idx = get_stridx (src, stmt);
3329   if (idx == 0)
3330     return;
3331 
3332   bool full_string_p;
3333   if (idx > 0)
3334     {
3335       gimple *def_stmt;
3336 
3337       /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
3338 	 is known.  */
3339       si = get_strinfo (idx);
3340       if (si == NULL || si->nonzero_chars == NULL_TREE)
3341 	return;
3342       if (TREE_CODE (len) == INTEGER_CST
3343 	  && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
3344 	{
3345 	  if (tree_int_cst_le (len, si->nonzero_chars))
3346 	    {
3347 	      /* Copying LEN nonzero characters, where LEN is constant.  */
3348 	      newlen = len;
3349 	      full_string_p = false;
3350 	    }
3351 	  else
3352 	    {
3353 	      /* Copying the whole of the analyzed part of SI.  */
3354 	      newlen = si->nonzero_chars;
3355 	      full_string_p = si->full_string_p;
3356 	    }
3357 	}
3358       else
3359 	{
3360 	  if (!si->full_string_p)
3361 	    return;
3362 	  if (TREE_CODE (len) != SSA_NAME)
3363 	    return;
3364 	  def_stmt = SSA_NAME_DEF_STMT (len);
3365 	  if (!is_gimple_assign (def_stmt)
3366 	      || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
3367 	      || gimple_assign_rhs1 (def_stmt) != si->nonzero_chars
3368 	      || !integer_onep (gimple_assign_rhs2 (def_stmt)))
3369 	    return;
3370 	  /* Copying variable-length string SI (and no more).  */
3371 	  newlen = si->nonzero_chars;
3372 	  full_string_p = true;
3373 	}
3374     }
3375   else
3376     {
3377       si = NULL;
3378       /* Handle memcpy (x, "abcd", 5) or
3379 	 memcpy (x, "abc\0uvw", 7).  */
3380       if (!tree_fits_uhwi_p (len))
3381 	return;
3382 
3383       unsigned HOST_WIDE_INT clen = tree_to_uhwi (len);
3384       unsigned HOST_WIDE_INT nonzero_chars = ~idx;
3385       newlen = build_int_cst (size_type_node, MIN (nonzero_chars, clen));
3386       full_string_p = clen > nonzero_chars;
3387     }
3388 
3389   if (!full_string_p
3390       && olddsi
3391       && olddsi->nonzero_chars
3392       && TREE_CODE (olddsi->nonzero_chars) == INTEGER_CST
3393       && tree_int_cst_le (newlen, olddsi->nonzero_chars))
3394     {
3395       /* The SRC substring being written strictly overlaps
3396 	 a subsequence of the existing string OLDDSI.  */
3397       newlen = olddsi->nonzero_chars;
3398       full_string_p = olddsi->full_string_p;
3399     }
3400 
3401   if (olddsi != NULL && TREE_CODE (len) == SSA_NAME)
3402     adjust_last_stmt (olddsi, stmt, false);
3403 
3404   if (didx == 0)
3405     {
3406       didx = new_stridx (dst);
3407       if (didx == 0)
3408 	return;
3409     }
3410   oldlen = NULL_TREE;
3411   if (olddsi != NULL)
3412     {
3413       dsi = unshare_strinfo (olddsi);
3414       oldlen = olddsi->nonzero_chars;
3415       dsi->nonzero_chars = newlen;
3416       dsi->full_string_p = full_string_p;
3417       /* Break the chain, so adjust_related_strinfo on later pointers in
3418 	 the chain won't adjust this one anymore.  */
3419       dsi->next = 0;
3420       dsi->stmt = NULL;
3421       dsi->endptr = NULL_TREE;
3422     }
3423   else
3424     {
3425       dsi = new_strinfo (dst, didx, newlen, full_string_p);
3426       set_strinfo (didx, dsi);
3427       find_equal_ptrs (dst, didx);
3428     }
3429   dsi->writable = true;
3430   dsi->dont_invalidate = true;
3431   if (olddsi != NULL)
3432     {
3433       tree adj = NULL_TREE;
3434       location_t loc = gimple_location (stmt);
3435       if (oldlen == NULL_TREE)
3436 	;
3437       else if (integer_zerop (oldlen))
3438 	adj = newlen;
3439       else if (TREE_CODE (oldlen) == INTEGER_CST
3440 	       || TREE_CODE (newlen) == INTEGER_CST)
3441 	adj = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (newlen), newlen,
3442 			       fold_convert_loc (loc, TREE_TYPE (newlen),
3443 						 oldlen));
3444       if (adj != NULL_TREE)
3445 	adjust_related_strinfos (loc, dsi, adj);
3446       else
3447 	dsi->prev = 0;
3448     }
3449   /* memcpy src may not overlap dst, so src doesn't need to be
3450      invalidated either.  */
3451   if (si != NULL)
3452     si->dont_invalidate = true;
3453 
3454   if (full_string_p)
3455     {
3456       lhs = gimple_call_lhs (stmt);
3457       switch (bcode)
3458 	{
3459 	case BUILT_IN_MEMCPY:
3460 	case BUILT_IN_MEMCPY_CHK:
3461 	  /* Allow adjust_last_stmt to decrease this memcpy's size.  */
3462 	  laststmt.stmt = stmt;
3463 	  laststmt.len = dsi->nonzero_chars;
3464 	  laststmt.stridx = dsi->idx;
3465 	  if (lhs)
3466 	    ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
3467 	  break;
3468 	case BUILT_IN_MEMPCPY:
3469 	case BUILT_IN_MEMPCPY_CHK:
3470 	  break;
3471 	default:
3472 	  gcc_unreachable ();
3473 	}
3474     }
3475 }
3476 
3477 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
3478    If strlen of the second argument is known, strlen of the first argument
3479    is increased by the length of the second argument.  Furthermore, attempt
3480    to convert it to memcpy/strcpy if the length of the first argument
3481    is known.  */
3482 
3483 void
handle_builtin_strcat(built_in_function bcode)3484 strlen_pass::handle_builtin_strcat (built_in_function bcode)
3485 {
3486   int idx, didx;
3487   tree srclen, args, type, fn, objsz, endptr;
3488   bool success;
3489   gimple *stmt = gsi_stmt (m_gsi);
3490   strinfo *si, *dsi;
3491   location_t loc = gimple_location (stmt);
3492 
3493   tree src = gimple_call_arg (stmt, 1);
3494   tree dst = gimple_call_arg (stmt, 0);
3495 
3496   /* Bail if the source is the same as destination.  It will be diagnosed
3497      elsewhere.  */
3498   if (operand_equal_p (src, dst, 0))
3499     return;
3500 
3501   tree lhs = gimple_call_lhs (stmt);
3502 
3503   didx = get_stridx (dst, stmt);
3504   if (didx < 0)
3505     return;
3506 
3507   dsi = NULL;
3508   if (didx > 0)
3509     dsi = get_strinfo (didx);
3510 
3511   srclen = NULL_TREE;
3512   si = NULL;
3513   idx = get_stridx (src, stmt);
3514   if (idx < 0)
3515     srclen = build_int_cst (size_type_node, ~idx);
3516   else if (idx > 0)
3517     {
3518       si = get_strinfo (idx);
3519       if (si != NULL)
3520 	srclen = get_string_length (si);
3521     }
3522 
3523   /* Disable warning for the transformed statement?  */
3524   opt_code no_warning_opt = no_warning;
3525 
3526   if (dsi == NULL || get_string_length (dsi) == NULL_TREE)
3527     {
3528       {
3529 	  /* The concatenation always involves copying at least one byte
3530 	     (the terminating nul), even if the source string is empty.
3531 	     If the source is unknown assume it's one character long and
3532 	     used that as both sizes.  */
3533 	tree slen = srclen;
3534 	if (slen)
3535 	  {
3536 	    tree type = TREE_TYPE (slen);
3537 	    slen = fold_build2 (PLUS_EXPR, type, slen, build_int_cst (type, 1));
3538 	  }
3539 
3540 	tree sptr = si && si->ptr ? si->ptr : src;
3541 	no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE,
3542 						  slen);
3543 	if (no_warning_opt)
3544 	  suppress_warning (stmt, no_warning_opt);
3545       }
3546 
3547       /* strcat (p, q) can be transformed into
3548 	 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
3549 	 with length endptr - p if we need to compute the length
3550 	 later on.  Don't do this transformation if we don't need
3551 	 it.  */
3552       if (builtin_decl_implicit_p (BUILT_IN_STPCPY) && lhs == NULL_TREE)
3553 	{
3554 	  if (didx == 0)
3555 	    {
3556 	      didx = new_stridx (dst);
3557 	      if (didx == 0)
3558 		return;
3559 	    }
3560 	  if (dsi == NULL)
3561 	    {
3562 	      dsi = new_strinfo (dst, didx, NULL_TREE, false);
3563 	      set_strinfo (didx, dsi);
3564 	      find_equal_ptrs (dst, didx);
3565 	    }
3566 	  else
3567 	    {
3568 	      dsi = unshare_strinfo (dsi);
3569 	      dsi->nonzero_chars = NULL_TREE;
3570 	      dsi->full_string_p = false;
3571 	      dsi->next = 0;
3572 	      dsi->endptr = NULL_TREE;
3573 	    }
3574 	  dsi->writable = true;
3575 	  dsi->stmt = stmt;
3576 	  dsi->dont_invalidate = true;
3577 	}
3578       return;
3579     }
3580 
3581   tree dstlen = dsi->nonzero_chars;
3582   endptr = dsi->endptr;
3583 
3584   dsi = unshare_strinfo (dsi);
3585   dsi->endptr = NULL_TREE;
3586   dsi->stmt = NULL;
3587   dsi->writable = true;
3588 
3589   if (srclen != NULL_TREE)
3590     {
3591       dsi->nonzero_chars = fold_build2_loc (loc, PLUS_EXPR,
3592 					    TREE_TYPE (dsi->nonzero_chars),
3593 					    dsi->nonzero_chars, srclen);
3594       gcc_assert (dsi->full_string_p);
3595       adjust_related_strinfos (loc, dsi, srclen);
3596       dsi->dont_invalidate = true;
3597     }
3598   else
3599     {
3600       dsi->nonzero_chars = NULL;
3601       dsi->full_string_p = false;
3602       if (lhs == NULL_TREE && builtin_decl_implicit_p (BUILT_IN_STPCPY))
3603 	dsi->dont_invalidate = true;
3604     }
3605 
3606   if (si != NULL)
3607     /* strcat src may not overlap dst, so src doesn't need to be
3608        invalidated either.  */
3609     si->dont_invalidate = true;
3610 
3611   /* For now.  Could remove the lhs from the call and add
3612      lhs = dst; afterwards.  */
3613   if (lhs)
3614     return;
3615 
3616   fn = NULL_TREE;
3617   objsz = NULL_TREE;
3618   switch (bcode)
3619     {
3620     case BUILT_IN_STRCAT:
3621       if (srclen != NULL_TREE)
3622 	fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3623       else
3624 	fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3625       break;
3626     case BUILT_IN_STRCAT_CHK:
3627       if (srclen != NULL_TREE)
3628 	fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3629       else
3630 	fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
3631       objsz = gimple_call_arg (stmt, 2);
3632       break;
3633     default:
3634       gcc_unreachable ();
3635     }
3636 
3637   if (fn == NULL_TREE)
3638     return;
3639 
3640   if (dsi && dstlen)
3641     {
3642       tree type = TREE_TYPE (dstlen);
3643 
3644       /* Compute the size of the source sequence, including the nul.  */
3645       tree srcsize = srclen ? srclen : size_zero_node;
3646       tree one = build_int_cst (type, 1);
3647       srcsize = fold_build2 (PLUS_EXPR, type, srcsize, one);
3648       tree dstsize = fold_build2 (PLUS_EXPR, type, dstlen, one);
3649       tree sptr = si && si->ptr ? si->ptr : src;
3650 
3651       no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, dstsize,
3652 						srcsize);
3653       if (no_warning_opt)
3654 	suppress_warning (stmt, no_warning_opt);
3655     }
3656 
3657   tree len = NULL_TREE;
3658   if (srclen != NULL_TREE)
3659     {
3660       args = TYPE_ARG_TYPES (TREE_TYPE (fn));
3661       type = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
3662 
3663       len = fold_convert_loc (loc, type, unshare_expr (srclen));
3664       len = fold_build2_loc (loc, PLUS_EXPR, type, len,
3665 			     build_int_cst (type, 1));
3666       len = force_gimple_operand_gsi (&m_gsi, len, true, NULL_TREE, true,
3667 				      GSI_SAME_STMT);
3668     }
3669   if (endptr)
3670     dst = fold_convert_loc (loc, TREE_TYPE (dst), unshare_expr (endptr));
3671   else
3672     dst = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dst), dst,
3673 			   fold_convert_loc (loc, sizetype,
3674 					     unshare_expr (dstlen)));
3675   dst = force_gimple_operand_gsi (&m_gsi, dst, true, NULL_TREE, true,
3676 				  GSI_SAME_STMT);
3677   if (objsz)
3678     {
3679       objsz = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (objsz), objsz,
3680 			       fold_convert_loc (loc, TREE_TYPE (objsz),
3681 						 unshare_expr (dstlen)));
3682       objsz = force_gimple_operand_gsi (&m_gsi, objsz, true, NULL_TREE, true,
3683 					GSI_SAME_STMT);
3684     }
3685   if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3686     {
3687       fprintf (dump_file, "Optimizing: ");
3688       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3689     }
3690   if (srclen != NULL_TREE)
3691     success = update_gimple_call (&m_gsi, fn, 3 + (objsz != NULL_TREE),
3692 				  dst, src, len, objsz);
3693   else
3694     success = update_gimple_call (&m_gsi, fn, 2 + (objsz != NULL_TREE),
3695 				  dst, src, objsz);
3696   if (success)
3697     {
3698       stmt = gsi_stmt (m_gsi);
3699       update_stmt (stmt);
3700       if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3701 	{
3702 	  fprintf (dump_file, "into: ");
3703 	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3704 	}
3705       /* If srclen == NULL, note that current string length can be
3706 	 computed by transforming this strcpy into stpcpy.  */
3707       if (srclen == NULL_TREE && dsi->dont_invalidate)
3708 	dsi->stmt = stmt;
3709       adjust_last_stmt (dsi, stmt, true);
3710       if (srclen != NULL_TREE)
3711 	{
3712 	  laststmt.stmt = stmt;
3713 	  laststmt.len = srclen;
3714 	  laststmt.stridx = dsi->idx;
3715 	}
3716     }
3717   else if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3718     fprintf (dump_file, "not possible.\n");
3719 
3720   if (no_warning_opt)
3721     suppress_warning (stmt, no_warning_opt);
3722 }
3723 
3724 /* Handle a call to an allocation function like alloca, malloc or calloc,
3725    or an ordinary allocation function declared with attribute alloc_size.  */
3726 
3727 void
handle_alloc_call(built_in_function bcode)3728 strlen_pass::handle_alloc_call (built_in_function bcode)
3729 {
3730   gimple *stmt = gsi_stmt (m_gsi);
3731   tree lhs = gimple_call_lhs (stmt);
3732   if (lhs == NULL_TREE)
3733     return;
3734 
3735   gcc_assert (get_stridx (lhs, stmt) == 0);
3736   int idx = new_stridx (lhs);
3737   tree length = NULL_TREE;
3738   if (bcode == BUILT_IN_CALLOC)
3739     length = build_int_cst (size_type_node, 0);
3740   strinfo *si = new_strinfo (lhs, idx, length, length != NULL_TREE);
3741   if (bcode == BUILT_IN_CALLOC)
3742     {
3743       /* Only set STMT for calloc and malloc.  */
3744       si->stmt = stmt;
3745       /* Only set ENDPTR for calloc.  */
3746       si->endptr = lhs;
3747     }
3748   else if (bcode == BUILT_IN_MALLOC)
3749     si->stmt = stmt;
3750 
3751   /* Set ALLOC is set for all allocation functions.  */
3752   si->alloc = stmt;
3753   set_strinfo (idx, si);
3754   si->writable = true;
3755   si->dont_invalidate = true;
3756 }
3757 
3758 /* Handle a call to memset.
3759    After a call to calloc, memset(,0,) is unnecessary.
3760    memset(malloc(n),0,n) is calloc(n,1).
3761    return true when the call is transformed, false otherwise.
3762    When nonnull uses RVALS to determine range information.  */
3763 
3764 bool
handle_builtin_memset(bool * zero_write)3765 strlen_pass::handle_builtin_memset (bool *zero_write)
3766 {
3767   gimple *memset_stmt = gsi_stmt (m_gsi);
3768   tree ptr = gimple_call_arg (memset_stmt, 0);
3769   /* Set to the non-constant offset added to PTR.  */
3770   wide_int offrng[2];
3771   int idx1 = get_stridx (ptr, memset_stmt, offrng, ptr_qry.rvals);
3772   if (idx1 <= 0)
3773     return false;
3774   strinfo *si1 = get_strinfo (idx1);
3775   if (!si1)
3776     return false;
3777   gimple *alloc_stmt = si1->alloc;
3778   if (!alloc_stmt || !is_gimple_call (alloc_stmt))
3779     return false;
3780   tree callee1 = gimple_call_fndecl (alloc_stmt);
3781   if (!valid_builtin_call (alloc_stmt))
3782     return false;
3783   tree alloc_size = gimple_call_arg (alloc_stmt, 0);
3784   tree memset_size = gimple_call_arg (memset_stmt, 2);
3785 
3786   /* Check for overflow.  */
3787   maybe_warn_overflow (memset_stmt, false, memset_size, NULL, false, true);
3788 
3789   /* Bail when there is no statement associated with the destination
3790      (the statement may be null even when SI1->ALLOC is not).  */
3791   if (!si1->stmt)
3792     return false;
3793 
3794   /* Avoid optimizing if store is at a variable offset from the beginning
3795      of the allocated object.  */
3796   if (offrng[0] != 0 || offrng[0] != offrng[1])
3797     return false;
3798 
3799   /* Bail when the call writes a non-zero value.  */
3800   if (!integer_zerop (gimple_call_arg (memset_stmt, 1)))
3801     return false;
3802 
3803   /* Let the caller know the memset call cleared the destination.  */
3804   *zero_write = true;
3805 
3806   enum built_in_function code1 = DECL_FUNCTION_CODE (callee1);
3807   if (code1 == BUILT_IN_CALLOC)
3808     /* Not touching alloc_stmt */ ;
3809   else if (code1 == BUILT_IN_MALLOC
3810 	   && operand_equal_p (memset_size, alloc_size, 0))
3811     {
3812       /* Replace the malloc + memset calls with calloc.  */
3813       gimple_stmt_iterator gsi1 = gsi_for_stmt (si1->stmt);
3814       update_gimple_call (&gsi1, builtin_decl_implicit (BUILT_IN_CALLOC), 2,
3815 			  alloc_size, build_one_cst (size_type_node));
3816       si1->nonzero_chars = build_int_cst (size_type_node, 0);
3817       si1->full_string_p = true;
3818       si1->stmt = gsi_stmt (gsi1);
3819     }
3820   else
3821     return false;
3822   tree lhs = gimple_call_lhs (memset_stmt);
3823   unlink_stmt_vdef (memset_stmt);
3824   if (lhs)
3825     {
3826       gimple *assign = gimple_build_assign (lhs, ptr);
3827       gsi_replace (&m_gsi, assign, false);
3828     }
3829   else
3830     {
3831       gsi_remove (&m_gsi, true);
3832       release_defs (memset_stmt);
3833     }
3834 
3835   return true;
3836 }
3837 
3838 /* Return first such statement if RES is used in statements testing its
3839    equality to zero, and null otherwise.  If EXCLUSIVE is true, return
3840    nonnull if and only RES is used in such expressions exclusively and
3841    in none other.  */
3842 
3843 static gimple *
3844 use_in_zero_equality (tree res, bool exclusive = true)
3845 {
3846   gimple *first_use = NULL;
3847 
3848   use_operand_p use_p;
3849   imm_use_iterator iter;
3850 
FOR_EACH_IMM_USE_FAST(use_p,iter,res)3851   FOR_EACH_IMM_USE_FAST (use_p, iter, res)
3852     {
3853       gimple *use_stmt = USE_STMT (use_p);
3854 
3855       if (is_gimple_debug (use_stmt))
3856         continue;
3857 
3858       if (gimple_code (use_stmt) == GIMPLE_ASSIGN)
3859 	{
3860 	  tree_code code = gimple_assign_rhs_code (use_stmt);
3861 	  if (code == COND_EXPR)
3862 	    {
3863 	      tree cond_expr = gimple_assign_rhs1 (use_stmt);
3864 	      if ((TREE_CODE (cond_expr) != EQ_EXPR
3865 		   && (TREE_CODE (cond_expr) != NE_EXPR))
3866 		  || !integer_zerop (TREE_OPERAND (cond_expr, 1)))
3867 		{
3868 		  if (exclusive)
3869 		    return NULL;
3870 		  continue;
3871 		}
3872 	    }
3873 	  else if (code == EQ_EXPR || code == NE_EXPR)
3874 	    {
3875 	      if (!integer_zerop (gimple_assign_rhs2 (use_stmt)))
3876 		{
3877 		  if (exclusive)
3878 		    return NULL;
3879 		  continue;
3880 		}
3881             }
3882 	  else if (exclusive)
3883 	    return NULL;
3884 	  else
3885 	    continue;
3886 	}
3887       else if (gimple_code (use_stmt) == GIMPLE_COND)
3888 	{
3889 	  tree_code code = gimple_cond_code (use_stmt);
3890 	  if ((code != EQ_EXPR && code != NE_EXPR)
3891 	      || !integer_zerop (gimple_cond_rhs (use_stmt)))
3892 	    {
3893 	      if (exclusive)
3894 		return NULL;
3895 	      continue;
3896 	    }
3897 	}
3898       else if (exclusive)
3899 	return NULL;
3900       else
3901 	continue;
3902 
3903       if (!first_use)
3904 	first_use = use_stmt;
3905     }
3906 
3907   return first_use;
3908 }
3909 
3910 /* Handle a call to memcmp.  We try to handle small comparisons by
3911    converting them to load and compare, and replacing the call to memcmp
3912    with a __builtin_memcmp_eq call where possible.
3913    return true when call is transformed, return false otherwise.  */
3914 
3915 bool
handle_builtin_memcmp()3916 strlen_pass::handle_builtin_memcmp ()
3917 {
3918   gcall *stmt = as_a <gcall *> (gsi_stmt (m_gsi));
3919   tree res = gimple_call_lhs (stmt);
3920 
3921   if (!res || !use_in_zero_equality (res))
3922     return false;
3923 
3924   tree arg1 = gimple_call_arg (stmt, 0);
3925   tree arg2 = gimple_call_arg (stmt, 1);
3926   tree len = gimple_call_arg (stmt, 2);
3927   unsigned HOST_WIDE_INT leni;
3928 
3929   if (tree_fits_uhwi_p (len)
3930       && (leni = tree_to_uhwi (len)) <= GET_MODE_SIZE (word_mode)
3931       && pow2p_hwi (leni))
3932     {
3933       leni *= CHAR_TYPE_SIZE;
3934       unsigned align1 = get_pointer_alignment (arg1);
3935       unsigned align2 = get_pointer_alignment (arg2);
3936       unsigned align = MIN (align1, align2);
3937       scalar_int_mode mode;
3938       if (int_mode_for_size (leni, 1).exists (&mode)
3939 	  && (align >= leni || !targetm.slow_unaligned_access (mode, align)))
3940 	{
3941 	  location_t loc = gimple_location (stmt);
3942 	  tree type, off;
3943 	  type = build_nonstandard_integer_type (leni, 1);
3944 	  gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type)), leni));
3945 	  tree ptrtype = build_pointer_type_for_mode (char_type_node,
3946 						      ptr_mode, true);
3947 	  off = build_int_cst (ptrtype, 0);
3948 	  arg1 = build2_loc (loc, MEM_REF, type, arg1, off);
3949 	  arg2 = build2_loc (loc, MEM_REF, type, arg2, off);
3950 	  tree tem1 = fold_const_aggregate_ref (arg1);
3951 	  if (tem1)
3952 	    arg1 = tem1;
3953 	  tree tem2 = fold_const_aggregate_ref (arg2);
3954 	  if (tem2)
3955 	    arg2 = tem2;
3956 	  res = fold_convert_loc (loc, TREE_TYPE (res),
3957 				  fold_build2_loc (loc, NE_EXPR,
3958 						   boolean_type_node,
3959 						   arg1, arg2));
3960 	  gimplify_and_update_call_from_tree (&m_gsi, res);
3961 	  return true;
3962 	}
3963     }
3964 
3965   gimple_call_set_fndecl (stmt, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ));
3966   return true;
3967 }
3968 
3969 /* Given strinfo IDX for ARG, sets LENRNG[] to the range of lengths
3970    of the string(s) referenced by ARG if it can be determined.
3971    If the length cannot be determined, sets *SIZE to the size of
3972    the array the string is stored in, if any.  If no such array is
3973    known, sets *SIZE to -1.  When the strings are nul-terminated sets
3974    *NULTERM to true, otherwise to false.  When nonnull uses RVALS to
3975    determine range information. Returns true on success.  */
3976 
3977 bool
get_len_or_size(gimple * stmt,tree arg,int idx,unsigned HOST_WIDE_INT lenrng[2],unsigned HOST_WIDE_INT * size,bool * nulterm)3978 strlen_pass::get_len_or_size (gimple *stmt, tree arg, int idx,
3979 			      unsigned HOST_WIDE_INT lenrng[2],
3980 			      unsigned HOST_WIDE_INT *size, bool *nulterm)
3981 {
3982   /* Invalidate.  */
3983   *size = HOST_WIDE_INT_M1U;
3984 
3985   if (idx < 0)
3986     {
3987       /* IDX is the inverted constant string length.  */
3988       lenrng[0] = ~idx;
3989       lenrng[1] = lenrng[0];
3990       *nulterm = true;
3991       return true;
3992     }
3993 
3994   /* Set so that both LEN and ~LEN are invalid lengths, i.e., maximum
3995      possible length + 1.  */
3996   lenrng[0] = lenrng[1] = HOST_WIDE_INT_MAX;
3997 
3998   if (strinfo *si = idx ? get_strinfo (idx) : NULL)
3999     {
4000       /* FIXME: Handle all this in_range_strlen_dynamic.  */
4001       if (!si->nonzero_chars)
4002 	;
4003       else if (tree_fits_uhwi_p (si->nonzero_chars))
4004 	{
4005 	  lenrng[0] = tree_to_uhwi (si->nonzero_chars);
4006 	  *nulterm = si->full_string_p;
4007 	  /* Set the upper bound only if the string is known to be
4008 	     nul-terminated, otherwise leave it at maximum + 1.  */
4009 	  if (*nulterm)
4010 	    lenrng[1] = lenrng[0];
4011 	}
4012       else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
4013 	{
4014 	  value_range r;
4015 	  get_range_query (cfun)->range_of_expr (r, si->nonzero_chars);
4016 	  if (r.kind () == VR_RANGE)
4017 	    {
4018 	      lenrng[0] = r.lower_bound ().to_uhwi ();
4019 	      lenrng[1] = r.upper_bound ().to_uhwi ();
4020 	      *nulterm = si->full_string_p;
4021 	    }
4022 	}
4023     }
4024 
4025   if (lenrng[0] != HOST_WIDE_INT_MAX)
4026     return true;
4027 
4028   /* Compute the minimum and maximum real or possible lengths.  */
4029   c_strlen_data lendata = { };
4030   /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
4031      to have it set to the length of the longest string in a PHI.  */
4032   lendata.maxbound = arg;
4033   get_range_strlen_dynamic (arg, stmt, &lendata, ptr_qry.rvals);
4034 
4035   unsigned HOST_WIDE_INT maxbound = HOST_WIDE_INT_M1U;
4036   if (tree_fits_uhwi_p (lendata.maxbound)
4037       && !integer_all_onesp (lendata.maxbound))
4038     maxbound = tree_to_uhwi (lendata.maxbound);
4039 
4040   if (tree_fits_uhwi_p (lendata.minlen) && tree_fits_uhwi_p (lendata.maxlen))
4041     {
4042       unsigned HOST_WIDE_INT minlen = tree_to_uhwi (lendata.minlen);
4043       unsigned HOST_WIDE_INT maxlen = tree_to_uhwi (lendata.maxlen);
4044 
4045       /* The longest string in this data model.  */
4046       const unsigned HOST_WIDE_INT lenmax
4047 	= tree_to_uhwi (max_object_size ()) - 2;
4048 
4049       if (maxbound == HOST_WIDE_INT_M1U)
4050 	{
4051 	  lenrng[0] = minlen;
4052 	  lenrng[1] = maxlen;
4053 	  *nulterm = minlen == maxlen;
4054 	}
4055       else if (maxlen < lenmax)
4056 	{
4057 	  *size = maxbound + 1;
4058 	  *nulterm = false;
4059 	}
4060       else
4061 	return false;
4062 
4063       return true;
4064     }
4065 
4066   if (maxbound != HOST_WIDE_INT_M1U
4067       && lendata.maxlen
4068       && !integer_all_onesp (lendata.maxlen))
4069     {
4070       /* Set *SIZE to LENDATA.MAXBOUND which is a conservative estimate
4071 	 of the longest string based on the sizes of the arrays referenced
4072 	 by ARG.  */
4073       *size = maxbound + 1;
4074       *nulterm = false;
4075       return true;
4076     }
4077 
4078   return false;
4079 }
4080 
4081 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
4082    the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
4083    for a sufficiently large BOUND).  If the result is based on the length
4084    of one string being greater than the longest string that would fit in
4085    the array pointer to by the argument, set *PLEN and *PSIZE to
4086    the corresponding length (or its complement when the string is known
4087    to be at least as long and need not be nul-terminated) and size.
4088    Otherwise return null.  */
4089 
4090 tree
strxcmp_eqz_result(gimple * stmt,tree arg1,int idx1,tree arg2,int idx2,unsigned HOST_WIDE_INT bound,unsigned HOST_WIDE_INT len[2],unsigned HOST_WIDE_INT * psize)4091 strlen_pass::strxcmp_eqz_result (gimple *stmt, tree arg1, int idx1,
4092 				 tree arg2, int idx2,
4093 				 unsigned HOST_WIDE_INT bound,
4094 				 unsigned HOST_WIDE_INT len[2],
4095 				 unsigned HOST_WIDE_INT *psize)
4096 {
4097   /* Determine the range the length of each string is in and whether it's
4098      known to be nul-terminated, or the size of the array it's stored in.  */
4099   bool nul1, nul2;
4100   unsigned HOST_WIDE_INT siz1, siz2;
4101   unsigned HOST_WIDE_INT len1rng[2], len2rng[2];
4102   if (!get_len_or_size (stmt, arg1, idx1, len1rng, &siz1, &nul1)
4103       || !get_len_or_size (stmt, arg2, idx2, len2rng, &siz2, &nul2))
4104     return NULL_TREE;
4105 
4106   /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
4107      to HWI_MAX when invalid.  Adjust the length of each string to consider
4108      to be no more than BOUND.  */
4109   if (len1rng[0] < HOST_WIDE_INT_MAX && len1rng[0] > bound)
4110     len1rng[0] = bound;
4111   if (len1rng[1] < HOST_WIDE_INT_MAX && len1rng[1] > bound)
4112     len1rng[1] = bound;
4113   if (len2rng[0] < HOST_WIDE_INT_MAX && len2rng[0] > bound)
4114     len2rng[0] = bound;
4115   if (len2rng[1] < HOST_WIDE_INT_MAX && len2rng[1] > bound)
4116     len2rng[1] = bound;
4117 
4118   /* Two empty strings are equal.  */
4119   if (len1rng[1] == 0 && len2rng[1] == 0)
4120     return integer_one_node;
4121 
4122   /* The strings are definitely unequal when the lower bound of the length
4123      of one of them is greater than the length of the longest string that
4124      would fit into the other array.  */
4125   if (len1rng[0] == HOST_WIDE_INT_MAX
4126       && len2rng[0] != HOST_WIDE_INT_MAX
4127       && ((len2rng[0] < bound && len2rng[0] >= siz1)
4128 	  || len2rng[0] > siz1))
4129     {
4130       *psize = siz1;
4131       len[0] = len1rng[0];
4132       /* Set LEN[0] to the lower bound of ARG1's length when it's
4133 	 nul-terminated or to the complement of its minimum length
4134 	 otherwise,  */
4135       len[1] = nul2 ? len2rng[0] : ~len2rng[0];
4136       return integer_zero_node;
4137     }
4138 
4139   if (len2rng[0] == HOST_WIDE_INT_MAX
4140       && len1rng[0] != HOST_WIDE_INT_MAX
4141       && ((len1rng[0] < bound && len1rng[0] >= siz2)
4142 	  || len1rng[0] > siz2))
4143     {
4144       *psize = siz2;
4145       len[0] = nul1 ? len1rng[0] : ~len1rng[0];
4146       len[1] = len2rng[0];
4147       return integer_zero_node;
4148     }
4149 
4150   /* The strings are also definitely unequal when their lengths are unequal
4151      and at least one is nul-terminated.  */
4152   if (len1rng[0] != HOST_WIDE_INT_MAX
4153       && len2rng[0] != HOST_WIDE_INT_MAX
4154       && ((len1rng[1] < len2rng[0] && nul1)
4155 	  || (len2rng[1] < len1rng[0] && nul2)))
4156     {
4157       if (bound <= len1rng[0] || bound <= len2rng[0])
4158 	*psize = bound;
4159       else
4160 	*psize = HOST_WIDE_INT_M1U;
4161 
4162       len[0] = len1rng[0];
4163       len[1] = len2rng[0];
4164       return integer_zero_node;
4165     }
4166 
4167   /* The string lengths may be equal or unequal.  Even when equal and
4168      both strings nul-terminated, without the string contents there's
4169      no way to determine whether they are equal.  */
4170   return NULL_TREE;
4171 }
4172 
4173 /* Diagnose pointless calls to strcmp or strncmp STMT with string
4174    arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
4175    whose result is used in equality expressions that evaluate to
4176    a constant due to one argument being longer than the size of
4177    the other.  */
4178 
4179 static void
maybe_warn_pointless_strcmp(gimple * stmt,HOST_WIDE_INT bound,unsigned HOST_WIDE_INT len[2],unsigned HOST_WIDE_INT siz)4180 maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound,
4181 			     unsigned HOST_WIDE_INT len[2],
4182 			     unsigned HOST_WIDE_INT siz)
4183 {
4184   tree lhs = gimple_call_lhs (stmt);
4185   gimple *use = use_in_zero_equality (lhs, /* exclusive = */ false);
4186   if (!use)
4187     return;
4188 
4189   bool at_least = false;
4190 
4191   /* Excessive LEN[i] indicates a lower bound.  */
4192   if (len[0] > HOST_WIDE_INT_MAX)
4193     {
4194       at_least = true;
4195       len[0] = ~len[0];
4196     }
4197 
4198   if (len[1] > HOST_WIDE_INT_MAX)
4199     {
4200       at_least = true;
4201       len[1] = ~len[1];
4202     }
4203 
4204   unsigned HOST_WIDE_INT minlen = MIN (len[0], len[1]);
4205 
4206   /* FIXME: Include a note pointing to the declaration of the smaller
4207      array.  */
4208   location_t stmt_loc = gimple_or_expr_nonartificial_location (stmt, lhs);
4209 
4210   tree callee = gimple_call_fndecl (stmt);
4211   bool warned = false;
4212   if (siz <= minlen && bound == -1)
4213     warned = warning_at (stmt_loc, OPT_Wstring_compare,
4214 			 (at_least
4215 			  ? G_("%qD of a string of length %wu or more and "
4216 			       "an array of size %wu evaluates to nonzero")
4217 			  : G_("%qD of a string of length %wu and an array "
4218 			       "of size %wu evaluates to nonzero")),
4219 			 callee, minlen, siz);
4220   else if (!at_least && siz <= HOST_WIDE_INT_MAX)
4221     {
4222       if (len[0] != HOST_WIDE_INT_MAX && len[1] != HOST_WIDE_INT_MAX)
4223 	warned = warning_at (stmt_loc, OPT_Wstring_compare,
4224 			     "%qD of strings of length %wu and %wu "
4225 			     "and bound of %wu evaluates to nonzero",
4226 			     callee, len[0], len[1], bound);
4227       else
4228 	warned = warning_at (stmt_loc, OPT_Wstring_compare,
4229 			     "%qD of a string of length %wu, an array "
4230 			     "of size %wu and bound of %wu evaluates to "
4231 			     "nonzero",
4232 			     callee, minlen, siz, bound);
4233     }
4234 
4235   if (!warned)
4236     return;
4237 
4238   location_t use_loc = gimple_location (use);
4239   if (LOCATION_LINE (stmt_loc) != LOCATION_LINE (use_loc))
4240     inform (use_loc, "in this expression");
4241 }
4242 
4243 
4244 /* Optimize a call to strcmp or strncmp either by folding it to a constant
4245    when possible or by transforming the latter to the former.  Warn about
4246    calls where the length of one argument is greater than the size of
4247    the array to which the other argument points if the latter's length
4248    is not known.  Return true when the call has been transformed into
4249    another and false otherwise.  */
4250 
4251 bool
handle_builtin_string_cmp()4252 strlen_pass::handle_builtin_string_cmp ()
4253 {
4254   gcall *stmt = as_a <gcall *> (gsi_stmt (m_gsi));
4255   tree lhs = gimple_call_lhs (stmt);
4256 
4257   if (!lhs)
4258     return false;
4259 
4260   tree arg1 = gimple_call_arg (stmt, 0);
4261   tree arg2 = gimple_call_arg (stmt, 1);
4262   int idx1 = get_stridx (arg1, stmt);
4263   int idx2 = get_stridx (arg2, stmt);
4264 
4265   /* For strncmp set to the value of the third argument if known.  */
4266   HOST_WIDE_INT bound = -1;
4267   tree len = NULL_TREE;
4268   /* Extract the strncmp bound.  */
4269   if (gimple_call_num_args (stmt) == 3)
4270     {
4271       len = gimple_call_arg (stmt, 2);
4272       if (tree_fits_shwi_p (len))
4273         bound = tree_to_shwi (len);
4274 
4275       /* If the bound argument is NOT known, do nothing.  */
4276       if (bound < 0)
4277 	return false;
4278     }
4279 
4280   /* Avoid folding if either argument is not a nul-terminated array.
4281      Defer warning until later.  */
4282   if (!check_nul_terminated_array (NULL_TREE, arg1, len)
4283       || !check_nul_terminated_array (NULL_TREE, arg2, len))
4284     return false;
4285 
4286   {
4287     /* Set to the length of one argument (or its complement if it's
4288        the lower bound of a range) and the size of the array storing
4289        the other if the result is based on the former being equal to
4290        or greater than the latter.  */
4291     unsigned HOST_WIDE_INT len[2] = { HOST_WIDE_INT_MAX, HOST_WIDE_INT_MAX };
4292     unsigned HOST_WIDE_INT siz = HOST_WIDE_INT_M1U;
4293 
4294     /* Try to determine if the two strings are either definitely equal
4295        or definitely unequal and if so, either fold the result to zero
4296        (when equal) or set the range of the result to ~[0, 0] otherwise.  */
4297     if (tree eqz = strxcmp_eqz_result (stmt, arg1, idx1, arg2, idx2, bound,
4298 				       len, &siz))
4299       {
4300 	if (integer_zerop (eqz))
4301 	  {
4302 	    maybe_warn_pointless_strcmp (stmt, bound, len, siz);
4303 
4304 	    /* When the lengths of the first two string arguments are
4305 	       known to be unequal set the range of the result to non-zero.
4306 	       This allows the call to be eliminated if its result is only
4307 	       used in tests for equality to zero.  */
4308 	    wide_int zero = wi::zero (TYPE_PRECISION (TREE_TYPE (lhs)));
4309 	    set_range_info (lhs, VR_ANTI_RANGE, zero, zero);
4310 	    return false;
4311 	  }
4312 	/* When the two strings are definitely equal (such as when they
4313 	   are both empty) fold the call to the constant result.  */
4314 	replace_call_with_value (&m_gsi, integer_zero_node);
4315 	return true;
4316       }
4317   }
4318 
4319   /* Return if nothing is known about the strings pointed to by ARG1
4320      and ARG2.  */
4321   if (idx1 == 0 && idx2 == 0)
4322     return false;
4323 
4324   /* Determine either the length or the size of each of the strings,
4325      whichever is available.  */
4326   HOST_WIDE_INT cstlen1 = -1, cstlen2 = -1;
4327   HOST_WIDE_INT arysiz1 = -1, arysiz2 = -1;
4328 
4329   {
4330     unsigned HOST_WIDE_INT len1rng[2], len2rng[2];
4331     unsigned HOST_WIDE_INT arsz1, arsz2;
4332     bool nulterm[2];
4333 
4334     if (!get_len_or_size (stmt, arg1, idx1, len1rng, &arsz1, nulterm)
4335 	|| !get_len_or_size (stmt, arg2, idx2, len2rng, &arsz2, nulterm + 1))
4336       return false;
4337 
4338     if (len1rng[0] == len1rng[1] && len1rng[0] < HOST_WIDE_INT_MAX)
4339       cstlen1 = len1rng[0];
4340     else if (arsz1 < HOST_WIDE_INT_M1U)
4341       arysiz1 = arsz1;
4342 
4343     if (len2rng[0] == len2rng[1] && len2rng[0] < HOST_WIDE_INT_MAX)
4344       cstlen2 = len2rng[0];
4345     else if (arsz2 < HOST_WIDE_INT_M1U)
4346       arysiz2 = arsz2;
4347   }
4348 
4349   /* Bail if neither the string length nor the size of the array
4350      it is stored in can be determined.  */
4351   if ((cstlen1 < 0 && arysiz1 < 0)
4352       || (cstlen2 < 0 && arysiz2 < 0)
4353       || (cstlen1 < 0 && cstlen2 < 0))
4354     return false;
4355 
4356   if (cstlen1 >= 0)
4357     ++cstlen1;
4358   if (cstlen2 >= 0)
4359     ++cstlen2;
4360 
4361   /* The exact number of characters to compare.  */
4362   HOST_WIDE_INT cmpsiz;
4363   if (cstlen1 >= 0 && cstlen2 >= 0)
4364     cmpsiz = MIN (cstlen1, cstlen2);
4365   else if (cstlen1 >= 0)
4366     cmpsiz = cstlen1;
4367   else
4368     cmpsiz = cstlen2;
4369   if (bound >= 0)
4370     cmpsiz = MIN (cmpsiz, bound);
4371   /* The size of the array in which the unknown string is stored.  */
4372   HOST_WIDE_INT varsiz = arysiz1 < 0 ? arysiz2 : arysiz1;
4373 
4374   if ((varsiz < 0 || cmpsiz < varsiz) && use_in_zero_equality (lhs))
4375     {
4376       /* If the known length is less than the size of the other array
4377 	 and the strcmp result is only used to test equality to zero,
4378 	 transform the call to the equivalent _eq call.  */
4379       if (tree fn = builtin_decl_implicit (bound < 0 ? BUILT_IN_STRCMP_EQ
4380 					   : BUILT_IN_STRNCMP_EQ))
4381 	{
4382 	  tree n = build_int_cst (size_type_node, cmpsiz);
4383 	  update_gimple_call (&m_gsi, fn, 3, arg1, arg2, n);
4384 	  return true;
4385 	}
4386     }
4387 
4388   return false;
4389 }
4390 
4391 /* Handle a POINTER_PLUS_EXPR statement.
4392    For p = "abcd" + 2; compute associated length, or if
4393    p = q + off is pointing to a '\0' character of a string, call
4394    zero_length_string on it.  */
4395 
4396 void
handle_pointer_plus()4397 strlen_pass::handle_pointer_plus ()
4398 {
4399   gimple *stmt = gsi_stmt (m_gsi);
4400   tree lhs = gimple_assign_lhs (stmt), off;
4401   int idx = get_stridx (gimple_assign_rhs1 (stmt), stmt);
4402   strinfo *si, *zsi;
4403 
4404   if (idx == 0)
4405     return;
4406 
4407   if (idx < 0)
4408     {
4409       tree off = gimple_assign_rhs2 (stmt);
4410       if (tree_fits_uhwi_p (off)
4411 	  && tree_to_uhwi (off) <= (unsigned HOST_WIDE_INT) ~idx)
4412 	ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)]
4413 	    = ~(~idx - (int) tree_to_uhwi (off));
4414       return;
4415     }
4416 
4417   si = get_strinfo (idx);
4418   if (si == NULL || si->nonzero_chars == NULL_TREE)
4419     return;
4420 
4421   off = gimple_assign_rhs2 (stmt);
4422   zsi = NULL;
4423   if (si->full_string_p && operand_equal_p (si->nonzero_chars, off, 0))
4424     zsi = zero_length_string (lhs, si);
4425   else if (TREE_CODE (off) == SSA_NAME)
4426     {
4427       gimple *def_stmt = SSA_NAME_DEF_STMT (off);
4428       if (gimple_assign_single_p (def_stmt)
4429 	  && si->full_string_p
4430 	  && operand_equal_p (si->nonzero_chars,
4431 			      gimple_assign_rhs1 (def_stmt), 0))
4432 	zsi = zero_length_string (lhs, si);
4433     }
4434   if (zsi != NULL
4435       && si->endptr != NULL_TREE
4436       && si->endptr != lhs
4437       && TREE_CODE (si->endptr) == SSA_NAME)
4438     {
4439       enum tree_code rhs_code
4440 	= useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (si->endptr))
4441 	  ? SSA_NAME : NOP_EXPR;
4442       gimple_assign_set_rhs_with_ops (&m_gsi, rhs_code, si->endptr);
4443       gcc_assert (gsi_stmt (m_gsi) == stmt);
4444       update_stmt (stmt);
4445     }
4446 }
4447 
4448 /* Set LENRANGE to the number of nonzero bytes for a store of TYPE and
4449    clear all flags.  Return true on success and false on failure.  */
4450 
4451 static bool
nonzero_bytes_for_type(tree type,unsigned lenrange[3],bool * nulterm,bool * allnul,bool * allnonnul)4452 nonzero_bytes_for_type (tree type, unsigned lenrange[3],
4453 			bool *nulterm, bool *allnul, bool *allnonnul)
4454 {
4455   /* Use the size of the type of the expression as the size of the store,
4456      and set the upper bound of the length range to that of the size.
4457      Nothing is known about the contents so clear all flags.  */
4458   tree typesize = TYPE_SIZE_UNIT (type);
4459   if (!type)
4460     return false;
4461 
4462   if (!tree_fits_uhwi_p (typesize))
4463     return false;
4464 
4465   unsigned HOST_WIDE_INT sz = tree_to_uhwi (typesize);
4466   if (sz > UINT_MAX)
4467     return false;
4468 
4469   lenrange[2] = sz;
4470   lenrange[1] = lenrange[2] ? lenrange[2] - 1 : 0;
4471   lenrange[0] = 0;
4472   *nulterm = false;
4473   *allnul = false;
4474   *allnonnul = false;
4475   return true;
4476 }
4477 
4478 /* Recursively determine the minimum and maximum number of leading nonzero
4479    bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
4480    to each.
4481    Sets LENRANGE[2] to the total size of the access (which may be less
4482    than LENRANGE[1] when what's being referenced by EXP is a pointer
4483    rather than an array).
4484    Sets *NULTERM if the representation contains a zero byte, sets *ALLNUL
4485    if all the bytes are zero, and *ALLNONNUL is all are nonzero.
4486    OFFSET and NBYTES are the offset into the representation and
4487    the size of the access to it determined from an ADDR_EXPR (i.e.,
4488    a pointer) or MEM_REF or zero for other expressions.
4489    Uses RVALS to determine range information.
4490    Avoids recursing deeper than the limits in SNLIM allow.
4491    Returns true on success and false otherwise.  */
4492 
4493 bool
count_nonzero_bytes(tree exp,gimple * stmt,unsigned HOST_WIDE_INT offset,unsigned HOST_WIDE_INT nbytes,unsigned lenrange[3],bool * nulterm,bool * allnul,bool * allnonnul,ssa_name_limit_t & snlim)4494 strlen_pass::count_nonzero_bytes (tree exp, gimple *stmt,
4495 				  unsigned HOST_WIDE_INT offset,
4496 				  unsigned HOST_WIDE_INT nbytes,
4497 				  unsigned lenrange[3], bool *nulterm,
4498 				  bool *allnul, bool *allnonnul,
4499 				  ssa_name_limit_t &snlim)
4500 {
4501   if (TREE_CODE (exp) == SSA_NAME)
4502     {
4503       /* Handle non-zero single-character stores specially.  */
4504       tree type = TREE_TYPE (exp);
4505       if (TREE_CODE (type) == INTEGER_TYPE
4506 	  && TYPE_MODE (type) == TYPE_MODE (char_type_node)
4507 	  && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node)
4508 	  && tree_expr_nonzero_p (exp))
4509 	{
4510 	  /* If the character EXP is known to be non-zero (even if its
4511 	     exact value is not known) recurse once to set the range
4512 	     for an arbitrary constant.  */
4513 	  exp = build_int_cst (type, 1);
4514 	  return count_nonzero_bytes (exp, stmt,
4515 				      offset, 1, lenrange,
4516 				      nulterm, allnul, allnonnul, snlim);
4517 	}
4518 
4519       gimple *stmt = SSA_NAME_DEF_STMT (exp);
4520       if (gimple_assign_single_p (stmt))
4521 	{
4522 	  exp = gimple_assign_rhs1 (stmt);
4523 	  if (!DECL_P (exp)
4524 	      && TREE_CODE (exp) != CONSTRUCTOR
4525 	      && TREE_CODE (exp) != MEM_REF)
4526 	    return false;
4527 	  /* Handle DECLs, CONSTRUCTOR and MEM_REF below.  */
4528 	}
4529       else if (gimple_code (stmt) == GIMPLE_PHI)
4530 	{
4531 	  /* Avoid processing an SSA_NAME that has already been visited
4532 	     or if an SSA_NAME limit has been reached.  Indicate success
4533 	     if the former and failure if the latter.  */
4534 	  if (int res = snlim.next_phi (exp))
4535 	    return res > 0;
4536 
4537 	  /* Determine the minimum and maximum from the PHI arguments.  */
4538 	  unsigned int n = gimple_phi_num_args (stmt);
4539 	  for (unsigned i = 0; i != n; i++)
4540 	    {
4541 	      tree def = gimple_phi_arg_def (stmt, i);
4542 	      if (!count_nonzero_bytes (def, stmt,
4543 					offset, nbytes, lenrange, nulterm,
4544 					allnul, allnonnul, snlim))
4545 		return false;
4546 	    }
4547 
4548 	  return true;
4549 	}
4550     }
4551 
4552   if (TREE_CODE (exp) == CONSTRUCTOR)
4553     {
4554       if (nbytes)
4555 	/* If NBYTES has already been determined by an outer MEM_REF
4556 	   fail rather than overwriting it (this shouldn't happen).  */
4557 	return false;
4558 
4559       tree type = TREE_TYPE (exp);
4560       tree size = TYPE_SIZE_UNIT (type);
4561       if (!size || !tree_fits_uhwi_p (size))
4562 	return false;
4563 
4564       unsigned HOST_WIDE_INT byte_size = tree_to_uhwi (size);
4565       if (byte_size < offset)
4566 	return false;
4567 
4568       nbytes = byte_size - offset;
4569     }
4570 
4571   if (TREE_CODE (exp) == MEM_REF)
4572     {
4573       if (nbytes)
4574 	return false;
4575 
4576       tree arg = TREE_OPERAND (exp, 0);
4577       tree off = TREE_OPERAND (exp, 1);
4578 
4579       if (TREE_CODE (off) != INTEGER_CST || !tree_fits_uhwi_p (off))
4580 	return false;
4581 
4582       unsigned HOST_WIDE_INT wioff = tree_to_uhwi (off);
4583       if (INT_MAX < wioff)
4584 	return false;
4585 
4586       offset += wioff;
4587       if (INT_MAX < offset)
4588 	return false;
4589 
4590       /* The size of the MEM_REF access determines the number of bytes.  */
4591       tree type = TREE_TYPE (exp);
4592       tree typesize = TYPE_SIZE_UNIT (type);
4593       if (!typesize || !tree_fits_uhwi_p (typesize))
4594 	return false;
4595       nbytes = tree_to_uhwi (typesize);
4596       if (!nbytes)
4597 	return false;
4598 
4599       /* Handle MEM_REF = SSA_NAME types of assignments.  */
4600       return count_nonzero_bytes_addr (arg, stmt,
4601 				       offset, nbytes, lenrange, nulterm,
4602 				       allnul, allnonnul, snlim);
4603     }
4604 
4605   if (VAR_P (exp) || TREE_CODE (exp) == CONST_DECL)
4606     {
4607       /* If EXP can be folded into a constant use the result.  Otherwise
4608 	 proceed to use EXP to determine a range of the result.  */
4609       if (tree fold_exp = ctor_for_folding (exp))
4610 	if (fold_exp != error_mark_node)
4611 	  exp = fold_exp;
4612     }
4613 
4614   const char *prep = NULL;
4615   if (TREE_CODE (exp) == STRING_CST)
4616     {
4617       unsigned nchars = TREE_STRING_LENGTH (exp);
4618       if (nchars < offset)
4619 	return false;
4620 
4621       if (!nbytes)
4622 	/* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
4623 	   (i.e., it's the size of a pointer), or from MEM_REF (as the size
4624 	   of the access), set it here to the size of the string, including
4625 	   all internal and trailing nuls if the string has any.  */
4626 	nbytes = nchars - offset;
4627       else if (nchars - offset < nbytes)
4628 	return false;
4629 
4630       prep = TREE_STRING_POINTER (exp) + offset;
4631     }
4632 
4633   unsigned char buf[256];
4634   if (!prep)
4635     {
4636       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
4637 	return false;
4638       /* If the pointer to representation hasn't been set above
4639 	 for STRING_CST point it at the buffer.  */
4640       prep = reinterpret_cast <char *>(buf);
4641       /* Try to extract the representation of the constant object
4642 	 or expression starting from the offset.  */
4643       unsigned repsize = native_encode_expr (exp, buf, sizeof buf, offset);
4644       if (repsize < nbytes)
4645 	{
4646 	  /* This should only happen when REPSIZE is zero because EXP
4647 	     doesn't denote an object with a known initializer, except
4648 	     perhaps when the reference reads past its end.  */
4649 	  lenrange[0] = 0;
4650 	  prep = NULL;
4651 	}
4652       else if (!nbytes)
4653 	nbytes = repsize;
4654       else if (nbytes < repsize)
4655 	return false;
4656     }
4657 
4658   if (!nbytes)
4659     return nonzero_bytes_for_type (TREE_TYPE (exp), lenrange,
4660 				   nulterm, allnul, allnonnul);
4661 
4662   /* Compute the number of leading nonzero bytes in the representation
4663      and update the minimum and maximum.  */
4664   unsigned n = prep ? strnlen (prep, nbytes) : nbytes;
4665 
4666   if (n < lenrange[0])
4667     lenrange[0] = n;
4668   if (lenrange[1] < n)
4669     lenrange[1] = n;
4670 
4671   /* Set the size of the representation.  */
4672   if (lenrange[2] < nbytes)
4673     lenrange[2] = nbytes;
4674 
4675   /* Clear NULTERM if none of the bytes is zero.  */
4676   if (n == nbytes)
4677     *nulterm = false;
4678 
4679   if (n)
4680     {
4681       /* When the initial number of non-zero bytes N is non-zero, reset
4682 	 *ALLNUL; if N is less than that the size of the representation
4683 	 also clear *ALLNONNUL.  */
4684       *allnul = false;
4685       if (n < nbytes)
4686 	*allnonnul = false;
4687     }
4688   else if (*allnul || *allnonnul)
4689     {
4690       *allnonnul = false;
4691 
4692       if (*allnul)
4693 	{
4694 	  /* When either ALLNUL is set and N is zero, also determine
4695 	     whether all subsequent bytes after the first one (which
4696 	     is nul) are zero or nonzero and clear ALLNUL if not.  */
4697 	  for (const char *p = prep; p != prep + nbytes; ++p)
4698 	    if (*p)
4699 	      {
4700 		*allnul = false;
4701 		break;
4702 	      }
4703 	}
4704     }
4705 
4706   return true;
4707 }
4708 
4709 /* Like count_nonzero_bytes, but instead of counting bytes in EXP, count
4710    bytes that are pointed to by EXP, which should be a pointer.  */
4711 
4712 bool
count_nonzero_bytes_addr(tree exp,gimple * stmt,unsigned HOST_WIDE_INT offset,unsigned HOST_WIDE_INT nbytes,unsigned lenrange[3],bool * nulterm,bool * allnul,bool * allnonnul,ssa_name_limit_t & snlim)4713 strlen_pass::count_nonzero_bytes_addr (tree exp, gimple *stmt,
4714 				       unsigned HOST_WIDE_INT offset,
4715 				       unsigned HOST_WIDE_INT nbytes,
4716 				       unsigned lenrange[3], bool *nulterm,
4717 				       bool *allnul, bool *allnonnul,
4718 				       ssa_name_limit_t &snlim)
4719 {
4720   int idx = get_stridx (exp, stmt);
4721   if (idx > 0)
4722     {
4723       strinfo *si = get_strinfo (idx);
4724       if (!si)
4725 	return false;
4726 
4727       /* Handle both constant lengths as well non-constant lengths
4728 	 in some range.  */
4729       unsigned HOST_WIDE_INT minlen, maxlen;
4730       if (tree_fits_shwi_p (si->nonzero_chars))
4731 	minlen = maxlen = tree_to_shwi (si->nonzero_chars);
4732       else if (si->nonzero_chars
4733 	       && TREE_CODE (si->nonzero_chars) == SSA_NAME)
4734 	{
4735 	  value_range vr;
4736 	  ptr_qry.rvals->range_of_expr (vr, si->nonzero_chars, stmt);
4737 	  if (vr.kind () != VR_RANGE)
4738 	    return false;
4739 
4740 	  minlen = tree_to_uhwi (vr.min ());
4741 	  maxlen = tree_to_uhwi (vr.max ());
4742 	}
4743       else
4744 	return false;
4745 
4746       if (maxlen < offset)
4747 	return false;
4748 
4749       minlen = minlen < offset ? 0 : minlen - offset;
4750       maxlen -= offset;
4751       if (maxlen + 1 < nbytes)
4752 	return false;
4753 
4754       if (nbytes <= minlen)
4755 	*nulterm = false;
4756 
4757       if (nbytes < minlen)
4758 	{
4759 	  minlen = nbytes;
4760 	  if (nbytes < maxlen)
4761 	    maxlen = nbytes;
4762 	}
4763 
4764       if (minlen < lenrange[0])
4765 	lenrange[0] = minlen;
4766       if (lenrange[1] < maxlen)
4767 	lenrange[1] = maxlen;
4768 
4769       if (lenrange[2] < nbytes)
4770 	lenrange[2] = nbytes;
4771 
4772       /* Since only the length of the string are known and not its contents,
4773 	 clear ALLNUL and ALLNONNUL purely on the basis of the length.  */
4774       *allnul = false;
4775       if (minlen < nbytes)
4776 	*allnonnul = false;
4777 
4778       return true;
4779     }
4780 
4781   if (TREE_CODE (exp) == ADDR_EXPR)
4782     return count_nonzero_bytes (TREE_OPERAND (exp, 0), stmt,
4783 				offset, nbytes,
4784 				lenrange, nulterm, allnul, allnonnul, snlim);
4785 
4786   if (TREE_CODE (exp) == SSA_NAME)
4787     {
4788       gimple *stmt = SSA_NAME_DEF_STMT (exp);
4789       if (gimple_code (stmt) == GIMPLE_PHI)
4790 	{
4791 	  /* Avoid processing an SSA_NAME that has already been visited
4792 	     or if an SSA_NAME limit has been reached.  Indicate success
4793 	     if the former and failure if the latter.  */
4794 	  if (int res = snlim.next_phi (exp))
4795 	    return res > 0;
4796 
4797 	  /* Determine the minimum and maximum from the PHI arguments.  */
4798 	  unsigned int n = gimple_phi_num_args (stmt);
4799 	  for (unsigned i = 0; i != n; i++)
4800 	    {
4801 	      tree def = gimple_phi_arg_def (stmt, i);
4802 	      if (!count_nonzero_bytes_addr (def, stmt,
4803 					     offset, nbytes, lenrange,
4804 					     nulterm, allnul, allnonnul,
4805 					     snlim))
4806 		return false;
4807 	    }
4808 
4809 	  return true;
4810 	}
4811     }
4812 
4813   /* Otherwise we don't know anything.  */
4814   lenrange[0] = 0;
4815   if (lenrange[1] < nbytes)
4816     lenrange[1] = nbytes;
4817   if (lenrange[2] < nbytes)
4818     lenrange[2] = nbytes;
4819   *nulterm = false;
4820   *allnul = false;
4821   *allnonnul = false;
4822   return true;
4823 }
4824 
4825 /* Same as above except with an implicit SSA_NAME limit.  When EXPR_OR_TYPE
4826    is a type rather than an expression use its size to compute the range.
4827    RVALS is used to determine ranges of dynamically computed string lengths
4828    (the results of strlen).  */
4829 
4830 bool
count_nonzero_bytes(tree expr_or_type,gimple * stmt,unsigned lenrange[3],bool * nulterm,bool * allnul,bool * allnonnul)4831 strlen_pass::count_nonzero_bytes (tree expr_or_type, gimple *stmt,
4832 				  unsigned lenrange[3], bool *nulterm,
4833 				  bool *allnul, bool *allnonnul)
4834 {
4835   if (TYPE_P (expr_or_type))
4836     return nonzero_bytes_for_type (expr_or_type, lenrange,
4837 				   nulterm, allnul, allnonnul);
4838 
4839   /* Set to optimistic values so the caller doesn't have to worry about
4840      initializing these and to what.  On success, the function will clear
4841      these if it determines their values are different but being recursive
4842      it never sets either to true.  On failure, their values are
4843      unspecified.  */
4844   *nulterm = true;
4845   *allnul = true;
4846   *allnonnul = true;
4847 
4848   ssa_name_limit_t snlim;
4849   tree expr = expr_or_type;
4850   return count_nonzero_bytes (expr, stmt,
4851 			      0, 0, lenrange, nulterm, allnul, allnonnul,
4852 			      snlim);
4853 }
4854 
4855 /* Handle a single or multibyte store other than by a built-in function,
4856    either via a single character assignment or by multi-byte assignment
4857    either via MEM_REF or via a type other than char (such as in
4858    '*(int*)a = 12345').  Return true to let the caller advance *GSI to
4859    the next statement in the basic block and false otherwise.  */
4860 
4861 bool
handle_store(bool * zero_write)4862 strlen_pass::handle_store (bool *zero_write)
4863 {
4864   gimple *stmt = gsi_stmt (m_gsi);
4865   /* The LHS and RHS of the store.  The RHS is null if STMT is a function
4866      call.  STORETYPE is the type of the store (determined from either
4867      the RHS of the assignment statement or the LHS of a function call.  */
4868   tree lhs, rhs, storetype;
4869   if (is_gimple_assign (stmt))
4870     {
4871       lhs = gimple_assign_lhs (stmt);
4872       rhs = gimple_assign_rhs1 (stmt);
4873       storetype = TREE_TYPE (rhs);
4874     }
4875   else if (is_gimple_call (stmt))
4876     {
4877       lhs = gimple_call_lhs (stmt);
4878       rhs = NULL_TREE;
4879       storetype = TREE_TYPE (lhs);
4880     }
4881   else
4882     return true;
4883 
4884   tree ssaname = NULL_TREE;
4885   strinfo *si = NULL;
4886   int idx = -1;
4887 
4888   range_query *const rvals = ptr_qry.rvals;
4889 
4890   /* The offset of the first byte in LHS modified by the store.  */
4891   unsigned HOST_WIDE_INT offset = 0;
4892 
4893   if (TREE_CODE (lhs) == MEM_REF
4894       && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
4895     {
4896       tree mem_offset = TREE_OPERAND (lhs, 1);
4897       if (tree_fits_uhwi_p (mem_offset))
4898 	{
4899 	  /* Get the strinfo for the base, and use it if it starts with at
4900 	     least OFFSET nonzero characters.  This is trivially true if
4901 	     OFFSET is zero.  */
4902 	  offset = tree_to_uhwi (mem_offset);
4903 	  idx = get_stridx (TREE_OPERAND (lhs, 0), stmt);
4904 	  if (idx > 0)
4905 	    si = get_strinfo (idx);
4906 	  if (offset == 0)
4907 	    ssaname = TREE_OPERAND (lhs, 0);
4908 	  else if (si == NULL
4909 		   || compare_nonzero_chars (si, stmt, offset, rvals) < 0)
4910 	    {
4911 	      *zero_write = rhs ? initializer_zerop (rhs) : false;
4912 
4913 	      bool dummy;
4914 	      unsigned lenrange[] = { UINT_MAX, 0, 0 };
4915 	      if (count_nonzero_bytes (rhs ? rhs : storetype, stmt, lenrange,
4916 				       &dummy, &dummy, &dummy))
4917 		maybe_warn_overflow (stmt, true, lenrange[2]);
4918 
4919 	      return true;
4920 	    }
4921 	}
4922     }
4923   else
4924     {
4925       idx = get_addr_stridx (lhs, stmt, NULL_TREE, &offset, rvals);
4926       if (idx > 0)
4927 	si = get_strinfo (idx);
4928     }
4929 
4930   /* Minimum and maximum leading non-zero bytes and the size of the store.  */
4931   unsigned lenrange[] = { UINT_MAX, 0, 0 };
4932 
4933   /* Set to the minimum length of the string being assigned if known.  */
4934   unsigned HOST_WIDE_INT rhs_minlen;
4935 
4936   /* STORING_NONZERO_P is true iff not all stored characters are zero.
4937      STORING_ALL_NONZERO_P is true if all stored characters are zero.
4938      STORING_ALL_ZEROS_P is true iff all stored characters are zero.
4939      Both are false when it's impossible to determine which is true.  */
4940   bool storing_nonzero_p;
4941   bool storing_all_nonzero_p;
4942   bool storing_all_zeros_p;
4943   /* FULL_STRING_P is set when the stored sequence of characters form
4944      a nul-terminated string.  */
4945   bool full_string_p;
4946 
4947   const bool ranges_valid
4948     = count_nonzero_bytes (rhs ? rhs : storetype, stmt,
4949 			   lenrange, &full_string_p,
4950 			   &storing_all_zeros_p, &storing_all_nonzero_p);
4951 
4952   if (ranges_valid)
4953     {
4954       rhs_minlen = lenrange[0];
4955       storing_nonzero_p = lenrange[1] > 0;
4956       *zero_write = storing_all_zeros_p;
4957 
4958       maybe_warn_overflow (stmt, true, lenrange[2]);
4959     }
4960   else
4961     {
4962       rhs_minlen = HOST_WIDE_INT_M1U;
4963       full_string_p = false;
4964       storing_nonzero_p = false;
4965       storing_all_zeros_p = false;
4966       storing_all_nonzero_p = false;
4967     }
4968 
4969   if (si != NULL)
4970     {
4971       /* The corresponding element is set to 1 if the first and last
4972 	 element, respectively, of the sequence of characters being
4973 	 written over the string described by SI ends before
4974 	 the terminating nul (if it has one), to zero if the nul is
4975 	 being overwritten but not beyond, or negative otherwise.  */
4976       int store_before_nul[2];
4977       if (ranges_valid)
4978 	{
4979 	  /* The offset of the last stored byte.  */
4980 	  unsigned HOST_WIDE_INT endoff = offset + lenrange[2] - 1;
4981 	  store_before_nul[0]
4982 	    = compare_nonzero_chars (si, stmt, offset, rvals);
4983 	  if (endoff == offset)
4984 	    store_before_nul[1] = store_before_nul[0];
4985 	  else
4986 	    store_before_nul[1]
4987 	      = compare_nonzero_chars (si, stmt, endoff, rvals);
4988 	}
4989       else
4990 	{
4991 	  store_before_nul[0]
4992 	    = compare_nonzero_chars (si, stmt, offset, rvals);
4993 	  store_before_nul[1] = store_before_nul[0];
4994 	  gcc_assert (offset == 0 || store_before_nul[0] >= 0);
4995 	}
4996 
4997       if (storing_all_zeros_p
4998 	  && store_before_nul[0] == 0
4999 	  && store_before_nul[1] == 0
5000 	  && si->full_string_p)
5001 	{
5002 	  /* When overwriting a '\0' with a '\0', the store can be removed
5003 	     if we know it has been stored in the current function.  */
5004 	  if (!stmt_could_throw_p (cfun, stmt) && si->writable)
5005 	    {
5006 	      unlink_stmt_vdef (stmt);
5007 	      release_defs (stmt);
5008 	      gsi_remove (&m_gsi, true);
5009 	      return false;
5010 	    }
5011 	  else
5012 	    {
5013 	      si->writable = true;
5014 	      gsi_next (&m_gsi);
5015 	      return false;
5016 	    }
5017 	}
5018 
5019       if (store_before_nul[1] > 0
5020 	  && storing_nonzero_p
5021 	  && lenrange[0] == lenrange[1]
5022 	  && lenrange[0] == lenrange[2]
5023 	  && TREE_CODE (storetype) == INTEGER_TYPE)
5024 	{
5025 	  /* Handle a store of one or more non-nul characters that ends
5026 	     before the terminating nul of the destination and so does
5027 	     not affect its length
5028 	     If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
5029 	     and if we aren't storing '\0', we know that the length of
5030 	     the string and any other zero terminated string in memory
5031 	     remains the same.  In that case we move to the next gimple
5032 	     statement and return to signal the caller that it shouldn't
5033 	     invalidate anything.
5034 
5035 	     This is beneficial for cases like:
5036 
5037 	     char p[20];
5038 	     void foo (char *q)
5039 	     {
5040 	       strcpy (p, "foobar");
5041 	       size_t len = strlen (p);     // can be folded to 6
5042 	       size_t len2 = strlen (q);    // has to be computed
5043 	       p[0] = 'X';
5044 	       size_t len3 = strlen (p);    // can be folded to 6
5045 	       size_t len4 = strlen (q);    // can be folded to len2
5046 	       bar (len, len2, len3, len4);
5047 	       } */
5048 	  gsi_next (&m_gsi);
5049 	  return false;
5050 	}
5051 
5052       if (storing_all_zeros_p
5053 	  || storing_nonzero_p
5054 	  || (offset != 0 && store_before_nul[1] > 0))
5055 	{
5056 	  /* When STORING_NONZERO_P, we know that the string will start
5057 	     with at least OFFSET + 1 nonzero characters.  If storing
5058 	     a single character, set si->NONZERO_CHARS to the result.
5059 	     If storing multiple characters, try to determine the number
5060 	     of leading non-zero characters and set si->NONZERO_CHARS to
5061 	     the result instead.
5062 
5063 	     When STORING_ALL_ZEROS_P, we know that the string is now
5064 	     OFFSET characters long.
5065 
5066 	     Otherwise, we're storing an unknown value at offset OFFSET,
5067 	     so need to clip the nonzero_chars to OFFSET.
5068 	     Use the minimum length of the string (or individual character)
5069 	     being stored if it's known.  Otherwise, STORING_NONZERO_P
5070 	     guarantees it's at least 1.  */
5071 	  HOST_WIDE_INT len
5072 	    = storing_nonzero_p && ranges_valid ? lenrange[0] : 1;
5073 	  location_t loc = gimple_location (stmt);
5074 	  tree oldlen = si->nonzero_chars;
5075 	  if (store_before_nul[1] == 0 && si->full_string_p)
5076 	    /* We're overwriting the nul terminator with a nonzero or
5077 	       unknown character.  If the previous stmt was a memcpy,
5078 	       its length may be decreased.  */
5079 	    adjust_last_stmt (si, stmt, false);
5080 	  si = unshare_strinfo (si);
5081 	  if (storing_nonzero_p)
5082 	    {
5083 	      gcc_assert (len >= 0);
5084 	      si->nonzero_chars = build_int_cst (size_type_node, offset + len);
5085 	    }
5086 	  else
5087 	    si->nonzero_chars = build_int_cst (size_type_node, offset);
5088 
5089 	  /* Set FULL_STRING_P only if the length of the strings being
5090 	     written is the same, and clear it if the strings have
5091 	     different lengths.  In the latter case the length stored
5092 	     in si->NONZERO_CHARS becomes the lower bound.
5093 	     FIXME: Handle the upper bound of the length if possible.  */
5094 	  si->full_string_p = full_string_p && lenrange[0] == lenrange[1];
5095 
5096 	  if (storing_all_zeros_p
5097 	      && ssaname
5098 	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname))
5099 	    si->endptr = ssaname;
5100 	  else
5101 	    si->endptr = NULL;
5102 	  si->next = 0;
5103 	  si->stmt = NULL;
5104 	  si->writable = true;
5105 	  si->dont_invalidate = true;
5106 	  if (oldlen)
5107 	    {
5108 	      tree adj = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
5109 					  si->nonzero_chars, oldlen);
5110 	      adjust_related_strinfos (loc, si, adj);
5111 	    }
5112 	  else
5113 	    si->prev = 0;
5114 	}
5115     }
5116   else if (idx == 0 && (storing_all_zeros_p || storing_nonzero_p))
5117     {
5118       if (ssaname)
5119 	idx = new_stridx (ssaname);
5120       else
5121 	idx = new_addr_stridx (lhs);
5122       if (idx != 0)
5123 	{
5124 	  tree ptr = (ssaname ? ssaname : build_fold_addr_expr (lhs));
5125 
5126 	  HOST_WIDE_INT slen;
5127 	  if (storing_all_zeros_p)
5128 	    slen = 0;
5129 	  else if (storing_nonzero_p && ranges_valid)
5130 	    {
5131 	      /* FIXME: Handle the upper bound of the length when
5132 		 LENRANGE[0] != LENRANGE[1].  */
5133 	      slen = lenrange[0];
5134 	      if (lenrange[0] != lenrange[1])
5135 		/* Set the minimum length but ignore the maximum
5136 		   for now.  */
5137 		full_string_p = false;
5138 	    }
5139 	  else
5140 	    slen = -1;
5141 
5142 	  tree len = (slen <= 0
5143 		      ? size_zero_node
5144 		      : build_int_cst (size_type_node, slen));
5145 	  si = new_strinfo (ptr, idx, len, slen >= 0 && full_string_p);
5146 	  set_strinfo (idx, si);
5147 	  if (storing_all_zeros_p
5148 	      && ssaname
5149 	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname))
5150 	    si->endptr = ssaname;
5151 	  si->dont_invalidate = true;
5152 	  si->writable = true;
5153 	}
5154     }
5155   else if (idx == 0
5156 	   && rhs_minlen < HOST_WIDE_INT_M1U
5157 	   && ssaname == NULL_TREE
5158 	   && TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE)
5159     {
5160       HOST_WIDE_INT a = int_size_in_bytes (TREE_TYPE (lhs));
5161       if (a > 0 && (unsigned HOST_WIDE_INT) a > rhs_minlen)
5162 	{
5163 	  int idx = new_addr_stridx (lhs);
5164 	  if (idx != 0)
5165 	    {
5166 	      si = new_strinfo (build_fold_addr_expr (lhs), idx,
5167 				build_int_cst (size_type_node, rhs_minlen),
5168 				full_string_p);
5169 	      set_strinfo (idx, si);
5170 	      si->dont_invalidate = true;
5171 	    }
5172 	}
5173     }
5174 
5175   if (si != NULL && offset == 0 && storing_all_zeros_p && lenrange[2] == 1)
5176     {
5177       /* For single-byte stores only, allow adjust_last_stmt to remove
5178 	 the statement if the stored '\0' is immediately overwritten.  */
5179       laststmt.stmt = stmt;
5180       laststmt.len = build_int_cst (size_type_node, 1);
5181       laststmt.stridx = si->idx;
5182     }
5183   return true;
5184 }
5185 
5186 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0.  */
5187 
5188 static void
fold_strstr_to_strncmp(tree rhs1,tree rhs2,gimple * stmt)5189 fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
5190 {
5191   if (TREE_CODE (rhs1) != SSA_NAME
5192       || TREE_CODE (rhs2) != SSA_NAME)
5193     return;
5194 
5195   gimple *call_stmt = NULL;
5196   for (int pass = 0; pass < 2; pass++)
5197     {
5198       gimple *g = SSA_NAME_DEF_STMT (rhs1);
5199       if (gimple_call_builtin_p (g, BUILT_IN_STRSTR)
5200 	  && has_single_use (rhs1)
5201 	  && gimple_call_arg (g, 0) == rhs2)
5202 	{
5203 	  call_stmt = g;
5204 	  break;
5205 	}
5206       std::swap (rhs1, rhs2);
5207     }
5208 
5209   if (call_stmt)
5210     {
5211       tree arg0 = gimple_call_arg (call_stmt, 0);
5212 
5213       if (arg0 == rhs2)
5214 	{
5215 	  tree arg1 = gimple_call_arg (call_stmt, 1);
5216 	  tree arg1_len = NULL_TREE;
5217 	  int idx = get_stridx (arg1, call_stmt);
5218 
5219 	  if (idx)
5220 	    {
5221 	      if (idx < 0)
5222 		arg1_len = build_int_cst (size_type_node, ~idx);
5223 	      else
5224 		{
5225 		  strinfo *si = get_strinfo (idx);
5226 		  if (si)
5227 		    arg1_len = get_string_length (si);
5228 		}
5229 	    }
5230 
5231 	  if (arg1_len != NULL_TREE)
5232 	    {
5233 	      gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
5234 	      tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
5235 
5236 	      if (!is_gimple_val (arg1_len))
5237 		{
5238 		  tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
5239 		  gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
5240 							    arg1_len);
5241 		  gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT);
5242 		  arg1_len = arg1_len_tmp;
5243 		}
5244 
5245 	      gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
5246 						      arg0, arg1, arg1_len);
5247 	      tree strncmp_lhs = make_ssa_name (integer_type_node);
5248 	      gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
5249 	      gimple_call_set_lhs (strncmp_call, strncmp_lhs);
5250 	      gsi_remove (&gsi, true);
5251 	      gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
5252 	      tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
5253 
5254 	      if (is_gimple_assign (stmt))
5255 		{
5256 		  if (gimple_assign_rhs_code (stmt) == COND_EXPR)
5257 		    {
5258 		      tree cond = gimple_assign_rhs1 (stmt);
5259 		      TREE_OPERAND (cond, 0) = strncmp_lhs;
5260 		      TREE_OPERAND (cond, 1) = zero;
5261 		    }
5262 		  else
5263 		    {
5264 		      gimple_assign_set_rhs1 (stmt, strncmp_lhs);
5265 		      gimple_assign_set_rhs2 (stmt, zero);
5266 		    }
5267 		}
5268 	      else
5269 		{
5270 		  gcond *cond = as_a<gcond *> (stmt);
5271 		  gimple_cond_set_lhs (cond, strncmp_lhs);
5272 		  gimple_cond_set_rhs (cond, zero);
5273 		}
5274 	      update_stmt (stmt);
5275 	    }
5276 	}
5277     }
5278 }
5279 
5280 /* Return true if TYPE corresponds to a narrow character type.  */
5281 
5282 static bool
is_char_type(tree type)5283 is_char_type (tree type)
5284 {
5285   return (TREE_CODE (type) == INTEGER_TYPE
5286 	  && TYPE_MODE (type) == TYPE_MODE (char_type_node)
5287 	  && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node));
5288 }
5289 
5290 /* Check the built-in call at GSI for validity and optimize it.
5291    Uses RVALS to determine range information.
5292    Return true to let the caller advance *GSI to the next statement
5293    in the basic block and false otherwise.  */
5294 
5295 bool
check_and_optimize_call(bool * zero_write)5296 strlen_pass::check_and_optimize_call (bool *zero_write)
5297 {
5298   gimple *stmt = gsi_stmt (m_gsi);
5299 
5300   if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
5301     {
5302       tree fntype = gimple_call_fntype (stmt);
5303       if (!fntype)
5304 	return true;
5305 
5306       if (lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype)))
5307 	{
5308 	  handle_alloc_call (BUILT_IN_NONE);
5309 	  return true;
5310 	}
5311 
5312       if (tree lhs = gimple_call_lhs (stmt))
5313 	handle_assign (lhs, zero_write);
5314 
5315       /* Proceed to handle user-defined formatting functions.  */
5316     }
5317 
5318   /* When not optimizing we must be checking printf calls which
5319      we do even for user-defined functions when they are declared
5320      with attribute format.  */
5321   if (!flag_optimize_strlen
5322       || !strlen_optimize
5323       || !valid_builtin_call (stmt))
5324     return !handle_printf_call (&m_gsi, ptr_qry);
5325 
5326   tree callee = gimple_call_fndecl (stmt);
5327   switch (DECL_FUNCTION_CODE (callee))
5328     {
5329     case BUILT_IN_STRLEN:
5330     case BUILT_IN_STRNLEN:
5331       handle_builtin_strlen ();
5332       break;
5333     case BUILT_IN_STRCHR:
5334       handle_builtin_strchr ();
5335       break;
5336     case BUILT_IN_STRCPY:
5337     case BUILT_IN_STRCPY_CHK:
5338     case BUILT_IN_STPCPY:
5339     case BUILT_IN_STPCPY_CHK:
5340       handle_builtin_strcpy (DECL_FUNCTION_CODE (callee));
5341       break;
5342 
5343     case BUILT_IN_STRNCAT:
5344     case BUILT_IN_STRNCAT_CHK:
5345       handle_builtin_strncat (DECL_FUNCTION_CODE (callee));
5346       break;
5347 
5348     case BUILT_IN_STPNCPY:
5349     case BUILT_IN_STPNCPY_CHK:
5350     case BUILT_IN_STRNCPY:
5351     case BUILT_IN_STRNCPY_CHK:
5352       handle_builtin_stxncpy_strncat (false);
5353       break;
5354 
5355     case BUILT_IN_MEMCPY:
5356     case BUILT_IN_MEMCPY_CHK:
5357     case BUILT_IN_MEMPCPY:
5358     case BUILT_IN_MEMPCPY_CHK:
5359       handle_builtin_memcpy (DECL_FUNCTION_CODE (callee));
5360       break;
5361     case BUILT_IN_STRCAT:
5362     case BUILT_IN_STRCAT_CHK:
5363       handle_builtin_strcat (DECL_FUNCTION_CODE (callee));
5364       break;
5365     case BUILT_IN_ALLOCA:
5366     case BUILT_IN_ALLOCA_WITH_ALIGN:
5367     case BUILT_IN_MALLOC:
5368     case BUILT_IN_CALLOC:
5369       handle_alloc_call (DECL_FUNCTION_CODE (callee));
5370       break;
5371     case BUILT_IN_MEMSET:
5372       if (handle_builtin_memset (zero_write))
5373 	return false;
5374       break;
5375     case BUILT_IN_MEMCMP:
5376       if (handle_builtin_memcmp ())
5377 	return false;
5378       break;
5379     case BUILT_IN_STRCMP:
5380     case BUILT_IN_STRNCMP:
5381       if (handle_builtin_string_cmp ())
5382 	return false;
5383       break;
5384     default:
5385       if (handle_printf_call (&m_gsi, ptr_qry))
5386 	return false;
5387       break;
5388     }
5389 
5390   return true;
5391 }
5392 
5393 /* Handle an assignment statement at *GSI to a LHS of integral type.
5394    If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true.  */
5395 
5396 void
handle_integral_assign(bool * cleanup_eh)5397 strlen_pass::handle_integral_assign (bool *cleanup_eh)
5398 {
5399   gimple *stmt = gsi_stmt (m_gsi);
5400   tree lhs = gimple_assign_lhs (stmt);
5401   tree lhs_type = TREE_TYPE (lhs);
5402 
5403   enum tree_code code = gimple_assign_rhs_code (stmt);
5404   if (code == COND_EXPR)
5405     {
5406       tree cond = gimple_assign_rhs1 (stmt);
5407       enum tree_code cond_code = TREE_CODE (cond);
5408 
5409       if (cond_code == EQ_EXPR || cond_code == NE_EXPR)
5410 	fold_strstr_to_strncmp (TREE_OPERAND (cond, 0),
5411 				TREE_OPERAND (cond, 1), stmt);
5412     }
5413   else if (code == EQ_EXPR || code == NE_EXPR)
5414     fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt),
5415 			    gimple_assign_rhs2 (stmt), stmt);
5416   else if (gimple_assign_load_p (stmt)
5417 	   && TREE_CODE (lhs_type) == INTEGER_TYPE
5418 	   && TYPE_MODE (lhs_type) == TYPE_MODE (char_type_node)
5419 	   && (TYPE_PRECISION (lhs_type)
5420 	       == TYPE_PRECISION (char_type_node))
5421 	   && !gimple_has_volatile_ops (stmt))
5422     {
5423       tree off = integer_zero_node;
5424       unsigned HOST_WIDE_INT coff = 0;
5425       int idx = 0;
5426       tree rhs1 = gimple_assign_rhs1 (stmt);
5427       if (code == MEM_REF)
5428 	{
5429 	  idx = get_stridx (TREE_OPERAND (rhs1, 0), stmt);
5430 	  if (idx > 0)
5431 	    {
5432 	      strinfo *si = get_strinfo (idx);
5433 	      if (si
5434 		  && si->nonzero_chars
5435 		  && TREE_CODE (si->nonzero_chars) == INTEGER_CST
5436 		  && (wi::to_widest (si->nonzero_chars)
5437 		      >= wi::to_widest (off)))
5438 		off = TREE_OPERAND (rhs1, 1);
5439 	      else
5440 		/* This case is not useful.  See if get_addr_stridx
5441 		   returns something usable.  */
5442 		idx = 0;
5443 	    }
5444 	}
5445       if (idx <= 0)
5446 	idx = get_addr_stridx (rhs1, stmt, NULL_TREE, &coff);
5447       if (idx > 0)
5448 	{
5449 	  strinfo *si = get_strinfo (idx);
5450 	  if (si
5451 	      && si->nonzero_chars
5452 	      && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
5453 	    {
5454 	      widest_int w1 = wi::to_widest (si->nonzero_chars);
5455 	      widest_int w2 = wi::to_widest (off) + coff;
5456 	      if (w1 == w2
5457 		  && si->full_string_p)
5458 		{
5459 		  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
5460 		    {
5461 		      fprintf (dump_file, "Optimizing: ");
5462 		      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
5463 		    }
5464 
5465 		  /* Reading the final '\0' character.  */
5466 		  tree zero = build_int_cst (lhs_type, 0);
5467 		  gimple_set_vuse (stmt, NULL_TREE);
5468 		  gimple_assign_set_rhs_from_tree (&m_gsi, zero);
5469 		  *cleanup_eh
5470 		    |= maybe_clean_or_replace_eh_stmt (stmt,
5471 						       gsi_stmt (m_gsi));
5472 		  stmt = gsi_stmt (m_gsi);
5473 		  update_stmt (stmt);
5474 
5475 		  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
5476 		    {
5477 		      fprintf (dump_file, "into: ");
5478 		      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
5479 		    }
5480 		}
5481 	      else if (w1 > w2)
5482 		{
5483 		  /* Reading a character before the final '\0'
5484 		     character.  Just set the value range to ~[0, 0]
5485 		     if we don't have anything better.  */
5486 		  value_range r;
5487 		  if (!get_range_query (cfun)->range_of_expr (r, lhs)
5488 		      || r.varying_p ())
5489 		    {
5490 		      r.set_nonzero (lhs_type);
5491 		      set_range_info (lhs, r);
5492 		    }
5493 		}
5494 	    }
5495 	}
5496     }
5497   else if (code == MEM_REF && TREE_CODE (lhs) == SSA_NAME)
5498     {
5499       if (int idx = new_stridx (lhs))
5500 	{
5501 	  /* Record multi-byte assignments from MEM_REFs.  */
5502 	  bool storing_all_nonzero_p;
5503 	  bool storing_all_zeros_p;
5504 	  bool full_string_p;
5505 	  unsigned lenrange[] = { UINT_MAX, 0, 0 };
5506 	  tree rhs = gimple_assign_rhs1 (stmt);
5507 	  const bool ranges_valid
5508 	    = count_nonzero_bytes (rhs, stmt,
5509 				   lenrange, &full_string_p,
5510 				   &storing_all_zeros_p,
5511 				   &storing_all_nonzero_p);
5512 	  if (ranges_valid)
5513 	    {
5514 	      tree length = build_int_cst (sizetype, lenrange[0]);
5515 	      strinfo *si = new_strinfo (lhs, idx, length, full_string_p);
5516 	      set_strinfo (idx, si);
5517 	      si->writable = true;
5518 	      si->dont_invalidate = true;
5519 	    }
5520 	}
5521     }
5522 
5523   if (strlen_to_stridx)
5524     {
5525       tree rhs1 = gimple_assign_rhs1 (stmt);
5526       if (stridx_strlenloc *ps = strlen_to_stridx->get (rhs1))
5527 	strlen_to_stridx->put (lhs, stridx_strlenloc (*ps));
5528     }
5529 }
5530 
5531 /* Handle assignment statement at *GSI to LHS.  Set *ZERO_WRITE if
5532    the assignent stores all zero bytes..  */
5533 
5534 bool
handle_assign(tree lhs,bool * zero_write)5535 strlen_pass::handle_assign (tree lhs, bool *zero_write)
5536 {
5537   tree type = TREE_TYPE (lhs);
5538   if (TREE_CODE (type) == ARRAY_TYPE)
5539     type = TREE_TYPE (type);
5540 
5541   bool is_char_store = is_char_type (type);
5542   if (!is_char_store && TREE_CODE (lhs) == MEM_REF)
5543     {
5544       /* To consider stores into char objects via integer types other
5545 	 than char but not those to non-character objects, determine
5546 	 the type of the destination rather than just the type of
5547 	 the access.  */
5548       for (int i = 0; i != 2; ++i)
5549 	{
5550 	  tree ref = TREE_OPERAND (lhs, i);
5551 	  type = TREE_TYPE (ref);
5552 	  if (TREE_CODE (type) == POINTER_TYPE)
5553 	    type = TREE_TYPE (type);
5554 	  if (TREE_CODE (type) == ARRAY_TYPE)
5555 	    type = TREE_TYPE (type);
5556 	  if (is_char_type (type))
5557 	    {
5558 	      is_char_store = true;
5559 	      break;
5560 	    }
5561 	}
5562     }
5563 
5564   /* Handle a single or multibyte assignment.  */
5565   if (is_char_store && !handle_store (zero_write))
5566     return false;
5567 
5568   return true;
5569 }
5570 
5571 
5572 /* Attempt to check for validity of the performed access a single statement
5573    at *GSI using string length knowledge, and to optimize it.
5574    If the given basic block needs clean-up of EH, CLEANUP_EH is set to
5575    true.  Return true to let the caller advance *GSI to the next statement
5576    in the basic block and false otherwise.  */
5577 
5578 bool
check_and_optimize_stmt(bool * cleanup_eh)5579 strlen_pass::check_and_optimize_stmt (bool *cleanup_eh)
5580 {
5581   gimple *stmt = gsi_stmt (m_gsi);
5582 
5583   /* For statements that modify a string, set to true if the write
5584      is only zeros.  */
5585   bool zero_write = false;
5586 
5587   if (is_gimple_call (stmt))
5588     {
5589       if (!check_and_optimize_call (&zero_write))
5590 	return false;
5591     }
5592   else if (!flag_optimize_strlen || !strlen_optimize)
5593     return true;
5594   else if (is_gimple_assign (stmt) && !gimple_clobber_p (stmt))
5595     {
5596       /* Handle non-clobbering assignment.  */
5597       tree lhs = gimple_assign_lhs (stmt);
5598       tree lhs_type = TREE_TYPE (lhs);
5599 
5600       if (TREE_CODE (lhs) == SSA_NAME && POINTER_TYPE_P (lhs_type))
5601 	{
5602 	  if (gimple_assign_single_p (stmt)
5603 	      || (gimple_assign_cast_p (stmt)
5604 		  && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
5605 	    {
5606 	      int idx = get_stridx (gimple_assign_rhs1 (stmt), stmt);
5607 	      ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = idx;
5608 	    }
5609 	  else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
5610 	    handle_pointer_plus ();
5611 	}
5612       else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (lhs_type))
5613 	/* Handle assignment to a character.  */
5614 	handle_integral_assign (cleanup_eh);
5615       else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
5616 	if (!handle_assign (lhs, &zero_write))
5617 	  return false;
5618     }
5619   else if (gcond *cond = dyn_cast<gcond *> (stmt))
5620     {
5621       enum tree_code code = gimple_cond_code (cond);
5622       if (code == EQ_EXPR || code == NE_EXPR)
5623 	fold_strstr_to_strncmp (gimple_cond_lhs (stmt),
5624 				gimple_cond_rhs (stmt), stmt);
5625     }
5626 
5627   if (gimple_vdef (stmt))
5628     maybe_invalidate (stmt, zero_write);
5629   return true;
5630 }
5631 
5632 /* Recursively call maybe_invalidate on stmts that might be executed
5633    in between dombb and current bb and that contain a vdef.  Stop when
5634    *count stmts are inspected, or if the whole strinfo vector has
5635    been invalidated.  */
5636 
5637 static void
do_invalidate(basic_block dombb,gimple * phi,bitmap visited,int * count)5638 do_invalidate (basic_block dombb, gimple *phi, bitmap visited, int *count)
5639 {
5640   unsigned int i, n = gimple_phi_num_args (phi);
5641 
5642   for (i = 0; i < n; i++)
5643     {
5644       tree vuse = gimple_phi_arg_def (phi, i);
5645       gimple *stmt = SSA_NAME_DEF_STMT (vuse);
5646       basic_block bb = gimple_bb (stmt);
5647       if (bb == NULL
5648 	  || bb == dombb
5649 	  || !bitmap_set_bit (visited, bb->index)
5650 	  || !dominated_by_p (CDI_DOMINATORS, bb, dombb))
5651 	continue;
5652       while (1)
5653 	{
5654 	  if (gimple_code (stmt) == GIMPLE_PHI)
5655 	    {
5656 	      do_invalidate (dombb, stmt, visited, count);
5657 	      if (*count == 0)
5658 		return;
5659 	      break;
5660 	    }
5661 	  if (--*count == 0)
5662 	    return;
5663 	  if (!maybe_invalidate (stmt))
5664 	    {
5665 	      *count = 0;
5666 	      return;
5667 	    }
5668 	  vuse = gimple_vuse (stmt);
5669 	  stmt = SSA_NAME_DEF_STMT (vuse);
5670 	  if (gimple_bb (stmt) != bb)
5671 	    {
5672 	      bb = gimple_bb (stmt);
5673 	      if (bb == NULL
5674 		  || bb == dombb
5675 		  || !bitmap_set_bit (visited, bb->index)
5676 		  || !dominated_by_p (CDI_DOMINATORS, bb, dombb))
5677 		break;
5678 	    }
5679 	}
5680     }
5681 }
5682 
5683 /* Release pointer_query cache.  */
5684 
~strlen_pass()5685 strlen_pass::~strlen_pass ()
5686 {
5687   ptr_qry.flush_cache ();
5688 }
5689 
5690 /* Callback for walk_dominator_tree.  Attempt to optimize various
5691    string ops by remembering string lengths pointed by pointer SSA_NAMEs.  */
5692 
5693 edge
before_dom_children(basic_block bb)5694 strlen_pass::before_dom_children (basic_block bb)
5695 {
5696   basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
5697 
5698   if (dombb == NULL)
5699     stridx_to_strinfo = NULL;
5700   else
5701     {
5702       stridx_to_strinfo = ((vec<strinfo *, va_heap, vl_embed> *) dombb->aux);
5703       if (stridx_to_strinfo)
5704 	{
5705 	  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
5706 	       gsi_next (&gsi))
5707 	    {
5708 	      gphi *phi = gsi.phi ();
5709 	      if (virtual_operand_p (gimple_phi_result (phi)))
5710 		{
5711 		  bitmap visited = BITMAP_ALLOC (NULL);
5712 		  int count_vdef = 100;
5713 		  do_invalidate (dombb, phi, visited, &count_vdef);
5714 		  BITMAP_FREE (visited);
5715 		  if (count_vdef == 0)
5716 		    {
5717 		      /* If there were too many vdefs in between immediate
5718 			 dominator and current bb, invalidate everything.
5719 			 If stridx_to_strinfo has been unshared, we need
5720 			 to free it, otherwise just set it to NULL.  */
5721 		      if (!strinfo_shared ())
5722 			{
5723 			  unsigned int i;
5724 			  strinfo *si;
5725 
5726 			  for (i = 1;
5727 			       vec_safe_iterate (stridx_to_strinfo, i, &si);
5728 			       ++i)
5729 			    {
5730 			      free_strinfo (si);
5731 			      (*stridx_to_strinfo)[i] = NULL;
5732 			    }
5733 			}
5734 		      else
5735 			stridx_to_strinfo = NULL;
5736 		    }
5737 		  break;
5738 		}
5739 	    }
5740 	}
5741     }
5742 
5743   /* If all PHI arguments have the same string index, the PHI result
5744      has it as well.  */
5745   for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
5746        gsi_next (&gsi))
5747     {
5748       gphi *phi = gsi.phi ();
5749       tree result = gimple_phi_result (phi);
5750       if (!virtual_operand_p (result) && POINTER_TYPE_P (TREE_TYPE (result)))
5751 	{
5752 	  int idx = get_stridx (gimple_phi_arg_def (phi, 0), phi);
5753 	  if (idx != 0)
5754 	    {
5755 	      unsigned int i, n = gimple_phi_num_args (phi);
5756 	      for (i = 1; i < n; i++)
5757 		if (idx != get_stridx (gimple_phi_arg_def (phi, i), phi))
5758 		  break;
5759 	      if (i == n)
5760 		ssa_ver_to_stridx[SSA_NAME_VERSION (result)] = idx;
5761 	    }
5762 	}
5763     }
5764 
5765   bool cleanup_eh = false;
5766 
5767   /* Attempt to optimize individual statements.  */
5768   for (m_gsi = gsi_start_bb (bb); !gsi_end_p (m_gsi); )
5769     {
5770       /* Reset search depth preformance counter.  */
5771       ptr_qry.depth = 0;
5772 
5773       if (check_and_optimize_stmt (&cleanup_eh))
5774 	gsi_next (&m_gsi);
5775     }
5776 
5777   if (cleanup_eh && gimple_purge_dead_eh_edges (bb))
5778       m_cleanup_cfg = true;
5779 
5780   bb->aux = stridx_to_strinfo;
5781   if (vec_safe_length (stridx_to_strinfo) && !strinfo_shared ())
5782     (*stridx_to_strinfo)[0] = (strinfo *) bb;
5783   return NULL;
5784 }
5785 
5786 /* Callback for walk_dominator_tree.  Free strinfo vector if it is
5787    owned by the current bb, clear bb->aux.  */
5788 
5789 void
after_dom_children(basic_block bb)5790 strlen_pass::after_dom_children (basic_block bb)
5791 {
5792   if (bb->aux)
5793     {
5794       stridx_to_strinfo = ((vec<strinfo *, va_heap, vl_embed> *) bb->aux);
5795       if (vec_safe_length (stridx_to_strinfo)
5796 	  && (*stridx_to_strinfo)[0] == (strinfo *) bb)
5797 	{
5798 	  unsigned int i;
5799 	  strinfo *si;
5800 
5801 	  for (i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
5802 	    free_strinfo (si);
5803 	  vec_free (stridx_to_strinfo);
5804 	}
5805       bb->aux = NULL;
5806     }
5807 }
5808 
5809 namespace {
5810 
5811 static unsigned int
printf_strlen_execute(function * fun,bool warn_only)5812 printf_strlen_execute (function *fun, bool warn_only)
5813 {
5814   strlen_optimize = !warn_only;
5815 
5816   calculate_dominance_info (CDI_DOMINATORS);
5817 
5818   bool use_scev = optimize > 0 && flag_printf_return_value;
5819   if (use_scev)
5820     {
5821       loop_optimizer_init (LOOPS_NORMAL);
5822       scev_initialize ();
5823     }
5824 
5825   gcc_assert (!strlen_to_stridx);
5826   if (warn_stringop_overflow || warn_stringop_truncation)
5827     strlen_to_stridx = new hash_map<tree, stridx_strlenloc> ();
5828 
5829   /* This has to happen after initializing the loop optimizer
5830      and initializing SCEV as they create new SSA_NAMEs.  */
5831   ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
5832   max_stridx = 1;
5833 
5834   /* String length optimization is implemented as a walk of the dominator
5835      tree and a forward walk of statements within each block.  */
5836   strlen_pass walker (CDI_DOMINATORS);
5837   walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
5838 
5839   if (dump_file && (dump_flags & TDF_DETAILS))
5840     walker.ptr_qry.dump (dump_file, true);
5841 
5842   ssa_ver_to_stridx.release ();
5843   strinfo_pool.release ();
5844   if (decl_to_stridxlist_htab)
5845     {
5846       obstack_free (&stridx_obstack, NULL);
5847       delete decl_to_stridxlist_htab;
5848       decl_to_stridxlist_htab = NULL;
5849     }
5850   laststmt.stmt = NULL;
5851   laststmt.len = NULL_TREE;
5852   laststmt.stridx = 0;
5853 
5854   if (strlen_to_stridx)
5855     {
5856       strlen_to_stridx->empty ();
5857       delete strlen_to_stridx;
5858       strlen_to_stridx = NULL;
5859     }
5860 
5861   if (use_scev)
5862     {
5863       scev_finalize ();
5864       loop_optimizer_finalize ();
5865     }
5866 
5867   return walker.m_cleanup_cfg ? TODO_cleanup_cfg : 0;
5868 }
5869 
5870 /* This file defines two passes: one for warnings that runs only when
5871    optimization is disabled, and another that implements optimizations
5872    and also issues warnings.  */
5873 
5874 const pass_data pass_data_warn_printf =
5875 {
5876   GIMPLE_PASS, /* type */
5877   "warn-printf", /* name */
5878   OPTGROUP_NONE, /* optinfo_flags */
5879   TV_NONE, /* tv_id */
5880   /* Normally an optimization pass would require PROP_ssa but because
5881      this pass runs early, with no optimization, to do sprintf format
5882      checking, it only requires PROP_cfg.  */
5883   PROP_cfg, /* properties_required */
5884   0, /* properties_provided */
5885   0, /* properties_destroyed */
5886   0, /* todo_flags_start */
5887   0, /* todo_flags_finish */
5888 };
5889 
5890 class pass_warn_printf : public gimple_opt_pass
5891 {
5892 public:
pass_warn_printf(gcc::context * ctxt)5893   pass_warn_printf (gcc::context *ctxt)
5894     : gimple_opt_pass (pass_data_warn_printf, ctxt)
5895   {}
5896 
5897   virtual bool gate (function *);
execute(function * fun)5898   virtual unsigned int execute (function *fun)
5899   {
5900     return printf_strlen_execute (fun, true);
5901   }
5902 };
5903 
5904 
5905 /* Return true to run the warning pass only when not optimizing and
5906    iff either -Wformat-overflow or -Wformat-truncation is specified.  */
5907 
5908 bool
gate(function *)5909 pass_warn_printf::gate (function *)
5910 {
5911   return !optimize && (warn_format_overflow > 0 || warn_format_trunc > 0);
5912 }
5913 
5914 const pass_data pass_data_strlen =
5915 {
5916   GIMPLE_PASS, /* type */
5917   "strlen", /* name */
5918   OPTGROUP_NONE, /* optinfo_flags */
5919   TV_TREE_STRLEN, /* tv_id */
5920   PROP_cfg | PROP_ssa, /* properties_required */
5921   0, /* properties_provided */
5922   0, /* properties_destroyed */
5923   0, /* todo_flags_start */
5924   0, /* todo_flags_finish */
5925 };
5926 
5927 class pass_strlen : public gimple_opt_pass
5928 {
5929 public:
pass_strlen(gcc::context * ctxt)5930   pass_strlen (gcc::context *ctxt)
5931     : gimple_opt_pass (pass_data_strlen, ctxt)
5932   {}
5933 
clone()5934   opt_pass * clone () { return new pass_strlen (m_ctxt); }
5935 
5936   virtual bool gate (function *);
execute(function * fun)5937   virtual unsigned int execute (function *fun)
5938   {
5939     return printf_strlen_execute (fun, false);
5940   }
5941 };
5942 
5943 /* Return true to run the pass only when the sprintf and/or strlen
5944    optimizations are enabled and -Wformat-overflow or -Wformat-truncation
5945    are specified.  */
5946 
5947 bool
gate(function *)5948 pass_strlen::gate (function *)
5949 {
5950   return ((warn_format_overflow > 0
5951 	   || warn_format_trunc > 0
5952 	   || warn_restrict > 0
5953 	   || flag_optimize_strlen > 0
5954 	   || flag_printf_return_value)
5955 	  && optimize > 0);
5956 }
5957 
5958 } // anon namespace
5959 
5960 gimple_opt_pass *
make_pass_warn_printf(gcc::context * ctxt)5961 make_pass_warn_printf (gcc::context *ctxt)
5962 {
5963   return new pass_warn_printf (ctxt);
5964 }
5965 
5966 gimple_opt_pass *
make_pass_strlen(gcc::context * ctxt)5967 make_pass_strlen (gcc::context *ctxt)
5968 {
5969   return new pass_strlen (ctxt);
5970 }
5971