Fix previous commit
[official-gcc.git] / gcc / tree-ssa-strlen.c
blobef2717d6a29e230c3907e68960fb465be93100e0
1 /* String length optimization
2 Copyright (C) 2011-2019 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
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.
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.
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/>. */
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-restrict.h"
34 #include "fold-const.h"
35 #include "stor-layout.h"
36 #include "gimple-fold.h"
37 #include "tree-eh.h"
38 #include "gimplify.h"
39 #include "gimple-iterator.h"
40 #include "gimplify-me.h"
41 #include "expr.h"
42 #include "tree-cfg.h"
43 #include "tree-dfa.h"
44 #include "domwalk.h"
45 #include "tree-ssa-alias.h"
46 #include "tree-ssa-propagate.h"
47 #include "tree-ssa-strlen.h"
48 #include "params.h"
49 #include "tree-hash-traits.h"
50 #include "tree-object-size.h"
51 #include "builtins.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"
62 #include "vr-values.h"
63 #include "gimple-ssa-evrp-analyze.h"
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;
70 /* Number of currently active string indexes plus one. */
71 static int max_stridx;
73 /* Set to true to optimize, false when just checking. */
74 static bool strlen_optimize;
76 /* String information record. */
77 struct strinfo
79 /* Number of leading characters that are known to be nonzero. This is
80 also the length of the string if FULL_STRING_P.
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 /* This is used for two things:
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.
94 - To record the malloc or calloc call that produced this result. */
95 gimple *stmt;
96 /* Pointer to '\0' if known, if NULL, it can be computed as
97 ptr + length. */
98 tree endptr;
99 /* Reference count. Any changes to strinfo entry possibly shared
100 with dominating basic blocks need unshare_strinfo first, except
101 for dont_invalidate which affects only the immediately next
102 maybe_invalidate. */
103 int refcount;
104 /* Copy of index. get_strinfo (si->idx) should return si; */
105 int idx;
106 /* These 3 fields are for chaining related string pointers together.
107 E.g. for
108 bl = strlen (b); dl = strlen (d); strcpy (a, b); c = a + bl;
109 strcpy (c, d); e = c + dl;
110 strinfo(a) -> strinfo(c) -> strinfo(e)
111 All have ->first field equal to strinfo(a)->idx and are doubly
112 chained through prev/next fields. The later strinfos are required
113 to point into the same string with zero or more bytes after
114 the previous pointer and all bytes in between the two pointers
115 must be non-zero. Functions like strcpy or memcpy are supposed
116 to adjust all previous strinfo lengths, but not following strinfo
117 lengths (those are uncertain, usually invalidated during
118 maybe_invalidate, except when the alias oracle knows better).
119 Functions like strcat on the other side adjust the whole
120 related strinfo chain.
121 They are updated lazily, so to use the chain the same first fields
122 and si->prev->next == si->idx needs to be verified. */
123 int first;
124 int next;
125 int prev;
126 /* A flag whether the string is known to be written in the current
127 function. */
128 bool writable;
129 /* A flag for the next maybe_invalidate that this strinfo shouldn't
130 be invalidated. Always cleared by maybe_invalidate. */
131 bool dont_invalidate;
132 /* True if the string is known to be nul-terminated after NONZERO_CHARS
133 characters. False is useful when detecting strings that are built
134 up via successive memcpys. */
135 bool full_string_p;
138 /* Pool for allocating strinfo_struct entries. */
139 static object_allocator<strinfo> strinfo_pool ("strinfo pool");
141 /* Vector mapping positive string indexes to strinfo, for the
142 current basic block. The first pointer in the vector is special,
143 it is either NULL, meaning the vector isn't shared, or it is
144 a basic block pointer to the owner basic_block if shared.
145 If some other bb wants to modify the vector, the vector needs
146 to be unshared first, and only the owner bb is supposed to free it. */
147 static vec<strinfo *, va_heap, vl_embed> *stridx_to_strinfo;
149 /* One OFFSET->IDX mapping. */
150 struct stridxlist
152 struct stridxlist *next;
153 HOST_WIDE_INT offset;
154 int idx;
157 /* Hash table entry, mapping a DECL to a chain of OFFSET->IDX mappings. */
158 struct decl_stridxlist_map
160 struct tree_map_base base;
161 struct stridxlist list;
164 /* Hash table for mapping decls to a chained list of offset -> idx
165 mappings. */
166 typedef hash_map<tree_decl_hash, stridxlist> decl_to_stridxlist_htab_t;
167 static decl_to_stridxlist_htab_t *decl_to_stridxlist_htab;
169 /* Hash table mapping strlen (or strnlen with constant bound and return
170 smaller than bound) calls to stridx instances describing
171 the calls' arguments. Non-null only when warn_stringop_truncation
172 is non-zero. */
173 typedef std::pair<int, location_t> stridx_strlenloc;
174 static hash_map<tree, stridx_strlenloc> *strlen_to_stridx;
176 /* Obstack for struct stridxlist and struct decl_stridxlist_map. */
177 static struct obstack stridx_obstack;
179 /* Last memcpy statement if it could be adjusted if the trailing
180 '\0' written is immediately overwritten, or
181 *x = '\0' store that could be removed if it is immediately overwritten. */
182 struct laststmt_struct
184 gimple *stmt;
185 tree len;
186 int stridx;
187 } laststmt;
189 static int get_stridx_plus_constant (strinfo *, unsigned HOST_WIDE_INT, tree);
190 static void handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *);
192 /* Return:
194 - 1 if SI is known to start with more than OFF nonzero characters.
196 - 0 if SI is known to start with OFF nonzero characters,
197 but is not known to start with more.
199 - -1 if SI might not start with OFF nonzero characters. */
201 static inline int
202 compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off)
204 if (si->nonzero_chars
205 && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
206 return compare_tree_int (si->nonzero_chars, off);
207 else
208 return -1;
211 /* Return true if SI is known to be a zero-length string. */
213 static inline bool
214 zero_length_string_p (strinfo *si)
216 return si->full_string_p && integer_zerop (si->nonzero_chars);
219 /* Return strinfo vector entry IDX. */
221 static inline strinfo *
222 get_strinfo (int idx)
224 if (vec_safe_length (stridx_to_strinfo) <= (unsigned int) idx)
225 return NULL;
226 return (*stridx_to_strinfo)[idx];
229 /* Get the next strinfo in the chain after SI, or null if none. */
231 static inline strinfo *
232 get_next_strinfo (strinfo *si)
234 if (si->next == 0)
235 return NULL;
236 strinfo *nextsi = get_strinfo (si->next);
237 if (nextsi == NULL || nextsi->first != si->first || nextsi->prev != si->idx)
238 return NULL;
239 return nextsi;
242 /* Helper function for get_stridx. Return the strinfo index of the address
243 of EXP, which is available in PTR if nonnull. If OFFSET_OUT, it is
244 OK to return the index for some X <= &EXP and store &EXP - X in
245 *OFFSET_OUT. */
247 static int
248 get_addr_stridx (tree exp, tree ptr, unsigned HOST_WIDE_INT *offset_out)
250 HOST_WIDE_INT off;
251 struct stridxlist *list, *last = NULL;
252 tree base;
254 if (!decl_to_stridxlist_htab)
255 return 0;
257 poly_int64 poff;
258 base = get_addr_base_and_unit_offset (exp, &poff);
259 if (base == NULL || !DECL_P (base) || !poff.is_constant (&off))
260 return 0;
262 list = decl_to_stridxlist_htab->get (base);
263 if (list == NULL)
264 return 0;
268 if (list->offset == off)
270 if (offset_out)
271 *offset_out = 0;
272 return list->idx;
274 if (list->offset > off)
275 return 0;
276 last = list;
277 list = list->next;
279 while (list);
281 if ((offset_out || ptr) && last && last->idx > 0)
283 unsigned HOST_WIDE_INT rel_off
284 = (unsigned HOST_WIDE_INT) off - last->offset;
285 strinfo *si = get_strinfo (last->idx);
286 if (si && compare_nonzero_chars (si, rel_off) >= 0)
288 if (offset_out)
290 *offset_out = rel_off;
291 return last->idx;
293 else
294 return get_stridx_plus_constant (si, rel_off, ptr);
297 return 0;
300 /* Return string index for EXP. */
302 static int
303 get_stridx (tree exp)
305 if (TREE_CODE (exp) == SSA_NAME)
307 if (ssa_ver_to_stridx[SSA_NAME_VERSION (exp)])
308 return ssa_ver_to_stridx[SSA_NAME_VERSION (exp)];
310 tree e = exp;
311 HOST_WIDE_INT offset = 0;
312 /* Follow a chain of at most 5 assignments. */
313 for (int i = 0; i < 5; i++)
315 gimple *def_stmt = SSA_NAME_DEF_STMT (e);
316 if (!is_gimple_assign (def_stmt))
317 return 0;
319 tree_code rhs_code = gimple_assign_rhs_code (def_stmt);
320 tree ptr, off;
322 if (rhs_code == ADDR_EXPR)
324 /* Handle indices/offsets into VLAs which are implemented
325 as pointers to arrays. */
326 ptr = gimple_assign_rhs1 (def_stmt);
327 ptr = TREE_OPERAND (ptr, 0);
329 /* Handle also VLAs of types larger than char. */
330 if (tree eltsize = TYPE_SIZE_UNIT (TREE_TYPE (ptr)))
332 if (TREE_CODE (ptr) == ARRAY_REF)
334 off = TREE_OPERAND (ptr, 1);
335 ptr = TREE_OPERAND (ptr, 0);
336 if (!integer_onep (eltsize))
338 /* Scale the array index by the size of the element
339 type in the rare case that it's greater than
340 the typical 1 for char, making sure both operands
341 have the same type. */
342 eltsize = fold_convert (ssizetype, eltsize);
343 off = fold_convert (ssizetype, off);
344 off = fold_build2 (MULT_EXPR, ssizetype, off, eltsize);
347 else
348 off = integer_zero_node;
350 else
351 return 0;
353 if (TREE_CODE (ptr) != MEM_REF)
354 return 0;
356 /* Add the MEM_REF byte offset. */
357 tree mem_off = TREE_OPERAND (ptr, 1);
358 off = fold_build2 (PLUS_EXPR, TREE_TYPE (off), off, mem_off);
359 ptr = TREE_OPERAND (ptr, 0);
361 else if (rhs_code == POINTER_PLUS_EXPR)
363 ptr = gimple_assign_rhs1 (def_stmt);
364 off = gimple_assign_rhs2 (def_stmt);
366 else
367 return 0;
369 if (TREE_CODE (ptr) != SSA_NAME
370 || !tree_fits_shwi_p (off))
371 return 0;
372 HOST_WIDE_INT this_off = tree_to_shwi (off);
373 if (this_off < 0)
374 return 0;
375 offset = (unsigned HOST_WIDE_INT) offset + this_off;
376 if (offset < 0)
377 return 0;
378 if (ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)])
380 strinfo *si
381 = get_strinfo (ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)]);
382 if (si && compare_nonzero_chars (si, offset) >= 0)
383 return get_stridx_plus_constant (si, offset, exp);
385 e = ptr;
387 return 0;
390 if (TREE_CODE (exp) == ADDR_EXPR)
392 int idx = get_addr_stridx (TREE_OPERAND (exp, 0), exp, NULL);
393 if (idx != 0)
394 return idx;
397 const char *p = c_getstr (exp);
398 if (p)
399 return ~(int) strlen (p);
401 return 0;
404 /* Return true if strinfo vector is shared with the immediate dominator. */
406 static inline bool
407 strinfo_shared (void)
409 return vec_safe_length (stridx_to_strinfo)
410 && (*stridx_to_strinfo)[0] != NULL;
413 /* Unshare strinfo vector that is shared with the immediate dominator. */
415 static void
416 unshare_strinfo_vec (void)
418 strinfo *si;
419 unsigned int i = 0;
421 gcc_assert (strinfo_shared ());
422 stridx_to_strinfo = vec_safe_copy (stridx_to_strinfo);
423 for (i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
424 if (si != NULL)
425 si->refcount++;
426 (*stridx_to_strinfo)[0] = NULL;
429 /* Attempt to create a string index for exp, ADDR_EXPR's operand.
430 Return a pointer to the location where the string index can
431 be stored (if 0) or is stored, or NULL if this can't be tracked. */
433 static int *
434 addr_stridxptr (tree exp)
436 HOST_WIDE_INT off;
438 poly_int64 poff;
439 tree base = get_addr_base_and_unit_offset (exp, &poff);
440 if (base == NULL_TREE || !DECL_P (base) || !poff.is_constant (&off))
441 return NULL;
443 if (!decl_to_stridxlist_htab)
445 decl_to_stridxlist_htab
446 = new hash_map<tree_decl_hash, stridxlist> (64);
447 gcc_obstack_init (&stridx_obstack);
450 bool existed;
451 stridxlist *list = &decl_to_stridxlist_htab->get_or_insert (base, &existed);
452 if (existed)
454 int i;
455 stridxlist *before = NULL;
456 for (i = 0; i < 32; i++)
458 if (list->offset == off)
459 return &list->idx;
460 if (list->offset > off && before == NULL)
461 before = list;
462 if (list->next == NULL)
463 break;
464 list = list->next;
466 if (i == 32)
467 return NULL;
468 if (before)
470 list = before;
471 before = XOBNEW (&stridx_obstack, struct stridxlist);
472 *before = *list;
473 list->next = before;
474 list->offset = off;
475 list->idx = 0;
476 return &list->idx;
478 list->next = XOBNEW (&stridx_obstack, struct stridxlist);
479 list = list->next;
482 list->next = NULL;
483 list->offset = off;
484 list->idx = 0;
485 return &list->idx;
488 /* Create a new string index, or return 0 if reached limit. */
490 static int
491 new_stridx (tree exp)
493 int idx;
494 if (max_stridx >= PARAM_VALUE (PARAM_MAX_TRACKED_STRLENS))
495 return 0;
496 if (TREE_CODE (exp) == SSA_NAME)
498 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp))
499 return 0;
500 idx = max_stridx++;
501 ssa_ver_to_stridx[SSA_NAME_VERSION (exp)] = idx;
502 return idx;
504 if (TREE_CODE (exp) == ADDR_EXPR)
506 int *pidx = addr_stridxptr (TREE_OPERAND (exp, 0));
507 if (pidx != NULL)
509 gcc_assert (*pidx == 0);
510 *pidx = max_stridx++;
511 return *pidx;
514 return 0;
517 /* Like new_stridx, but for ADDR_EXPR's operand instead. */
519 static int
520 new_addr_stridx (tree exp)
522 int *pidx;
523 if (max_stridx >= PARAM_VALUE (PARAM_MAX_TRACKED_STRLENS))
524 return 0;
525 pidx = addr_stridxptr (exp);
526 if (pidx != NULL)
528 gcc_assert (*pidx == 0);
529 *pidx = max_stridx++;
530 return *pidx;
532 return 0;
535 /* Create a new strinfo. */
537 static strinfo *
538 new_strinfo (tree ptr, int idx, tree nonzero_chars, bool full_string_p)
540 strinfo *si = strinfo_pool.allocate ();
541 si->nonzero_chars = nonzero_chars;
542 si->ptr = ptr;
543 si->stmt = NULL;
544 si->endptr = NULL_TREE;
545 si->refcount = 1;
546 si->idx = idx;
547 si->first = 0;
548 si->prev = 0;
549 si->next = 0;
550 si->writable = false;
551 si->dont_invalidate = false;
552 si->full_string_p = full_string_p;
553 return si;
556 /* Decrease strinfo refcount and free it if not referenced anymore. */
558 static inline void
559 free_strinfo (strinfo *si)
561 if (si && --si->refcount == 0)
562 strinfo_pool.remove (si);
565 /* Set strinfo in the vector entry IDX to SI. */
567 static inline void
568 set_strinfo (int idx, strinfo *si)
570 if (vec_safe_length (stridx_to_strinfo) && (*stridx_to_strinfo)[0])
571 unshare_strinfo_vec ();
572 if (vec_safe_length (stridx_to_strinfo) <= (unsigned int) idx)
573 vec_safe_grow_cleared (stridx_to_strinfo, idx + 1);
574 (*stridx_to_strinfo)[idx] = si;
577 /* Return the first strinfo in the related strinfo chain
578 if all strinfos in between belong to the chain, otherwise NULL. */
580 static strinfo *
581 verify_related_strinfos (strinfo *origsi)
583 strinfo *si = origsi, *psi;
585 if (origsi->first == 0)
586 return NULL;
587 for (; si->prev; si = psi)
589 if (si->first != origsi->first)
590 return NULL;
591 psi = get_strinfo (si->prev);
592 if (psi == NULL)
593 return NULL;
594 if (psi->next != si->idx)
595 return NULL;
597 if (si->idx != si->first)
598 return NULL;
599 return si;
602 /* Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
603 Use LOC for folding. */
605 static void
606 set_endptr_and_length (location_t loc, strinfo *si, tree endptr)
608 si->endptr = endptr;
609 si->stmt = NULL;
610 tree start_as_size = fold_convert_loc (loc, size_type_node, si->ptr);
611 tree end_as_size = fold_convert_loc (loc, size_type_node, endptr);
612 si->nonzero_chars = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
613 end_as_size, start_as_size);
614 si->full_string_p = true;
617 /* Return the string length, or NULL if it can't be computed.
618 The length may but need not be constant. Instead, it might be
619 the result of a strlen() call. */
621 static tree
622 get_string_length (strinfo *si)
624 /* If the length has already been computed return it if it's exact
625 (i.e., the string is nul-terminated at NONZERO_CHARS), or return
626 null if it isn't. */
627 if (si->nonzero_chars)
628 return si->full_string_p ? si->nonzero_chars : NULL;
630 /* If the string is the result of one of the built-in calls below
631 attempt to compute the length from the call statement. */
632 if (si->stmt)
634 gimple *stmt = si->stmt, *lenstmt;
635 tree callee, lhs, fn, tem;
636 location_t loc;
637 gimple_stmt_iterator gsi;
639 gcc_assert (is_gimple_call (stmt));
640 callee = gimple_call_fndecl (stmt);
641 gcc_assert (callee && fndecl_built_in_p (callee, BUILT_IN_NORMAL));
642 lhs = gimple_call_lhs (stmt);
643 /* unshare_strinfo is intentionally not called here. The (delayed)
644 transformation of strcpy or strcat into stpcpy is done at the place
645 of the former strcpy/strcat call and so can affect all the strinfos
646 with the same stmt. If they were unshared before and transformation
647 has been already done, the handling of BUILT_IN_STPCPY{,_CHK} should
648 just compute the right length. */
649 switch (DECL_FUNCTION_CODE (callee))
651 case BUILT_IN_STRCAT:
652 case BUILT_IN_STRCAT_CHK:
653 gsi = gsi_for_stmt (stmt);
654 fn = builtin_decl_implicit (BUILT_IN_STRLEN);
655 gcc_assert (lhs == NULL_TREE);
656 tem = unshare_expr (gimple_call_arg (stmt, 0));
657 lenstmt = gimple_build_call (fn, 1, tem);
658 lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), lenstmt);
659 gimple_call_set_lhs (lenstmt, lhs);
660 gimple_set_vuse (lenstmt, gimple_vuse (stmt));
661 gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT);
662 tem = gimple_call_arg (stmt, 0);
663 if (!ptrofftype_p (TREE_TYPE (lhs)))
665 lhs = convert_to_ptrofftype (lhs);
666 lhs = force_gimple_operand_gsi (&gsi, lhs, true, NULL_TREE,
667 true, GSI_SAME_STMT);
669 lenstmt = gimple_build_assign
670 (make_ssa_name (TREE_TYPE (gimple_call_arg (stmt, 0))),
671 POINTER_PLUS_EXPR,tem, lhs);
672 gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT);
673 gimple_call_set_arg (stmt, 0, gimple_assign_lhs (lenstmt));
674 lhs = NULL_TREE;
675 /* FALLTHRU */
676 case BUILT_IN_STRCPY:
677 case BUILT_IN_STRCPY_CHK:
678 gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY));
679 if (gimple_call_num_args (stmt) == 2)
680 fn = builtin_decl_implicit (BUILT_IN_STPCPY);
681 else
682 fn = builtin_decl_explicit (BUILT_IN_STPCPY_CHK);
683 gcc_assert (lhs == NULL_TREE);
684 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
686 fprintf (dump_file, "Optimizing: ");
687 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
689 gimple_call_set_fndecl (stmt, fn);
690 lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), stmt);
691 gimple_call_set_lhs (stmt, lhs);
692 update_stmt (stmt);
693 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
695 fprintf (dump_file, "into: ");
696 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
698 /* FALLTHRU */
699 case BUILT_IN_STPCPY:
700 case BUILT_IN_STPCPY_CHK:
701 gcc_assert (lhs != NULL_TREE);
702 loc = gimple_location (stmt);
703 set_endptr_and_length (loc, si, lhs);
704 for (strinfo *chainsi = verify_related_strinfos (si);
705 chainsi != NULL;
706 chainsi = get_next_strinfo (chainsi))
707 if (chainsi->nonzero_chars == NULL)
708 set_endptr_and_length (loc, chainsi, lhs);
709 break;
710 case BUILT_IN_MALLOC:
711 break;
712 /* BUILT_IN_CALLOC always has si->nonzero_chars set. */
713 default:
714 gcc_unreachable ();
715 break;
719 return si->nonzero_chars;
722 /* Dump strlen data to FP for statement STMT. When non-null, RVALS
723 points to EVRP info and is used to dump strlen range for non-constant
724 results. */
726 DEBUG_FUNCTION void
727 dump_strlen_info (FILE *fp, gimple *stmt, const vr_values *rvals)
729 if (stmt)
731 fprintf (fp, "\nDumping strlen pass data after ");
732 print_gimple_expr (fp, stmt, TDF_LINENO);
733 fputc ('\n', fp);
735 else
736 fprintf (fp, "\nDumping strlen pass data\n");
738 fprintf (fp, "max_stridx = %i\n", max_stridx);
739 fprintf (fp, "ssa_ver_to_stridx has %u elements\n",
740 ssa_ver_to_stridx.length ());
741 fprintf (fp, "stridx_to_strinfo");
742 if (stridx_to_strinfo)
744 fprintf (fp, " has %u elements\n", stridx_to_strinfo->length ());
745 for (unsigned i = 0; i != stridx_to_strinfo->length (); ++i)
747 if (strinfo *si = (*stridx_to_strinfo)[i])
749 if (!si->idx)
750 continue;
751 fprintf (fp, " idx = %i", si->idx);
752 if (si->ptr)
754 fprintf (fp, ", ptr = ");
755 print_generic_expr (fp, si->ptr);
757 fprintf (fp, ", nonzero_chars = ");
758 print_generic_expr (fp, si->nonzero_chars);
759 if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
761 value_range_kind rng = VR_UNDEFINED;
762 wide_int min, max;
763 if (rvals)
765 const value_range *vr
766 = CONST_CAST (class vr_values *, rvals)
767 ->get_value_range (si->nonzero_chars);
768 rng = vr->kind ();
769 if (range_int_cst_p (vr))
771 min = wi::to_wide (vr->min ());
772 max = wi::to_wide (vr->max ());
774 else
775 rng = VR_UNDEFINED;
777 else
778 rng = get_range_info (si->nonzero_chars, &min, &max);
780 if (rng == VR_RANGE || rng == VR_ANTI_RANGE)
782 fprintf (fp, " %s[%llu, %llu]",
783 rng == VR_RANGE ? "" : "~",
784 (long long) min.to_uhwi (),
785 (long long) max.to_uhwi ());
788 fprintf (fp, " , refcount = %i", si->refcount);
789 if (si->stmt)
791 fprintf (fp, ", stmt = ");
792 print_gimple_expr (fp, si->stmt, 0);
794 if (si->writable)
795 fprintf (fp, ", writable");
796 if (si->full_string_p)
797 fprintf (fp, ", full_string_p");
798 if (strinfo *next = get_next_strinfo (si))
800 fprintf (fp, ", {");
802 fprintf (fp, "%i%s", next->idx, next->first ? ", " : "");
803 while ((next = get_next_strinfo (next)));
804 fprintf (fp, "}");
806 fputs ("\n", fp);
810 else
811 fprintf (fp, " = null\n");
813 fprintf (fp, "decl_to_stridxlist_htab");
814 if (decl_to_stridxlist_htab)
816 fputs ("\n", fp);
817 typedef decl_to_stridxlist_htab_t::iterator iter_t;
818 for (iter_t it = decl_to_stridxlist_htab->begin ();
819 it != decl_to_stridxlist_htab->end (); ++it)
821 tree decl = (*it).first;
822 stridxlist *list = &(*it).second;
823 fprintf (fp, " decl = ");
824 print_generic_expr (fp, decl);
825 if (list)
827 fprintf (fp, ", offsets = {");
828 for (; list; list = list->next)
829 fprintf (fp, "%lli%s", (long long) list->offset,
830 list->next ? ", " : "");
831 fputs ("}", fp);
833 fputs ("\n", fp);
836 else
837 fprintf (fp, " = null\n");
839 if (laststmt.stmt)
841 fprintf (fp, "laststmt = ");
842 print_gimple_expr (fp, laststmt.stmt, 0);
843 fprintf (fp, ", len = ");
844 print_generic_expr (fp, laststmt.len);
845 fprintf (fp, ", stridx = %i\n", laststmt.stridx);
849 /* Attempt to determine the length of the string SRC. On success, store
850 the length in *PDATA and return true. Otherwise, return false.
851 VISITED is a bitmap of visited PHI nodes. RVALS points to EVRP info
852 and PSSA_DEF_MAX to an SSA_NAME assignment limit used to prevent runaway
853 recursion. */
855 static bool
856 get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited,
857 const vr_values *rvals, unsigned *pssa_def_max)
859 int idx = get_stridx (src);
860 if (!idx)
862 if (TREE_CODE (src) == SSA_NAME)
864 gimple *def_stmt = SSA_NAME_DEF_STMT (src);
865 if (gimple_code (def_stmt) == GIMPLE_PHI)
867 if (!*visited)
868 *visited = BITMAP_ALLOC (NULL);
870 if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (src)))
871 return true;
873 if (*pssa_def_max == 0)
874 return false;
876 --*pssa_def_max;
878 /* Iterate over the PHI arguments and determine the minimum
879 and maximum length/size of each and incorporate them into
880 the overall result. */
881 gphi *phi = as_a <gphi *> (def_stmt);
882 for (unsigned i = 0; i != gimple_phi_num_args (phi); ++i)
884 tree arg = gimple_phi_arg_def (phi, i);
885 if (arg == gimple_phi_result (def_stmt))
886 continue;
888 c_strlen_data argdata = { };
889 if (get_range_strlen_dynamic (arg, &argdata, visited, rvals,
890 pssa_def_max))
892 /* Set the DECL of an unterminated array this argument
893 refers to if one hasn't been found yet. */
894 if (!pdata->decl && argdata.decl)
895 pdata->decl = argdata.decl;
897 if (!argdata.minlen
898 || (integer_zerop (argdata.minlen)
899 && (!argdata.maxbound
900 || integer_all_onesp (argdata.maxbound))
901 && integer_all_onesp (argdata.maxlen)))
903 /* Set the upper bound of the length to unbounded. */
904 pdata->maxlen = build_all_ones_cst (size_type_node);
905 continue;
908 /* Adjust the minimum and maximum length determined
909 so far and the upper bound on the array size. */
910 if (!pdata->minlen
911 || tree_int_cst_lt (argdata.minlen, pdata->minlen))
912 pdata->minlen = argdata.minlen;
913 if (!pdata->maxlen
914 || (argdata.maxlen
915 && tree_int_cst_lt (pdata->maxlen, argdata.maxlen)))
916 pdata->maxlen = argdata.maxlen;
917 if (!pdata->maxbound
918 || TREE_CODE (pdata->maxbound) != INTEGER_CST
919 || (argdata.maxbound
920 && tree_int_cst_lt (pdata->maxbound,
921 argdata.maxbound)
922 && !integer_all_onesp (argdata.maxbound)))
923 pdata->maxbound = argdata.maxbound;
925 else
926 pdata->maxlen = build_all_ones_cst (size_type_node);
929 return true;
933 /* Return success regardless of the result and handle *PDATA
934 in the caller. */
935 get_range_strlen (src, pdata, 1);
936 return true;
939 if (idx < 0)
941 /* SRC is a string of constant length. */
942 pdata->minlen = build_int_cst (size_type_node, ~idx);
943 pdata->maxlen = pdata->minlen;
944 pdata->maxbound = pdata->maxlen;
945 return true;
948 if (strinfo *si = get_strinfo (idx))
950 pdata->minlen = get_string_length (si);
951 if (!pdata->minlen && si->nonzero_chars)
953 if (TREE_CODE (si->nonzero_chars) == INTEGER_CST)
954 pdata->minlen = si->nonzero_chars;
955 else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
957 const value_range *vr
958 = CONST_CAST (class vr_values *, rvals)
959 ->get_value_range (si->nonzero_chars);
960 if (vr->kind () == VR_RANGE
961 && range_int_cst_p (vr))
963 pdata->minlen = vr->min ();
964 pdata->maxlen = vr->max ();
966 else
967 pdata->minlen = build_zero_cst (size_type_node);
969 else
970 pdata->minlen = build_zero_cst (size_type_node);
972 tree base = si->ptr;
973 if (TREE_CODE (base) == ADDR_EXPR)
974 base = TREE_OPERAND (base, 0);
976 HOST_WIDE_INT off;
977 poly_int64 poff;
978 base = get_addr_base_and_unit_offset (base, &poff);
979 if (base
980 && DECL_P (base)
981 && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE
982 && TYPE_SIZE_UNIT (TREE_TYPE (base))
983 && poff.is_constant (&off))
985 tree basetype = TREE_TYPE (base);
986 tree size = TYPE_SIZE_UNIT (basetype);
987 ++off; /* Increment for the terminating nul. */
988 pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size,
989 build_int_cst (size_type_node, off));
990 pdata->maxbound = pdata->maxlen;
992 else
993 pdata->maxlen = build_all_ones_cst (size_type_node);
995 else if (pdata->minlen && TREE_CODE (pdata->minlen) == SSA_NAME)
997 const value_range *vr
998 = CONST_CAST (class vr_values *, rvals)
999 ->get_value_range (si->nonzero_chars);
1000 if (vr->kind () == VR_RANGE
1001 && range_int_cst_p (vr))
1003 pdata->minlen = vr->min ();
1004 pdata->maxlen = vr->max ();
1005 pdata->maxbound = pdata->maxlen;
1007 else
1009 pdata->minlen = build_zero_cst (size_type_node);
1010 pdata->maxlen = build_all_ones_cst (size_type_node);
1013 else if (pdata->minlen && TREE_CODE (pdata->minlen) == INTEGER_CST)
1015 pdata->maxlen = pdata->minlen;
1016 pdata->maxbound = pdata->minlen;
1018 else
1020 /* For PDATA->MINLEN that's a non-constant expression such
1021 as PLUS_EXPR whose value range is unknown, set the bounds
1022 to zero and SIZE_MAX. */
1023 pdata->minlen = build_zero_cst (size_type_node);
1024 pdata->maxlen = build_all_ones_cst (size_type_node);
1027 return true;
1030 return false;
1033 /* Analogous to get_range_strlen but for dynamically created strings,
1034 i.e., those created by calls to strcpy as opposed to just string
1035 constants.
1036 Try to obtain the range of the lengths of the string(s) referenced
1037 by SRC, or the size of the largest array SRC refers to if the range
1038 of lengths cannot be determined, and store all in *PDATA. RVALS
1039 points to EVRP info. */
1041 void
1042 get_range_strlen_dynamic (tree src, c_strlen_data *pdata,
1043 const vr_values *rvals)
1045 bitmap visited = NULL;
1046 tree maxbound = pdata->maxbound;
1048 unsigned limit = PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT);
1049 if (!get_range_strlen_dynamic (src, pdata, &visited, rvals, &limit))
1051 /* On failure extend the length range to an impossible maximum
1052 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1053 members can stay unchanged regardless. */
1054 pdata->minlen = ssize_int (0);
1055 pdata->maxlen = build_all_ones_cst (size_type_node);
1057 else if (!pdata->minlen)
1058 pdata->minlen = ssize_int (0);
1060 /* If it's unchanged from it initial non-null value, set the conservative
1061 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1062 if (maxbound && pdata->maxbound == maxbound)
1063 pdata->maxbound = build_all_ones_cst (size_type_node);
1065 if (visited)
1066 BITMAP_FREE (visited);
1069 /* Invalidate string length information for strings whose length
1070 might change due to stores in stmt. */
1072 static bool
1073 maybe_invalidate (gimple *stmt)
1075 strinfo *si;
1076 unsigned int i;
1077 bool nonempty = false;
1079 for (i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
1080 if (si != NULL)
1082 if (!si->dont_invalidate)
1084 ao_ref r;
1085 /* Do not use si->nonzero_chars. */
1086 ao_ref_init_from_ptr_and_size (&r, si->ptr, NULL_TREE);
1087 if (stmt_may_clobber_ref_p_1 (stmt, &r))
1089 set_strinfo (i, NULL);
1090 free_strinfo (si);
1091 continue;
1094 si->dont_invalidate = false;
1095 nonempty = true;
1097 return nonempty;
1100 /* Unshare strinfo record SI, if it has refcount > 1 or
1101 if stridx_to_strinfo vector is shared with some other
1102 bbs. */
1104 static strinfo *
1105 unshare_strinfo (strinfo *si)
1107 strinfo *nsi;
1109 if (si->refcount == 1 && !strinfo_shared ())
1110 return si;
1112 nsi = new_strinfo (si->ptr, si->idx, si->nonzero_chars, si->full_string_p);
1113 nsi->stmt = si->stmt;
1114 nsi->endptr = si->endptr;
1115 nsi->first = si->first;
1116 nsi->prev = si->prev;
1117 nsi->next = si->next;
1118 nsi->writable = si->writable;
1119 set_strinfo (si->idx, nsi);
1120 free_strinfo (si);
1121 return nsi;
1124 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1125 strinfo if there is any. Return it's idx, or 0 if no strinfo has
1126 been created. */
1128 static int
1129 get_stridx_plus_constant (strinfo *basesi, unsigned HOST_WIDE_INT off,
1130 tree ptr)
1132 if (TREE_CODE (ptr) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr))
1133 return 0;
1135 if (compare_nonzero_chars (basesi, off) < 0
1136 || !tree_fits_uhwi_p (basesi->nonzero_chars))
1137 return 0;
1139 unsigned HOST_WIDE_INT nonzero_chars
1140 = tree_to_uhwi (basesi->nonzero_chars) - off;
1141 strinfo *si = basesi, *chainsi;
1142 if (si->first || si->prev || si->next)
1143 si = verify_related_strinfos (basesi);
1144 if (si == NULL
1145 || si->nonzero_chars == NULL_TREE
1146 || TREE_CODE (si->nonzero_chars) != INTEGER_CST)
1147 return 0;
1149 if (TREE_CODE (ptr) == SSA_NAME
1150 && ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
1151 ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
1153 gcc_checking_assert (compare_tree_int (si->nonzero_chars, off) != -1);
1154 for (chainsi = si; chainsi->next; chainsi = si)
1156 si = get_next_strinfo (chainsi);
1157 if (si == NULL
1158 || si->nonzero_chars == NULL_TREE
1159 || TREE_CODE (si->nonzero_chars) != INTEGER_CST)
1160 break;
1161 int r = compare_tree_int (si->nonzero_chars, nonzero_chars);
1162 if (r != 1)
1164 if (r == 0)
1166 if (TREE_CODE (ptr) == SSA_NAME)
1167 ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = si->idx;
1168 else
1170 int *pidx = addr_stridxptr (TREE_OPERAND (ptr, 0));
1171 if (pidx != NULL && *pidx == 0)
1172 *pidx = si->idx;
1174 return si->idx;
1176 break;
1180 int idx = new_stridx (ptr);
1181 if (idx == 0)
1182 return 0;
1183 si = new_strinfo (ptr, idx, build_int_cst (size_type_node, nonzero_chars),
1184 basesi->full_string_p);
1185 set_strinfo (idx, si);
1186 if (strinfo *nextsi = get_strinfo (chainsi->next))
1188 nextsi = unshare_strinfo (nextsi);
1189 si->next = nextsi->idx;
1190 nextsi->prev = idx;
1192 chainsi = unshare_strinfo (chainsi);
1193 if (chainsi->first == 0)
1194 chainsi->first = chainsi->idx;
1195 chainsi->next = idx;
1196 if (chainsi->endptr == NULL_TREE && zero_length_string_p (si))
1197 chainsi->endptr = ptr;
1198 si->endptr = chainsi->endptr;
1199 si->prev = chainsi->idx;
1200 si->first = chainsi->first;
1201 si->writable = chainsi->writable;
1202 return si->idx;
1205 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1206 to a zero-length string and if possible chain it to a related strinfo
1207 chain whose part is or might be CHAINSI. */
1209 static strinfo *
1210 zero_length_string (tree ptr, strinfo *chainsi)
1212 strinfo *si;
1213 int idx;
1214 if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
1215 ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
1216 gcc_checking_assert (TREE_CODE (ptr) == SSA_NAME
1217 && ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] == 0);
1219 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr))
1220 return NULL;
1221 if (chainsi != NULL)
1223 si = verify_related_strinfos (chainsi);
1224 if (si)
1228 /* We shouldn't mix delayed and non-delayed lengths. */
1229 gcc_assert (si->full_string_p);
1230 if (si->endptr == NULL_TREE)
1232 si = unshare_strinfo (si);
1233 si->endptr = ptr;
1235 chainsi = si;
1236 si = get_next_strinfo (si);
1238 while (si != NULL);
1239 if (zero_length_string_p (chainsi))
1241 if (chainsi->next)
1243 chainsi = unshare_strinfo (chainsi);
1244 chainsi->next = 0;
1246 ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = chainsi->idx;
1247 return chainsi;
1250 else
1252 /* We shouldn't mix delayed and non-delayed lengths. */
1253 gcc_assert (chainsi->full_string_p);
1254 if (chainsi->first || chainsi->prev || chainsi->next)
1256 chainsi = unshare_strinfo (chainsi);
1257 chainsi->first = 0;
1258 chainsi->prev = 0;
1259 chainsi->next = 0;
1263 idx = new_stridx (ptr);
1264 if (idx == 0)
1265 return NULL;
1266 si = new_strinfo (ptr, idx, build_int_cst (size_type_node, 0), true);
1267 set_strinfo (idx, si);
1268 si->endptr = ptr;
1269 if (chainsi != NULL)
1271 chainsi = unshare_strinfo (chainsi);
1272 if (chainsi->first == 0)
1273 chainsi->first = chainsi->idx;
1274 chainsi->next = idx;
1275 if (chainsi->endptr == NULL_TREE)
1276 chainsi->endptr = ptr;
1277 si->prev = chainsi->idx;
1278 si->first = chainsi->first;
1279 si->writable = chainsi->writable;
1281 return si;
1284 /* For strinfo ORIGSI whose length has been just updated, adjust other
1285 related strinfos so that they match the new ORIGSI. This involves:
1287 - adding ADJ to the nonzero_chars fields
1288 - copying full_string_p from the new ORIGSI. */
1290 static void
1291 adjust_related_strinfos (location_t loc, strinfo *origsi, tree adj)
1293 strinfo *si = verify_related_strinfos (origsi);
1295 if (si == NULL)
1296 return;
1298 while (1)
1300 strinfo *nsi;
1302 if (si != origsi)
1304 tree tem;
1306 si = unshare_strinfo (si);
1307 /* We shouldn't see delayed lengths here; the caller must
1308 have calculated the old length in order to calculate
1309 the adjustment. */
1310 gcc_assert (si->nonzero_chars);
1311 tem = fold_convert_loc (loc, TREE_TYPE (si->nonzero_chars), adj);
1312 si->nonzero_chars = fold_build2_loc (loc, PLUS_EXPR,
1313 TREE_TYPE (si->nonzero_chars),
1314 si->nonzero_chars, tem);
1315 si->full_string_p = origsi->full_string_p;
1317 si->endptr = NULL_TREE;
1318 si->dont_invalidate = true;
1320 nsi = get_next_strinfo (si);
1321 if (nsi == NULL)
1322 return;
1323 si = nsi;
1327 /* Find if there are other SSA_NAME pointers equal to PTR
1328 for which we don't track their string lengths yet. If so, use
1329 IDX for them. */
1331 static void
1332 find_equal_ptrs (tree ptr, int idx)
1334 if (TREE_CODE (ptr) != SSA_NAME)
1335 return;
1336 while (1)
1338 gimple *stmt = SSA_NAME_DEF_STMT (ptr);
1339 if (!is_gimple_assign (stmt))
1340 return;
1341 ptr = gimple_assign_rhs1 (stmt);
1342 switch (gimple_assign_rhs_code (stmt))
1344 case SSA_NAME:
1345 break;
1346 CASE_CONVERT:
1347 if (!POINTER_TYPE_P (TREE_TYPE (ptr)))
1348 return;
1349 if (TREE_CODE (ptr) == SSA_NAME)
1350 break;
1351 if (TREE_CODE (ptr) != ADDR_EXPR)
1352 return;
1353 /* FALLTHRU */
1354 case ADDR_EXPR:
1356 int *pidx = addr_stridxptr (TREE_OPERAND (ptr, 0));
1357 if (pidx != NULL && *pidx == 0)
1358 *pidx = idx;
1359 return;
1361 default:
1362 return;
1365 /* We might find an endptr created in this pass. Grow the
1366 vector in that case. */
1367 if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
1368 ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
1370 if (ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] != 0)
1371 return;
1372 ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = idx;
1376 /* Return true if STMT is a call to a builtin function with the right
1377 arguments and attributes that should be considered for optimization
1378 by this pass. */
1380 static bool
1381 valid_builtin_call (gimple *stmt)
1383 if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
1384 return false;
1386 tree callee = gimple_call_fndecl (stmt);
1387 tree decl = builtin_decl_explicit (DECL_FUNCTION_CODE (callee));
1388 if (decl
1389 && decl != callee
1390 && !gimple_builtin_call_types_compatible_p (stmt, decl))
1391 return false;
1393 switch (DECL_FUNCTION_CODE (callee))
1395 case BUILT_IN_MEMCMP:
1396 case BUILT_IN_MEMCMP_EQ:
1397 case BUILT_IN_STRCMP:
1398 case BUILT_IN_STRNCMP:
1399 case BUILT_IN_STRCHR:
1400 case BUILT_IN_STRLEN:
1401 case BUILT_IN_STRNLEN:
1402 /* The above functions should be pure. Punt if they aren't. */
1403 if (gimple_vdef (stmt) || gimple_vuse (stmt) == NULL_TREE)
1404 return false;
1405 break;
1407 case BUILT_IN_CALLOC:
1408 case BUILT_IN_MALLOC:
1409 case BUILT_IN_MEMCPY:
1410 case BUILT_IN_MEMCPY_CHK:
1411 case BUILT_IN_MEMPCPY:
1412 case BUILT_IN_MEMPCPY_CHK:
1413 case BUILT_IN_MEMSET:
1414 case BUILT_IN_STPCPY:
1415 case BUILT_IN_STPCPY_CHK:
1416 case BUILT_IN_STPNCPY:
1417 case BUILT_IN_STPNCPY_CHK:
1418 case BUILT_IN_STRCAT:
1419 case BUILT_IN_STRCAT_CHK:
1420 case BUILT_IN_STRCPY:
1421 case BUILT_IN_STRCPY_CHK:
1422 case BUILT_IN_STRNCAT:
1423 case BUILT_IN_STRNCAT_CHK:
1424 case BUILT_IN_STRNCPY:
1425 case BUILT_IN_STRNCPY_CHK:
1426 /* The above functions should be neither const nor pure. Punt if they
1427 aren't. */
1428 if (gimple_vdef (stmt) == NULL_TREE || gimple_vuse (stmt) == NULL_TREE)
1429 return false;
1430 break;
1432 default:
1433 break;
1436 return true;
1439 /* If the last .MEM setter statement before STMT is
1440 memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1441 and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1442 just memcpy (x, y, strlen (y)). SI must be the zero length
1443 strinfo. */
1445 static void
1446 adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat)
1448 tree vuse, callee, len;
1449 struct laststmt_struct last = laststmt;
1450 strinfo *lastsi, *firstsi;
1451 unsigned len_arg_no = 2;
1453 laststmt.stmt = NULL;
1454 laststmt.len = NULL_TREE;
1455 laststmt.stridx = 0;
1457 if (last.stmt == NULL)
1458 return;
1460 vuse = gimple_vuse (stmt);
1461 if (vuse == NULL_TREE
1462 || SSA_NAME_DEF_STMT (vuse) != last.stmt
1463 || !has_single_use (vuse))
1464 return;
1466 gcc_assert (last.stridx > 0);
1467 lastsi = get_strinfo (last.stridx);
1468 if (lastsi == NULL)
1469 return;
1471 if (lastsi != si)
1473 if (lastsi->first == 0 || lastsi->first != si->first)
1474 return;
1476 firstsi = verify_related_strinfos (si);
1477 if (firstsi == NULL)
1478 return;
1479 while (firstsi != lastsi)
1481 firstsi = get_next_strinfo (firstsi);
1482 if (firstsi == NULL)
1483 return;
1487 if (!is_strcat && !zero_length_string_p (si))
1488 return;
1490 if (is_gimple_assign (last.stmt))
1492 gimple_stmt_iterator gsi;
1494 if (!integer_zerop (gimple_assign_rhs1 (last.stmt)))
1495 return;
1496 if (stmt_could_throw_p (cfun, last.stmt))
1497 return;
1498 gsi = gsi_for_stmt (last.stmt);
1499 unlink_stmt_vdef (last.stmt);
1500 release_defs (last.stmt);
1501 gsi_remove (&gsi, true);
1502 return;
1505 if (!valid_builtin_call (last.stmt))
1506 return;
1508 callee = gimple_call_fndecl (last.stmt);
1509 switch (DECL_FUNCTION_CODE (callee))
1511 case BUILT_IN_MEMCPY:
1512 case BUILT_IN_MEMCPY_CHK:
1513 break;
1514 default:
1515 return;
1518 len = gimple_call_arg (last.stmt, len_arg_no);
1519 if (tree_fits_uhwi_p (len))
1521 if (!tree_fits_uhwi_p (last.len)
1522 || integer_zerop (len)
1523 || tree_to_uhwi (len) != tree_to_uhwi (last.len) + 1)
1524 return;
1525 /* Don't adjust the length if it is divisible by 4, it is more efficient
1526 to store the extra '\0' in that case. */
1527 if ((tree_to_uhwi (len) & 3) == 0)
1528 return;
1530 /* Don't fold away an out of bounds access, as this defeats proper
1531 warnings. */
1532 tree dst = gimple_call_arg (last.stmt, 0);
1533 tree size = compute_objsize (dst, 0);
1534 if (size && tree_int_cst_lt (size, len))
1535 return;
1537 else if (TREE_CODE (len) == SSA_NAME)
1539 gimple *def_stmt = SSA_NAME_DEF_STMT (len);
1540 if (!is_gimple_assign (def_stmt)
1541 || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
1542 || gimple_assign_rhs1 (def_stmt) != last.len
1543 || !integer_onep (gimple_assign_rhs2 (def_stmt)))
1544 return;
1546 else
1547 return;
1549 gimple_call_set_arg (last.stmt, len_arg_no, last.len);
1550 update_stmt (last.stmt);
1553 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1554 call, or when BOUND is non-null, of a strnlen() call, set LHS
1555 range info to [0, min (MAX, BOUND)] when the range includes more
1556 than one value and return LHS. Otherwise, when the range
1557 [MIN, MAX] is such that MIN == MAX, return the tree representation
1558 of (MIN). The latter allows callers to fold suitable strnlen() calls
1559 to constants. */
1561 tree
1562 set_strlen_range (tree lhs, wide_int min, wide_int max,
1563 tree bound /* = NULL_TREE */)
1565 if (TREE_CODE (lhs) != SSA_NAME
1566 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
1567 return NULL_TREE;
1569 if (bound)
1571 /* For strnlen, adjust MIN and MAX as necessary. If the bound
1572 is less than the size of the array set MAX to it. It it's
1573 greater than MAX and MAX is non-zero bump MAX down to account
1574 for the necessary terminating nul. Otherwise leave it alone. */
1575 if (TREE_CODE (bound) == INTEGER_CST)
1577 wide_int wibnd = wi::to_wide (bound);
1578 int cmp = wi::cmpu (wibnd, max);
1579 if (cmp < 0)
1580 max = wibnd;
1581 else if (cmp && wi::ne_p (max, min))
1582 --max;
1584 else if (TREE_CODE (bound) == SSA_NAME)
1586 wide_int minbound, maxbound;
1587 value_range_kind rng = get_range_info (bound, &minbound, &maxbound);
1588 if (rng == VR_RANGE)
1590 /* For a bound in a known range, adjust the range determined
1591 above as necessary. For a bound in some anti-range or
1592 in an unknown range, use the range determined by callers. */
1593 if (wi::ltu_p (minbound, min))
1594 min = minbound;
1595 if (wi::ltu_p (maxbound, max))
1596 max = maxbound;
1601 if (min == max)
1602 return wide_int_to_tree (size_type_node, min);
1604 set_range_info (lhs, VR_RANGE, min, max);
1605 return lhs;
1608 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1609 SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1610 a character array A[N] with unknown length bounded by N, and for
1611 strnlen(), by min (N, BOUND). */
1613 static tree
1614 maybe_set_strlen_range (tree lhs, tree src, tree bound)
1616 if (TREE_CODE (lhs) != SSA_NAME
1617 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
1618 return NULL_TREE;
1620 if (TREE_CODE (src) == SSA_NAME)
1622 gimple *def = SSA_NAME_DEF_STMT (src);
1623 if (is_gimple_assign (def)
1624 && gimple_assign_rhs_code (def) == ADDR_EXPR)
1625 src = gimple_assign_rhs1 (def);
1628 /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1629 NUL so that the difference between a pointer to just past it and
1630 one to its beginning is positive. */
1631 wide_int max = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2;
1633 if (TREE_CODE (src) == ADDR_EXPR)
1635 /* The last array member of a struct can be bigger than its size
1636 suggests if it's treated as a poor-man's flexible array member. */
1637 src = TREE_OPERAND (src, 0);
1638 if (TREE_CODE (src) != MEM_REF
1639 && !array_at_struct_end_p (src))
1641 tree type = TREE_TYPE (src);
1642 tree size = TYPE_SIZE_UNIT (type);
1643 if (size
1644 && TREE_CODE (size) == INTEGER_CST
1645 && !integer_zerop (size))
1647 /* Even though such uses of strlen would be undefined,
1648 avoid relying on arrays of arrays in case some genius
1649 decides to call strlen on an unterminated array element
1650 that's followed by a terminated one. Likewise, avoid
1651 assuming that a struct array member is necessarily
1652 nul-terminated (the nul may be in the member that
1653 follows). In those cases, assume that the length
1654 of the string stored in such an array is bounded
1655 by the size of the enclosing object if one can be
1656 determined. */
1657 tree base = get_base_address (src);
1658 if (VAR_P (base))
1660 if (tree size = DECL_SIZE_UNIT (base))
1661 if (size
1662 && TREE_CODE (size) == INTEGER_CST
1663 && TREE_CODE (TREE_TYPE (base)) != POINTER_TYPE)
1664 max = wi::to_wide (size);
1668 /* For strlen() the upper bound above is equal to
1669 the longest string that can be stored in the array
1670 (i.e., it accounts for the terminating nul. For
1671 strnlen() bump up the maximum by one since the array
1672 need not be nul-terminated. */
1673 if (!bound && max != 0)
1674 --max;
1678 wide_int min = wi::zero (max.get_precision ());
1679 return set_strlen_range (lhs, min, max, bound);
1682 /* Handle a strlen call. If strlen of the argument is known, replace
1683 the strlen call with the known value, otherwise remember that strlen
1684 of the argument is stored in the lhs SSA_NAME. */
1686 static void
1687 handle_builtin_strlen (gimple_stmt_iterator *gsi)
1689 gimple *stmt = gsi_stmt (*gsi);
1690 tree lhs = gimple_call_lhs (stmt);
1692 if (lhs == NULL_TREE)
1693 return;
1695 location_t loc = gimple_location (stmt);
1696 tree callee = gimple_call_fndecl (stmt);
1697 tree src = gimple_call_arg (stmt, 0);
1698 tree bound = (DECL_FUNCTION_CODE (callee) == BUILT_IN_STRNLEN
1699 ? gimple_call_arg (stmt, 1) : NULL_TREE);
1700 int idx = get_stridx (src);
1701 if (idx || (bound && integer_zerop (bound)))
1703 strinfo *si = NULL;
1704 tree rhs;
1706 if (idx < 0)
1707 rhs = build_int_cst (TREE_TYPE (lhs), ~idx);
1708 else if (idx == 0)
1709 rhs = bound;
1710 else
1712 rhs = NULL_TREE;
1713 si = get_strinfo (idx);
1714 if (si != NULL)
1716 rhs = get_string_length (si);
1717 /* For strnlen, if bound is constant, even if si is not known
1718 to be zero terminated, if we know at least bound bytes are
1719 not zero, the return value will be bound. */
1720 if (rhs == NULL_TREE
1721 && bound != NULL_TREE
1722 && TREE_CODE (bound) == INTEGER_CST
1723 && si->nonzero_chars != NULL_TREE
1724 && TREE_CODE (si->nonzero_chars) == INTEGER_CST
1725 && tree_int_cst_le (bound, si->nonzero_chars))
1726 rhs = bound;
1729 if (rhs != NULL_TREE)
1731 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
1733 fprintf (dump_file, "Optimizing: ");
1734 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1736 rhs = unshare_expr (rhs);
1737 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
1738 rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
1740 if (bound)
1741 rhs = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (rhs), rhs, bound);
1743 if (!update_call_from_tree (gsi, rhs))
1744 gimplify_and_update_call_from_tree (gsi, rhs);
1745 stmt = gsi_stmt (*gsi);
1746 update_stmt (stmt);
1747 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
1749 fprintf (dump_file, "into: ");
1750 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1753 if (si != NULL
1754 /* Don't update anything for strnlen. */
1755 && bound == NULL_TREE
1756 && TREE_CODE (si->nonzero_chars) != SSA_NAME
1757 && TREE_CODE (si->nonzero_chars) != INTEGER_CST
1758 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1760 si = unshare_strinfo (si);
1761 si->nonzero_chars = lhs;
1762 gcc_assert (si->full_string_p);
1765 if (strlen_to_stridx
1766 && (bound == NULL_TREE
1767 /* For strnlen record this only if the call is proven
1768 to return the same value as strlen would. */
1769 || (TREE_CODE (bound) == INTEGER_CST
1770 && TREE_CODE (rhs) == INTEGER_CST
1771 && tree_int_cst_lt (rhs, bound))))
1772 strlen_to_stridx->put (lhs, stridx_strlenloc (idx, loc));
1774 return;
1777 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1778 return;
1780 if (idx == 0)
1781 idx = new_stridx (src);
1782 else
1784 strinfo *si = get_strinfo (idx);
1785 if (si != NULL)
1787 if (!si->full_string_p && !si->stmt)
1789 /* Until now we only had a lower bound on the string length.
1790 Install LHS as the actual length. */
1791 si = unshare_strinfo (si);
1792 tree old = si->nonzero_chars;
1793 si->nonzero_chars = lhs;
1794 si->full_string_p = true;
1795 if (TREE_CODE (old) == INTEGER_CST)
1797 old = fold_convert_loc (loc, TREE_TYPE (lhs), old);
1798 tree adj = fold_build2_loc (loc, MINUS_EXPR,
1799 TREE_TYPE (lhs), lhs, old);
1800 adjust_related_strinfos (loc, si, adj);
1801 /* Use the constant minimim length as the lower bound
1802 of the non-constant length. */
1803 wide_int min = wi::to_wide (old);
1804 wide_int max
1805 = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2;
1806 set_strlen_range (lhs, min, max);
1808 else
1810 si->first = 0;
1811 si->prev = 0;
1812 si->next = 0;
1815 return;
1818 if (idx)
1820 if (!bound)
1822 /* Only store the new length information for calls to strlen(),
1823 not for those to strnlen(). */
1824 strinfo *si = new_strinfo (src, idx, lhs, true);
1825 set_strinfo (idx, si);
1826 find_equal_ptrs (src, idx);
1829 /* For SRC that is an array of N elements, set LHS's range
1830 to [0, min (N, BOUND)]. A constant return value means
1831 the range would have consisted of a single value. In
1832 that case, fold the result into the returned constant. */
1833 if (tree ret = maybe_set_strlen_range (lhs, src, bound))
1834 if (TREE_CODE (ret) == INTEGER_CST)
1836 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
1838 fprintf (dump_file, "Optimizing: ");
1839 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1841 if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (ret)))
1842 ret = fold_convert_loc (loc, TREE_TYPE (lhs), ret);
1843 if (!update_call_from_tree (gsi, ret))
1844 gimplify_and_update_call_from_tree (gsi, ret);
1845 stmt = gsi_stmt (*gsi);
1846 update_stmt (stmt);
1847 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
1849 fprintf (dump_file, "into: ");
1850 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1854 if (strlen_to_stridx && !bound)
1855 strlen_to_stridx->put (lhs, stridx_strlenloc (idx, loc));
1859 /* Handle a strchr call. If strlen of the first argument is known, replace
1860 the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
1861 that lhs of the call is endptr and strlen of the argument is endptr - x. */
1863 static void
1864 handle_builtin_strchr (gimple_stmt_iterator *gsi)
1866 int idx;
1867 tree src;
1868 gimple *stmt = gsi_stmt (*gsi);
1869 tree lhs = gimple_call_lhs (stmt);
1871 if (lhs == NULL_TREE)
1872 return;
1874 if (!integer_zerop (gimple_call_arg (stmt, 1)))
1875 return;
1877 src = gimple_call_arg (stmt, 0);
1878 idx = get_stridx (src);
1879 if (idx)
1881 strinfo *si = NULL;
1882 tree rhs;
1884 if (idx < 0)
1885 rhs = build_int_cst (size_type_node, ~idx);
1886 else
1888 rhs = NULL_TREE;
1889 si = get_strinfo (idx);
1890 if (si != NULL)
1891 rhs = get_string_length (si);
1893 if (rhs != NULL_TREE)
1895 location_t loc = gimple_location (stmt);
1897 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
1899 fprintf (dump_file, "Optimizing: ");
1900 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1902 if (si != NULL && si->endptr != NULL_TREE)
1904 rhs = unshare_expr (si->endptr);
1905 if (!useless_type_conversion_p (TREE_TYPE (lhs),
1906 TREE_TYPE (rhs)))
1907 rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
1909 else
1911 rhs = fold_convert_loc (loc, sizetype, unshare_expr (rhs));
1912 rhs = fold_build2_loc (loc, POINTER_PLUS_EXPR,
1913 TREE_TYPE (src), src, rhs);
1914 if (!useless_type_conversion_p (TREE_TYPE (lhs),
1915 TREE_TYPE (rhs)))
1916 rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
1918 if (!update_call_from_tree (gsi, rhs))
1919 gimplify_and_update_call_from_tree (gsi, rhs);
1920 stmt = gsi_stmt (*gsi);
1921 update_stmt (stmt);
1922 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
1924 fprintf (dump_file, "into: ");
1925 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1927 if (si != NULL
1928 && si->endptr == NULL_TREE
1929 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1931 si = unshare_strinfo (si);
1932 si->endptr = lhs;
1934 zero_length_string (lhs, si);
1935 return;
1938 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1939 return;
1940 if (TREE_CODE (src) != SSA_NAME || !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src))
1942 if (idx == 0)
1943 idx = new_stridx (src);
1944 else if (get_strinfo (idx) != NULL)
1946 zero_length_string (lhs, NULL);
1947 return;
1949 if (idx)
1951 location_t loc = gimple_location (stmt);
1952 tree lhsu = fold_convert_loc (loc, size_type_node, lhs);
1953 tree srcu = fold_convert_loc (loc, size_type_node, src);
1954 tree length = fold_build2_loc (loc, MINUS_EXPR,
1955 size_type_node, lhsu, srcu);
1956 strinfo *si = new_strinfo (src, idx, length, true);
1957 si->endptr = lhs;
1958 set_strinfo (idx, si);
1959 find_equal_ptrs (src, idx);
1960 zero_length_string (lhs, si);
1963 else
1964 zero_length_string (lhs, NULL);
1967 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
1968 If strlen of the second argument is known, strlen of the first argument
1969 is the same after this call. Furthermore, attempt to convert it to
1970 memcpy. */
1972 static void
1973 handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi)
1975 int idx, didx;
1976 tree src, dst, srclen, len, lhs, type, fn, oldlen;
1977 bool success;
1978 gimple *stmt = gsi_stmt (*gsi);
1979 strinfo *si, *dsi, *olddsi, *zsi;
1980 location_t loc;
1982 src = gimple_call_arg (stmt, 1);
1983 dst = gimple_call_arg (stmt, 0);
1984 lhs = gimple_call_lhs (stmt);
1985 idx = get_stridx (src);
1986 si = NULL;
1987 if (idx > 0)
1988 si = get_strinfo (idx);
1990 didx = get_stridx (dst);
1991 olddsi = NULL;
1992 oldlen = NULL_TREE;
1993 if (didx > 0)
1994 olddsi = get_strinfo (didx);
1995 else if (didx < 0)
1996 return;
1998 if (olddsi != NULL)
1999 adjust_last_stmt (olddsi, stmt, false);
2001 srclen = NULL_TREE;
2002 if (si != NULL)
2003 srclen = get_string_length (si);
2004 else if (idx < 0)
2005 srclen = build_int_cst (size_type_node, ~idx);
2007 loc = gimple_location (stmt);
2008 if (srclen == NULL_TREE)
2009 switch (bcode)
2011 case BUILT_IN_STRCPY:
2012 case BUILT_IN_STRCPY_CHK:
2013 if (lhs != NULL_TREE || !builtin_decl_implicit_p (BUILT_IN_STPCPY))
2014 return;
2015 break;
2016 case BUILT_IN_STPCPY:
2017 case BUILT_IN_STPCPY_CHK:
2018 if (lhs == NULL_TREE)
2019 return;
2020 else
2022 tree lhsuint = fold_convert_loc (loc, size_type_node, lhs);
2023 srclen = fold_convert_loc (loc, size_type_node, dst);
2024 srclen = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
2025 lhsuint, srclen);
2027 break;
2028 default:
2029 gcc_unreachable ();
2032 if (didx == 0)
2034 didx = new_stridx (dst);
2035 if (didx == 0)
2036 return;
2038 if (olddsi != NULL)
2040 oldlen = olddsi->nonzero_chars;
2041 dsi = unshare_strinfo (olddsi);
2042 dsi->nonzero_chars = srclen;
2043 dsi->full_string_p = (srclen != NULL_TREE);
2044 /* Break the chain, so adjust_related_strinfo on later pointers in
2045 the chain won't adjust this one anymore. */
2046 dsi->next = 0;
2047 dsi->stmt = NULL;
2048 dsi->endptr = NULL_TREE;
2050 else
2052 dsi = new_strinfo (dst, didx, srclen, srclen != NULL_TREE);
2053 set_strinfo (didx, dsi);
2054 find_equal_ptrs (dst, didx);
2056 dsi->writable = true;
2057 dsi->dont_invalidate = true;
2059 if (dsi->nonzero_chars == NULL_TREE)
2061 strinfo *chainsi;
2063 /* If string length of src is unknown, use delayed length
2064 computation. If string lenth of dst will be needed, it
2065 can be computed by transforming this strcpy call into
2066 stpcpy and subtracting dst from the return value. */
2068 /* Look for earlier strings whose length could be determined if
2069 this strcpy is turned into an stpcpy. */
2071 if (dsi->prev != 0 && (chainsi = verify_related_strinfos (dsi)) != NULL)
2073 for (; chainsi && chainsi != dsi; chainsi = get_strinfo (chainsi->next))
2075 /* When setting a stmt for delayed length computation
2076 prevent all strinfos through dsi from being
2077 invalidated. */
2078 chainsi = unshare_strinfo (chainsi);
2079 chainsi->stmt = stmt;
2080 chainsi->nonzero_chars = NULL_TREE;
2081 chainsi->full_string_p = false;
2082 chainsi->endptr = NULL_TREE;
2083 chainsi->dont_invalidate = true;
2086 dsi->stmt = stmt;
2088 /* Try to detect overlap before returning. This catches cases
2089 like strcpy (d, d + n) where n is non-constant whose range
2090 is such that (n <= strlen (d) holds).
2092 OLDDSI->NONZERO_chars may have been reset by this point with
2093 oldlen holding it original value. */
2094 if (olddsi && oldlen)
2096 /* Add 1 for the terminating NUL. */
2097 tree type = TREE_TYPE (oldlen);
2098 oldlen = fold_build2 (PLUS_EXPR, type, oldlen,
2099 build_int_cst (type, 1));
2100 check_bounds_or_overlap (stmt, olddsi->ptr, src, oldlen, NULL_TREE);
2103 return;
2106 if (olddsi != NULL)
2108 tree adj = NULL_TREE;
2109 if (oldlen == NULL_TREE)
2111 else if (integer_zerop (oldlen))
2112 adj = srclen;
2113 else if (TREE_CODE (oldlen) == INTEGER_CST
2114 || TREE_CODE (srclen) == INTEGER_CST)
2115 adj = fold_build2_loc (loc, MINUS_EXPR,
2116 TREE_TYPE (srclen), srclen,
2117 fold_convert_loc (loc, TREE_TYPE (srclen),
2118 oldlen));
2119 if (adj != NULL_TREE)
2120 adjust_related_strinfos (loc, dsi, adj);
2121 else
2122 dsi->prev = 0;
2124 /* strcpy src may not overlap dst, so src doesn't need to be
2125 invalidated either. */
2126 if (si != NULL)
2127 si->dont_invalidate = true;
2129 fn = NULL_TREE;
2130 zsi = NULL;
2131 switch (bcode)
2133 case BUILT_IN_STRCPY:
2134 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2135 if (lhs)
2136 ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
2137 break;
2138 case BUILT_IN_STRCPY_CHK:
2139 fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
2140 if (lhs)
2141 ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
2142 break;
2143 case BUILT_IN_STPCPY:
2144 /* This would need adjustment of the lhs (subtract one),
2145 or detection that the trailing '\0' doesn't need to be
2146 written, if it will be immediately overwritten.
2147 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); */
2148 if (lhs)
2150 dsi->endptr = lhs;
2151 zsi = zero_length_string (lhs, dsi);
2153 break;
2154 case BUILT_IN_STPCPY_CHK:
2155 /* This would need adjustment of the lhs (subtract one),
2156 or detection that the trailing '\0' doesn't need to be
2157 written, if it will be immediately overwritten.
2158 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK); */
2159 if (lhs)
2161 dsi->endptr = lhs;
2162 zsi = zero_length_string (lhs, dsi);
2164 break;
2165 default:
2166 gcc_unreachable ();
2168 if (zsi != NULL)
2169 zsi->dont_invalidate = true;
2171 if (fn)
2173 tree args = TYPE_ARG_TYPES (TREE_TYPE (fn));
2174 type = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
2176 else
2177 type = size_type_node;
2179 len = fold_convert_loc (loc, type, unshare_expr (srclen));
2180 len = fold_build2_loc (loc, PLUS_EXPR, type, len, build_int_cst (type, 1));
2182 /* Set the no-warning bit on the transformed statement? */
2183 bool set_no_warning = false;
2185 if (const strinfo *chksi = olddsi ? olddsi : dsi)
2186 if (si
2187 && check_bounds_or_overlap (stmt, chksi->ptr, si->ptr, NULL_TREE, len))
2189 gimple_set_no_warning (stmt, true);
2190 set_no_warning = true;
2193 if (fn == NULL_TREE)
2194 return;
2196 len = force_gimple_operand_gsi (gsi, len, true, NULL_TREE, true,
2197 GSI_SAME_STMT);
2198 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2200 fprintf (dump_file, "Optimizing: ");
2201 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2203 if (gimple_call_num_args (stmt) == 2)
2204 success = update_gimple_call (gsi, fn, 3, dst, src, len);
2205 else
2206 success = update_gimple_call (gsi, fn, 4, dst, src, len,
2207 gimple_call_arg (stmt, 2));
2208 if (success)
2210 stmt = gsi_stmt (*gsi);
2211 update_stmt (stmt);
2212 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2214 fprintf (dump_file, "into: ");
2215 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2217 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2218 laststmt.stmt = stmt;
2219 laststmt.len = srclen;
2220 laststmt.stridx = dsi->idx;
2222 else if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2223 fprintf (dump_file, "not possible.\n");
2225 if (set_no_warning)
2226 gimple_set_no_warning (stmt, true);
2229 /* Check the size argument to the built-in forms of stpncpy and strncpy
2230 for out-of-bounds offsets or overlapping access, and to see if the
2231 size argument is derived from a call to strlen() on the source argument,
2232 and if so, issue an appropriate warning. */
2234 static void
2235 handle_builtin_strncat (built_in_function bcode, gimple_stmt_iterator *gsi)
2237 /* Same as stxncpy(). */
2238 handle_builtin_stxncpy (bcode, gsi);
2241 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2242 way. LEN can either be an integer expression, or a pointer (to char).
2243 When it is the latter (such as in recursive calls to self) is is
2244 assumed to be the argument in some call to strlen() whose relationship
2245 to SRC is being ascertained. */
2247 bool
2248 is_strlen_related_p (tree src, tree len)
2250 if (TREE_CODE (TREE_TYPE (len)) == POINTER_TYPE
2251 && operand_equal_p (src, len, 0))
2252 return true;
2254 if (TREE_CODE (len) != SSA_NAME)
2255 return false;
2257 gimple *def_stmt = SSA_NAME_DEF_STMT (len);
2258 if (!def_stmt)
2259 return false;
2261 if (is_gimple_call (def_stmt))
2263 tree func = gimple_call_fndecl (def_stmt);
2264 if (!valid_builtin_call (def_stmt)
2265 || DECL_FUNCTION_CODE (func) != BUILT_IN_STRLEN)
2266 return false;
2268 tree arg = gimple_call_arg (def_stmt, 0);
2269 return is_strlen_related_p (src, arg);
2272 if (!is_gimple_assign (def_stmt))
2273 return false;
2275 tree_code code = gimple_assign_rhs_code (def_stmt);
2276 tree rhs1 = gimple_assign_rhs1 (def_stmt);
2277 tree rhstype = TREE_TYPE (rhs1);
2279 if ((TREE_CODE (rhstype) == POINTER_TYPE && code == POINTER_PLUS_EXPR)
2280 || (INTEGRAL_TYPE_P (rhstype)
2281 && (code == BIT_AND_EXPR
2282 || code == NOP_EXPR)))
2284 /* Pointer plus (an integer), and truncation are considered among
2285 the (potentially) related expressions to strlen. */
2286 return is_strlen_related_p (src, rhs1);
2289 if (tree rhs2 = gimple_assign_rhs2 (def_stmt))
2291 /* Integer subtraction is considered strlen-related when both
2292 arguments are integers and second one is strlen-related. */
2293 rhstype = TREE_TYPE (rhs2);
2294 if (INTEGRAL_TYPE_P (rhstype) && code == MINUS_EXPR)
2295 return is_strlen_related_p (src, rhs2);
2298 return false;
2301 /* Called by handle_builtin_stxncpy and by gimple_fold_builtin_strncpy
2302 in gimple-fold.c.
2303 Check to see if the specified bound is a) equal to the size of
2304 the destination DST and if so, b) if it's immediately followed by
2305 DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise,
2306 do nothing. Return true if diagnostic has been issued.
2308 The purpose is to diagnose calls to strncpy and stpncpy that do
2309 not nul-terminate the copy while allowing for the idiom where
2310 such a call is immediately followed by setting the last element
2311 to nul, as in:
2312 char a[32];
2313 strncpy (a, s, sizeof a);
2314 a[sizeof a - 1] = '\0';
2317 bool
2318 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
2320 gimple *stmt = gsi_stmt (gsi);
2321 if (gimple_no_warning_p (stmt))
2322 return false;
2324 wide_int cntrange[2];
2326 if (TREE_CODE (cnt) == INTEGER_CST)
2327 cntrange[0] = cntrange[1] = wi::to_wide (cnt);
2328 else if (TREE_CODE (cnt) == SSA_NAME)
2330 enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
2331 if (rng == VR_RANGE)
2333 else if (rng == VR_ANTI_RANGE)
2335 wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));
2337 if (wi::ltu_p (cntrange[1], maxobjsize))
2339 cntrange[0] = cntrange[1] + 1;
2340 cntrange[1] = maxobjsize;
2342 else
2344 cntrange[1] = cntrange[0] - 1;
2345 cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt)));
2348 else
2349 return false;
2351 else
2352 return false;
2354 /* Negative value is the constant string length. If it's less than
2355 the lower bound there is no truncation. Avoid calling get_stridx()
2356 when ssa_ver_to_stridx is empty. That implies the caller isn't
2357 running under the control of this pass and ssa_ver_to_stridx hasn't
2358 been created yet. */
2359 int sidx = ssa_ver_to_stridx.length () ? get_stridx (src) : 0;
2360 if (sidx < 0 && wi::gtu_p (cntrange[0], ~sidx))
2361 return false;
2363 tree dst = gimple_call_arg (stmt, 0);
2364 tree dstdecl = dst;
2365 if (TREE_CODE (dstdecl) == ADDR_EXPR)
2366 dstdecl = TREE_OPERAND (dstdecl, 0);
2368 tree ref = NULL_TREE;
2370 if (!sidx)
2372 /* If the source is a non-string return early to avoid warning
2373 for possible truncation (if the truncation is certain SIDX
2374 is non-zero). */
2375 tree srcdecl = gimple_call_arg (stmt, 1);
2376 if (TREE_CODE (srcdecl) == ADDR_EXPR)
2377 srcdecl = TREE_OPERAND (srcdecl, 0);
2378 if (get_attr_nonstring_decl (srcdecl, &ref))
2379 return false;
2382 /* Likewise, if the destination refers to a an array/pointer declared
2383 nonstring return early. */
2384 if (get_attr_nonstring_decl (dstdecl, &ref))
2385 return false;
2387 /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2388 avoid the truncation warning. */
2389 gsi_next_nondebug (&gsi);
2390 gimple *next_stmt = gsi_stmt (gsi);
2391 if (!next_stmt)
2393 /* When there is no statement in the same basic block check
2394 the immediate successor block. */
2395 if (basic_block bb = gimple_bb (stmt))
2397 if (single_succ_p (bb))
2399 /* For simplicity, ignore blocks with multiple outgoing
2400 edges for now and only consider successor blocks along
2401 normal edges. */
2402 edge e = EDGE_SUCC (bb, 0);
2403 if (!(e->flags & EDGE_ABNORMAL))
2405 gsi = gsi_start_bb (e->dest);
2406 next_stmt = gsi_stmt (gsi);
2407 if (next_stmt && is_gimple_debug (next_stmt))
2409 gsi_next_nondebug (&gsi);
2410 next_stmt = gsi_stmt (gsi);
2417 if (next_stmt && is_gimple_assign (next_stmt))
2419 tree lhs = gimple_assign_lhs (next_stmt);
2420 tree_code code = TREE_CODE (lhs);
2421 if (code == ARRAY_REF || code == MEM_REF)
2422 lhs = TREE_OPERAND (lhs, 0);
2424 tree func = gimple_call_fndecl (stmt);
2425 if (DECL_FUNCTION_CODE (func) == BUILT_IN_STPNCPY)
2427 tree ret = gimple_call_lhs (stmt);
2428 if (ret && operand_equal_p (ret, lhs, 0))
2429 return false;
2432 /* Determine the base address and offset of the reference,
2433 ignoring the innermost array index. */
2434 if (TREE_CODE (ref) == ARRAY_REF)
2435 ref = TREE_OPERAND (ref, 0);
2437 poly_int64 dstoff;
2438 tree dstbase = get_addr_base_and_unit_offset (ref, &dstoff);
2440 poly_int64 lhsoff;
2441 tree lhsbase = get_addr_base_and_unit_offset (lhs, &lhsoff);
2442 if (lhsbase
2443 && dstbase
2444 && known_eq (dstoff, lhsoff)
2445 && operand_equal_p (dstbase, lhsbase, 0))
2446 return false;
2449 int prec = TYPE_PRECISION (TREE_TYPE (cnt));
2450 wide_int lenrange[2];
2451 if (strinfo *sisrc = sidx > 0 ? get_strinfo (sidx) : NULL)
2453 lenrange[0] = (sisrc->nonzero_chars
2454 && TREE_CODE (sisrc->nonzero_chars) == INTEGER_CST
2455 ? wi::to_wide (sisrc->nonzero_chars)
2456 : wi::zero (prec));
2457 lenrange[1] = lenrange[0];
2459 else if (sidx < 0)
2460 lenrange[0] = lenrange[1] = wi::shwi (~sidx, prec);
2461 else
2463 c_strlen_data lendata = { };
2464 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
2465 to have it set to the length of the longest string in a PHI. */
2466 lendata.maxbound = src;
2467 get_range_strlen (src, &lendata, /* eltsize = */1);
2468 if (TREE_CODE (lendata.minlen) == INTEGER_CST
2469 && TREE_CODE (lendata.maxbound) == INTEGER_CST)
2471 /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
2472 which stores the length of the shortest known string. */
2473 if (integer_all_onesp (lendata.maxlen))
2474 lenrange[0] = wi::shwi (0, prec);
2475 else
2476 lenrange[0] = wi::to_wide (lendata.minlen, prec);
2477 lenrange[1] = wi::to_wide (lendata.maxbound, prec);
2479 else
2481 lenrange[0] = wi::shwi (0, prec);
2482 lenrange[1] = wi::shwi (-1, prec);
2486 location_t callloc = gimple_nonartificial_location (stmt);
2487 callloc = expansion_point_location_if_in_system_header (callloc);
2489 tree func = gimple_call_fndecl (stmt);
2491 if (lenrange[0] != 0 || !wi::neg_p (lenrange[1]))
2493 /* If the longest source string is shorter than the lower bound
2494 of the specified count the copy is definitely nul-terminated. */
2495 if (wi::ltu_p (lenrange[1], cntrange[0]))
2496 return false;
2498 if (wi::neg_p (lenrange[1]))
2500 /* The length of one of the strings is unknown but at least
2501 one has non-zero length and that length is stored in
2502 LENRANGE[1]. Swap the bounds to force a "may be truncated"
2503 warning below. */
2504 lenrange[1] = lenrange[0];
2505 lenrange[0] = wi::shwi (0, prec);
2508 /* Set to true for strncat whose bound is derived from the length
2509 of the destination (the expected usage pattern). */
2510 bool cat_dstlen_bounded = false;
2511 if (DECL_FUNCTION_CODE (func) == BUILT_IN_STRNCAT)
2512 cat_dstlen_bounded = is_strlen_related_p (dst, cnt);
2514 if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1])
2515 return warning_n (callloc, OPT_Wstringop_truncation,
2516 cntrange[0].to_uhwi (),
2517 "%G%qD output truncated before terminating "
2518 "nul copying %E byte from a string of the "
2519 "same length",
2520 "%G%qD output truncated before terminating nul "
2521 "copying %E bytes from a string of the same "
2522 "length",
2523 stmt, func, cnt);
2524 else if (!cat_dstlen_bounded)
2526 if (wi::geu_p (lenrange[0], cntrange[1]))
2528 /* The shortest string is longer than the upper bound of
2529 the count so the truncation is certain. */
2530 if (cntrange[0] == cntrange[1])
2531 return warning_n (callloc, OPT_Wstringop_truncation,
2532 cntrange[0].to_uhwi (),
2533 "%G%qD output truncated copying %E byte "
2534 "from a string of length %wu",
2535 "%G%qD output truncated copying %E bytes "
2536 "from a string of length %wu",
2537 stmt, func, cnt, lenrange[0].to_uhwi ());
2539 return warning_at (callloc, OPT_Wstringop_truncation,
2540 "%G%qD output truncated copying between %wu "
2541 "and %wu bytes from a string of length %wu",
2542 stmt, func, cntrange[0].to_uhwi (),
2543 cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
2545 else if (wi::geu_p (lenrange[1], cntrange[1]))
2547 /* The longest string is longer than the upper bound of
2548 the count so the truncation is possible. */
2549 if (cntrange[0] == cntrange[1])
2550 return warning_n (callloc, OPT_Wstringop_truncation,
2551 cntrange[0].to_uhwi (),
2552 "%G%qD output may be truncated copying %E "
2553 "byte from a string of length %wu",
2554 "%G%qD output may be truncated copying %E "
2555 "bytes from a string of length %wu",
2556 stmt, func, cnt, lenrange[1].to_uhwi ());
2558 return warning_at (callloc, OPT_Wstringop_truncation,
2559 "%G%qD output may be truncated copying between "
2560 "%wu and %wu bytes from a string of length %wu",
2561 stmt, func, cntrange[0].to_uhwi (),
2562 cntrange[1].to_uhwi (), lenrange[1].to_uhwi ());
2566 if (!cat_dstlen_bounded
2567 && cntrange[0] != cntrange[1]
2568 && wi::leu_p (cntrange[0], lenrange[0])
2569 && wi::leu_p (cntrange[1], lenrange[0] + 1))
2571 /* If the source (including the terminating nul) is longer than
2572 the lower bound of the specified count but shorter than the
2573 upper bound the copy may (but need not) be truncated. */
2574 return warning_at (callloc, OPT_Wstringop_truncation,
2575 "%G%qD output may be truncated copying between "
2576 "%wu and %wu bytes from a string of length %wu",
2577 stmt, func, cntrange[0].to_uhwi (),
2578 cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
2582 if (tree dstsize = compute_objsize (dst, 1))
2584 /* The source length is uknown. Try to determine the destination
2585 size and see if it matches the specified bound. If not, bail.
2586 Otherwise go on to see if it should be diagnosed for possible
2587 truncation. */
2588 if (!dstsize)
2589 return false;
2591 if (wi::to_wide (dstsize) != cntrange[1])
2592 return false;
2594 /* Avoid warning for strncpy(a, b, N) calls where the following
2595 equalities hold:
2596 N == sizeof a && N == sizeof b */
2597 if (tree srcsize = compute_objsize (src, 1))
2598 if (wi::to_wide (srcsize) == cntrange[1])
2599 return false;
2601 if (cntrange[0] == cntrange[1])
2602 return warning_at (callloc, OPT_Wstringop_truncation,
2603 "%G%qD specified bound %E equals destination size",
2604 stmt, func, cnt);
2607 return false;
2610 /* Check the arguments to the built-in forms of stpncpy and strncpy for
2611 out-of-bounds offsets or overlapping access, and to see if the size
2612 is derived from calling strlen() on the source argument, and if so,
2613 issue the appropriate warning. */
2615 static void
2616 handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *gsi)
2618 if (!strlen_to_stridx)
2619 return;
2621 gimple *stmt = gsi_stmt (*gsi);
2623 tree dst = gimple_call_arg (stmt, 0);
2624 tree src = gimple_call_arg (stmt, 1);
2625 tree len = gimple_call_arg (stmt, 2);
2626 tree dstsize = NULL_TREE, srcsize = NULL_TREE;
2628 int didx = get_stridx (dst);
2629 if (strinfo *sidst = didx > 0 ? get_strinfo (didx) : NULL)
2631 /* Compute the size of the destination string including the nul
2632 if it is known to be nul-terminated. */
2633 if (sidst->nonzero_chars)
2635 if (sidst->full_string_p)
2637 /* String is known to be nul-terminated. */
2638 tree type = TREE_TYPE (sidst->nonzero_chars);
2639 dstsize = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
2640 build_int_cst (type, 1));
2642 else
2643 dstsize = sidst->nonzero_chars;
2646 dst = sidst->ptr;
2649 int sidx = get_stridx (src);
2650 strinfo *sisrc = sidx > 0 ? get_strinfo (sidx) : NULL;
2651 if (sisrc)
2653 /* strncat() and strncpy() can modify the source string by writing
2654 over the terminating nul so SISRC->DONT_INVALIDATE must be left
2655 clear. */
2657 /* Compute the size of the source string including the terminating
2658 nul if its known to be nul-terminated. */
2659 if (sisrc->nonzero_chars)
2661 if (sisrc->full_string_p)
2663 tree type = TREE_TYPE (sisrc->nonzero_chars);
2664 srcsize = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
2665 build_int_cst (type, 1));
2667 else
2668 srcsize = sisrc->nonzero_chars;
2671 src = sisrc->ptr;
2673 else
2674 srcsize = NULL_TREE;
2676 if (check_bounds_or_overlap (stmt, dst, src, dstsize, srcsize))
2678 gimple_set_no_warning (stmt, true);
2679 return;
2682 /* If the length argument was computed from strlen(S) for some string
2683 S retrieve the strinfo index for the string (PSS->FIRST) alonng with
2684 the location of the strlen() call (PSS->SECOND). */
2685 stridx_strlenloc *pss = strlen_to_stridx->get (len);
2686 if (!pss || pss->first <= 0)
2688 if (maybe_diag_stxncpy_trunc (*gsi, src, len))
2689 gimple_set_no_warning (stmt, true);
2691 return;
2694 /* Retrieve the strinfo data for the string S that LEN was computed
2695 from as some function F of strlen (S) (i.e., LEN need not be equal
2696 to strlen(S)). */
2697 strinfo *silen = get_strinfo (pss->first);
2699 location_t callloc = gimple_nonartificial_location (stmt);
2700 callloc = expansion_point_location_if_in_system_header (callloc);
2702 tree func = gimple_call_fndecl (stmt);
2704 bool warned = false;
2706 /* When -Wstringop-truncation is set, try to determine truncation
2707 before diagnosing possible overflow. Truncation is implied by
2708 the LEN argument being equal to strlen(SRC), regardless of
2709 whether its value is known. Otherwise, issue the more generic
2710 -Wstringop-overflow which triggers for LEN arguments that in
2711 any meaningful way depend on strlen(SRC). */
2712 if (sisrc == silen
2713 && is_strlen_related_p (src, len)
2714 && warning_at (callloc, OPT_Wstringop_truncation,
2715 "%G%qD output truncated before terminating nul "
2716 "copying as many bytes from a string as its length",
2717 stmt, func))
2718 warned = true;
2719 else if (silen && is_strlen_related_p (src, silen->ptr))
2720 warned = warning_at (callloc, OPT_Wstringop_overflow_,
2721 "%G%qD specified bound depends on the length "
2722 "of the source argument",
2723 stmt, func);
2724 if (warned)
2726 location_t strlenloc = pss->second;
2727 if (strlenloc != UNKNOWN_LOCATION && strlenloc != callloc)
2728 inform (strlenloc, "length computed here");
2732 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
2733 If strlen of the second argument is known and length of the third argument
2734 is that plus one, strlen of the first argument is the same after this
2735 call. */
2737 static void
2738 handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi)
2740 int idx, didx;
2741 tree src, dst, len, lhs, oldlen, newlen;
2742 gimple *stmt = gsi_stmt (*gsi);
2743 strinfo *si, *dsi, *olddsi;
2745 len = gimple_call_arg (stmt, 2);
2746 src = gimple_call_arg (stmt, 1);
2747 dst = gimple_call_arg (stmt, 0);
2748 idx = get_stridx (src);
2749 if (idx == 0)
2750 return;
2752 didx = get_stridx (dst);
2753 olddsi = NULL;
2754 if (didx > 0)
2755 olddsi = get_strinfo (didx);
2756 else if (didx < 0)
2757 return;
2759 if (olddsi != NULL
2760 && tree_fits_uhwi_p (len)
2761 && !integer_zerop (len))
2762 adjust_last_stmt (olddsi, stmt, false);
2764 bool full_string_p;
2765 if (idx > 0)
2767 gimple *def_stmt;
2769 /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
2770 is known. */
2771 si = get_strinfo (idx);
2772 if (si == NULL || si->nonzero_chars == NULL_TREE)
2773 return;
2774 if (TREE_CODE (len) == INTEGER_CST
2775 && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
2777 if (tree_int_cst_le (len, si->nonzero_chars))
2779 /* Copying LEN nonzero characters, where LEN is constant. */
2780 newlen = len;
2781 full_string_p = false;
2783 else
2785 /* Copying the whole of the analyzed part of SI. */
2786 newlen = si->nonzero_chars;
2787 full_string_p = si->full_string_p;
2790 else
2792 if (!si->full_string_p)
2793 return;
2794 if (TREE_CODE (len) != SSA_NAME)
2795 return;
2796 def_stmt = SSA_NAME_DEF_STMT (len);
2797 if (!is_gimple_assign (def_stmt)
2798 || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
2799 || gimple_assign_rhs1 (def_stmt) != si->nonzero_chars
2800 || !integer_onep (gimple_assign_rhs2 (def_stmt)))
2801 return;
2802 /* Copying variable-length string SI (and no more). */
2803 newlen = si->nonzero_chars;
2804 full_string_p = true;
2807 else
2809 si = NULL;
2810 /* Handle memcpy (x, "abcd", 5) or
2811 memcpy (x, "abc\0uvw", 7). */
2812 if (!tree_fits_uhwi_p (len))
2813 return;
2815 unsigned HOST_WIDE_INT clen = tree_to_uhwi (len);
2816 unsigned HOST_WIDE_INT nonzero_chars = ~idx;
2817 newlen = build_int_cst (size_type_node, MIN (nonzero_chars, clen));
2818 full_string_p = clen > nonzero_chars;
2821 if (!full_string_p
2822 && olddsi
2823 && olddsi->nonzero_chars
2824 && TREE_CODE (olddsi->nonzero_chars) == INTEGER_CST
2825 && tree_int_cst_le (newlen, olddsi->nonzero_chars))
2827 /* The SRC substring being written strictly overlaps
2828 a subsequence of the existing string OLDDSI. */
2829 newlen = olddsi->nonzero_chars;
2830 full_string_p = olddsi->full_string_p;
2833 if (olddsi != NULL && TREE_CODE (len) == SSA_NAME)
2834 adjust_last_stmt (olddsi, stmt, false);
2836 if (didx == 0)
2838 didx = new_stridx (dst);
2839 if (didx == 0)
2840 return;
2842 oldlen = NULL_TREE;
2843 if (olddsi != NULL)
2845 dsi = unshare_strinfo (olddsi);
2846 oldlen = olddsi->nonzero_chars;
2847 dsi->nonzero_chars = newlen;
2848 dsi->full_string_p = full_string_p;
2849 /* Break the chain, so adjust_related_strinfo on later pointers in
2850 the chain won't adjust this one anymore. */
2851 dsi->next = 0;
2852 dsi->stmt = NULL;
2853 dsi->endptr = NULL_TREE;
2855 else
2857 dsi = new_strinfo (dst, didx, newlen, full_string_p);
2858 set_strinfo (didx, dsi);
2859 find_equal_ptrs (dst, didx);
2861 dsi->writable = true;
2862 dsi->dont_invalidate = true;
2863 if (olddsi != NULL)
2865 tree adj = NULL_TREE;
2866 location_t loc = gimple_location (stmt);
2867 if (oldlen == NULL_TREE)
2869 else if (integer_zerop (oldlen))
2870 adj = newlen;
2871 else if (TREE_CODE (oldlen) == INTEGER_CST
2872 || TREE_CODE (newlen) == INTEGER_CST)
2873 adj = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (newlen), newlen,
2874 fold_convert_loc (loc, TREE_TYPE (newlen),
2875 oldlen));
2876 if (adj != NULL_TREE)
2877 adjust_related_strinfos (loc, dsi, adj);
2878 else
2879 dsi->prev = 0;
2881 /* memcpy src may not overlap dst, so src doesn't need to be
2882 invalidated either. */
2883 if (si != NULL)
2884 si->dont_invalidate = true;
2886 if (full_string_p)
2888 lhs = gimple_call_lhs (stmt);
2889 switch (bcode)
2891 case BUILT_IN_MEMCPY:
2892 case BUILT_IN_MEMCPY_CHK:
2893 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2894 laststmt.stmt = stmt;
2895 laststmt.len = dsi->nonzero_chars;
2896 laststmt.stridx = dsi->idx;
2897 if (lhs)
2898 ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
2899 break;
2900 case BUILT_IN_MEMPCPY:
2901 case BUILT_IN_MEMPCPY_CHK:
2902 break;
2903 default:
2904 gcc_unreachable ();
2909 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
2910 If strlen of the second argument is known, strlen of the first argument
2911 is increased by the length of the second argument. Furthermore, attempt
2912 to convert it to memcpy/strcpy if the length of the first argument
2913 is known. */
2915 static void
2916 handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi)
2918 int idx, didx;
2919 tree srclen, args, type, fn, objsz, endptr;
2920 bool success;
2921 gimple *stmt = gsi_stmt (*gsi);
2922 strinfo *si, *dsi;
2923 location_t loc = gimple_location (stmt);
2925 tree src = gimple_call_arg (stmt, 1);
2926 tree dst = gimple_call_arg (stmt, 0);
2928 /* Bail if the source is the same as destination. It will be diagnosed
2929 elsewhere. */
2930 if (operand_equal_p (src, dst, 0))
2931 return;
2933 tree lhs = gimple_call_lhs (stmt);
2935 didx = get_stridx (dst);
2936 if (didx < 0)
2937 return;
2939 dsi = NULL;
2940 if (didx > 0)
2941 dsi = get_strinfo (didx);
2943 srclen = NULL_TREE;
2944 si = NULL;
2945 idx = get_stridx (src);
2946 if (idx < 0)
2947 srclen = build_int_cst (size_type_node, ~idx);
2948 else if (idx > 0)
2950 si = get_strinfo (idx);
2951 if (si != NULL)
2952 srclen = get_string_length (si);
2955 /* Set the no-warning bit on the transformed statement? */
2956 bool set_no_warning = false;
2958 if (dsi == NULL || get_string_length (dsi) == NULL_TREE)
2961 /* The concatenation always involves copying at least one byte
2962 (the terminating nul), even if the source string is empty.
2963 If the source is unknown assume it's one character long and
2964 used that as both sizes. */
2965 tree slen = srclen;
2966 if (slen)
2968 tree type = TREE_TYPE (slen);
2969 slen = fold_build2 (PLUS_EXPR, type, slen, build_int_cst (type, 1));
2972 tree sptr = si && si->ptr ? si->ptr : src;
2974 if (check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE, slen))
2976 gimple_set_no_warning (stmt, true);
2977 set_no_warning = true;
2981 /* strcat (p, q) can be transformed into
2982 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
2983 with length endptr - p if we need to compute the length
2984 later on. Don't do this transformation if we don't need
2985 it. */
2986 if (builtin_decl_implicit_p (BUILT_IN_STPCPY) && lhs == NULL_TREE)
2988 if (didx == 0)
2990 didx = new_stridx (dst);
2991 if (didx == 0)
2992 return;
2994 if (dsi == NULL)
2996 dsi = new_strinfo (dst, didx, NULL_TREE, false);
2997 set_strinfo (didx, dsi);
2998 find_equal_ptrs (dst, didx);
3000 else
3002 dsi = unshare_strinfo (dsi);
3003 dsi->nonzero_chars = NULL_TREE;
3004 dsi->full_string_p = false;
3005 dsi->next = 0;
3006 dsi->endptr = NULL_TREE;
3008 dsi->writable = true;
3009 dsi->stmt = stmt;
3010 dsi->dont_invalidate = true;
3012 return;
3015 tree dstlen = dsi->nonzero_chars;
3016 endptr = dsi->endptr;
3018 dsi = unshare_strinfo (dsi);
3019 dsi->endptr = NULL_TREE;
3020 dsi->stmt = NULL;
3021 dsi->writable = true;
3023 if (srclen != NULL_TREE)
3025 dsi->nonzero_chars = fold_build2_loc (loc, PLUS_EXPR,
3026 TREE_TYPE (dsi->nonzero_chars),
3027 dsi->nonzero_chars, srclen);
3028 gcc_assert (dsi->full_string_p);
3029 adjust_related_strinfos (loc, dsi, srclen);
3030 dsi->dont_invalidate = true;
3032 else
3034 dsi->nonzero_chars = NULL;
3035 dsi->full_string_p = false;
3036 if (lhs == NULL_TREE && builtin_decl_implicit_p (BUILT_IN_STPCPY))
3037 dsi->dont_invalidate = true;
3040 if (si != NULL)
3041 /* strcat src may not overlap dst, so src doesn't need to be
3042 invalidated either. */
3043 si->dont_invalidate = true;
3045 /* For now. Could remove the lhs from the call and add
3046 lhs = dst; afterwards. */
3047 if (lhs)
3048 return;
3050 fn = NULL_TREE;
3051 objsz = NULL_TREE;
3052 switch (bcode)
3054 case BUILT_IN_STRCAT:
3055 if (srclen != NULL_TREE)
3056 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3057 else
3058 fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3059 break;
3060 case BUILT_IN_STRCAT_CHK:
3061 if (srclen != NULL_TREE)
3062 fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3063 else
3064 fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
3065 objsz = gimple_call_arg (stmt, 2);
3066 break;
3067 default:
3068 gcc_unreachable ();
3071 if (fn == NULL_TREE)
3072 return;
3074 if (dsi && dstlen)
3076 tree type = TREE_TYPE (dstlen);
3078 /* Compute the size of the source sequence, including the nul. */
3079 tree srcsize = srclen ? srclen : size_zero_node;
3080 tree one = build_int_cst (type, 1);
3081 srcsize = fold_build2 (PLUS_EXPR, type, srcsize, one);
3082 tree dstsize = fold_build2 (PLUS_EXPR, type, dstlen, one);
3083 tree sptr = si && si->ptr ? si->ptr : src;
3085 if (check_bounds_or_overlap (stmt, dst, sptr, dstsize, srcsize))
3087 gimple_set_no_warning (stmt, true);
3088 set_no_warning = true;
3092 tree len = NULL_TREE;
3093 if (srclen != NULL_TREE)
3095 args = TYPE_ARG_TYPES (TREE_TYPE (fn));
3096 type = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
3098 len = fold_convert_loc (loc, type, unshare_expr (srclen));
3099 len = fold_build2_loc (loc, PLUS_EXPR, type, len,
3100 build_int_cst (type, 1));
3101 len = force_gimple_operand_gsi (gsi, len, true, NULL_TREE, true,
3102 GSI_SAME_STMT);
3104 if (endptr)
3105 dst = fold_convert_loc (loc, TREE_TYPE (dst), unshare_expr (endptr));
3106 else
3107 dst = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dst), dst,
3108 fold_convert_loc (loc, sizetype,
3109 unshare_expr (dstlen)));
3110 dst = force_gimple_operand_gsi (gsi, dst, true, NULL_TREE, true,
3111 GSI_SAME_STMT);
3112 if (objsz)
3114 objsz = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (objsz), objsz,
3115 fold_convert_loc (loc, TREE_TYPE (objsz),
3116 unshare_expr (dstlen)));
3117 objsz = force_gimple_operand_gsi (gsi, objsz, true, NULL_TREE, true,
3118 GSI_SAME_STMT);
3120 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3122 fprintf (dump_file, "Optimizing: ");
3123 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3125 if (srclen != NULL_TREE)
3126 success = update_gimple_call (gsi, fn, 3 + (objsz != NULL_TREE),
3127 dst, src, len, objsz);
3128 else
3129 success = update_gimple_call (gsi, fn, 2 + (objsz != NULL_TREE),
3130 dst, src, objsz);
3131 if (success)
3133 stmt = gsi_stmt (*gsi);
3134 update_stmt (stmt);
3135 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3137 fprintf (dump_file, "into: ");
3138 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3140 /* If srclen == NULL, note that current string length can be
3141 computed by transforming this strcpy into stpcpy. */
3142 if (srclen == NULL_TREE && dsi->dont_invalidate)
3143 dsi->stmt = stmt;
3144 adjust_last_stmt (dsi, stmt, true);
3145 if (srclen != NULL_TREE)
3147 laststmt.stmt = stmt;
3148 laststmt.len = srclen;
3149 laststmt.stridx = dsi->idx;
3152 else if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3153 fprintf (dump_file, "not possible.\n");
3155 if (set_no_warning)
3156 gimple_set_no_warning (stmt, true);
3159 /* Handle a call to malloc or calloc. */
3161 static void
3162 handle_builtin_malloc (enum built_in_function bcode, gimple_stmt_iterator *gsi)
3164 gimple *stmt = gsi_stmt (*gsi);
3165 tree lhs = gimple_call_lhs (stmt);
3166 if (lhs == NULL_TREE)
3167 return;
3169 gcc_assert (get_stridx (lhs) == 0);
3170 int idx = new_stridx (lhs);
3171 tree length = NULL_TREE;
3172 if (bcode == BUILT_IN_CALLOC)
3173 length = build_int_cst (size_type_node, 0);
3174 strinfo *si = new_strinfo (lhs, idx, length, length != NULL_TREE);
3175 if (bcode == BUILT_IN_CALLOC)
3176 si->endptr = lhs;
3177 set_strinfo (idx, si);
3178 si->writable = true;
3179 si->stmt = stmt;
3180 si->dont_invalidate = true;
3183 /* Handle a call to memset.
3184 After a call to calloc, memset(,0,) is unnecessary.
3185 memset(malloc(n),0,n) is calloc(n,1).
3186 return true when the call is transfomred, false otherwise. */
3188 static bool
3189 handle_builtin_memset (gimple_stmt_iterator *gsi)
3191 gimple *stmt2 = gsi_stmt (*gsi);
3192 if (!integer_zerop (gimple_call_arg (stmt2, 1)))
3193 return false;
3194 tree ptr = gimple_call_arg (stmt2, 0);
3195 int idx1 = get_stridx (ptr);
3196 if (idx1 <= 0)
3197 return false;
3198 strinfo *si1 = get_strinfo (idx1);
3199 if (!si1)
3200 return false;
3201 gimple *stmt1 = si1->stmt;
3202 if (!stmt1 || !is_gimple_call (stmt1))
3203 return false;
3204 tree callee1 = gimple_call_fndecl (stmt1);
3205 if (!valid_builtin_call (stmt1))
3206 return false;
3207 enum built_in_function code1 = DECL_FUNCTION_CODE (callee1);
3208 tree size = gimple_call_arg (stmt2, 2);
3209 if (code1 == BUILT_IN_CALLOC)
3210 /* Not touching stmt1 */ ;
3211 else if (code1 == BUILT_IN_MALLOC
3212 && operand_equal_p (gimple_call_arg (stmt1, 0), size, 0))
3214 gimple_stmt_iterator gsi1 = gsi_for_stmt (stmt1);
3215 update_gimple_call (&gsi1, builtin_decl_implicit (BUILT_IN_CALLOC), 2,
3216 size, build_one_cst (size_type_node));
3217 si1->nonzero_chars = build_int_cst (size_type_node, 0);
3218 si1->full_string_p = true;
3219 si1->stmt = gsi_stmt (gsi1);
3221 else
3222 return false;
3223 tree lhs = gimple_call_lhs (stmt2);
3224 unlink_stmt_vdef (stmt2);
3225 if (lhs)
3227 gimple *assign = gimple_build_assign (lhs, ptr);
3228 gsi_replace (gsi, assign, false);
3230 else
3232 gsi_remove (gsi, true);
3233 release_defs (stmt2);
3236 return true;
3239 /* Return a pointer to the first such equality expression if RES is used
3240 only in expressions testing its equality to zero, and null otherwise. */
3242 static gimple *
3243 used_only_for_zero_equality (tree res)
3245 gimple *first_use = NULL;
3247 use_operand_p use_p;
3248 imm_use_iterator iter;
3250 FOR_EACH_IMM_USE_FAST (use_p, iter, res)
3252 gimple *use_stmt = USE_STMT (use_p);
3254 if (is_gimple_debug (use_stmt))
3255 continue;
3256 if (gimple_code (use_stmt) == GIMPLE_ASSIGN)
3258 tree_code code = gimple_assign_rhs_code (use_stmt);
3259 if (code == COND_EXPR)
3261 tree cond_expr = gimple_assign_rhs1 (use_stmt);
3262 if ((TREE_CODE (cond_expr) != EQ_EXPR
3263 && (TREE_CODE (cond_expr) != NE_EXPR))
3264 || !integer_zerop (TREE_OPERAND (cond_expr, 1)))
3265 return NULL;
3267 else if (code == EQ_EXPR || code == NE_EXPR)
3269 if (!integer_zerop (gimple_assign_rhs2 (use_stmt)))
3270 return NULL;
3272 else
3273 return NULL;
3275 else if (gimple_code (use_stmt) == GIMPLE_COND)
3277 tree_code code = gimple_cond_code (use_stmt);
3278 if ((code != EQ_EXPR && code != NE_EXPR)
3279 || !integer_zerop (gimple_cond_rhs (use_stmt)))
3280 return NULL;
3282 else
3283 return NULL;
3285 if (!first_use)
3286 first_use = use_stmt;
3289 return first_use;
3292 /* Handle a call to memcmp. We try to handle small comparisons by
3293 converting them to load and compare, and replacing the call to memcmp
3294 with a __builtin_memcmp_eq call where possible.
3295 return true when call is transformed, return false otherwise. */
3297 static bool
3298 handle_builtin_memcmp (gimple_stmt_iterator *gsi)
3300 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3301 tree res = gimple_call_lhs (stmt);
3303 if (!res || !used_only_for_zero_equality (res))
3304 return false;
3306 tree arg1 = gimple_call_arg (stmt, 0);
3307 tree arg2 = gimple_call_arg (stmt, 1);
3308 tree len = gimple_call_arg (stmt, 2);
3309 unsigned HOST_WIDE_INT leni;
3311 if (tree_fits_uhwi_p (len)
3312 && (leni = tree_to_uhwi (len)) <= GET_MODE_SIZE (word_mode)
3313 && pow2p_hwi (leni))
3315 leni *= CHAR_TYPE_SIZE;
3316 unsigned align1 = get_pointer_alignment (arg1);
3317 unsigned align2 = get_pointer_alignment (arg2);
3318 unsigned align = MIN (align1, align2);
3319 scalar_int_mode mode;
3320 if (int_mode_for_size (leni, 1).exists (&mode)
3321 && (align >= leni || !targetm.slow_unaligned_access (mode, align)))
3323 location_t loc = gimple_location (stmt);
3324 tree type, off;
3325 type = build_nonstandard_integer_type (leni, 1);
3326 gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type)), leni));
3327 tree ptrtype = build_pointer_type_for_mode (char_type_node,
3328 ptr_mode, true);
3329 off = build_int_cst (ptrtype, 0);
3330 arg1 = build2_loc (loc, MEM_REF, type, arg1, off);
3331 arg2 = build2_loc (loc, MEM_REF, type, arg2, off);
3332 tree tem1 = fold_const_aggregate_ref (arg1);
3333 if (tem1)
3334 arg1 = tem1;
3335 tree tem2 = fold_const_aggregate_ref (arg2);
3336 if (tem2)
3337 arg2 = tem2;
3338 res = fold_convert_loc (loc, TREE_TYPE (res),
3339 fold_build2_loc (loc, NE_EXPR,
3340 boolean_type_node,
3341 arg1, arg2));
3342 gimplify_and_update_call_from_tree (gsi, res);
3343 return true;
3347 gimple_call_set_fndecl (stmt, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ));
3348 return true;
3351 /* Given an index to the strinfo vector, compute the string length
3352 for the corresponding string. Return -1 when unknown. */
3354 static HOST_WIDE_INT
3355 compute_string_length (int idx)
3357 HOST_WIDE_INT string_leni = -1;
3358 gcc_assert (idx != 0);
3360 if (idx < 0)
3361 return ~idx;
3363 strinfo *si = get_strinfo (idx);
3364 if (si)
3366 tree const_string_len = get_string_length (si);
3367 if (const_string_len && tree_fits_shwi_p (const_string_len))
3368 string_leni = tree_to_shwi (const_string_len);
3371 if (string_leni < 0)
3372 return -1;
3374 return string_leni;
3377 /* Determine the minimum size of the object referenced by DEST expression
3378 which must have a pointer type.
3379 Return the minimum size of the object if successful or HWI_M1U when
3380 the size cannot be determined. */
3382 static unsigned HOST_WIDE_INT
3383 determine_min_objsize (tree dest)
3385 unsigned HOST_WIDE_INT size = 0;
3387 if (compute_builtin_object_size (dest, 2, &size))
3388 return size;
3390 /* Try to determine the size of the object through the RHS
3391 of the assign statement. */
3392 if (TREE_CODE (dest) == SSA_NAME)
3394 gimple *stmt = SSA_NAME_DEF_STMT (dest);
3395 if (!is_gimple_assign (stmt))
3396 return HOST_WIDE_INT_M1U;
3398 if (!gimple_assign_single_p (stmt)
3399 && !gimple_assign_unary_nop_p (stmt))
3400 return HOST_WIDE_INT_M1U;
3402 dest = gimple_assign_rhs1 (stmt);
3403 return determine_min_objsize (dest);
3406 /* Try to determine the size of the object from its type. */
3407 if (TREE_CODE (dest) != ADDR_EXPR)
3408 return HOST_WIDE_INT_M1U;
3410 tree type = TREE_TYPE (dest);
3411 if (TREE_CODE (type) == POINTER_TYPE)
3412 type = TREE_TYPE (type);
3414 type = TYPE_MAIN_VARIANT (type);
3416 /* The size of a flexible array cannot be determined. Otherwise,
3417 for arrays with more than one element, return the size of its
3418 type. GCC itself misuses arrays of both zero and one elements
3419 as flexible array members so they are excluded as well. */
3420 if (TREE_CODE (type) != ARRAY_TYPE
3421 || !array_at_struct_end_p (dest))
3423 tree type_size = TYPE_SIZE_UNIT (type);
3424 if (type_size && TREE_CODE (type_size) == INTEGER_CST
3425 && !integer_onep (type_size)
3426 && !integer_zerop (type_size))
3427 return tree_to_uhwi (type_size);
3430 return HOST_WIDE_INT_M1U;
3433 /* Given strinfo IDX for ARG, set LENRNG[] to the range of lengths
3434 of the string(s) referenced by ARG if it can be determined.
3435 If the length cannot be determined, set *SIZE to the size of
3436 the array the string is stored in, if any. If no such array is
3437 known, set *SIZE to -1. When the strings are nul-terminated set
3438 *NULTERM to true, otherwise to false. Return true on success. */
3440 static bool
3441 get_len_or_size (tree arg, int idx, unsigned HOST_WIDE_INT lenrng[2],
3442 unsigned HOST_WIDE_INT *size, bool *nulterm)
3444 /* Set so that both LEN and ~LEN are invalid lengths, i.e.,
3445 maximum possible length + 1. */
3446 lenrng[0] = lenrng[1] = HOST_WIDE_INT_MAX;
3448 *size = HOST_WIDE_INT_M1U;
3450 if (idx < 0)
3452 /* IDX is the inverted constant string length. */
3453 lenrng[0] = ~idx;
3454 lenrng[1] = lenrng[0];
3455 *nulterm = true;
3457 else if (idx == 0)
3458 ; /* Handled below. */
3459 else if (strinfo *si = get_strinfo (idx))
3461 if (!si->nonzero_chars)
3462 arg = si->ptr;
3463 else if (tree_fits_uhwi_p (si->nonzero_chars))
3465 lenrng[0] = tree_to_uhwi (si->nonzero_chars);
3466 *nulterm = si->full_string_p;
3467 /* Set the upper bound only if the string is known to be
3468 nul-terminated, otherwise leave it at maximum + 1. */
3469 if (*nulterm)
3470 lenrng[1] = lenrng[0];
3472 else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
3474 wide_int min, max;
3475 value_range_kind rng = get_range_info (si->nonzero_chars, &min, &max);
3476 if (rng == VR_RANGE)
3478 lenrng[0] = min.to_uhwi ();
3479 lenrng[1] = max.to_uhwi ();
3480 *nulterm = si->full_string_p;
3483 else if (si->ptr)
3484 arg = si->ptr;
3487 if (lenrng[0] == HOST_WIDE_INT_MAX)
3489 /* Compute the minimum and maximum real or possible lengths. */
3490 c_strlen_data lendata = { };
3491 if (get_range_strlen (arg, &lendata, /* eltsize = */1))
3493 if (tree_fits_shwi_p (lendata.maxlen) && !lendata.maxbound)
3495 lenrng[0] = tree_to_shwi (lendata.minlen);
3496 lenrng[1] = tree_to_shwi (lendata.maxlen);
3497 *nulterm = true;
3499 else if (lendata.maxbound && tree_fits_shwi_p (lendata.maxbound))
3501 /* Set *SIZE to the conservative LENDATA.MAXBOUND which
3502 is a conservative estimate of the longest string based
3503 on the sizes of the arrays referenced by ARG. */
3504 *size = tree_to_uhwi (lendata.maxbound) + 1;
3505 *nulterm = false;
3508 else
3510 /* Set *SIZE to the size of the smallest object referenced
3511 by ARG if ARG denotes a single object, or to HWI_M1U
3512 otherwise. */
3513 *size = determine_min_objsize (arg);
3514 *nulterm = false;
3518 return lenrng[0] != HOST_WIDE_INT_MAX || *size != HOST_WIDE_INT_M1U;
3521 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
3522 the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
3523 for a sufficiently large BOUND). If the result is based on the length
3524 of one string being greater than the longest string that would fit in
3525 the array pointer to by the argument, set *PLEN and *PSIZE to
3526 the corresponding length (or its complement when the string is known
3527 to be at least as long and need not be nul-terminated) and size.
3528 Otherwise return null. */
3530 static tree
3531 strxcmp_eqz_result (tree arg1, int idx1, tree arg2, int idx2,
3532 unsigned HOST_WIDE_INT bound, unsigned HOST_WIDE_INT len[2],
3533 unsigned HOST_WIDE_INT *psize)
3535 /* Determine the range the length of each string is in and whether it's
3536 known to be nul-terminated, or the size of the array it's stored in. */
3537 bool nul1, nul2;
3538 unsigned HOST_WIDE_INT siz1, siz2;
3539 unsigned HOST_WIDE_INT len1rng[2], len2rng[2];
3540 if (!get_len_or_size (arg1, idx1, len1rng, &siz1, &nul1)
3541 || !get_len_or_size (arg2, idx2, len2rng, &siz2, &nul2))
3542 return NULL_TREE;
3544 /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
3545 to HWI_MAX when invalid. Adjust the length of each string to consider
3546 to be no more than BOUND. */
3547 if (len1rng[0] < HOST_WIDE_INT_MAX && len1rng[0] > bound)
3548 len1rng[0] = bound;
3549 if (len1rng[1] < HOST_WIDE_INT_MAX && len1rng[1] > bound)
3550 len1rng[1] = bound;
3551 if (len2rng[0] < HOST_WIDE_INT_MAX && len2rng[0] > bound)
3552 len2rng[0] = bound;
3553 if (len2rng[1] < HOST_WIDE_INT_MAX && len2rng[1] > bound)
3554 len2rng[1] = bound;
3556 /* Two empty strings are equal. */
3557 if (len1rng[1] == 0 && len2rng[1] == 0)
3558 return integer_one_node;
3560 /* The strings are definitely unequal when the lower bound of the length
3561 of one of them is greater than the length of the longest string that
3562 would fit into the other array. */
3563 if (len1rng[0] == HOST_WIDE_INT_MAX
3564 && len2rng[0] != HOST_WIDE_INT_MAX
3565 && ((len2rng[0] < bound && len2rng[0] >= siz1)
3566 || len2rng[0] > siz1))
3568 *psize = siz1;
3569 len[0] = len1rng[0];
3570 /* Set LEN[0] to the lower bound of ARG1's length when it's
3571 nul-terminated or to the complement of its minimum length
3572 otherwise, */
3573 len[1] = nul2 ? len2rng[0] : ~len2rng[0];
3574 return integer_zero_node;
3577 if (len2rng[0] == HOST_WIDE_INT_MAX
3578 && len1rng[0] != HOST_WIDE_INT_MAX
3579 && ((len1rng[0] < bound && len1rng[0] >= siz2)
3580 || len1rng[0] > siz2))
3582 *psize = siz2;
3583 len[0] = nul1 ? len1rng[0] : ~len1rng[0];
3584 len[1] = len2rng[0];
3585 return integer_zero_node;
3588 /* The strings are also definitely unequal when their lengths are unequal
3589 and at least one is nul-terminated. */
3590 if (len1rng[0] != HOST_WIDE_INT_MAX
3591 && len2rng[0] != HOST_WIDE_INT_MAX
3592 && ((len1rng[1] < len2rng[0] && nul1)
3593 || (len2rng[1] < len1rng[0] && nul2)))
3595 if (bound <= len1rng[0] || bound <= len2rng[0])
3596 *psize = bound;
3597 else
3598 *psize = HOST_WIDE_INT_M1U;
3600 len[0] = len1rng[0];
3601 len[1] = len2rng[0];
3602 return integer_zero_node;
3605 /* The string lengths may be equal or unequal. Even when equal and
3606 both strings nul-terminated, without the string contents there's
3607 no way to determine whether they are equal. */
3608 return NULL_TREE;
3611 /* Diagnose pointless calls to strcmp or strncmp STMT with string
3612 arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
3613 whose result is used in equality expressions that evaluate to
3614 a constant due to one argument being longer than the size of
3615 the other. */
3617 static void
3618 maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound,
3619 unsigned HOST_WIDE_INT len[2],
3620 unsigned HOST_WIDE_INT siz)
3622 gimple *use = used_only_for_zero_equality (gimple_call_lhs (stmt));
3623 if (!use)
3624 return;
3626 bool at_least = false;
3628 /* Excessive LEN[i] indicates a lower bound. */
3629 if (len[0] > HOST_WIDE_INT_MAX)
3631 at_least = true;
3632 len[0] = ~len[0];
3635 if (len[1] > HOST_WIDE_INT_MAX)
3637 at_least = true;
3638 len[1] = ~len[1];
3641 unsigned HOST_WIDE_INT minlen = MIN (len[0], len[1]);
3643 /* FIXME: Include a note pointing to the declaration of the smaller
3644 array. */
3645 location_t stmt_loc = gimple_location (stmt);
3646 tree callee = gimple_call_fndecl (stmt);
3647 bool warned = false;
3648 if (siz <= minlen && bound == -1)
3649 warned = warning_at (stmt_loc, OPT_Wstring_compare,
3650 (at_least
3651 ? G_("%G%qD of a string of length %wu or more and "
3652 "an array of size %wu evaluates to nonzero")
3653 : G_("%G%qD of a string of length %wu and an array "
3654 "of size %wu evaluates to nonzero")),
3655 stmt, callee, minlen, siz);
3656 else if (!at_least && siz <= HOST_WIDE_INT_MAX)
3658 if (len[0] != HOST_WIDE_INT_MAX && len[1] != HOST_WIDE_INT_MAX)
3659 warned = warning_at (stmt_loc, OPT_Wstring_compare,
3660 "%G%qD of strings of length %wu and %wu "
3661 "and bound of %wu evaluates to nonzero",
3662 stmt, callee, len[0], len[1], bound);
3663 else
3664 warned = warning_at (stmt_loc, OPT_Wstring_compare,
3665 "%G%qD of a string of length %wu, an array "
3666 "of size %wu and bound of %wu evaluates to "
3667 "nonzero",
3668 stmt, callee, minlen, siz, bound);
3671 if (warned)
3673 location_t use_loc = gimple_location (use);
3674 if (LOCATION_LINE (stmt_loc) != LOCATION_LINE (use_loc))
3675 inform (use_loc, "in this expression");
3680 /* Optimize a call to strcmp or strncmp either by folding it to a constant
3681 when possible or by transforming the latter to the former. Warn about
3682 calls where the length of one argument is greater than the size of
3683 the array to which the other argument points if the latter's length
3684 is not known. Return true when the call has been transformed into
3685 another and false otherwise. */
3687 static bool
3688 handle_builtin_string_cmp (gimple_stmt_iterator *gsi)
3690 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3691 tree lhs = gimple_call_lhs (stmt);
3693 if (!lhs)
3694 return false;
3696 tree arg1 = gimple_call_arg (stmt, 0);
3697 tree arg2 = gimple_call_arg (stmt, 1);
3698 int idx1 = get_stridx (arg1);
3699 int idx2 = get_stridx (arg2);
3701 /* For strncmp set to the the value of the third argument if known. */
3702 HOST_WIDE_INT bound = -1;
3704 /* Extract the strncmp bound. */
3705 if (gimple_call_num_args (stmt) == 3)
3707 tree len = gimple_call_arg (stmt, 2);
3708 if (tree_fits_shwi_p (len))
3709 bound = tree_to_shwi (len);
3711 /* If the bound argument is NOT known, do nothing. */
3712 if (bound < 0)
3713 return false;
3717 /* Set to the length of one argument (or its complement if it's
3718 the lower bound of a range) and the size of the array storing
3719 the other if the result is based on the former being equal to
3720 or greater than the latter. */
3721 unsigned HOST_WIDE_INT len[2] = { HOST_WIDE_INT_MAX, HOST_WIDE_INT_MAX };
3722 unsigned HOST_WIDE_INT siz = HOST_WIDE_INT_M1U;
3724 /* Try to determine if the two strings are either definitely equal
3725 or definitely unequal and if so, either fold the result to zero
3726 (when equal) or set the range of the result to ~[0, 0] otherwise. */
3727 if (tree eqz = strxcmp_eqz_result (arg1, idx1, arg2, idx2, bound,
3728 len, &siz))
3730 if (integer_zerop (eqz))
3732 maybe_warn_pointless_strcmp (stmt, bound, len, siz);
3734 /* When the lengths of the first two string arguments are
3735 known to be unequal set the range of the result to non-zero.
3736 This allows the call to be eliminated if its result is only
3737 used in tests for equality to zero. */
3738 wide_int zero = wi::zero (TYPE_PRECISION (TREE_TYPE (lhs)));
3739 set_range_info (lhs, VR_ANTI_RANGE, zero, zero);
3740 return false;
3742 /* When the two strings are definitely equal (such as when they
3743 are both empty) fold the call to the constant result. */
3744 replace_call_with_value (gsi, integer_zero_node);
3745 return true;
3749 /* Return if nothing is known about the strings pointed to by ARG1
3750 and ARG2. */
3751 if (idx1 == 0 && idx2 == 0)
3752 return false;
3754 /* Determine either the length or the size of each of the strings,
3755 whichever is available. */
3756 HOST_WIDE_INT cstlen1 = -1, cstlen2 = -1;
3757 HOST_WIDE_INT arysiz1 = -1, arysiz2 = -1;
3759 if (idx1)
3760 cstlen1 = compute_string_length (idx1) + 1;
3761 else
3762 arysiz1 = determine_min_objsize (arg1);
3764 /* Bail if neither the string length nor the size of the array
3765 it is stored in can be determined. */
3766 if (cstlen1 < 0 && arysiz1 < 0)
3767 return false;
3769 /* Repeat for the second argument. */
3770 if (idx2)
3771 cstlen2 = compute_string_length (idx2) + 1;
3772 else
3773 arysiz2 = determine_min_objsize (arg2);
3775 if (cstlen2 < 0 && arysiz2 < 0)
3776 return false;
3778 /* The exact number of characters to compare. */
3779 HOST_WIDE_INT cmpsiz = bound < 0 ? cstlen1 < 0 ? cstlen2 : cstlen1 : bound;
3780 /* The size of the array in which the unknown string is stored. */
3781 HOST_WIDE_INT varsiz = arysiz1 < 0 ? arysiz2 : arysiz1;
3783 if (cmpsiz < varsiz && used_only_for_zero_equality (lhs))
3785 /* If the known length is less than the size of the other array
3786 and the strcmp result is only used to test equality to zero,
3787 transform the call to the equivalent _eq call. */
3788 if (tree fn = builtin_decl_implicit (bound < 0 ? BUILT_IN_STRCMP_EQ
3789 : BUILT_IN_STRNCMP_EQ))
3791 tree n = build_int_cst (size_type_node, cmpsiz);
3792 update_gimple_call (gsi, fn, 3, arg1, arg2, n);
3793 return true;
3797 return false;
3800 /* Handle a POINTER_PLUS_EXPR statement.
3801 For p = "abcd" + 2; compute associated length, or if
3802 p = q + off is pointing to a '\0' character of a string, call
3803 zero_length_string on it. */
3805 static void
3806 handle_pointer_plus (gimple_stmt_iterator *gsi)
3808 gimple *stmt = gsi_stmt (*gsi);
3809 tree lhs = gimple_assign_lhs (stmt), off;
3810 int idx = get_stridx (gimple_assign_rhs1 (stmt));
3811 strinfo *si, *zsi;
3813 if (idx == 0)
3814 return;
3816 if (idx < 0)
3818 tree off = gimple_assign_rhs2 (stmt);
3819 if (tree_fits_uhwi_p (off)
3820 && tree_to_uhwi (off) <= (unsigned HOST_WIDE_INT) ~idx)
3821 ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)]
3822 = ~(~idx - (int) tree_to_uhwi (off));
3823 return;
3826 si = get_strinfo (idx);
3827 if (si == NULL || si->nonzero_chars == NULL_TREE)
3828 return;
3830 off = gimple_assign_rhs2 (stmt);
3831 zsi = NULL;
3832 if (si->full_string_p && operand_equal_p (si->nonzero_chars, off, 0))
3833 zsi = zero_length_string (lhs, si);
3834 else if (TREE_CODE (off) == SSA_NAME)
3836 gimple *def_stmt = SSA_NAME_DEF_STMT (off);
3837 if (gimple_assign_single_p (def_stmt)
3838 && si->full_string_p
3839 && operand_equal_p (si->nonzero_chars,
3840 gimple_assign_rhs1 (def_stmt), 0))
3841 zsi = zero_length_string (lhs, si);
3843 if (zsi != NULL
3844 && si->endptr != NULL_TREE
3845 && si->endptr != lhs
3846 && TREE_CODE (si->endptr) == SSA_NAME)
3848 enum tree_code rhs_code
3849 = useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (si->endptr))
3850 ? SSA_NAME : NOP_EXPR;
3851 gimple_assign_set_rhs_with_ops (gsi, rhs_code, si->endptr);
3852 gcc_assert (gsi_stmt (*gsi) == stmt);
3853 update_stmt (stmt);
3857 /* Describes recursion limits used by count_nonzero_bytes. */
3859 class ssa_name_limit_t
3861 bitmap visited; /* Bitmap of visited SSA_NAMEs. */
3862 unsigned ssa_def_max; /* Longest chain of SSA_NAMEs to follow. */
3864 /* Not copyable or assignable. */
3865 ssa_name_limit_t (ssa_name_limit_t&);
3866 void operator= (ssa_name_limit_t&);
3868 public:
3870 ssa_name_limit_t ()
3871 : visited (NULL),
3872 ssa_def_max (PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT)) { }
3874 int next_ssa_name (tree);
3876 ~ssa_name_limit_t ()
3878 if (visited)
3879 BITMAP_FREE (visited);
3883 /* If the SSA_NAME has already been "seen" return a positive value.
3884 Otherwise add it to VISITED. If the SSA_NAME limit has been
3885 reached, return a negative value. Otherwise return zero. */
3887 int ssa_name_limit_t::next_ssa_name (tree ssa_name)
3889 if (!visited)
3890 visited = BITMAP_ALLOC (NULL);
3892 /* Return a positive value if SSA_NAME has already been visited. */
3893 if (!bitmap_set_bit (visited, SSA_NAME_VERSION (ssa_name)))
3894 return 1;
3896 /* Return a negative value to let caller avoid recursing beyond
3897 the specified limit. */
3898 if (ssa_def_max == 0)
3899 return -1;
3901 --ssa_def_max;
3903 return 0;
3906 /* Determines the minimum and maximum number of leading non-zero bytes
3907 in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
3908 to each. Sets LENRANGE[2] to the total number of bytes in
3909 the representation. Sets *NULTREM if the representation contains
3910 a zero byte, and sets *ALLNUL if all the bytes are zero.
3911 OFFSET and NBYTES are the offset into the representation and
3912 the size of the access to it determined from a MEM_REF or zero
3913 for other expressions.
3914 Avoid recursing deeper than the limits in SNLIM allow.
3915 Returns true on success and false otherwise. */
3917 static bool
3918 count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
3919 unsigned HOST_WIDE_INT nbytes,
3920 unsigned lenrange[3], bool *nulterm,
3921 bool *allnul, bool *allnonnul, ssa_name_limit_t &snlim)
3923 int idx = get_stridx (exp);
3924 if (idx > 0)
3926 strinfo *si = get_strinfo (idx);
3927 /* FIXME: Handle non-constant lengths in some range. */
3928 if (!si || !tree_fits_shwi_p (si->nonzero_chars))
3929 return false;
3931 unsigned len = tree_to_shwi (si->nonzero_chars);
3932 unsigned size = len + si->full_string_p;
3933 if (size <= offset)
3934 return false;
3936 len -= offset;
3938 if (len < lenrange[0])
3939 lenrange[0] = len;
3940 if (lenrange[1] < len)
3941 lenrange[1] = len;
3942 if (lenrange[2] < nbytes)
3943 lenrange[2] = nbytes;
3945 if (!si->full_string_p)
3946 *nulterm = false;
3948 /* Since only the length of the string are known and
3949 its contents, clear ALLNUL and ALLNONNUL purely on
3950 the basis of the length. */
3951 if (len)
3952 *allnul = false;
3953 else
3954 *allnonnul = false;
3955 return true;
3958 if (TREE_CODE (exp) == ADDR_EXPR)
3959 exp = TREE_OPERAND (exp, 0);
3961 if (TREE_CODE (exp) == SSA_NAME)
3963 /* Handle a single-character specially. */
3964 tree type = TREE_TYPE (exp);
3965 if (TREE_CODE (type) == INTEGER_TYPE
3966 && TYPE_MODE (type) == TYPE_MODE (char_type_node)
3967 && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node)
3968 && tree_expr_nonzero_p (exp))
3970 /* If the character EXP is known to be non-zero (even if its
3971 exact value is not known) recurse once to set the range
3972 for an arbitrary constant. */
3973 exp = build_int_cst (type, 1);
3974 return count_nonzero_bytes (exp, offset, 1, lenrange,
3975 nulterm, allnul, allnonnul, snlim);
3978 gimple *stmt = SSA_NAME_DEF_STMT (exp);
3979 if (gimple_assign_single_p (stmt))
3981 exp = gimple_assign_rhs1 (stmt);
3982 if (TREE_CODE (exp) != MEM_REF)
3983 return false;
3985 else if (gimple_code (stmt) == GIMPLE_PHI)
3987 /* Avoid processing an SSA_NAME that has already been visited
3988 or if an SSA_NAME limit has been reached. Indicate success
3989 if the former and failure if the latter. */
3990 if (int res = snlim.next_ssa_name (exp))
3991 return res > 0;
3993 /* Determine the minimum and maximum from the PHI arguments. */
3994 unsigned int n = gimple_phi_num_args (stmt);
3995 for (unsigned i = 0; i != n; i++)
3997 tree def = gimple_phi_arg_def (stmt, i);
3998 if (!count_nonzero_bytes (def, offset, nbytes, lenrange, nulterm,
3999 allnul, allnonnul, snlim))
4000 return false;
4003 return true;
4007 if (TREE_CODE (exp) == MEM_REF)
4009 if (nbytes)
4010 return false;
4012 tree arg = TREE_OPERAND (exp, 0);
4013 tree off = TREE_OPERAND (exp, 1);
4015 if (TREE_CODE (off) != INTEGER_CST
4016 || !tree_fits_uhwi_p (off))
4017 return false;
4019 unsigned HOST_WIDE_INT wioff = tree_to_uhwi (off);
4020 if (INT_MAX < wioff)
4021 return false;
4023 offset += wioff;
4024 if (INT_MAX < offset)
4025 return false;
4027 /* The size of the MEM_REF access determines the number of bytes. */
4028 tree type = TREE_TYPE (exp);
4029 if (tree typesize = TYPE_SIZE_UNIT (type))
4030 nbytes = tree_to_uhwi (typesize);
4031 else
4032 return false;
4034 /* Handle MEM_REF = SSA_NAME types of assignments. */
4035 return count_nonzero_bytes (arg, offset, nbytes, lenrange, nulterm,
4036 allnul, allnonnul, snlim);
4039 if (TREE_CODE (exp) == VAR_DECL && TREE_READONLY (exp))
4041 exp = DECL_INITIAL (exp);
4042 if (!exp)
4043 return false;
4046 const char *prep = NULL;
4047 if (TREE_CODE (exp) == STRING_CST)
4049 unsigned nchars = TREE_STRING_LENGTH (exp);
4050 if (nchars < offset)
4051 return false;
4053 if (!nbytes)
4054 /* If NBYTES hasn't been determined earlier from MEM_REF,
4055 set it here. It includes all internal nuls, including
4056 the terminating one if the string has one. */
4057 nbytes = nchars - offset;
4059 prep = TREE_STRING_POINTER (exp) + offset;
4062 unsigned char buf[256];
4063 if (!prep)
4065 /* If the pointer to representation hasn't been set above
4066 for STRING_CST point it at the buffer. */
4067 prep = reinterpret_cast <char *>(buf);
4068 /* Try to extract the representation of the constant object
4069 or expression starting from the offset. */
4070 unsigned repsize = native_encode_expr (exp, buf, sizeof buf, offset);
4071 if (repsize < nbytes)
4073 /* This should only happen when REPSIZE is zero because EXP
4074 doesn't denote an object with a known initializer, except
4075 perhaps when the reference reads past its end. */
4076 lenrange[0] = 0;
4077 prep = NULL;
4079 else if (!nbytes)
4080 nbytes = repsize;
4081 else if (nbytes < repsize)
4082 return false;
4085 if (!nbytes)
4086 return false;
4088 /* Compute the number of leading nonzero bytes in the representation
4089 and update the minimum and maximum. */
4090 unsigned n = prep ? strnlen (prep, nbytes) : nbytes;
4092 if (n < lenrange[0])
4093 lenrange[0] = n;
4094 if (lenrange[1] < n)
4095 lenrange[1] = n;
4097 /* Set the size of the representation. */
4098 if (lenrange[2] < nbytes)
4099 lenrange[2] = nbytes;
4101 /* Clear NULTERM if none of the bytes is zero. */
4102 if (n == nbytes)
4103 *nulterm = false;
4105 if (n)
4107 /* When the initial number of non-zero bytes N is non-zero, reset
4108 *ALLNUL; if N is less than that the size of the representation
4109 also clear *ALLNONNUL. */
4110 *allnul = false;
4111 if (n < nbytes)
4112 *allnonnul = false;
4114 else if (*allnul || *allnonnul)
4116 *allnonnul = false;
4118 if (*allnul)
4120 /* When either ALLNUL is set and N is zero, also determine
4121 whether all subsequent bytes after the first one (which
4122 is nul) are zero or nonzero and clear ALLNUL if not. */
4123 for (const char *p = prep; p != prep + nbytes; ++p)
4124 if (*p)
4126 *allnul = false;
4127 break;
4132 return true;
4135 /* Same as above except with an implicit SSA_NAME limit. */
4137 static bool
4138 count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm,
4139 bool *allnul, bool *allnonnul)
4141 /* Set to optimistic values so the caller doesn't have to worry about
4142 initializing these and to what. On success, the function will clear
4143 these if it determines their values are different but being recursive
4144 it never sets either to true. On failure, their values are
4145 unspecified. */
4146 *nulterm = true;
4147 *allnul = true;
4148 *allnonnul = true;
4150 ssa_name_limit_t snlim;
4151 return count_nonzero_bytes (exp, 0, 0, lenrange, nulterm, allnul, allnonnul,
4152 snlim);
4155 /* Handle a single or multibyte store other than by a built-in function,
4156 either via a single character assignment or by multi-byte assignment
4157 either via MEM_REF or via a type other than char (such as in
4158 '*(int*)a = 12345'). Return true when handled. */
4160 static bool
4161 handle_store (gimple_stmt_iterator *gsi)
4163 int idx = -1;
4164 strinfo *si = NULL;
4165 gimple *stmt = gsi_stmt (*gsi);
4166 tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
4167 tree rhs = gimple_assign_rhs1 (stmt);
4169 /* The offset of the first byte in LHS modified by the the store. */
4170 unsigned HOST_WIDE_INT offset = 0;
4172 if (TREE_CODE (lhs) == MEM_REF
4173 && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
4175 tree mem_offset = TREE_OPERAND (lhs, 1);
4176 if (tree_fits_uhwi_p (mem_offset))
4178 /* Get the strinfo for the base, and use it if it starts with at
4179 least OFFSET nonzero characters. This is trivially true if
4180 OFFSET is zero. */
4181 offset = tree_to_uhwi (mem_offset);
4182 idx = get_stridx (TREE_OPERAND (lhs, 0));
4183 if (idx > 0)
4184 si = get_strinfo (idx);
4185 if (offset == 0)
4186 ssaname = TREE_OPERAND (lhs, 0);
4187 else if (si == NULL || compare_nonzero_chars (si, offset) < 0)
4188 return true;
4191 else
4193 idx = get_addr_stridx (lhs, NULL_TREE, &offset);
4194 if (idx > 0)
4195 si = get_strinfo (idx);
4198 /* Minimum and maximum leading non-zero bytes and the size of the store. */
4199 unsigned lenrange[] = { UINT_MAX, 0, 0 };
4201 /* Set to the minimum length of the string being assigned if known. */
4202 unsigned HOST_WIDE_INT rhs_minlen;
4204 /* STORING_NONZERO_P is true iff not all stored characters are zero.
4205 STORING_ALL_NONZERO_P is true if all stored characters are zero.
4206 STORING_ALL_ZEROS_P is true iff all stored characters are zero.
4207 Both are false when it's impossible to determine which is true. */
4208 bool storing_nonzero_p;
4209 bool storing_all_nonzero_p;
4210 bool storing_all_zeros_p;
4211 /* FULL_STRING_P is set when the stored sequence of characters form
4212 a nul-terminated string. */
4213 bool full_string_p;
4215 const bool ranges_valid
4216 = count_nonzero_bytes (rhs, lenrange, &full_string_p,
4217 &storing_all_zeros_p, &storing_all_nonzero_p);
4218 if (ranges_valid)
4220 rhs_minlen = lenrange[0];
4221 storing_nonzero_p = lenrange[1] > 0;
4223 /* Avoid issuing multiple warnings for the same LHS or statement.
4224 For example, -Warray-bounds may have already been issued for
4225 an out-of-bounds subscript. */
4226 if (!TREE_NO_WARNING (lhs) && !gimple_no_warning_p (stmt))
4228 /* Set to the declaration referenced by LHS (if known). */
4229 tree decl = NULL_TREE;
4230 if (tree dstsize = compute_objsize (lhs, 1, &decl))
4231 if (compare_tree_int (dstsize, lenrange[2]) < 0)
4233 /* Fall back on the LHS location if the statement
4234 doesn't have one. */
4235 location_t loc = gimple_nonartificial_location (stmt);
4236 if (loc == UNKNOWN_LOCATION)
4237 loc = tree_nonartificial_location (lhs);
4238 loc = expansion_point_location_if_in_system_header (loc);
4239 if (warning_n (loc, OPT_Wstringop_overflow_,
4240 lenrange[2],
4241 "%Gwriting %u byte into a region of size %E",
4242 "%Gwriting %u bytes into a region of size %E",
4243 stmt, lenrange[2], dstsize))
4245 if (decl)
4246 inform (DECL_SOURCE_LOCATION (decl),
4247 "destination object declared here");
4248 gimple_set_no_warning (stmt, true);
4253 else
4255 rhs_minlen = HOST_WIDE_INT_M1U;
4256 full_string_p = false;
4257 storing_nonzero_p = false;
4258 storing_all_zeros_p = false;
4259 storing_all_nonzero_p = false;
4262 if (si != NULL)
4264 /* The corresponding element is set to 1 if the first and last
4265 element, respectively, of the sequence of characters being
4266 written over the string described by SI ends before
4267 the terminating nul (if it has one), to zero if the nul is
4268 being overwritten but not beyond, or negative otherwise. */
4269 int store_before_nul[2];
4270 if (ranges_valid)
4272 /* The offset of the last stored byte. */
4273 unsigned HOST_WIDE_INT endoff = offset + lenrange[2] - 1;
4274 store_before_nul[0] = compare_nonzero_chars (si, offset);
4275 if (endoff == offset)
4276 store_before_nul[1] = store_before_nul[0];
4277 else
4278 store_before_nul[1] = compare_nonzero_chars (si, endoff);
4280 else
4282 store_before_nul[0] = compare_nonzero_chars (si, offset);
4283 store_before_nul[1] = store_before_nul[0];
4284 gcc_assert (offset == 0 || store_before_nul[0] >= 0);
4287 if (storing_all_zeros_p
4288 && store_before_nul[0] == 0
4289 && store_before_nul[1] == 0
4290 && si->full_string_p)
4292 /* When overwriting a '\0' with a '\0', the store can be removed
4293 if we know it has been stored in the current function. */
4294 if (!stmt_could_throw_p (cfun, stmt) && si->writable)
4296 unlink_stmt_vdef (stmt);
4297 release_defs (stmt);
4298 gsi_remove (gsi, true);
4299 return false;
4301 else
4303 si->writable = true;
4304 gsi_next (gsi);
4305 return false;
4309 if (store_before_nul[1] > 0
4310 && storing_nonzero_p
4311 && lenrange[0] == lenrange[1]
4312 && lenrange[0] == lenrange[2]
4313 && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)
4315 /* Handle a store of one or more non-nul characters that ends
4316 before the terminating nul of the destination and so does
4317 not affect its length
4318 If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
4319 and if we aren't storing '\0', we know that the length of
4320 the string and any other zero terminated string in memory
4321 remains the same. In that case we move to the next gimple
4322 statement and return to signal the caller that it shouldn't
4323 invalidate anything.
4325 This is benefical for cases like:
4327 char p[20];
4328 void foo (char *q)
4330 strcpy (p, "foobar");
4331 size_t len = strlen (p); // can be folded to 6
4332 size_t len2 = strlen (q); // has to be computed
4333 p[0] = 'X';
4334 size_t len3 = strlen (p); // can be folded to 6
4335 size_t len4 = strlen (q); // can be folded to len2
4336 bar (len, len2, len3, len4);
4337 } */
4338 gsi_next (gsi);
4339 return false;
4342 if (storing_all_zeros_p
4343 || storing_nonzero_p
4344 || (offset != 0 && store_before_nul[1] > 0))
4346 /* When STORING_NONZERO_P, we know that the string will start
4347 with at least OFFSET + 1 nonzero characters. If storing
4348 a single character, set si->NONZERO_CHARS to the result.
4349 If storing multiple characters, try to determine the number
4350 of leading non-zero characters and set si->NONZERO_CHARS to
4351 the result instead.
4353 When STORING_ALL_ZEROS_P, we know that the string is now
4354 OFFSET characters long.
4356 Otherwise, we're storing an unknown value at offset OFFSET,
4357 so need to clip the nonzero_chars to OFFSET.
4358 Use the minimum length of the string (or individual character)
4359 being stored if it's known. Otherwise, STORING_NONZERO_P
4360 guarantees it's at least 1. */
4361 HOST_WIDE_INT len
4362 = storing_nonzero_p && ranges_valid ? lenrange[0] : 1;
4363 location_t loc = gimple_location (stmt);
4364 tree oldlen = si->nonzero_chars;
4365 if (store_before_nul[1] == 0 && si->full_string_p)
4366 /* We're overwriting the nul terminator with a nonzero or
4367 unknown character. If the previous stmt was a memcpy,
4368 its length may be decreased. */
4369 adjust_last_stmt (si, stmt, false);
4370 si = unshare_strinfo (si);
4371 if (storing_nonzero_p)
4373 gcc_assert (len >= 0);
4374 si->nonzero_chars = build_int_cst (size_type_node, offset + len);
4376 else
4377 si->nonzero_chars = build_int_cst (size_type_node, offset);
4379 /* Set FULL_STRING_P only if the length of the strings being
4380 written is the same, and clear it if the strings have
4381 different lengths. In the latter case the length stored
4382 in si->NONZERO_CHARS becomes the lower bound.
4383 FIXME: Handle the upper bound of the length if possible. */
4384 si->full_string_p = full_string_p && lenrange[0] == lenrange[1];
4386 if (storing_all_zeros_p
4387 && ssaname
4388 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname))
4389 si->endptr = ssaname;
4390 else
4391 si->endptr = NULL;
4392 si->next = 0;
4393 si->stmt = NULL;
4394 si->writable = true;
4395 si->dont_invalidate = true;
4396 if (oldlen)
4398 tree adj = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
4399 si->nonzero_chars, oldlen);
4400 adjust_related_strinfos (loc, si, adj);
4402 else
4403 si->prev = 0;
4406 else if (idx == 0 && (storing_all_zeros_p || storing_nonzero_p))
4408 if (ssaname)
4409 idx = new_stridx (ssaname);
4410 else
4411 idx = new_addr_stridx (lhs);
4412 if (idx != 0)
4414 tree ptr = (ssaname ? ssaname : build_fold_addr_expr (lhs));
4416 HOST_WIDE_INT slen;
4417 if (storing_all_zeros_p)
4418 slen = 0;
4419 else if (storing_nonzero_p && ranges_valid)
4421 /* FIXME: Handle the upper bound of the length when
4422 LENRANGE[0] != LENRANGE[1]. */
4423 slen = lenrange[0];
4424 if (lenrange[0] != lenrange[1])
4425 /* Set the minimum length but ignore the maximum
4426 for now. */
4427 full_string_p = false;
4429 else
4430 slen = -1;
4432 tree len = (slen <= 0
4433 ? size_zero_node
4434 : build_int_cst (size_type_node, slen));
4435 si = new_strinfo (ptr, idx, len, slen >= 0 && full_string_p);
4436 set_strinfo (idx, si);
4437 if (storing_all_zeros_p
4438 && ssaname
4439 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname))
4440 si->endptr = ssaname;
4441 si->dont_invalidate = true;
4442 si->writable = true;
4445 else if (idx == 0
4446 && rhs_minlen < HOST_WIDE_INT_M1U
4447 && ssaname == NULL_TREE
4448 && TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE)
4450 HOST_WIDE_INT a = int_size_in_bytes (TREE_TYPE (lhs));
4451 if (a > 0 && (unsigned HOST_WIDE_INT) a > rhs_minlen)
4453 int idx = new_addr_stridx (lhs);
4454 if (idx != 0)
4456 si = new_strinfo (build_fold_addr_expr (lhs), idx,
4457 build_int_cst (size_type_node, rhs_minlen),
4458 full_string_p);
4459 set_strinfo (idx, si);
4460 si->dont_invalidate = true;
4465 if (si != NULL && offset == 0 && storing_all_zeros_p)
4467 /* Allow adjust_last_stmt to remove it if the stored '\0'
4468 is immediately overwritten. */
4469 laststmt.stmt = stmt;
4470 laststmt.len = build_int_cst (size_type_node, 1);
4471 laststmt.stridx = si->idx;
4473 return true;
4476 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0. */
4478 static void
4479 fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
4481 if (TREE_CODE (rhs1) != SSA_NAME
4482 || TREE_CODE (rhs2) != SSA_NAME)
4483 return;
4485 gimple *call_stmt = NULL;
4486 for (int pass = 0; pass < 2; pass++)
4488 gimple *g = SSA_NAME_DEF_STMT (rhs1);
4489 if (gimple_call_builtin_p (g, BUILT_IN_STRSTR)
4490 && has_single_use (rhs1)
4491 && gimple_call_arg (g, 0) == rhs2)
4493 call_stmt = g;
4494 break;
4496 std::swap (rhs1, rhs2);
4499 if (call_stmt)
4501 tree arg0 = gimple_call_arg (call_stmt, 0);
4503 if (arg0 == rhs2)
4505 tree arg1 = gimple_call_arg (call_stmt, 1);
4506 tree arg1_len = NULL_TREE;
4507 int idx = get_stridx (arg1);
4509 if (idx)
4511 if (idx < 0)
4512 arg1_len = build_int_cst (size_type_node, ~idx);
4513 else
4515 strinfo *si = get_strinfo (idx);
4516 if (si)
4517 arg1_len = get_string_length (si);
4521 if (arg1_len != NULL_TREE)
4523 gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
4524 tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);
4526 if (!is_gimple_val (arg1_len))
4528 tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
4529 gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
4530 arg1_len);
4531 gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT);
4532 arg1_len = arg1_len_tmp;
4535 gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
4536 arg0, arg1, arg1_len);
4537 tree strncmp_lhs = make_ssa_name (integer_type_node);
4538 gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
4539 gimple_call_set_lhs (strncmp_call, strncmp_lhs);
4540 gsi_remove (&gsi, true);
4541 gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
4542 tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));
4544 if (is_gimple_assign (stmt))
4546 if (gimple_assign_rhs_code (stmt) == COND_EXPR)
4548 tree cond = gimple_assign_rhs1 (stmt);
4549 TREE_OPERAND (cond, 0) = strncmp_lhs;
4550 TREE_OPERAND (cond, 1) = zero;
4552 else
4554 gimple_assign_set_rhs1 (stmt, strncmp_lhs);
4555 gimple_assign_set_rhs2 (stmt, zero);
4558 else
4560 gcond *cond = as_a<gcond *> (stmt);
4561 gimple_cond_set_lhs (cond, strncmp_lhs);
4562 gimple_cond_set_rhs (cond, zero);
4564 update_stmt (stmt);
4570 /* Return true if TYPE corresponds to a narrow character type. */
4572 static bool
4573 is_char_type (tree type)
4575 return (TREE_CODE (type) == INTEGER_TYPE
4576 && TYPE_MODE (type) == TYPE_MODE (char_type_node)
4577 && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node));
4580 /* Check the built-in call at GSI for validity and optimize it.
4581 Return true to let the caller advance *GSI to the statement
4582 in the CFG and false otherwise. */
4584 static bool
4585 strlen_check_and_optimize_call (gimple_stmt_iterator *gsi,
4586 const vr_values *rvals)
4588 gimple *stmt = gsi_stmt (*gsi);
4590 if (!flag_optimize_strlen
4591 || !strlen_optimize
4592 || !valid_builtin_call (stmt))
4594 /* When not optimizing we must be checking printf calls which
4595 we do even for user-defined functions when they are declared
4596 with attribute format. */
4597 handle_printf_call (gsi, rvals);
4598 return true;
4601 tree callee = gimple_call_fndecl (stmt);
4602 switch (DECL_FUNCTION_CODE (callee))
4604 case BUILT_IN_STRLEN:
4605 case BUILT_IN_STRNLEN:
4606 handle_builtin_strlen (gsi);
4607 break;
4608 case BUILT_IN_STRCHR:
4609 handle_builtin_strchr (gsi);
4610 break;
4611 case BUILT_IN_STRCPY:
4612 case BUILT_IN_STRCPY_CHK:
4613 case BUILT_IN_STPCPY:
4614 case BUILT_IN_STPCPY_CHK:
4615 handle_builtin_strcpy (DECL_FUNCTION_CODE (callee), gsi);
4616 break;
4618 case BUILT_IN_STRNCAT:
4619 case BUILT_IN_STRNCAT_CHK:
4620 handle_builtin_strncat (DECL_FUNCTION_CODE (callee), gsi);
4621 break;
4623 case BUILT_IN_STPNCPY:
4624 case BUILT_IN_STPNCPY_CHK:
4625 case BUILT_IN_STRNCPY:
4626 case BUILT_IN_STRNCPY_CHK:
4627 handle_builtin_stxncpy (DECL_FUNCTION_CODE (callee), gsi);
4628 break;
4630 case BUILT_IN_MEMCPY:
4631 case BUILT_IN_MEMCPY_CHK:
4632 case BUILT_IN_MEMPCPY:
4633 case BUILT_IN_MEMPCPY_CHK:
4634 handle_builtin_memcpy (DECL_FUNCTION_CODE (callee), gsi);
4635 break;
4636 case BUILT_IN_STRCAT:
4637 case BUILT_IN_STRCAT_CHK:
4638 handle_builtin_strcat (DECL_FUNCTION_CODE (callee), gsi);
4639 break;
4640 case BUILT_IN_MALLOC:
4641 case BUILT_IN_CALLOC:
4642 handle_builtin_malloc (DECL_FUNCTION_CODE (callee), gsi);
4643 break;
4644 case BUILT_IN_MEMSET:
4645 if (handle_builtin_memset (gsi))
4646 return false;
4647 break;
4648 case BUILT_IN_MEMCMP:
4649 if (handle_builtin_memcmp (gsi))
4650 return false;
4651 break;
4652 case BUILT_IN_STRCMP:
4653 case BUILT_IN_STRNCMP:
4654 if (handle_builtin_string_cmp (gsi))
4655 return false;
4656 break;
4657 default:
4658 handle_printf_call (gsi, rvals);
4659 break;
4662 return true;
4665 /* Handle an assignment statement at *GSI to a LHS of integral type.
4666 If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */
4668 static void
4669 handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh)
4671 gimple *stmt = gsi_stmt (*gsi);
4672 tree lhs = gimple_assign_lhs (stmt);
4673 tree lhs_type = TREE_TYPE (lhs);
4675 enum tree_code code = gimple_assign_rhs_code (stmt);
4676 if (code == COND_EXPR)
4678 tree cond = gimple_assign_rhs1 (stmt);
4679 enum tree_code cond_code = TREE_CODE (cond);
4681 if (cond_code == EQ_EXPR || cond_code == NE_EXPR)
4682 fold_strstr_to_strncmp (TREE_OPERAND (cond, 0),
4683 TREE_OPERAND (cond, 1), stmt);
4685 else if (code == EQ_EXPR || code == NE_EXPR)
4686 fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt),
4687 gimple_assign_rhs2 (stmt), stmt);
4688 else if (gimple_assign_load_p (stmt)
4689 && TREE_CODE (lhs_type) == INTEGER_TYPE
4690 && TYPE_MODE (lhs_type) == TYPE_MODE (char_type_node)
4691 && (TYPE_PRECISION (lhs_type)
4692 == TYPE_PRECISION (char_type_node))
4693 && !gimple_has_volatile_ops (stmt))
4695 tree off = integer_zero_node;
4696 unsigned HOST_WIDE_INT coff = 0;
4697 int idx = 0;
4698 tree rhs1 = gimple_assign_rhs1 (stmt);
4699 if (code == MEM_REF)
4701 idx = get_stridx (TREE_OPERAND (rhs1, 0));
4702 if (idx > 0)
4704 strinfo *si = get_strinfo (idx);
4705 if (si
4706 && si->nonzero_chars
4707 && TREE_CODE (si->nonzero_chars) == INTEGER_CST
4708 && (wi::to_widest (si->nonzero_chars)
4709 >= wi::to_widest (off)))
4710 off = TREE_OPERAND (rhs1, 1);
4711 else
4712 /* This case is not useful. See if get_addr_stridx
4713 returns something usable. */
4714 idx = 0;
4717 if (idx <= 0)
4718 idx = get_addr_stridx (rhs1, NULL_TREE, &coff);
4719 if (idx > 0)
4721 strinfo *si = get_strinfo (idx);
4722 if (si
4723 && si->nonzero_chars
4724 && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
4726 widest_int w1 = wi::to_widest (si->nonzero_chars);
4727 widest_int w2 = wi::to_widest (off) + coff;
4728 if (w1 == w2
4729 && si->full_string_p)
4731 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
4733 fprintf (dump_file, "Optimizing: ");
4734 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
4737 /* Reading the final '\0' character. */
4738 tree zero = build_int_cst (lhs_type, 0);
4739 gimple_set_vuse (stmt, NULL_TREE);
4740 gimple_assign_set_rhs_from_tree (gsi, zero);
4741 *cleanup_eh
4742 |= maybe_clean_or_replace_eh_stmt (stmt,
4743 gsi_stmt (*gsi));
4744 stmt = gsi_stmt (*gsi);
4745 update_stmt (stmt);
4747 if (dump_file && (dump_flags & TDF_DETAILS) != 0)
4749 fprintf (dump_file, "into: ");
4750 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
4753 else if (w1 > w2)
4755 /* Reading a character before the final '\0'
4756 character. Just set the value range to ~[0, 0]
4757 if we don't have anything better. */
4758 wide_int min, max;
4759 signop sign = TYPE_SIGN (lhs_type);
4760 int prec = TYPE_PRECISION (lhs_type);
4761 value_range_kind vr = get_range_info (lhs, &min, &max);
4762 if (vr == VR_VARYING
4763 || (vr == VR_RANGE
4764 && min == wi::min_value (prec, sign)
4765 && max == wi::max_value (prec, sign)))
4766 set_range_info (lhs, VR_ANTI_RANGE,
4767 wi::zero (prec), wi::zero (prec));
4773 if (strlen_to_stridx)
4775 tree rhs1 = gimple_assign_rhs1 (stmt);
4776 if (stridx_strlenloc *ps = strlen_to_stridx->get (rhs1))
4777 strlen_to_stridx->put (lhs, stridx_strlenloc (*ps));
4781 /* Attempt to check for validity of the performed access a single statement
4782 at *GSI using string length knowledge, and to optimize it.
4783 If the given basic block needs clean-up of EH, CLEANUP_EH is set to
4784 true. */
4786 static bool
4787 check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
4788 const vr_values *rvals)
4790 gimple *stmt = gsi_stmt (*gsi);
4792 if (is_gimple_call (stmt))
4794 if (!strlen_check_and_optimize_call (gsi, rvals))
4795 return false;
4797 else if (!flag_optimize_strlen || !strlen_optimize)
4798 return true;
4799 else if (is_gimple_assign (stmt) && !gimple_clobber_p (stmt))
4801 /* Handle non-clobbering assignment. */
4802 tree lhs = gimple_assign_lhs (stmt);
4803 tree lhs_type = TREE_TYPE (lhs);
4805 if (TREE_CODE (lhs) == SSA_NAME && POINTER_TYPE_P (lhs_type))
4807 if (gimple_assign_single_p (stmt)
4808 || (gimple_assign_cast_p (stmt)
4809 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
4811 int idx = get_stridx (gimple_assign_rhs1 (stmt));
4812 ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = idx;
4814 else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
4815 handle_pointer_plus (gsi);
4817 else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (lhs_type))
4818 /* Handle assignment to a character. */
4819 handle_integral_assign (gsi, cleanup_eh);
4820 else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
4822 tree type = TREE_TYPE (lhs);
4823 if (TREE_CODE (type) == ARRAY_TYPE)
4824 type = TREE_TYPE (type);
4826 bool is_char_store = is_char_type (type);
4827 if (!is_char_store && TREE_CODE (lhs) == MEM_REF)
4829 /* To consider stores into char objects via integer types
4830 other than char but not those to non-character objects,
4831 determine the type of the destination rather than just
4832 the type of the access. */
4833 tree ref = TREE_OPERAND (lhs, 0);
4834 type = TREE_TYPE (ref);
4835 if (TREE_CODE (type) == POINTER_TYPE)
4836 type = TREE_TYPE (type);
4837 if (TREE_CODE (type) == ARRAY_TYPE)
4838 type = TREE_TYPE (type);
4839 if (is_char_type (type))
4840 is_char_store = true;
4843 /* Handle a single or multibyte assignment. */
4844 if (is_char_store && !handle_store (gsi))
4845 return false;
4848 else if (gcond *cond = dyn_cast<gcond *> (stmt))
4850 enum tree_code code = gimple_cond_code (cond);
4851 if (code == EQ_EXPR || code == NE_EXPR)
4852 fold_strstr_to_strncmp (gimple_cond_lhs (stmt),
4853 gimple_cond_rhs (stmt), stmt);
4856 if (gimple_vdef (stmt))
4857 maybe_invalidate (stmt);
4858 return true;
4861 /* Recursively call maybe_invalidate on stmts that might be executed
4862 in between dombb and current bb and that contain a vdef. Stop when
4863 *count stmts are inspected, or if the whole strinfo vector has
4864 been invalidated. */
4866 static void
4867 do_invalidate (basic_block dombb, gimple *phi, bitmap visited, int *count)
4869 unsigned int i, n = gimple_phi_num_args (phi);
4871 for (i = 0; i < n; i++)
4873 tree vuse = gimple_phi_arg_def (phi, i);
4874 gimple *stmt = SSA_NAME_DEF_STMT (vuse);
4875 basic_block bb = gimple_bb (stmt);
4876 if (bb == NULL
4877 || bb == dombb
4878 || !bitmap_set_bit (visited, bb->index)
4879 || !dominated_by_p (CDI_DOMINATORS, bb, dombb))
4880 continue;
4881 while (1)
4883 if (gimple_code (stmt) == GIMPLE_PHI)
4885 do_invalidate (dombb, stmt, visited, count);
4886 if (*count == 0)
4887 return;
4888 break;
4890 if (--*count == 0)
4891 return;
4892 if (!maybe_invalidate (stmt))
4894 *count = 0;
4895 return;
4897 vuse = gimple_vuse (stmt);
4898 stmt = SSA_NAME_DEF_STMT (vuse);
4899 if (gimple_bb (stmt) != bb)
4901 bb = gimple_bb (stmt);
4902 if (bb == NULL
4903 || bb == dombb
4904 || !bitmap_set_bit (visited, bb->index)
4905 || !dominated_by_p (CDI_DOMINATORS, bb, dombb))
4906 break;
4912 class strlen_dom_walker : public dom_walker
4914 public:
4915 strlen_dom_walker (cdi_direction direction)
4916 : dom_walker (direction),
4917 evrp (false),
4918 m_cleanup_cfg (false)
4921 virtual edge before_dom_children (basic_block);
4922 virtual void after_dom_children (basic_block);
4924 /* EVRP analyzer used for printf argument range processing, and
4925 to track strlen results across integer variable assignments. */
4926 evrp_range_analyzer evrp;
4928 /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
4929 execute function. */
4930 bool m_cleanup_cfg;
4933 /* Callback for walk_dominator_tree. Attempt to optimize various
4934 string ops by remembering string lengths pointed by pointer SSA_NAMEs. */
4936 edge
4937 strlen_dom_walker::before_dom_children (basic_block bb)
4939 evrp.enter (bb);
4941 basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
4943 if (dombb == NULL)
4944 stridx_to_strinfo = NULL;
4945 else
4947 stridx_to_strinfo = ((vec<strinfo *, va_heap, vl_embed> *) dombb->aux);
4948 if (stridx_to_strinfo)
4950 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4951 gsi_next (&gsi))
4953 gphi *phi = gsi.phi ();
4954 if (virtual_operand_p (gimple_phi_result (phi)))
4956 bitmap visited = BITMAP_ALLOC (NULL);
4957 int count_vdef = 100;
4958 do_invalidate (dombb, phi, visited, &count_vdef);
4959 BITMAP_FREE (visited);
4960 if (count_vdef == 0)
4962 /* If there were too many vdefs in between immediate
4963 dominator and current bb, invalidate everything.
4964 If stridx_to_strinfo has been unshared, we need
4965 to free it, otherwise just set it to NULL. */
4966 if (!strinfo_shared ())
4968 unsigned int i;
4969 strinfo *si;
4971 for (i = 1;
4972 vec_safe_iterate (stridx_to_strinfo, i, &si);
4973 ++i)
4975 free_strinfo (si);
4976 (*stridx_to_strinfo)[i] = NULL;
4979 else
4980 stridx_to_strinfo = NULL;
4982 break;
4988 /* If all PHI arguments have the same string index, the PHI result
4989 has it as well. */
4990 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
4991 gsi_next (&gsi))
4993 gphi *phi = gsi.phi ();
4994 tree result = gimple_phi_result (phi);
4995 if (!virtual_operand_p (result) && POINTER_TYPE_P (TREE_TYPE (result)))
4997 int idx = get_stridx (gimple_phi_arg_def (phi, 0));
4998 if (idx != 0)
5000 unsigned int i, n = gimple_phi_num_args (phi);
5001 for (i = 1; i < n; i++)
5002 if (idx != get_stridx (gimple_phi_arg_def (phi, i)))
5003 break;
5004 if (i == n)
5005 ssa_ver_to_stridx[SSA_NAME_VERSION (result)] = idx;
5010 bool cleanup_eh = false;
5012 /* Attempt to optimize individual statements. */
5013 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
5015 gimple *stmt = gsi_stmt (gsi);
5017 /* First record ranges generated by this statement so they
5018 can be used by printf argument processing. */
5019 evrp.record_ranges_from_stmt (stmt, false);
5021 if (check_and_optimize_stmt (&gsi, &cleanup_eh, evrp.get_vr_values ()))
5022 gsi_next (&gsi);
5025 if (cleanup_eh && gimple_purge_dead_eh_edges (bb))
5026 m_cleanup_cfg = true;
5028 bb->aux = stridx_to_strinfo;
5029 if (vec_safe_length (stridx_to_strinfo) && !strinfo_shared ())
5030 (*stridx_to_strinfo)[0] = (strinfo *) bb;
5031 return NULL;
5034 /* Callback for walk_dominator_tree. Free strinfo vector if it is
5035 owned by the current bb, clear bb->aux. */
5037 void
5038 strlen_dom_walker::after_dom_children (basic_block bb)
5040 evrp.leave (bb);
5042 if (bb->aux)
5044 stridx_to_strinfo = ((vec<strinfo *, va_heap, vl_embed> *) bb->aux);
5045 if (vec_safe_length (stridx_to_strinfo)
5046 && (*stridx_to_strinfo)[0] == (strinfo *) bb)
5048 unsigned int i;
5049 strinfo *si;
5051 for (i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
5052 free_strinfo (si);
5053 vec_free (stridx_to_strinfo);
5055 bb->aux = NULL;
5059 namespace {
5061 static unsigned int
5062 printf_strlen_execute (function *fun, bool warn_only)
5064 strlen_optimize = !warn_only;
5066 calculate_dominance_info (CDI_DOMINATORS);
5068 bool use_scev = optimize > 0 && flag_printf_return_value;
5069 if (use_scev)
5071 loop_optimizer_init (LOOPS_NORMAL);
5072 scev_initialize ();
5075 gcc_assert (!strlen_to_stridx);
5076 if (warn_stringop_overflow || warn_stringop_truncation)
5077 strlen_to_stridx = new hash_map<tree, stridx_strlenloc> ();
5079 /* This has to happen after initializing the loop optimizer
5080 and initializing SCEV as they create new SSA_NAMEs. */
5081 ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
5082 max_stridx = 1;
5084 /* String length optimization is implemented as a walk of the dominator
5085 tree and a forward walk of statements within each block. */
5086 strlen_dom_walker walker (CDI_DOMINATORS);
5087 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
5089 ssa_ver_to_stridx.release ();
5090 strinfo_pool.release ();
5091 if (decl_to_stridxlist_htab)
5093 obstack_free (&stridx_obstack, NULL);
5094 delete decl_to_stridxlist_htab;
5095 decl_to_stridxlist_htab = NULL;
5097 laststmt.stmt = NULL;
5098 laststmt.len = NULL_TREE;
5099 laststmt.stridx = 0;
5101 if (strlen_to_stridx)
5103 strlen_to_stridx->empty ();
5104 delete strlen_to_stridx;
5105 strlen_to_stridx = NULL;
5108 if (use_scev)
5110 scev_finalize ();
5111 loop_optimizer_finalize ();
5114 /* Clean up object size info. */
5115 fini_object_sizes ();
5117 return walker.m_cleanup_cfg ? TODO_cleanup_cfg : 0;
5120 /* This file defines two passes: one for warnings that runs only when
5121 optimization is disabled, and another that implements optimizations
5122 and also issues warnings. */
5124 const pass_data pass_data_warn_printf =
5126 GIMPLE_PASS, /* type */
5127 "warn-printf", /* name */
5128 OPTGROUP_NONE, /* optinfo_flags */
5129 TV_NONE, /* tv_id */
5130 /* Normally an optimization pass would require PROP_ssa but because
5131 this pass runs early, with no optimization, to do sprintf format
5132 checking, it only requires PROP_cfg. */
5133 PROP_cfg, /* properties_required */
5134 0, /* properties_provided */
5135 0, /* properties_destroyed */
5136 0, /* todo_flags_start */
5137 0, /* todo_flags_finish */
5140 class pass_warn_printf : public gimple_opt_pass
5142 public:
5143 pass_warn_printf (gcc::context *ctxt)
5144 : gimple_opt_pass (pass_data_warn_printf, ctxt)
5147 virtual bool gate (function *);
5148 virtual unsigned int execute (function *fun)
5150 return printf_strlen_execute (fun, true);
5155 /* Return true to run the warning pass only when not optimizing and
5156 iff either -Wformat-overflow or -Wformat-truncation is specified. */
5158 bool
5159 pass_warn_printf::gate (function *)
5161 return !optimize && (warn_format_overflow > 0 || warn_format_trunc > 0);
5164 const pass_data pass_data_strlen =
5166 GIMPLE_PASS, /* type */
5167 "strlen", /* name */
5168 OPTGROUP_NONE, /* optinfo_flags */
5169 TV_TREE_STRLEN, /* tv_id */
5170 PROP_cfg | PROP_ssa, /* properties_required */
5171 0, /* properties_provided */
5172 0, /* properties_destroyed */
5173 0, /* todo_flags_start */
5174 0, /* todo_flags_finish */
5177 class pass_strlen : public gimple_opt_pass
5179 public:
5180 pass_strlen (gcc::context *ctxt)
5181 : gimple_opt_pass (pass_data_strlen, ctxt)
5184 opt_pass * clone () { return new pass_strlen (m_ctxt); }
5186 virtual bool gate (function *);
5187 virtual unsigned int execute (function *fun)
5189 return printf_strlen_execute (fun, false);
5193 /* Return true to run the pass only when the sprintf and/or strlen
5194 optimizations are enabled and -Wformat-overflow or -Wformat-truncation
5195 are specified. */
5197 bool
5198 pass_strlen::gate (function *)
5200 return ((warn_format_overflow > 0
5201 || warn_format_trunc > 0
5202 || flag_optimize_strlen > 0
5203 || flag_printf_return_value)
5204 && optimize > 0);
5207 } // anon namespace
5209 gimple_opt_pass *
5210 make_pass_warn_printf (gcc::context *ctxt)
5212 return new pass_warn_printf (ctxt);
5215 gimple_opt_pass *
5216 make_pass_strlen (gcc::context *ctxt)
5218 return new pass_strlen (ctxt);