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