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