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