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