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