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