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