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