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