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