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