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