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