1 /* String length optimization
2 Copyright (C) 2011-2023 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "alloc-pool.h"
29 #include "tree-pass.h"
32 #include "gimple-pretty-print.h"
33 #include "gimple-ssa-warn-access.h"
34 #include "gimple-ssa-warn-restrict.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "gimple-iterator.h"
38 #include "gimple-fold.h"
41 #include "gimplify-me.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-ssa-propagate.h"
48 #include "tree-ssa-strlen.h"
49 #include "tree-hash-traits.h"
51 #include "pointer-query.h"
53 #include "diagnostic-core.h"
54 #include "diagnostic.h"
59 #include "tree-ssa-loop.h"
60 #include "tree-scalar-evolution.h"
61 #include "vr-values.h"
62 #include "gimple-range.h"
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). */
68 static vec
<int> ssa_ver_to_stridx
;
70 /* Number of currently active string indexes plus one. */
71 static int max_stridx
;
73 /* Set to true to optimize, false when just checking. */
74 static bool strlen_optimize
;
76 /* String information record. */
79 /* Number of leading characters that are known to be nonzero. This is
80 also the length of the string if FULL_STRING_P.
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. */
86 /* Any of the corresponding pointers for querying alias oracle. */
88 /* STMT is used for two things:
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.
94 - To record the malloc or calloc call that produced this result
95 to optimize away malloc/memset sequences. STMT is reset after
96 a calloc-allocated object has been stored a non-zero value into. */
98 /* Set to the dynamic allocation statement for the object (alloca,
99 calloc, malloc, or VLA). Unlike STMT, once set for a strinfo
100 object, ALLOC doesn't change. */
102 /* Pointer to '\0' if known, if NULL, it can be computed as
105 /* Reference count. Any changes to strinfo entry possibly shared
106 with dominating basic blocks need unshare_strinfo first, except
107 for dont_invalidate which affects only the immediately next
110 /* Copy of index. get_strinfo (si->idx) should return si; */
112 /* These 3 fields are for chaining related string pointers together.
114 bl = strlen (b); dl = strlen (d); strcpy (a, b); c = a + bl;
115 strcpy (c, d); e = c + dl;
116 strinfo(a) -> strinfo(c) -> strinfo(e)
117 All have ->first field equal to strinfo(a)->idx and are doubly
118 chained through prev/next fields. The later strinfos are required
119 to point into the same string with zero or more bytes after
120 the previous pointer and all bytes in between the two pointers
121 must be non-zero. Functions like strcpy or memcpy are supposed
122 to adjust all previous strinfo lengths, but not following strinfo
123 lengths (those are uncertain, usually invalidated during
124 maybe_invalidate, except when the alias oracle knows better).
125 Functions like strcat on the other side adjust the whole
126 related strinfo chain.
127 They are updated lazily, so to use the chain the same first fields
128 and si->prev->next == si->idx needs to be verified. */
132 /* A flag whether the string is known to be written in the current
135 /* A flag for the next maybe_invalidate that this strinfo shouldn't
136 be invalidated. Always cleared by maybe_invalidate. */
137 bool dont_invalidate
;
138 /* True if the string is known to be nul-terminated after NONZERO_CHARS
139 characters. False is useful when detecting strings that are built
140 up via successive memcpys. */
144 /* Pool for allocating strinfo_struct entries. */
145 static object_allocator
<strinfo
> strinfo_pool ("strinfo pool");
147 /* Vector mapping positive string indexes to strinfo, for the
148 current basic block. The first pointer in the vector is special,
149 it is either NULL, meaning the vector isn't shared, or it is
150 a basic block pointer to the owner basic_block if shared.
151 If some other bb wants to modify the vector, the vector needs
152 to be unshared first, and only the owner bb is supposed to free it. */
153 static vec
<strinfo
*, va_heap
, vl_embed
> *stridx_to_strinfo
;
155 /* One OFFSET->IDX mapping. */
158 struct stridxlist
*next
;
159 HOST_WIDE_INT offset
;
163 /* Hash table entry, mapping a DECL to a chain of OFFSET->IDX mappings. */
164 struct decl_stridxlist_map
166 struct tree_map_base base
;
167 struct stridxlist list
;
170 /* Hash table for mapping decls to a chained list of offset -> idx
172 typedef hash_map
<tree_decl_hash
, stridxlist
> decl_to_stridxlist_htab_t
;
173 static decl_to_stridxlist_htab_t
*decl_to_stridxlist_htab
;
175 /* Hash table mapping strlen (or strnlen with constant bound and return
176 smaller than bound) calls to stridx instances describing
177 the calls' arguments. Non-null only when warn_stringop_truncation
179 typedef std::pair
<int, location_t
> stridx_strlenloc
;
180 static hash_map
<tree
, stridx_strlenloc
> *strlen_to_stridx
;
182 /* Obstack for struct stridxlist and struct decl_stridxlist_map. */
183 static struct obstack stridx_obstack
;
185 /* Last memcpy statement if it could be adjusted if the trailing
186 '\0' written is immediately overwritten, or
187 *x = '\0' store that could be removed if it is immediately overwritten. */
188 struct laststmt_struct
195 static int get_stridx_plus_constant (strinfo
*, unsigned HOST_WIDE_INT
, tree
);
196 static bool get_range_strlen_dynamic (tree
, gimple
*, c_strlen_data
*,
197 bitmap
, pointer_query
*, unsigned *);
199 /* Sets MINMAX to either the constant value or the range VAL is in
200 and returns either the constant value or VAL on success or null
201 when the range couldn't be determined. Uses RVALS or CFUN for
202 range info, whichever is nonnull. */
205 get_range (tree val
, gimple
*stmt
, wide_int minmax
[2],
206 range_query
*rvals
/* = NULL */)
211 /* When called from front ends for global initializers CFUN
215 rvals
= get_range_query (cfun
);
219 if (!rvals
->range_of_expr (vr
, val
, stmt
))
222 value_range_kind rng
= vr
.kind ();
225 /* Only handle straight ranges. */
226 minmax
[0] = wi::to_wide (vr
.min ());
227 minmax
[1] = wi::to_wide (vr
.max ());
234 class strlen_pass
: public dom_walker
237 strlen_pass (cdi_direction direction
)
238 : dom_walker (direction
),
240 m_cleanup_cfg (false)
246 edge
before_dom_children (basic_block
) final override
;
247 void after_dom_children (basic_block
) final override
;
249 bool check_and_optimize_stmt (bool *cleanup_eh
);
250 bool check_and_optimize_call (bool *zero_write
);
251 bool handle_assign (tree lhs
, bool *zero_write
);
252 bool handle_store (bool *zero_write
);
253 void handle_pointer_plus ();
254 void handle_builtin_strlen ();
255 void handle_builtin_strchr ();
256 void handle_builtin_strcpy (built_in_function
);
257 void handle_integral_assign (bool *cleanup_eh
);
258 void handle_builtin_stxncpy_strncat (bool append_p
);
259 void handle_builtin_memcpy (built_in_function bcode
);
260 void handle_builtin_strcat (built_in_function bcode
);
261 void handle_builtin_strncat (built_in_function
);
262 bool handle_builtin_memset (bool *zero_write
);
263 bool handle_builtin_memcmp ();
264 bool handle_builtin_string_cmp ();
265 void handle_alloc_call (built_in_function
);
266 void maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, tree len
,
267 strinfo
*si
= NULL
, bool plus_one
= false,
268 bool rawmem
= false);
269 void maybe_warn_overflow (gimple
*stmt
, bool call_lhs
,
270 unsigned HOST_WIDE_INT len
,
272 bool plus_one
= false, bool rawmem
= false);
273 void adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
);
274 tree
strxcmp_eqz_result (gimple
*stmt
, tree arg1
, int idx1
,
276 unsigned HOST_WIDE_INT bound
,
277 unsigned HOST_WIDE_INT len
[2],
278 unsigned HOST_WIDE_INT
*psize
);
279 bool count_nonzero_bytes (tree expr_or_type
,
281 unsigned lenrange
[3], bool *nulterm
,
282 bool *allnul
, bool *allnonnul
);
283 bool count_nonzero_bytes (tree exp
,
285 unsigned HOST_WIDE_INT offset
,
286 unsigned HOST_WIDE_INT nbytes
,
287 unsigned lenrange
[3], bool *nulterm
,
288 bool *allnul
, bool *allnonnul
,
289 ssa_name_limit_t
&snlim
);
290 bool count_nonzero_bytes_addr (tree exp
,
292 unsigned HOST_WIDE_INT offset
,
293 unsigned HOST_WIDE_INT nbytes
,
294 unsigned lenrange
[3], bool *nulterm
,
295 bool *allnul
, bool *allnonnul
,
296 ssa_name_limit_t
&snlim
);
297 bool get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
298 unsigned HOST_WIDE_INT lenrng
[2],
299 unsigned HOST_WIDE_INT
*size
, bool *nulterm
);
301 gimple_ranger m_ranger
;
303 /* A pointer_query object to store information about pointers and
305 pointer_query ptr_qry
;
307 gimple_stmt_iterator m_gsi
;
309 /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
316 * +1 if SI is known to start with more than OFF nonzero characters.
318 * 0 if SI is known to start with exactly OFF nonzero characters.
320 * -1 if SI either does not start with OFF nonzero characters
321 or the relationship between the number of leading nonzero
322 characters in SI and OFF is unknown. */
325 compare_nonzero_chars (strinfo
*si
, unsigned HOST_WIDE_INT off
)
327 if (si
->nonzero_chars
328 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
329 return compare_tree_int (si
->nonzero_chars
, off
);
334 /* Same as above but suitable also for strings with non-constant lengths.
335 Uses RVALS to determine length range. */
338 compare_nonzero_chars (strinfo
*si
, gimple
*stmt
,
339 unsigned HOST_WIDE_INT off
,
342 if (!si
->nonzero_chars
)
345 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
346 return compare_tree_int (si
->nonzero_chars
, off
);
348 if (!rvals
|| TREE_CODE (si
->nonzero_chars
) != SSA_NAME
)
352 if (!rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
))
354 value_range_kind rng
= vr
.kind ();
358 /* If the offset is less than the minimum length or if the bounds
359 of the length range are equal return the result of the comparison
360 same as in the constant case. Otherwise return a conservative
362 int cmpmin
= compare_tree_int (vr
.min (), off
);
363 if (cmpmin
> 0 || tree_int_cst_equal (vr
.min (), vr
.max ()))
369 /* Return true if SI is known to be a zero-length string. */
372 zero_length_string_p (strinfo
*si
)
374 return si
->full_string_p
&& integer_zerop (si
->nonzero_chars
);
377 /* Return strinfo vector entry IDX. */
379 static inline strinfo
*
380 get_strinfo (int idx
)
382 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
384 return (*stridx_to_strinfo
)[idx
];
387 /* Get the next strinfo in the chain after SI, or null if none. */
389 static inline strinfo
*
390 get_next_strinfo (strinfo
*si
)
394 strinfo
*nextsi
= get_strinfo (si
->next
);
395 if (nextsi
== NULL
|| nextsi
->first
!= si
->first
|| nextsi
->prev
!= si
->idx
)
400 /* Helper function for get_stridx. Return the strinfo index of the address
401 of EXP, which is available in PTR if nonnull. If OFFSET_OUT, it is
402 OK to return the index for some X <= &EXP and store &EXP - X in
403 *OFFSET_OUT. When RVALS is nonnull uses it to determine range
407 get_addr_stridx (tree exp
, gimple
*stmt
,
408 tree ptr
, unsigned HOST_WIDE_INT
*offset_out
,
409 range_query
*rvals
= NULL
)
412 struct stridxlist
*list
, *last
= NULL
;
415 if (!decl_to_stridxlist_htab
)
419 base
= get_addr_base_and_unit_offset (exp
, &poff
);
420 if (base
== NULL
|| !DECL_P (base
) || !poff
.is_constant (&off
))
423 list
= decl_to_stridxlist_htab
->get (base
);
429 if (list
->offset
== off
)
435 if (list
->offset
> off
)
442 if ((offset_out
|| ptr
) && last
&& last
->idx
> 0)
444 unsigned HOST_WIDE_INT rel_off
445 = (unsigned HOST_WIDE_INT
) off
- last
->offset
;
446 strinfo
*si
= get_strinfo (last
->idx
);
447 if (si
&& compare_nonzero_chars (si
, stmt
, rel_off
, rvals
) >= 0)
451 *offset_out
= rel_off
;
455 return get_stridx_plus_constant (si
, rel_off
, ptr
);
461 /* Returns string index for EXP. When EXP is an SSA_NAME that refers
462 to a known strinfo with an offset and OFFRNG is non-null, sets
463 both elements of the OFFRNG array to the range of the offset and
464 returns the index of the known strinfo. In this case the result
465 must not be used in for functions that modify the string.
466 When nonnull, uses RVALS to determine range information. */
469 get_stridx (tree exp
, gimple
*stmt
,
470 wide_int offrng
[2] = NULL
, range_query
*rvals
= NULL
)
473 offrng
[0] = offrng
[1] = wi::zero (TYPE_PRECISION (ptrdiff_type_node
));
475 if (TREE_CODE (exp
) == SSA_NAME
)
477 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)])
478 return ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)];
482 HOST_WIDE_INT offset
= 0;
483 /* Follow a chain of at most 5 assignments. */
484 for (int i
= 0; i
< 5; i
++)
486 gimple
*def_stmt
= SSA_NAME_DEF_STMT (e
);
487 if (!is_gimple_assign (def_stmt
))
490 tree_code rhs_code
= gimple_assign_rhs_code (def_stmt
);
493 if (rhs_code
== ADDR_EXPR
)
495 /* Handle indices/offsets into VLAs which are implemented
496 as pointers to arrays. */
497 ptr
= gimple_assign_rhs1 (def_stmt
);
498 ptr
= TREE_OPERAND (ptr
, 0);
500 /* Handle also VLAs of types larger than char. */
501 if (tree eltsize
= TYPE_SIZE_UNIT (TREE_TYPE (ptr
)))
503 if (TREE_CODE (ptr
) == ARRAY_REF
)
505 off
= TREE_OPERAND (ptr
, 1);
506 ptr
= TREE_OPERAND (ptr
, 0);
507 if (!integer_onep (eltsize
))
509 /* Scale the array index by the size of the element
510 type in the rare case that it's greater than
511 the typical 1 for char, making sure both operands
512 have the same type. */
513 eltsize
= fold_convert (ssizetype
, eltsize
);
514 off
= fold_convert (ssizetype
, off
);
515 off
= fold_build2 (MULT_EXPR
, ssizetype
, off
, eltsize
);
519 off
= integer_zero_node
;
524 if (TREE_CODE (ptr
) != MEM_REF
)
527 /* Add the MEM_REF byte offset. */
528 tree mem_off
= TREE_OPERAND (ptr
, 1);
529 off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (off
), off
, mem_off
);
530 ptr
= TREE_OPERAND (ptr
, 0);
532 else if (rhs_code
== POINTER_PLUS_EXPR
)
534 ptr
= gimple_assign_rhs1 (def_stmt
);
535 off
= gimple_assign_rhs2 (def_stmt
);
540 if (TREE_CODE (ptr
) != SSA_NAME
)
543 if (!tree_fits_shwi_p (off
))
545 if (int idx
= ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)])
548 /* Only when requested by setting OFFRNG to non-null,
549 return the index corresponding to the SSA_NAME.
550 Do this irrespective of the whether the offset
552 if (get_range (off
, def_stmt
, offrng
, rvals
))
554 /* When the offset range is known, increment it
555 it by the constant offset computed in prior
556 iterations and store it in the OFFRNG array. */
562 /* When the offset range cannot be determined
563 store [0, SIZE_MAX] and let the caller decide
564 if the offset matters. */
565 offrng
[1] = wi::to_wide (TYPE_MAX_VALUE (sizetype
));
566 offrng
[0] = wi::zero (offrng
[1].get_precision ());
573 HOST_WIDE_INT this_off
= tree_to_shwi (off
);
576 offrng
[0] += wi::shwi (this_off
, offrng
->get_precision ());
577 offrng
[1] += offrng
[0];
583 offset
= (unsigned HOST_WIDE_INT
) offset
+ this_off
;
587 if (int idx
= ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)])
589 strinfo
*si
= get_strinfo (idx
);
592 if (compare_nonzero_chars (si
, offset
) >= 0)
593 return get_stridx_plus_constant (si
, offset
, exp
);
605 if (TREE_CODE (exp
) == ADDR_EXPR
)
607 int idx
= get_addr_stridx (TREE_OPERAND (exp
, 0), stmt
, exp
, NULL
);
612 const char *p
= c_getstr (exp
);
614 return ~(int) strlen (p
);
619 /* Return true if strinfo vector is shared with the immediate dominator. */
622 strinfo_shared (void)
624 return vec_safe_length (stridx_to_strinfo
)
625 && (*stridx_to_strinfo
)[0] != NULL
;
628 /* Unshare strinfo vector that is shared with the immediate dominator. */
631 unshare_strinfo_vec (void)
636 gcc_assert (strinfo_shared ());
637 stridx_to_strinfo
= vec_safe_copy (stridx_to_strinfo
);
638 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
641 (*stridx_to_strinfo
)[0] = NULL
;
644 /* Attempt to create a string index for exp, ADDR_EXPR's operand.
645 Return a pointer to the location where the string index can
646 be stored (if 0) or is stored, or NULL if this can't be tracked. */
649 addr_stridxptr (tree exp
)
654 tree base
= get_addr_base_and_unit_offset (exp
, &poff
);
655 if (base
== NULL_TREE
|| !DECL_P (base
) || !poff
.is_constant (&off
))
658 if (!decl_to_stridxlist_htab
)
660 decl_to_stridxlist_htab
661 = new hash_map
<tree_decl_hash
, stridxlist
> (64);
662 gcc_obstack_init (&stridx_obstack
);
666 stridxlist
*list
= &decl_to_stridxlist_htab
->get_or_insert (base
, &existed
);
670 stridxlist
*before
= NULL
;
671 for (i
= 0; i
< 32; i
++)
673 if (list
->offset
== off
)
675 if (list
->offset
> off
&& before
== NULL
)
677 if (list
->next
== NULL
)
686 before
= XOBNEW (&stridx_obstack
, struct stridxlist
);
693 list
->next
= XOBNEW (&stridx_obstack
, struct stridxlist
);
703 /* Create a new string index, or return 0 if reached limit. */
706 new_stridx (tree exp
)
709 if (max_stridx
>= param_max_tracked_strlens
)
711 if (TREE_CODE (exp
) == SSA_NAME
)
713 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp
))
716 ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)] = idx
;
719 if (TREE_CODE (exp
) == ADDR_EXPR
)
721 int *pidx
= addr_stridxptr (TREE_OPERAND (exp
, 0));
724 gcc_assert (*pidx
== 0);
725 *pidx
= max_stridx
++;
732 /* Like new_stridx, but for ADDR_EXPR's operand instead. */
735 new_addr_stridx (tree exp
)
738 if (max_stridx
>= param_max_tracked_strlens
)
740 pidx
= addr_stridxptr (exp
);
743 gcc_assert (*pidx
== 0);
744 *pidx
= max_stridx
++;
750 /* Create a new strinfo. */
753 new_strinfo (tree ptr
, int idx
, tree nonzero_chars
, bool full_string_p
)
755 strinfo
*si
= strinfo_pool
.allocate ();
756 si
->nonzero_chars
= nonzero_chars
;
757 STRIP_USELESS_TYPE_CONVERSION (ptr
);
761 si
->endptr
= NULL_TREE
;
767 si
->writable
= false;
768 si
->dont_invalidate
= false;
769 si
->full_string_p
= full_string_p
;
773 /* Decrease strinfo refcount and free it if not referenced anymore. */
776 free_strinfo (strinfo
*si
)
778 if (si
&& --si
->refcount
== 0)
779 strinfo_pool
.remove (si
);
782 /* Set strinfo in the vector entry IDX to SI. */
785 set_strinfo (int idx
, strinfo
*si
)
787 if (vec_safe_length (stridx_to_strinfo
) && (*stridx_to_strinfo
)[0])
788 unshare_strinfo_vec ();
789 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
790 vec_safe_grow_cleared (stridx_to_strinfo
, idx
+ 1, true);
791 (*stridx_to_strinfo
)[idx
] = si
;
794 /* Return the first strinfo in the related strinfo chain
795 if all strinfos in between belong to the chain, otherwise NULL. */
798 verify_related_strinfos (strinfo
*origsi
)
800 strinfo
*si
= origsi
, *psi
;
802 if (origsi
->first
== 0)
804 for (; si
->prev
; si
= psi
)
806 if (si
->first
!= origsi
->first
)
808 psi
= get_strinfo (si
->prev
);
811 if (psi
->next
!= si
->idx
)
814 if (si
->idx
!= si
->first
)
819 /* Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
820 Use LOC for folding. */
823 set_endptr_and_length (location_t loc
, strinfo
*si
, tree endptr
)
827 tree start_as_size
= fold_convert_loc (loc
, size_type_node
, si
->ptr
);
828 tree end_as_size
= fold_convert_loc (loc
, size_type_node
, endptr
);
829 si
->nonzero_chars
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
830 end_as_size
, start_as_size
);
831 si
->full_string_p
= true;
834 /* Return the string length, or NULL if it can't be computed.
835 The length may but need not be constant. Instead, it might be
836 the result of a strlen() call. */
839 get_string_length (strinfo
*si
)
841 /* If the length has already been computed return it if it's exact
842 (i.e., the string is nul-terminated at NONZERO_CHARS), or return
844 if (si
->nonzero_chars
)
845 return si
->full_string_p
? si
->nonzero_chars
: NULL
;
847 /* If the string is the result of one of the built-in calls below
848 attempt to compute the length from the call statement. */
851 gimple
*stmt
= si
->stmt
, *lenstmt
;
852 tree callee
, lhs
, fn
, tem
;
854 gimple_stmt_iterator gsi
;
856 gcc_assert (is_gimple_call (stmt
));
857 callee
= gimple_call_fndecl (stmt
);
858 gcc_assert (callee
&& fndecl_built_in_p (callee
, BUILT_IN_NORMAL
));
859 lhs
= gimple_call_lhs (stmt
);
860 /* unshare_strinfo is intentionally not called here. The (delayed)
861 transformation of strcpy or strcat into stpcpy is done at the place
862 of the former strcpy/strcat call and so can affect all the strinfos
863 with the same stmt. If they were unshared before and transformation
864 has been already done, the handling of BUILT_IN_STPCPY{,_CHK} should
865 just compute the right length. */
866 switch (DECL_FUNCTION_CODE (callee
))
868 case BUILT_IN_STRCAT
:
869 case BUILT_IN_STRCAT_CHK
:
870 gsi
= gsi_for_stmt (stmt
);
871 fn
= builtin_decl_implicit (BUILT_IN_STRLEN
);
872 gcc_assert (lhs
== NULL_TREE
);
873 tem
= unshare_expr (gimple_call_arg (stmt
, 0));
874 lenstmt
= gimple_build_call (fn
, 1, tem
);
875 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), lenstmt
);
876 gimple_call_set_lhs (lenstmt
, lhs
);
877 gimple_set_vuse (lenstmt
, gimple_vuse (stmt
));
878 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
879 tem
= gimple_call_arg (stmt
, 0);
880 if (!ptrofftype_p (TREE_TYPE (lhs
)))
882 lhs
= convert_to_ptrofftype (lhs
);
883 lhs
= force_gimple_operand_gsi (&gsi
, lhs
, true, NULL_TREE
,
884 true, GSI_SAME_STMT
);
886 lenstmt
= gimple_build_assign
887 (make_ssa_name (TREE_TYPE (gimple_call_arg (stmt
, 0))),
888 POINTER_PLUS_EXPR
,tem
, lhs
);
889 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
890 gimple_call_set_arg (stmt
, 0, gimple_assign_lhs (lenstmt
));
893 case BUILT_IN_STRCPY
:
894 case BUILT_IN_STRCPY_CHK
:
895 gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY
));
896 if (gimple_call_num_args (stmt
) == 2)
897 fn
= builtin_decl_implicit (BUILT_IN_STPCPY
);
899 fn
= builtin_decl_explicit (BUILT_IN_STPCPY_CHK
);
900 gcc_assert (lhs
== NULL_TREE
);
901 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
903 fprintf (dump_file
, "Optimizing: ");
904 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
906 gimple_call_set_fndecl (stmt
, fn
);
907 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), stmt
);
908 gimple_call_set_lhs (stmt
, lhs
);
910 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
912 fprintf (dump_file
, "into: ");
913 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
916 case BUILT_IN_STPCPY
:
917 case BUILT_IN_STPCPY_CHK
:
918 gcc_assert (lhs
!= NULL_TREE
);
919 loc
= gimple_location (stmt
);
920 set_endptr_and_length (loc
, si
, lhs
);
921 for (strinfo
*chainsi
= verify_related_strinfos (si
);
923 chainsi
= get_next_strinfo (chainsi
))
924 if (chainsi
->nonzero_chars
== NULL
)
925 set_endptr_and_length (loc
, chainsi
, lhs
);
927 case BUILT_IN_ALLOCA
:
928 case BUILT_IN_ALLOCA_WITH_ALIGN
:
929 case BUILT_IN_MALLOC
:
931 /* BUILT_IN_CALLOC always has si->nonzero_chars set. */
938 return si
->nonzero_chars
;
941 /* Dump strlen data to FP for statement STMT. When non-null, RVALS
942 points to the valuation engine used to calculate ranges, and is
943 used to dump strlen range for non-constant results. */
946 dump_strlen_info (FILE *fp
, gimple
*stmt
, range_query
*rvals
)
950 fprintf (fp
, "\nDumping strlen pass data after ");
951 print_gimple_expr (fp
, stmt
, TDF_LINENO
);
955 fprintf (fp
, "\nDumping strlen pass data\n");
957 fprintf (fp
, "max_stridx = %i\n", max_stridx
);
958 fprintf (fp
, "ssa_ver_to_stridx has %u elements\n",
959 ssa_ver_to_stridx
.length ());
960 fprintf (fp
, "stridx_to_strinfo");
961 if (stridx_to_strinfo
)
963 fprintf (fp
, " has %u elements\n", stridx_to_strinfo
->length ());
964 for (unsigned i
= 0; i
!= stridx_to_strinfo
->length (); ++i
)
966 if (strinfo
*si
= (*stridx_to_strinfo
)[i
])
970 fprintf (fp
, " idx = %i", si
->idx
);
973 fprintf (fp
, ", ptr = ");
974 print_generic_expr (fp
, si
->ptr
);
977 if (si
->nonzero_chars
)
979 fprintf (fp
, ", nonzero_chars = ");
980 print_generic_expr (fp
, si
->nonzero_chars
);
981 if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
983 value_range_kind rng
= VR_UNDEFINED
;
988 rvals
->range_of_expr (vr
, si
->nonzero_chars
,
991 if (range_int_cst_p (&vr
))
993 min
= wi::to_wide (vr
.min ());
994 max
= wi::to_wide (vr
.max ());
1002 get_range_query (cfun
)
1003 ->range_of_expr (vr
, si
->nonzero_chars
);
1005 if (!vr
.undefined_p ())
1007 min
= wi::to_wide (vr
.min ());
1008 max
= wi::to_wide (vr
.max ());
1012 if (rng
== VR_RANGE
|| rng
== VR_ANTI_RANGE
)
1014 fprintf (fp
, " %s[%llu, %llu]",
1015 rng
== VR_RANGE
? "" : "~",
1016 (long long) min
.to_uhwi (),
1017 (long long) max
.to_uhwi ());
1022 fprintf (fp
, ", refcount = %i", si
->refcount
);
1025 fprintf (fp
, ", stmt = ");
1026 print_gimple_expr (fp
, si
->stmt
, 0);
1030 fprintf (fp
, ", alloc = ");
1031 print_gimple_expr (fp
, si
->alloc
, 0);
1034 fprintf (fp
, ", writable");
1035 if (si
->dont_invalidate
)
1036 fprintf (fp
, ", dont_invalidate");
1037 if (si
->full_string_p
)
1038 fprintf (fp
, ", full_string_p");
1039 if (strinfo
*next
= get_next_strinfo (si
))
1041 fprintf (fp
, ", {");
1043 fprintf (fp
, "%i%s", next
->idx
, next
->first
? ", " : "");
1044 while ((next
= get_next_strinfo (next
)));
1052 fprintf (fp
, " = null\n");
1054 fprintf (fp
, "decl_to_stridxlist_htab");
1055 if (decl_to_stridxlist_htab
)
1058 typedef decl_to_stridxlist_htab_t::iterator iter_t
;
1059 for (iter_t it
= decl_to_stridxlist_htab
->begin ();
1060 it
!= decl_to_stridxlist_htab
->end (); ++it
)
1062 tree decl
= (*it
).first
;
1063 stridxlist
*list
= &(*it
).second
;
1064 fprintf (fp
, " decl = ");
1065 print_generic_expr (fp
, decl
);
1068 fprintf (fp
, ", offsets = {");
1069 for (; list
; list
= list
->next
)
1070 fprintf (fp
, "%lli%s", (long long) list
->offset
,
1071 list
->next
? ", " : "");
1078 fprintf (fp
, " = null\n");
1082 fprintf (fp
, "laststmt = ");
1083 print_gimple_expr (fp
, laststmt
.stmt
, 0);
1084 fprintf (fp
, ", len = ");
1085 print_generic_expr (fp
, laststmt
.len
);
1086 fprintf (fp
, ", stridx = %i\n", laststmt
.stridx
);
1090 /* Helper of get_range_strlen_dynamic(). See below. */
1093 get_range_strlen_phi (tree src
, gphi
*phi
,
1094 c_strlen_data
*pdata
, bitmap visited
,
1095 pointer_query
*ptr_qry
, unsigned *pssa_def_max
)
1097 if (!bitmap_set_bit (visited
, SSA_NAME_VERSION (src
)))
1100 if (*pssa_def_max
== 0)
1105 /* Iterate over the PHI arguments and determine the minimum and maximum
1106 length/size of each and incorporate them into the overall result. */
1107 for (unsigned i
= 0; i
!= gimple_phi_num_args (phi
); ++i
)
1109 tree arg
= gimple_phi_arg_def (phi
, i
);
1110 if (arg
== gimple_phi_result (phi
))
1113 c_strlen_data argdata
= { };
1114 if (!get_range_strlen_dynamic (arg
, phi
, &argdata
, visited
, ptr_qry
,
1117 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1121 /* Set the DECL of an unterminated array this argument refers to
1122 if one hasn't been found yet. */
1123 if (!pdata
->decl
&& argdata
.decl
)
1124 pdata
->decl
= argdata
.decl
;
1127 || (integer_zerop (argdata
.minlen
)
1128 && (!argdata
.maxbound
1129 || integer_all_onesp (argdata
.maxbound
))
1130 && integer_all_onesp (argdata
.maxlen
)))
1132 /* Set the upper bound of the length to unbounded. */
1133 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1137 /* Adjust the minimum and maximum length determined so far and
1138 the upper bound on the array size. */
1139 if (TREE_CODE (argdata
.minlen
) == INTEGER_CST
1141 || tree_int_cst_lt (argdata
.minlen
, pdata
->minlen
)))
1142 pdata
->minlen
= argdata
.minlen
;
1144 if (TREE_CODE (argdata
.maxlen
) == INTEGER_CST
1147 && tree_int_cst_lt (pdata
->maxlen
, argdata
.maxlen
))))
1148 pdata
->maxlen
= argdata
.maxlen
;
1150 if (!pdata
->maxbound
1151 || TREE_CODE (pdata
->maxbound
) != INTEGER_CST
1152 || (argdata
.maxbound
1153 && tree_int_cst_lt (pdata
->maxbound
, argdata
.maxbound
)
1154 && !integer_all_onesp (argdata
.maxbound
)))
1155 pdata
->maxbound
= argdata
.maxbound
;
1161 /* Return the maximum possible length of the string PTR that's less
1162 than MAXLEN given the size of the object of subobject it points
1163 to at the given STMT. MAXLEN is the maximum length of the string
1164 determined so far. Return null when no such maximum can be
1168 get_maxbound (tree ptr
, gimple
*stmt
, offset_int maxlen
,
1169 pointer_query
*ptr_qry
)
1172 if (!ptr_qry
->get_ref (ptr
, stmt
, &aref
))
1175 offset_int sizrem
= aref
.size_remaining ();
1179 if (sizrem
< maxlen
)
1180 maxlen
= sizrem
- 1;
1182 /* Try to determine the maximum from the subobject at the offset.
1183 This handles MEM [&some-struct, member-offset] that's often
1184 the result of folding COMPONENT_REF [some-struct, member]. */
1185 tree reftype
= TREE_TYPE (aref
.ref
);
1186 if (!RECORD_OR_UNION_TYPE_P (reftype
)
1187 || aref
.offrng
[0] != aref
.offrng
[1]
1188 || !wi::fits_shwi_p (aref
.offrng
[0]))
1189 return wide_int_to_tree (size_type_node
, maxlen
);
1191 HOST_WIDE_INT off
= aref
.offrng
[0].to_shwi ();
1192 tree fld
= field_at_offset (reftype
, NULL_TREE
, off
);
1193 if (!fld
|| !DECL_SIZE_UNIT (fld
))
1194 return wide_int_to_tree (size_type_node
, maxlen
);
1196 offset_int size
= wi::to_offset (DECL_SIZE_UNIT (fld
));
1198 return wide_int_to_tree (size_type_node
, maxlen
);
1200 return wide_int_to_tree (size_type_node
, size
- 1);
1203 /* Attempt to determine the length of the string SRC. On success, store
1204 the length in *PDATA and return true. Otherwise, return false.
1205 VISITED is a bitmap of visited PHI nodes. RVALS points to the valuation
1206 engine used to calculate ranges. PSSA_DEF_MAX to an SSA_NAME
1207 assignment limit used to prevent runaway recursion. */
1210 get_range_strlen_dynamic (tree src
, gimple
*stmt
,
1211 c_strlen_data
*pdata
, bitmap visited
,
1212 pointer_query
*ptr_qry
, unsigned *pssa_def_max
)
1214 int idx
= get_stridx (src
, stmt
);
1217 if (TREE_CODE (src
) == SSA_NAME
)
1219 gimple
*def_stmt
= SSA_NAME_DEF_STMT (src
);
1220 if (gphi
*phi
= dyn_cast
<gphi
*>(def_stmt
))
1221 return get_range_strlen_phi (src
, phi
, pdata
, visited
, ptr_qry
,
1225 /* Return success regardless of the result and handle *PDATA
1227 get_range_strlen (src
, pdata
, 1);
1233 /* SRC is a string of constant length. */
1234 pdata
->minlen
= build_int_cst (size_type_node
, ~idx
);
1235 pdata
->maxlen
= pdata
->minlen
;
1236 pdata
->maxbound
= pdata
->maxlen
;
1240 if (strinfo
*si
= get_strinfo (idx
))
1242 pdata
->minlen
= get_string_length (si
);
1243 if (!pdata
->minlen
&& si
->nonzero_chars
)
1245 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
1246 pdata
->minlen
= si
->nonzero_chars
;
1247 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
1250 ptr_qry
->rvals
->range_of_expr (vr
, si
->nonzero_chars
, si
->stmt
);
1251 if (range_int_cst_p (&vr
))
1253 pdata
->minlen
= vr
.min ();
1254 pdata
->maxlen
= vr
.max ();
1257 pdata
->minlen
= build_zero_cst (size_type_node
);
1260 pdata
->minlen
= build_zero_cst (size_type_node
);
1262 tree base
= si
->ptr
;
1263 if (TREE_CODE (base
) == ADDR_EXPR
)
1264 base
= TREE_OPERAND (base
, 0);
1268 base
= get_addr_base_and_unit_offset (base
, &poff
);
1271 && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
1272 && TYPE_SIZE_UNIT (TREE_TYPE (base
))
1273 && poff
.is_constant (&off
))
1275 tree basetype
= TREE_TYPE (base
);
1276 tree size
= TYPE_SIZE_UNIT (basetype
);
1277 if (TREE_CODE (size
) == INTEGER_CST
)
1279 ++off
; /* Increment for the terminating nul. */
1280 tree toffset
= build_int_cst (size_type_node
, off
);
1281 pdata
->maxlen
= fold_build2 (MINUS_EXPR
, size_type_node
, size
,
1283 pdata
->maxbound
= pdata
->maxlen
;
1286 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1289 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1291 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == SSA_NAME
)
1294 ptr_qry
->rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
);
1295 if (range_int_cst_p (&vr
))
1297 pdata
->minlen
= vr
.min ();
1298 pdata
->maxlen
= vr
.max ();
1299 offset_int max
= offset_int::from (vr
.upper_bound (0), SIGNED
);
1300 if (tree maxbound
= get_maxbound (si
->ptr
, stmt
, max
, ptr_qry
))
1301 pdata
->maxbound
= maxbound
;
1303 pdata
->maxbound
= pdata
->maxlen
;
1307 pdata
->minlen
= build_zero_cst (size_type_node
);
1308 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1311 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == INTEGER_CST
)
1313 pdata
->maxlen
= pdata
->minlen
;
1314 pdata
->maxbound
= pdata
->minlen
;
1318 /* For PDATA->MINLEN that's a non-constant expression such
1319 as PLUS_EXPR whose value range is unknown, set the bounds
1320 to zero and SIZE_MAX. */
1321 pdata
->minlen
= build_zero_cst (size_type_node
);
1322 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1331 /* Analogous to get_range_strlen but for dynamically created strings,
1332 i.e., those created by calls to strcpy as opposed to just string
1334 Try to obtain the range of the lengths of the string(s) referenced
1335 by SRC, or the size of the largest array SRC refers to if the range
1336 of lengths cannot be determined, and store all in *PDATA. RVALS
1337 points to the valuation engine used to calculate ranges. */
1340 get_range_strlen_dynamic (tree src
, gimple
*stmt
, c_strlen_data
*pdata
,
1341 pointer_query
&ptr_qry
)
1343 auto_bitmap visited
;
1344 tree maxbound
= pdata
->maxbound
;
1346 unsigned limit
= param_ssa_name_def_chain_limit
;
1347 if (!get_range_strlen_dynamic (src
, stmt
, pdata
, visited
, &ptr_qry
, &limit
))
1349 /* On failure extend the length range to an impossible maximum
1350 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1351 members can stay unchanged regardless. */
1352 pdata
->minlen
= ssize_int (0);
1353 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1355 else if (!pdata
->minlen
)
1356 pdata
->minlen
= ssize_int (0);
1358 /* If it's unchanged from it initial non-null value, set the conservative
1359 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1360 if (maxbound
&& pdata
->maxbound
== maxbound
)
1361 pdata
->maxbound
= build_all_ones_cst (size_type_node
);
1364 /* Invalidate string length information for strings whose length might
1365 change due to stores in STMT, except those marked DONT_INVALIDATE.
1366 For string-modifying statements, ZERO_WRITE is set when the statement
1368 Returns true if any STRIDX_TO_STRINFO entries were considered
1369 for invalidation. */
1372 maybe_invalidate (gimple
*stmt
, bool zero_write
= false)
1374 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1376 fprintf (dump_file
, "%s called for ", __func__
);
1377 print_gimple_stmt (dump_file
, stmt
, TDF_LINENO
);
1381 bool nonempty
= false;
1383 for (unsigned i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
1385 if (si
== NULL
|| !POINTER_TYPE_P (TREE_TYPE (si
->ptr
)))
1390 /* Unconditionally reset DONT_INVALIDATE. */
1391 bool dont_invalidate
= si
->dont_invalidate
;
1392 si
->dont_invalidate
= false;
1394 if (dont_invalidate
)
1398 tree size
= si
->nonzero_chars
;
1399 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, size
);
1400 /* Include the terminating nul in the size of the string
1401 to consider when determining possible clobber. But do not
1402 add it to 'size' since we don't know whether it would
1403 actually fit the allocated area. */
1404 if (known_size_p (r
.size
))
1406 if (known_le (r
.size
, HOST_WIDE_INT_MAX
- BITS_PER_UNIT
))
1407 r
.max_size
+= BITS_PER_UNIT
;
1411 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1413 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1415 fputs (" statement may clobber object ", dump_file
);
1416 print_generic_expr (dump_file
, si
->ptr
);
1417 if (size
&& tree_fits_uhwi_p (size
))
1418 fprintf (dump_file
, " " HOST_WIDE_INT_PRINT_UNSIGNED
1419 " bytes in size", tree_to_uhwi (size
));
1420 fputc ('\n', dump_file
);
1423 set_strinfo (i
, NULL
);
1431 && is_gimple_call (si
->stmt
)
1432 && (DECL_FUNCTION_CODE (gimple_call_fndecl (si
->stmt
))
1433 == BUILT_IN_CALLOC
))
1435 /* If the clobber test above considered the length of
1436 the string (including the nul), then for (potentially)
1437 non-zero writes that might modify storage allocated by
1438 calloc consider the whole object and if it might be
1439 clobbered by the statement reset the statement. */
1440 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, NULL_TREE
);
1441 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1446 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1447 fprintf (dump_file
, "%s returns %i\n", __func__
, nonempty
);
1452 /* Unshare strinfo record SI, if it has refcount > 1 or
1453 if stridx_to_strinfo vector is shared with some other
1457 unshare_strinfo (strinfo
*si
)
1461 if (si
->refcount
== 1 && !strinfo_shared ())
1464 nsi
= new_strinfo (si
->ptr
, si
->idx
, si
->nonzero_chars
, si
->full_string_p
);
1465 nsi
->stmt
= si
->stmt
;
1466 nsi
->alloc
= si
->alloc
;
1467 nsi
->endptr
= si
->endptr
;
1468 nsi
->first
= si
->first
;
1469 nsi
->prev
= si
->prev
;
1470 nsi
->next
= si
->next
;
1471 nsi
->writable
= si
->writable
;
1472 set_strinfo (si
->idx
, nsi
);
1477 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1478 strinfo if there is any. Return it's idx, or 0 if no strinfo has
1482 get_stridx_plus_constant (strinfo
*basesi
, unsigned HOST_WIDE_INT off
,
1485 if (TREE_CODE (ptr
) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1488 if (compare_nonzero_chars (basesi
, off
) < 0
1489 || !tree_fits_uhwi_p (basesi
->nonzero_chars
))
1492 unsigned HOST_WIDE_INT nonzero_chars
1493 = tree_to_uhwi (basesi
->nonzero_chars
) - off
;
1494 strinfo
*si
= basesi
, *chainsi
;
1495 if (si
->first
|| si
->prev
|| si
->next
)
1496 si
= verify_related_strinfos (basesi
);
1498 || si
->nonzero_chars
== NULL_TREE
1499 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1502 if (TREE_CODE (ptr
) == SSA_NAME
1503 && ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1504 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1506 gcc_checking_assert (compare_tree_int (si
->nonzero_chars
, off
) != -1);
1507 for (chainsi
= si
; chainsi
->next
; chainsi
= si
)
1509 si
= get_next_strinfo (chainsi
);
1511 || si
->nonzero_chars
== NULL_TREE
1512 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1514 int r
= compare_tree_int (si
->nonzero_chars
, nonzero_chars
);
1519 if (TREE_CODE (ptr
) == SSA_NAME
)
1520 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = si
->idx
;
1523 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1524 if (pidx
!= NULL
&& *pidx
== 0)
1533 int idx
= new_stridx (ptr
);
1536 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, nonzero_chars
),
1537 basesi
->full_string_p
);
1538 set_strinfo (idx
, si
);
1539 if (strinfo
*nextsi
= get_strinfo (chainsi
->next
))
1541 nextsi
= unshare_strinfo (nextsi
);
1542 si
->next
= nextsi
->idx
;
1545 chainsi
= unshare_strinfo (chainsi
);
1546 if (chainsi
->first
== 0)
1547 chainsi
->first
= chainsi
->idx
;
1548 chainsi
->next
= idx
;
1549 if (chainsi
->endptr
== NULL_TREE
&& zero_length_string_p (si
))
1550 chainsi
->endptr
= ptr
;
1551 si
->endptr
= chainsi
->endptr
;
1552 si
->prev
= chainsi
->idx
;
1553 si
->first
= chainsi
->first
;
1554 si
->writable
= chainsi
->writable
;
1558 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1559 to a zero-length string and if possible chain it to a related strinfo
1560 chain whose part is or might be CHAINSI. */
1563 zero_length_string (tree ptr
, strinfo
*chainsi
)
1567 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1568 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1569 gcc_checking_assert (TREE_CODE (ptr
) == SSA_NAME
1570 && ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] == 0);
1572 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1574 if (chainsi
!= NULL
)
1576 si
= verify_related_strinfos (chainsi
);
1581 /* We shouldn't mix delayed and non-delayed lengths. */
1582 gcc_assert (si
->full_string_p
);
1583 if (si
->endptr
== NULL_TREE
)
1585 si
= unshare_strinfo (si
);
1589 si
= get_next_strinfo (si
);
1592 if (zero_length_string_p (chainsi
))
1596 chainsi
= unshare_strinfo (chainsi
);
1599 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = chainsi
->idx
;
1605 /* We shouldn't mix delayed and non-delayed lengths. */
1606 gcc_assert (chainsi
->full_string_p
);
1607 if (chainsi
->first
|| chainsi
->prev
|| chainsi
->next
)
1609 chainsi
= unshare_strinfo (chainsi
);
1616 idx
= new_stridx (ptr
);
1619 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, 0), true);
1620 set_strinfo (idx
, si
);
1622 if (chainsi
!= NULL
)
1624 chainsi
= unshare_strinfo (chainsi
);
1625 if (chainsi
->first
== 0)
1626 chainsi
->first
= chainsi
->idx
;
1627 chainsi
->next
= idx
;
1628 if (chainsi
->endptr
== NULL_TREE
)
1629 chainsi
->endptr
= ptr
;
1630 si
->prev
= chainsi
->idx
;
1631 si
->first
= chainsi
->first
;
1632 si
->writable
= chainsi
->writable
;
1637 /* For strinfo ORIGSI whose length has been just updated, adjust other
1638 related strinfos so that they match the new ORIGSI. This involves:
1640 - adding ADJ to the nonzero_chars fields
1641 - copying full_string_p from the new ORIGSI. */
1644 adjust_related_strinfos (location_t loc
, strinfo
*origsi
, tree adj
)
1646 strinfo
*si
= verify_related_strinfos (origsi
);
1659 si
= unshare_strinfo (si
);
1660 /* We shouldn't see delayed lengths here; the caller must
1661 have calculated the old length in order to calculate
1663 gcc_assert (si
->nonzero_chars
);
1664 tem
= fold_convert_loc (loc
, TREE_TYPE (si
->nonzero_chars
), adj
);
1665 si
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
1666 TREE_TYPE (si
->nonzero_chars
),
1667 si
->nonzero_chars
, tem
);
1668 si
->full_string_p
= origsi
->full_string_p
;
1670 si
->endptr
= NULL_TREE
;
1671 si
->dont_invalidate
= true;
1673 nsi
= get_next_strinfo (si
);
1680 /* Find if there are other SSA_NAME pointers equal to PTR
1681 for which we don't track their string lengths yet. If so, use
1685 find_equal_ptrs (tree ptr
, int idx
)
1687 if (TREE_CODE (ptr
) != SSA_NAME
)
1691 gimple
*stmt
= SSA_NAME_DEF_STMT (ptr
);
1692 if (!is_gimple_assign (stmt
))
1694 ptr
= gimple_assign_rhs1 (stmt
);
1695 switch (gimple_assign_rhs_code (stmt
))
1700 if (!POINTER_TYPE_P (TREE_TYPE (ptr
)))
1702 if (TREE_CODE (ptr
) == SSA_NAME
)
1704 if (TREE_CODE (ptr
) != ADDR_EXPR
)
1709 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1710 if (pidx
!= NULL
&& *pidx
== 0)
1718 /* We might find an endptr created in this pass. Grow the
1719 vector in that case. */
1720 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1721 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1723 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] != 0)
1725 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = idx
;
1729 /* Return true if STMT is a call to a builtin function with the right
1730 arguments and attributes that should be considered for optimization
1734 valid_builtin_call (gimple
*stmt
)
1736 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
1739 tree callee
= gimple_call_fndecl (stmt
);
1740 switch (DECL_FUNCTION_CODE (callee
))
1742 case BUILT_IN_MEMCMP
:
1743 case BUILT_IN_MEMCMP_EQ
:
1744 case BUILT_IN_STRCMP
:
1745 case BUILT_IN_STRNCMP
:
1746 case BUILT_IN_STRCHR
:
1747 case BUILT_IN_STRLEN
:
1748 case BUILT_IN_STRNLEN
:
1749 /* The above functions should be pure. Punt if they aren't. */
1750 if (gimple_vdef (stmt
) || gimple_vuse (stmt
) == NULL_TREE
)
1754 case BUILT_IN_ALLOCA
:
1755 case BUILT_IN_ALLOCA_WITH_ALIGN
:
1756 case BUILT_IN_CALLOC
:
1757 case BUILT_IN_MALLOC
:
1758 case BUILT_IN_MEMCPY
:
1759 case BUILT_IN_MEMCPY_CHK
:
1760 case BUILT_IN_MEMPCPY
:
1761 case BUILT_IN_MEMPCPY_CHK
:
1762 case BUILT_IN_MEMSET
:
1763 case BUILT_IN_STPCPY
:
1764 case BUILT_IN_STPCPY_CHK
:
1765 case BUILT_IN_STPNCPY
:
1766 case BUILT_IN_STPNCPY_CHK
:
1767 case BUILT_IN_STRCAT
:
1768 case BUILT_IN_STRCAT_CHK
:
1769 case BUILT_IN_STRCPY
:
1770 case BUILT_IN_STRCPY_CHK
:
1771 case BUILT_IN_STRNCAT
:
1772 case BUILT_IN_STRNCAT_CHK
:
1773 case BUILT_IN_STRNCPY
:
1774 case BUILT_IN_STRNCPY_CHK
:
1775 /* The above functions should be neither const nor pure. Punt if they
1777 if (gimple_vdef (stmt
) == NULL_TREE
|| gimple_vuse (stmt
) == NULL_TREE
)
1788 /* If the last .MEM setter statement before STMT is
1789 memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1790 and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1791 just memcpy (x, y, strlen (y)). SI must be the zero length
1795 strlen_pass::adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
)
1797 tree vuse
, callee
, len
;
1798 struct laststmt_struct last
= laststmt
;
1799 strinfo
*lastsi
, *firstsi
;
1800 unsigned len_arg_no
= 2;
1802 laststmt
.stmt
= NULL
;
1803 laststmt
.len
= NULL_TREE
;
1804 laststmt
.stridx
= 0;
1806 if (last
.stmt
== NULL
)
1809 vuse
= gimple_vuse (stmt
);
1810 if (vuse
== NULL_TREE
1811 || SSA_NAME_DEF_STMT (vuse
) != last
.stmt
1812 || !has_single_use (vuse
))
1815 gcc_assert (last
.stridx
> 0);
1816 lastsi
= get_strinfo (last
.stridx
);
1822 if (lastsi
->first
== 0 || lastsi
->first
!= si
->first
)
1825 firstsi
= verify_related_strinfos (si
);
1826 if (firstsi
== NULL
)
1828 while (firstsi
!= lastsi
)
1830 firstsi
= get_next_strinfo (firstsi
);
1831 if (firstsi
== NULL
)
1836 if (!is_strcat
&& !zero_length_string_p (si
))
1839 if (is_gimple_assign (last
.stmt
))
1841 gimple_stmt_iterator gsi
;
1843 if (!integer_zerop (gimple_assign_rhs1 (last
.stmt
)))
1845 if (stmt_could_throw_p (cfun
, last
.stmt
))
1847 gsi
= gsi_for_stmt (last
.stmt
);
1848 unlink_stmt_vdef (last
.stmt
);
1849 release_defs (last
.stmt
);
1850 gsi_remove (&gsi
, true);
1854 if (!valid_builtin_call (last
.stmt
))
1857 callee
= gimple_call_fndecl (last
.stmt
);
1858 switch (DECL_FUNCTION_CODE (callee
))
1860 case BUILT_IN_MEMCPY
:
1861 case BUILT_IN_MEMCPY_CHK
:
1867 len
= gimple_call_arg (last
.stmt
, len_arg_no
);
1868 if (tree_fits_uhwi_p (len
))
1870 if (!tree_fits_uhwi_p (last
.len
)
1871 || integer_zerop (len
)
1872 || tree_to_uhwi (len
) != tree_to_uhwi (last
.len
) + 1)
1874 /* Don't adjust the length if it is divisible by 4, it is more efficient
1875 to store the extra '\0' in that case. */
1876 if ((tree_to_uhwi (len
) & 3) == 0)
1879 /* Don't fold away an out of bounds access, as this defeats proper
1881 tree dst
= gimple_call_arg (last
.stmt
, 0);
1884 tree size
= compute_objsize (dst
, stmt
, 1, &aref
, &ptr_qry
);
1885 if (size
&& tree_int_cst_lt (size
, len
))
1888 else if (TREE_CODE (len
) == SSA_NAME
)
1890 gimple
*def_stmt
= SSA_NAME_DEF_STMT (len
);
1891 if (!is_gimple_assign (def_stmt
)
1892 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
1893 || gimple_assign_rhs1 (def_stmt
) != last
.len
1894 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
1900 gimple_call_set_arg (last
.stmt
, len_arg_no
, last
.len
);
1901 update_stmt (last
.stmt
);
1904 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1905 call, or when BOUND is non-null, of a strnlen() call, set LHS
1906 range info to [0, min (MAX, BOUND)] when the range includes more
1907 than one value and return LHS. Otherwise, when the range
1908 [MIN, MAX] is such that MIN == MAX, return the tree representation
1909 of (MIN). The latter allows callers to fold suitable strnlen() calls
1913 set_strlen_range (tree lhs
, wide_int min
, wide_int max
,
1914 tree bound
/* = NULL_TREE */)
1916 if (TREE_CODE (lhs
) != SSA_NAME
1917 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1922 /* For strnlen, adjust MIN and MAX as necessary. If the bound
1923 is less than the size of the array set MAX to it. It it's
1924 greater than MAX and MAX is non-zero bump MAX down to account
1925 for the necessary terminating nul. Otherwise leave it alone. */
1926 if (TREE_CODE (bound
) == INTEGER_CST
)
1928 wide_int wibnd
= wi::to_wide (bound
);
1929 int cmp
= wi::cmpu (wibnd
, max
);
1932 else if (cmp
&& wi::ne_p (max
, min
))
1935 else if (TREE_CODE (bound
) == SSA_NAME
)
1938 get_range_query (cfun
)->range_of_expr (r
, bound
);
1939 if (!r
.undefined_p ())
1941 /* For a bound in a known range, adjust the range determined
1942 above as necessary. For a bound in some anti-range or
1943 in an unknown range, use the range determined by callers. */
1944 if (wi::ltu_p (r
.lower_bound (), min
))
1945 min
= r
.lower_bound ();
1946 if (wi::ltu_p (r
.upper_bound (), max
))
1947 max
= r
.upper_bound ();
1953 return wide_int_to_tree (size_type_node
, min
);
1955 value_range
vr (TREE_TYPE (lhs
), min
, max
);
1956 set_range_info (lhs
, vr
);
1960 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1961 SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1962 a character array A[N] with unknown length bounded by N, and for
1963 strnlen(), by min (N, BOUND). */
1966 maybe_set_strlen_range (tree lhs
, tree src
, tree bound
)
1968 if (TREE_CODE (lhs
) != SSA_NAME
1969 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1972 if (TREE_CODE (src
) == SSA_NAME
)
1974 gimple
*def
= SSA_NAME_DEF_STMT (src
);
1975 if (is_gimple_assign (def
)
1976 && gimple_assign_rhs_code (def
) == ADDR_EXPR
)
1977 src
= gimple_assign_rhs1 (def
);
1980 /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1981 NUL so that the difference between a pointer to just past it and
1982 one to its beginning is positive. */
1983 wide_int max
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
1985 if (TREE_CODE (src
) == ADDR_EXPR
)
1987 /* The last array member of a struct can be bigger than its size
1988 suggests if it's treated as a poor-man's flexible array member. */
1989 src
= TREE_OPERAND (src
, 0);
1990 if (TREE_CODE (src
) != MEM_REF
1991 && !array_ref_flexible_size_p (src
))
1993 tree type
= TREE_TYPE (src
);
1994 tree size
= TYPE_SIZE_UNIT (type
);
1996 && TREE_CODE (size
) == INTEGER_CST
1997 && !integer_zerop (size
))
1999 /* Even though such uses of strlen would be undefined,
2000 avoid relying on arrays of arrays in case some genius
2001 decides to call strlen on an unterminated array element
2002 that's followed by a terminated one. Likewise, avoid
2003 assuming that a struct array member is necessarily
2004 nul-terminated (the nul may be in the member that
2005 follows). In those cases, assume that the length
2006 of the string stored in such an array is bounded
2007 by the size of the enclosing object if one can be
2009 tree base
= get_base_address (src
);
2012 if (tree size
= DECL_SIZE_UNIT (base
))
2014 && TREE_CODE (size
) == INTEGER_CST
2015 && TREE_CODE (TREE_TYPE (base
)) != POINTER_TYPE
)
2016 max
= wi::to_wide (size
);
2020 /* For strlen() the upper bound above is equal to
2021 the longest string that can be stored in the array
2022 (i.e., it accounts for the terminating nul. For
2023 strnlen() bump up the maximum by one since the array
2024 need not be nul-terminated. */
2025 if (!bound
&& max
!= 0)
2030 wide_int min
= wi::zero (max
.get_precision ());
2031 return set_strlen_range (lhs
, min
, max
, bound
);
2034 /* Diagnose buffer overflow by a STMT writing LEN + PLUS_ONE bytes,
2035 either into a region allocated for the object SI when non-null,
2036 or into an object designated by the LHS of STMT otherwise.
2037 For a call STMT, when CALL_LHS is set use its left hand side
2038 as the destination, otherwise use argument zero.
2039 When nonnull uses RVALS to determine range information.
2040 RAWMEM may be set by memcpy and other raw memory functions
2041 to allow accesses across subobject boundaries. */
2044 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, tree len
,
2045 strinfo
*si
, bool plus_one
, bool rawmem
)
2047 if (!len
|| warning_suppressed_p (stmt
, OPT_Wstringop_overflow_
))
2050 /* The DECL of the function performing the write if it is done
2052 tree writefn
= NULL_TREE
;
2053 /* The destination expression involved in the store or call STMT. */
2054 tree dest
= NULL_TREE
;
2056 if (is_gimple_assign (stmt
))
2057 dest
= gimple_assign_lhs (stmt
);
2058 else if (is_gimple_call (stmt
))
2061 dest
= gimple_call_lhs (stmt
);
2064 gcc_assert (gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
));
2065 dest
= gimple_call_arg (stmt
, 0);
2070 writefn
= gimple_call_fndecl (stmt
);
2075 if (warning_suppressed_p (dest
, OPT_Wstringop_overflow_
))
2078 const int ostype
= rawmem
? 0 : 1;
2080 /* Use maximum precision to avoid overflow in the addition below.
2081 Make sure all operands have the same precision to keep wide_int
2085 /* The size of the destination region (which is smaller than
2086 the destination object for stores at a non-zero offset). */
2087 tree destsize
= compute_objsize (dest
, stmt
, ostype
, &aref
, &ptr_qry
);
2092 aref
.sizrng
[1] = wi::to_offset (max_object_size ());
2095 /* Return early if the DESTSIZE size expression is the same as LEN
2096 and the offset into the destination is zero. This might happen
2097 in the case of a pair of malloc and memset calls to allocate
2098 an object and clear it as if by calloc. */
2099 if (destsize
== len
&& !plus_one
2100 && aref
.offrng
[0] == 0 && aref
.offrng
[0] == aref
.offrng
[1])
2104 if (!get_range (len
, stmt
, rng
, ptr_qry
.rvals
))
2107 widest_int lenrng
[2] =
2108 { widest_int::from (rng
[0], SIGNED
), widest_int::from (rng
[1], SIGNED
) };
2116 /* The size of the remaining space in the destination computed
2117 as the size of the latter minus the offset into it. */
2118 widest_int spcrng
[2];
2120 offset_int remrng
[2];
2121 remrng
[1] = aref
.size_remaining (remrng
);
2122 spcrng
[0] = remrng
[0] == -1 ? 0 : widest_int::from (remrng
[0], UNSIGNED
);
2123 spcrng
[1] = widest_int::from (remrng
[1], UNSIGNED
);
2126 if (wi::leu_p (lenrng
[0], spcrng
[0])
2127 && wi::leu_p (lenrng
[1], spcrng
[1]))
2130 location_t loc
= gimple_or_expr_nonartificial_location (stmt
, dest
);
2131 bool warned
= false;
2132 if (wi::leu_p (lenrng
[0], spcrng
[1]))
2135 && (!si
|| rawmem
|| !is_strlen_related_p (si
->ptr
, len
)))
2139 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2140 "%qD writing one too many bytes into a region "
2141 "of a size that depends on %<strlen%>",
2143 : warning_at (loc
, OPT_Wstringop_overflow_
,
2144 "writing one too many bytes into a region "
2145 "of a size that depends on %<strlen%>"));
2147 else if (lenrng
[0] == lenrng
[1])
2149 if (spcrng
[0] == spcrng
[1])
2151 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2152 lenrng
[0].to_uhwi (),
2153 "%qD writing %wu byte into a region "
2155 "%qD writing %wu bytes into a region "
2157 writefn
, lenrng
[0].to_uhwi (),
2158 spcrng
[0].to_uhwi ())
2159 : warning_n (loc
, OPT_Wstringop_overflow_
,
2160 lenrng
[0].to_uhwi (),
2161 "writing %wu byte into a region "
2163 "writing %wu bytes into a region "
2165 lenrng
[0].to_uhwi (),
2166 spcrng
[0].to_uhwi ()));
2169 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2170 lenrng
[0].to_uhwi (),
2171 "%qD writing %wu byte into a region "
2172 "of size between %wu and %wu",
2173 "%qD writing %wu bytes into a region "
2174 "of size between %wu and %wu",
2175 writefn
, lenrng
[0].to_uhwi (),
2176 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2177 : warning_n (loc
, OPT_Wstringop_overflow_
,
2178 lenrng
[0].to_uhwi (),
2179 "writing %wu byte into a region "
2180 "of size between %wu and %wu",
2181 "writing %wu bytes into a region "
2182 "of size between %wu and %wu",
2183 lenrng
[0].to_uhwi (),
2184 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2186 else if (spcrng
[0] == spcrng
[1])
2188 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2189 "%qD writing between %wu and %wu bytes "
2190 "into a region of size %wu",
2191 writefn
, lenrng
[0].to_uhwi (),
2192 lenrng
[1].to_uhwi (),
2193 spcrng
[0].to_uhwi ())
2194 : warning_at (loc
, OPT_Wstringop_overflow_
,
2195 "writing between %wu and %wu bytes "
2196 "into a region of size %wu",
2197 lenrng
[0].to_uhwi (),
2198 lenrng
[1].to_uhwi (),
2199 spcrng
[0].to_uhwi ()));
2202 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2203 "%qD writing between %wu and %wu bytes "
2204 "into a region of size between %wu and %wu",
2205 writefn
, lenrng
[0].to_uhwi (),
2206 lenrng
[1].to_uhwi (),
2207 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2208 : warning_at (loc
, OPT_Wstringop_overflow_
,
2209 "writing between %wu and %wu bytes "
2210 "into a region of size between %wu and %wu",
2211 lenrng
[0].to_uhwi (),
2212 lenrng
[1].to_uhwi (),
2213 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2218 suppress_warning (stmt
, OPT_Wstringop_overflow_
);
2220 aref
.inform_access (access_write_only
);
2223 /* Convenience wrapper for the above. */
2226 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
,
2227 unsigned HOST_WIDE_INT len
,
2228 strinfo
*si
, bool plus_one
, bool rawmem
)
2230 tree tlen
= build_int_cst (size_type_node
, len
);
2231 maybe_warn_overflow (stmt
, call_lhs
, tlen
, si
, plus_one
, rawmem
);
2234 /* Handle a strlen call. If strlen of the argument is known, replace
2235 the strlen call with the known value, otherwise remember that strlen
2236 of the argument is stored in the lhs SSA_NAME. */
2239 strlen_pass::handle_builtin_strlen ()
2241 gimple
*stmt
= gsi_stmt (m_gsi
);
2242 tree lhs
= gimple_call_lhs (stmt
);
2244 if (lhs
== NULL_TREE
)
2247 location_t loc
= gimple_location (stmt
);
2248 tree callee
= gimple_call_fndecl (stmt
);
2249 tree src
= gimple_call_arg (stmt
, 0);
2250 tree bound
= (DECL_FUNCTION_CODE (callee
) == BUILT_IN_STRNLEN
2251 ? gimple_call_arg (stmt
, 1) : NULL_TREE
);
2252 int idx
= get_stridx (src
, stmt
);
2253 if (idx
|| (bound
&& integer_zerop (bound
)))
2259 rhs
= build_int_cst (TREE_TYPE (lhs
), ~idx
);
2265 si
= get_strinfo (idx
);
2268 rhs
= get_string_length (si
);
2269 /* For strnlen, if bound is constant, even if si is not known
2270 to be zero terminated, if we know at least bound bytes are
2271 not zero, the return value will be bound. */
2272 if (rhs
== NULL_TREE
2273 && bound
!= NULL_TREE
2274 && TREE_CODE (bound
) == INTEGER_CST
2275 && si
->nonzero_chars
!= NULL_TREE
2276 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
2277 && tree_int_cst_le (bound
, si
->nonzero_chars
))
2281 if (rhs
!= NULL_TREE
)
2283 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2285 fprintf (dump_file
, "Optimizing: ");
2286 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2288 rhs
= unshare_expr (rhs
);
2289 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
2290 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2293 rhs
= fold_build2_loc (loc
, MIN_EXPR
, TREE_TYPE (rhs
), rhs
, bound
);
2295 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2296 stmt
= gsi_stmt (m_gsi
);
2298 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2300 fprintf (dump_file
, "into: ");
2301 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2305 /* Don't update anything for strnlen. */
2306 && bound
== NULL_TREE
2307 && TREE_CODE (si
->nonzero_chars
) != SSA_NAME
2308 && TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
2309 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2311 si
= unshare_strinfo (si
);
2312 si
->nonzero_chars
= lhs
;
2313 gcc_assert (si
->full_string_p
);
2316 if (strlen_to_stridx
2317 && (bound
== NULL_TREE
2318 /* For strnlen record this only if the call is proven
2319 to return the same value as strlen would. */
2320 || (TREE_CODE (bound
) == INTEGER_CST
2321 && TREE_CODE (rhs
) == INTEGER_CST
2322 && tree_int_cst_lt (rhs
, bound
))))
2323 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2328 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2332 idx
= new_stridx (src
);
2335 strinfo
*si
= get_strinfo (idx
);
2338 if (!si
->full_string_p
&& !si
->stmt
)
2340 /* Until now we only had a lower bound on the string length.
2341 Install LHS as the actual length. */
2342 si
= unshare_strinfo (si
);
2343 tree old
= si
->nonzero_chars
;
2344 si
->nonzero_chars
= lhs
;
2345 si
->full_string_p
= true;
2346 if (old
&& TREE_CODE (old
) == INTEGER_CST
)
2348 old
= fold_convert_loc (loc
, TREE_TYPE (lhs
), old
);
2349 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2350 TREE_TYPE (lhs
), lhs
, old
);
2351 adjust_related_strinfos (loc
, si
, adj
);
2352 /* Use the constant minimum length as the lower bound
2353 of the non-constant length. */
2354 wide_int min
= wi::to_wide (old
);
2356 = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
2357 set_strlen_range (lhs
, min
, max
);
2373 /* Only store the new length information for calls to strlen(),
2374 not for those to strnlen(). */
2375 strinfo
*si
= new_strinfo (src
, idx
, lhs
, true);
2376 set_strinfo (idx
, si
);
2377 find_equal_ptrs (src
, idx
);
2380 /* For SRC that is an array of N elements, set LHS's range
2381 to [0, min (N, BOUND)]. A constant return value means
2382 the range would have consisted of a single value. In
2383 that case, fold the result into the returned constant. */
2384 if (tree ret
= maybe_set_strlen_range (lhs
, src
, bound
))
2385 if (TREE_CODE (ret
) == INTEGER_CST
)
2387 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2389 fprintf (dump_file
, "Optimizing: ");
2390 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2392 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (ret
)))
2393 ret
= fold_convert_loc (loc
, TREE_TYPE (lhs
), ret
);
2394 gimplify_and_update_call_from_tree (&m_gsi
, ret
);
2395 stmt
= gsi_stmt (m_gsi
);
2397 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2399 fprintf (dump_file
, "into: ");
2400 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2404 if (strlen_to_stridx
&& !bound
)
2405 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2409 /* Handle a strchr call. If strlen of the first argument is known, replace
2410 the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
2411 that lhs of the call is endptr and strlen of the argument is endptr - x. */
2414 strlen_pass::handle_builtin_strchr ()
2416 gimple
*stmt
= gsi_stmt (m_gsi
);
2417 tree lhs
= gimple_call_lhs (stmt
);
2419 if (lhs
== NULL_TREE
)
2422 if (!integer_zerop (gimple_call_arg (stmt
, 1)))
2425 tree src
= gimple_call_arg (stmt
, 0);
2427 /* Avoid folding if the first argument is not a nul-terminated array.
2428 Defer warning until later. */
2429 if (!check_nul_terminated_array (NULL_TREE
, src
))
2432 int idx
= get_stridx (src
, stmt
);
2439 rhs
= build_int_cst (size_type_node
, ~idx
);
2443 si
= get_strinfo (idx
);
2445 rhs
= get_string_length (si
);
2447 if (rhs
!= NULL_TREE
)
2449 location_t loc
= gimple_location (stmt
);
2451 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2453 fprintf (dump_file
, "Optimizing: ");
2454 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2456 if (si
!= NULL
&& si
->endptr
!= NULL_TREE
)
2458 rhs
= unshare_expr (si
->endptr
);
2459 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2461 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2465 rhs
= fold_convert_loc (loc
, sizetype
, unshare_expr (rhs
));
2466 rhs
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
,
2467 TREE_TYPE (src
), src
, rhs
);
2468 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2470 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2472 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2473 stmt
= gsi_stmt (m_gsi
);
2475 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2477 fprintf (dump_file
, "into: ");
2478 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2481 && si
->endptr
== NULL_TREE
2482 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2484 si
= unshare_strinfo (si
);
2487 zero_length_string (lhs
, si
);
2491 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2493 if (TREE_CODE (src
) != SSA_NAME
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src
))
2496 idx
= new_stridx (src
);
2497 else if (get_strinfo (idx
) != NULL
)
2499 zero_length_string (lhs
, NULL
);
2504 location_t loc
= gimple_location (stmt
);
2505 tree lhsu
= fold_convert_loc (loc
, size_type_node
, lhs
);
2506 tree srcu
= fold_convert_loc (loc
, size_type_node
, src
);
2507 tree length
= fold_build2_loc (loc
, MINUS_EXPR
,
2508 size_type_node
, lhsu
, srcu
);
2509 strinfo
*si
= new_strinfo (src
, idx
, length
, true);
2511 set_strinfo (idx
, si
);
2512 find_equal_ptrs (src
, idx
);
2513 zero_length_string (lhs
, si
);
2517 zero_length_string (lhs
, NULL
);
2520 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
2521 If strlen of the second argument is known, strlen of the first argument
2522 is the same after this call. Furthermore, attempt to convert it to
2523 memcpy. Uses RVALS to determine range information. */
2526 strlen_pass::handle_builtin_strcpy (built_in_function bcode
)
2529 tree src
, dst
, srclen
, len
, lhs
, type
, fn
, oldlen
;
2531 gimple
*stmt
= gsi_stmt (m_gsi
);
2532 strinfo
*si
, *dsi
, *olddsi
, *zsi
;
2535 src
= gimple_call_arg (stmt
, 1);
2536 dst
= gimple_call_arg (stmt
, 0);
2537 lhs
= gimple_call_lhs (stmt
);
2538 idx
= get_stridx (src
, stmt
);
2541 si
= get_strinfo (idx
);
2543 didx
= get_stridx (dst
, stmt
);
2547 olddsi
= get_strinfo (didx
);
2552 adjust_last_stmt (olddsi
, stmt
, false);
2556 srclen
= get_string_length (si
);
2558 srclen
= build_int_cst (size_type_node
, ~idx
);
2560 maybe_warn_overflow (stmt
, false, srclen
, olddsi
, true);
2563 adjust_last_stmt (olddsi
, stmt
, false);
2565 loc
= gimple_location (stmt
);
2566 if (srclen
== NULL_TREE
)
2569 case BUILT_IN_STRCPY
:
2570 case BUILT_IN_STRCPY_CHK
:
2571 if (lhs
!= NULL_TREE
|| !builtin_decl_implicit_p (BUILT_IN_STPCPY
))
2574 case BUILT_IN_STPCPY
:
2575 case BUILT_IN_STPCPY_CHK
:
2576 if (lhs
== NULL_TREE
)
2580 tree lhsuint
= fold_convert_loc (loc
, size_type_node
, lhs
);
2581 srclen
= fold_convert_loc (loc
, size_type_node
, dst
);
2582 srclen
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
2592 didx
= new_stridx (dst
);
2598 oldlen
= olddsi
->nonzero_chars
;
2599 dsi
= unshare_strinfo (olddsi
);
2600 dsi
->nonzero_chars
= srclen
;
2601 dsi
->full_string_p
= (srclen
!= NULL_TREE
);
2602 /* Break the chain, so adjust_related_strinfo on later pointers in
2603 the chain won't adjust this one anymore. */
2606 dsi
->endptr
= NULL_TREE
;
2610 dsi
= new_strinfo (dst
, didx
, srclen
, srclen
!= NULL_TREE
);
2611 set_strinfo (didx
, dsi
);
2612 find_equal_ptrs (dst
, didx
);
2614 dsi
->writable
= true;
2615 dsi
->dont_invalidate
= true;
2617 if (dsi
->nonzero_chars
== NULL_TREE
)
2621 /* If string length of src is unknown, use delayed length
2622 computation. If string length of dst will be needed, it
2623 can be computed by transforming this strcpy call into
2624 stpcpy and subtracting dst from the return value. */
2626 /* Look for earlier strings whose length could be determined if
2627 this strcpy is turned into an stpcpy. */
2629 if (dsi
->prev
!= 0 && (chainsi
= verify_related_strinfos (dsi
)) != NULL
)
2631 for (; chainsi
&& chainsi
!= dsi
; chainsi
= get_strinfo (chainsi
->next
))
2633 /* When setting a stmt for delayed length computation
2634 prevent all strinfos through dsi from being
2636 chainsi
= unshare_strinfo (chainsi
);
2637 chainsi
->stmt
= stmt
;
2638 chainsi
->nonzero_chars
= NULL_TREE
;
2639 chainsi
->full_string_p
= false;
2640 chainsi
->endptr
= NULL_TREE
;
2641 chainsi
->dont_invalidate
= true;
2646 /* Try to detect overlap before returning. This catches cases
2647 like strcpy (d, d + n) where n is non-constant whose range
2648 is such that (n <= strlen (d) holds).
2650 OLDDSI->NONZERO_chars may have been reset by this point with
2651 oldlen holding it original value. */
2652 if (olddsi
&& oldlen
)
2654 /* Add 1 for the terminating NUL. */
2655 tree type
= TREE_TYPE (oldlen
);
2656 oldlen
= fold_build2 (PLUS_EXPR
, type
, oldlen
,
2657 build_int_cst (type
, 1));
2658 check_bounds_or_overlap (stmt
, olddsi
->ptr
, src
, oldlen
, NULL_TREE
);
2666 tree adj
= NULL_TREE
;
2667 if (oldlen
== NULL_TREE
)
2669 else if (integer_zerop (oldlen
))
2671 else if (TREE_CODE (oldlen
) == INTEGER_CST
2672 || TREE_CODE (srclen
) == INTEGER_CST
)
2673 adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2674 TREE_TYPE (srclen
), srclen
,
2675 fold_convert_loc (loc
, TREE_TYPE (srclen
),
2677 if (adj
!= NULL_TREE
)
2678 adjust_related_strinfos (loc
, dsi
, adj
);
2682 /* strcpy src may not overlap dst, so src doesn't need to be
2683 invalidated either. */
2685 si
->dont_invalidate
= true;
2691 case BUILT_IN_STRCPY
:
2692 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
2694 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2696 case BUILT_IN_STRCPY_CHK
:
2697 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
2699 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2701 case BUILT_IN_STPCPY
:
2702 /* This would need adjustment of the lhs (subtract one),
2703 or detection that the trailing '\0' doesn't need to be
2704 written, if it will be immediately overwritten.
2705 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); */
2709 zsi
= zero_length_string (lhs
, dsi
);
2712 case BUILT_IN_STPCPY_CHK
:
2713 /* This would need adjustment of the lhs (subtract one),
2714 or detection that the trailing '\0' doesn't need to be
2715 written, if it will be immediately overwritten.
2716 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK); */
2720 zsi
= zero_length_string (lhs
, dsi
);
2727 zsi
->dont_invalidate
= true;
2731 tree args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
2732 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
2735 type
= size_type_node
;
2737 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
2738 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
, build_int_cst (type
, 1));
2740 /* Disable warning for the transformed statement? */
2741 opt_code no_warning_opt
= no_warning
;
2743 if (const strinfo
*chksi
= si
? olddsi
? olddsi
: dsi
: NULL
)
2745 no_warning_opt
= check_bounds_or_overlap (stmt
, chksi
->ptr
, si
->ptr
,
2748 suppress_warning (stmt
, no_warning_opt
);
2751 if (fn
== NULL_TREE
)
2754 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
2756 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2758 fprintf (dump_file
, "Optimizing: ");
2759 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2761 if (gimple_call_num_args (stmt
) == 2)
2762 success
= update_gimple_call (&m_gsi
, fn
, 3, dst
, src
, len
);
2764 success
= update_gimple_call (&m_gsi
, fn
, 4, dst
, src
, len
,
2765 gimple_call_arg (stmt
, 2));
2768 stmt
= gsi_stmt (m_gsi
);
2770 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2772 fprintf (dump_file
, "into: ");
2773 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2775 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2776 laststmt
.stmt
= stmt
;
2777 laststmt
.len
= srclen
;
2778 laststmt
.stridx
= dsi
->idx
;
2780 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2781 fprintf (dump_file
, "not possible.\n");
2784 suppress_warning (stmt
, no_warning_opt
);
2787 /* Check the size argument to the built-in forms of stpncpy and strncpy
2788 for out-of-bounds offsets or overlapping access, and to see if the
2789 size argument is derived from a call to strlen() on the source argument,
2790 and if so, issue an appropriate warning. */
2793 strlen_pass::handle_builtin_strncat (built_in_function
)
2795 /* Same as stxncpy(). */
2796 handle_builtin_stxncpy_strncat (true);
2799 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2800 way. LEN can either be an integer expression, or a pointer (to char).
2801 When it is the latter (such as in recursive calls to self) it is
2802 assumed to be the argument in some call to strlen() whose relationship
2803 to SRC is being ascertained. */
2806 is_strlen_related_p (tree src
, tree len
)
2808 if (TREE_CODE (TREE_TYPE (len
)) == POINTER_TYPE
2809 && operand_equal_p (src
, len
, 0))
2812 if (TREE_CODE (len
) != SSA_NAME
)
2815 if (TREE_CODE (src
) == SSA_NAME
)
2817 gimple
*srcdef
= SSA_NAME_DEF_STMT (src
);
2818 if (is_gimple_assign (srcdef
))
2820 /* Handle bitwise AND used in conversions from wider size_t
2821 to narrower unsigned types. */
2822 tree_code code
= gimple_assign_rhs_code (srcdef
);
2823 if (code
== BIT_AND_EXPR
2824 || code
== NOP_EXPR
)
2825 return is_strlen_related_p (gimple_assign_rhs1 (srcdef
), len
);
2830 if (gimple_call_builtin_p (srcdef
, BUILT_IN_NORMAL
))
2832 /* If SRC is the result of a call to an allocation function
2833 or strlen, use the function's argument instead. */
2834 tree func
= gimple_call_fndecl (srcdef
);
2835 built_in_function code
= DECL_FUNCTION_CODE (func
);
2836 if (code
== BUILT_IN_ALLOCA
2837 || code
== BUILT_IN_ALLOCA_WITH_ALIGN
2838 || code
== BUILT_IN_MALLOC
2839 || code
== BUILT_IN_STRLEN
)
2840 return is_strlen_related_p (gimple_call_arg (srcdef
, 0), len
);
2842 /* FIXME: Handle other functions with attribute alloc_size. */
2847 gimple
*lendef
= SSA_NAME_DEF_STMT (len
);
2851 if (is_gimple_call (lendef
))
2853 tree func
= gimple_call_fndecl (lendef
);
2854 if (!valid_builtin_call (lendef
)
2855 || DECL_FUNCTION_CODE (func
) != BUILT_IN_STRLEN
)
2858 tree arg
= gimple_call_arg (lendef
, 0);
2859 return is_strlen_related_p (src
, arg
);
2862 if (!is_gimple_assign (lendef
))
2865 tree_code code
= gimple_assign_rhs_code (lendef
);
2866 tree rhs1
= gimple_assign_rhs1 (lendef
);
2867 tree rhstype
= TREE_TYPE (rhs1
);
2869 if ((TREE_CODE (rhstype
) == POINTER_TYPE
&& code
== POINTER_PLUS_EXPR
)
2870 || (INTEGRAL_TYPE_P (rhstype
)
2871 && (code
== BIT_AND_EXPR
2872 || code
== NOP_EXPR
)))
2874 /* Pointer plus (an integer), and truncation are considered among
2875 the (potentially) related expressions to strlen. */
2876 return is_strlen_related_p (src
, rhs1
);
2879 if (tree rhs2
= gimple_assign_rhs2 (lendef
))
2881 /* Integer subtraction is considered strlen-related when both
2882 arguments are integers and second one is strlen-related. */
2883 rhstype
= TREE_TYPE (rhs2
);
2884 if (INTEGRAL_TYPE_P (rhstype
) && code
== MINUS_EXPR
)
2885 return is_strlen_related_p (src
, rhs2
);
2891 /* Called by handle_builtin_stxncpy_strncat and by
2892 gimple_fold_builtin_strncpy in gimple-fold.cc.
2893 Check to see if the specified bound is a) equal to the size of
2894 the destination DST and if so, b) if it's immediately followed by
2895 DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise,
2896 do nothing. Return true if diagnostic has been issued.
2898 The purpose is to diagnose calls to strncpy and stpncpy that do
2899 not nul-terminate the copy while allowing for the idiom where
2900 such a call is immediately followed by setting the last element
2903 strncpy (a, s, sizeof a);
2904 a[sizeof a - 1] = '\0';
2908 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi
, tree src
, tree cnt
,
2909 pointer_query
*ptr_qry
/* = NULL */)
2911 gimple
*stmt
= gsi_stmt (gsi
);
2912 if (warning_suppressed_p (stmt
, OPT_Wstringop_truncation
))
2915 wide_int cntrange
[2];
2917 if (!get_range_query (cfun
)->range_of_expr (r
, cnt
)
2919 || r
.undefined_p ())
2922 cntrange
[0] = wi::to_wide (r
.min ());
2923 cntrange
[1] = wi::to_wide (r
.max ());
2924 if (r
.kind () == VR_ANTI_RANGE
)
2926 wide_int maxobjsize
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
));
2928 if (wi::ltu_p (cntrange
[1], maxobjsize
))
2930 cntrange
[0] = cntrange
[1] + 1;
2931 cntrange
[1] = maxobjsize
;
2935 cntrange
[1] = cntrange
[0] - 1;
2936 cntrange
[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt
)));
2940 /* Negative value is the constant string length. If it's less than
2941 the lower bound there is no truncation. Avoid calling get_stridx()
2942 when ssa_ver_to_stridx is empty. That implies the caller isn't
2943 running under the control of this pass and ssa_ver_to_stridx hasn't
2944 been created yet. */
2945 int sidx
= ssa_ver_to_stridx
.length () ? get_stridx (src
, stmt
) : 0;
2946 if (sidx
< 0 && wi::gtu_p (cntrange
[0], ~sidx
))
2949 tree dst
= gimple_call_arg (stmt
, 0);
2951 if (TREE_CODE (dstdecl
) == ADDR_EXPR
)
2952 dstdecl
= TREE_OPERAND (dstdecl
, 0);
2954 tree ref
= NULL_TREE
;
2958 /* If the source is a non-string return early to avoid warning
2959 for possible truncation (if the truncation is certain SIDX
2961 tree srcdecl
= gimple_call_arg (stmt
, 1);
2962 if (TREE_CODE (srcdecl
) == ADDR_EXPR
)
2963 srcdecl
= TREE_OPERAND (srcdecl
, 0);
2964 if (get_attr_nonstring_decl (srcdecl
, &ref
))
2968 /* Likewise, if the destination refers to an array/pointer declared
2969 nonstring return early. */
2970 if (get_attr_nonstring_decl (dstdecl
, &ref
))
2973 /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2974 avoid the truncation warning. */
2975 gsi_next_nondebug (&gsi
);
2976 gimple
*next_stmt
= gsi_stmt (gsi
);
2979 /* When there is no statement in the same basic block check
2980 the immediate successor block. */
2981 if (basic_block bb
= gimple_bb (stmt
))
2983 if (single_succ_p (bb
))
2985 /* For simplicity, ignore blocks with multiple outgoing
2986 edges for now and only consider successor blocks along
2988 edge e
= EDGE_SUCC (bb
, 0);
2989 if (!(e
->flags
& EDGE_ABNORMAL
))
2991 gsi
= gsi_start_bb (e
->dest
);
2992 next_stmt
= gsi_stmt (gsi
);
2993 if (next_stmt
&& is_gimple_debug (next_stmt
))
2995 gsi_next_nondebug (&gsi
);
2996 next_stmt
= gsi_stmt (gsi
);
3003 if (next_stmt
&& is_gimple_assign (next_stmt
))
3005 tree lhs
= gimple_assign_lhs (next_stmt
);
3006 tree_code code
= TREE_CODE (lhs
);
3007 if (code
== ARRAY_REF
|| code
== MEM_REF
)
3008 lhs
= TREE_OPERAND (lhs
, 0);
3010 tree func
= gimple_call_fndecl (stmt
);
3011 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STPNCPY
)
3013 tree ret
= gimple_call_lhs (stmt
);
3014 if (ret
&& operand_equal_p (ret
, lhs
, 0))
3018 /* Determine the base address and offset of the reference,
3019 ignoring the innermost array index. */
3020 if (TREE_CODE (ref
) == ARRAY_REF
)
3021 ref
= TREE_OPERAND (ref
, 0);
3024 tree dstbase
= get_addr_base_and_unit_offset (ref
, &dstoff
);
3027 tree lhsbase
= get_addr_base_and_unit_offset (lhs
, &lhsoff
);
3030 && known_eq (dstoff
, lhsoff
)
3031 && operand_equal_p (dstbase
, lhsbase
, 0))
3035 int prec
= TYPE_PRECISION (TREE_TYPE (cnt
));
3036 wide_int lenrange
[2];
3037 if (strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
)
3039 lenrange
[0] = (sisrc
->nonzero_chars
3040 && TREE_CODE (sisrc
->nonzero_chars
) == INTEGER_CST
3041 ? wi::to_wide (sisrc
->nonzero_chars
)
3043 lenrange
[1] = lenrange
[0];
3046 lenrange
[0] = lenrange
[1] = wi::shwi (~sidx
, prec
);
3049 c_strlen_data lendata
= { };
3050 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
3051 to have it set to the length of the longest string in a PHI. */
3052 lendata
.maxbound
= src
;
3053 get_range_strlen (src
, &lendata
, /* eltsize = */1);
3054 if (TREE_CODE (lendata
.minlen
) == INTEGER_CST
3055 && TREE_CODE (lendata
.maxbound
) == INTEGER_CST
)
3057 /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
3058 which stores the length of the shortest known string. */
3059 if (integer_all_onesp (lendata
.maxlen
))
3060 lenrange
[0] = wi::shwi (0, prec
);
3062 lenrange
[0] = wi::to_wide (lendata
.minlen
, prec
);
3063 lenrange
[1] = wi::to_wide (lendata
.maxbound
, prec
);
3067 lenrange
[0] = wi::shwi (0, prec
);
3068 lenrange
[1] = wi::shwi (-1, prec
);
3072 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3073 tree func
= gimple_call_fndecl (stmt
);
3075 if (lenrange
[0] != 0 || !wi::neg_p (lenrange
[1]))
3077 /* If the longest source string is shorter than the lower bound
3078 of the specified count the copy is definitely nul-terminated. */
3079 if (wi::ltu_p (lenrange
[1], cntrange
[0]))
3082 if (wi::neg_p (lenrange
[1]))
3084 /* The length of one of the strings is unknown but at least
3085 one has non-zero length and that length is stored in
3086 LENRANGE[1]. Swap the bounds to force a "may be truncated"
3088 lenrange
[1] = lenrange
[0];
3089 lenrange
[0] = wi::shwi (0, prec
);
3092 /* Set to true for strncat whose bound is derived from the length
3093 of the destination (the expected usage pattern). */
3094 bool cat_dstlen_bounded
= false;
3095 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STRNCAT
)
3096 cat_dstlen_bounded
= is_strlen_related_p (dst
, cnt
);
3098 if (lenrange
[0] == cntrange
[1] && cntrange
[0] == cntrange
[1])
3099 return warning_n (callloc
, OPT_Wstringop_truncation
,
3100 cntrange
[0].to_uhwi (),
3101 "%qD output truncated before terminating "
3102 "nul copying %E byte from a string of the "
3104 "%qD output truncated before terminating nul "
3105 "copying %E bytes from a string of the same "
3108 else if (!cat_dstlen_bounded
)
3110 if (wi::geu_p (lenrange
[0], cntrange
[1]))
3112 /* The shortest string is longer than the upper bound of
3113 the count so the truncation is certain. */
3114 if (cntrange
[0] == cntrange
[1])
3115 return warning_n (callloc
, OPT_Wstringop_truncation
,
3116 cntrange
[0].to_uhwi (),
3117 "%qD output truncated copying %E byte "
3118 "from a string of length %wu",
3119 "%qD output truncated copying %E bytes "
3120 "from a string of length %wu",
3121 func
, cnt
, lenrange
[0].to_uhwi ());
3123 return warning_at (callloc
, OPT_Wstringop_truncation
,
3124 "%qD output truncated copying between %wu "
3125 "and %wu bytes from a string of length %wu",
3126 func
, cntrange
[0].to_uhwi (),
3127 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3129 else if (wi::geu_p (lenrange
[1], cntrange
[1]))
3131 /* The longest string is longer than the upper bound of
3132 the count so the truncation is possible. */
3133 if (cntrange
[0] == cntrange
[1])
3134 return warning_n (callloc
, OPT_Wstringop_truncation
,
3135 cntrange
[0].to_uhwi (),
3136 "%qD output may be truncated copying %E "
3137 "byte from a string of length %wu",
3138 "%qD output may be truncated copying %E "
3139 "bytes from a string of length %wu",
3140 func
, cnt
, lenrange
[1].to_uhwi ());
3142 return warning_at (callloc
, OPT_Wstringop_truncation
,
3143 "%qD output may be truncated copying between "
3144 "%wu and %wu bytes from a string of length %wu",
3145 func
, cntrange
[0].to_uhwi (),
3146 cntrange
[1].to_uhwi (), lenrange
[1].to_uhwi ());
3150 if (!cat_dstlen_bounded
3151 && cntrange
[0] != cntrange
[1]
3152 && wi::leu_p (cntrange
[0], lenrange
[0])
3153 && wi::leu_p (cntrange
[1], lenrange
[0] + 1))
3155 /* If the source (including the terminating nul) is longer than
3156 the lower bound of the specified count but shorter than the
3157 upper bound the copy may (but need not) be truncated. */
3158 return warning_at (callloc
, OPT_Wstringop_truncation
,
3159 "%qD output may be truncated copying between "
3160 "%wu and %wu bytes from a string of length %wu",
3161 func
, cntrange
[0].to_uhwi (),
3162 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3167 if (tree dstsize
= compute_objsize (dst
, stmt
, 1, &aref
, ptr_qry
))
3169 /* The source length is unknown. Try to determine the destination
3170 size and see if it matches the specified bound. If not, bail.
3171 Otherwise go on to see if it should be diagnosed for possible
3176 if (wi::to_wide (dstsize
) != cntrange
[1])
3179 /* Avoid warning for strncpy(a, b, N) calls where the following
3181 N == sizeof a && N == sizeof b */
3182 if (tree srcsize
= compute_objsize (src
, stmt
, 1, &aref
, ptr_qry
))
3183 if (wi::to_wide (srcsize
) == cntrange
[1])
3186 if (cntrange
[0] == cntrange
[1])
3187 return warning_at (callloc
, OPT_Wstringop_truncation
,
3188 "%qD specified bound %E equals destination size",
3195 /* Check the arguments to the built-in forms of stpncpy, strncpy, and
3196 strncat, for out-of-bounds offsets or overlapping access, and to see
3197 if the size is derived from calling strlen() on the source argument,
3198 and if so, issue the appropriate warning.
3199 APPEND_P is true for strncat. */
3202 strlen_pass::handle_builtin_stxncpy_strncat (bool append_p
)
3204 if (!strlen_to_stridx
)
3207 gimple
*stmt
= gsi_stmt (m_gsi
);
3209 tree dst
= gimple_call_arg (stmt
, 0);
3210 tree src
= gimple_call_arg (stmt
, 1);
3211 tree len
= gimple_call_arg (stmt
, 2);
3212 /* An upper bound of the size of the destination. */
3213 tree dstsize
= NULL_TREE
;
3214 /* The length of the destination and source strings (plus 1 for those
3215 whose FULL_STRING_P is set, i.e., whose length is exact rather than
3217 tree dstlenp1
= NULL_TREE
, srclenp1
= NULL_TREE
;;
3219 int didx
= get_stridx (dst
, stmt
);
3220 if (strinfo
*sidst
= didx
> 0 ? get_strinfo (didx
) : NULL
)
3222 /* Compute the size of the destination string including the nul
3223 if it is known to be nul-terminated. */
3224 if (sidst
->nonzero_chars
)
3226 if (sidst
->full_string_p
)
3228 /* String is known to be nul-terminated. */
3229 tree type
= TREE_TYPE (sidst
->nonzero_chars
);
3230 dstlenp1
= fold_build2 (PLUS_EXPR
, type
, sidst
->nonzero_chars
,
3231 build_int_cst (type
, 1));
3234 dstlenp1
= sidst
->nonzero_chars
;
3236 else if (TREE_CODE (sidst
->ptr
) == SSA_NAME
)
3238 gimple
*def_stmt
= SSA_NAME_DEF_STMT (sidst
->ptr
);
3239 dstsize
= gimple_call_alloc_size (def_stmt
);
3245 int sidx
= get_stridx (src
, stmt
);
3246 strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
;
3249 /* strncat() and strncpy() can modify the source string by writing
3250 over the terminating nul so SISRC->DONT_INVALIDATE must be left
3253 /* Compute the size of the source string including the terminating
3254 nul if its known to be nul-terminated. */
3255 if (sisrc
->nonzero_chars
)
3257 if (sisrc
->full_string_p
)
3259 tree type
= TREE_TYPE (sisrc
->nonzero_chars
);
3260 srclenp1
= fold_build2 (PLUS_EXPR
, type
, sisrc
->nonzero_chars
,
3261 build_int_cst (type
, 1));
3264 srclenp1
= sisrc
->nonzero_chars
;
3270 srclenp1
= NULL_TREE
;
3272 opt_code opt
= check_bounds_or_overlap (stmt
, dst
, src
, dstlenp1
, srclenp1
);
3273 if (opt
!= no_warning
)
3275 suppress_warning (stmt
, opt
);
3279 /* If the length argument was computed from strlen(S) for some string
3280 S retrieve the strinfo index for the string (PSS->FIRST) along with
3281 the location of the strlen() call (PSS->SECOND). */
3282 stridx_strlenloc
*pss
= strlen_to_stridx
->get (len
);
3283 if (!pss
|| pss
->first
<= 0)
3285 if (maybe_diag_stxncpy_trunc (m_gsi
, src
, len
))
3286 suppress_warning (stmt
, OPT_Wstringop_truncation
);
3291 /* Retrieve the strinfo data for the string S that LEN was computed
3292 from as some function F of strlen (S) (i.e., LEN need not be equal
3294 strinfo
*silen
= get_strinfo (pss
->first
);
3296 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3298 tree func
= gimple_call_fndecl (stmt
);
3300 bool warned
= false;
3302 /* When -Wstringop-truncation is set, try to determine truncation
3303 before diagnosing possible overflow. Truncation is implied by
3304 the LEN argument being equal to strlen(SRC), regardless of
3305 whether its value is known. Otherwise, when appending, or
3306 when copying into a destination of known size, issue the more
3307 generic -Wstringop-overflow which triggers for LEN arguments
3308 that in any meaningful way depend on strlen(SRC). */
3311 && is_strlen_related_p (src
, len
)
3312 && warning_at (callloc
, OPT_Wstringop_truncation
,
3313 "%qD output truncated before terminating nul "
3314 "copying as many bytes from a string as its length",
3317 else if ((append_p
|| !dstsize
|| len
== dstlenp1
)
3318 && silen
&& is_strlen_related_p (src
, silen
->ptr
))
3320 /* Issue -Wstringop-overflow when appending or when writing into
3321 a destination of a known size. Otherwise, when copying into
3322 a destination of an unknown size, it's truncation. */
3323 opt_code opt
= (append_p
|| dstsize
3324 ? OPT_Wstringop_overflow_
: OPT_Wstringop_truncation
);
3325 warned
= warning_at (callloc
, opt
,
3326 "%qD specified bound depends on the length "
3327 "of the source argument",
3332 location_t strlenloc
= pss
->second
;
3333 if (strlenloc
!= UNKNOWN_LOCATION
&& strlenloc
!= callloc
)
3334 inform (strlenloc
, "length computed here");
3338 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
3339 If strlen of the second argument is known and length of the third argument
3340 is that plus one, strlen of the first argument is the same after this
3341 call. Uses RVALS to determine range information. */
3344 strlen_pass::handle_builtin_memcpy (built_in_function bcode
)
3346 tree lhs
, oldlen
, newlen
;
3347 gimple
*stmt
= gsi_stmt (m_gsi
);
3350 tree len
= gimple_call_arg (stmt
, 2);
3351 tree src
= gimple_call_arg (stmt
, 1);
3352 tree dst
= gimple_call_arg (stmt
, 0);
3354 int didx
= get_stridx (dst
, stmt
);
3355 strinfo
*olddsi
= NULL
;
3357 olddsi
= get_strinfo (didx
);
3362 && !integer_zerop (len
))
3364 maybe_warn_overflow (stmt
, false, len
, olddsi
, false, true);
3365 adjust_last_stmt (olddsi
, stmt
, false);
3368 int idx
= get_stridx (src
, stmt
);
3377 /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
3379 si
= get_strinfo (idx
);
3380 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
3382 if (TREE_CODE (len
) == INTEGER_CST
3383 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
3385 if (tree_int_cst_le (len
, si
->nonzero_chars
))
3387 /* Copying LEN nonzero characters, where LEN is constant. */
3389 full_string_p
= false;
3393 /* Copying the whole of the analyzed part of SI. */
3394 newlen
= si
->nonzero_chars
;
3395 full_string_p
= si
->full_string_p
;
3400 if (!si
->full_string_p
)
3402 if (TREE_CODE (len
) != SSA_NAME
)
3404 def_stmt
= SSA_NAME_DEF_STMT (len
);
3405 if (!is_gimple_assign (def_stmt
)
3406 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
3407 || gimple_assign_rhs1 (def_stmt
) != si
->nonzero_chars
3408 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
3410 /* Copying variable-length string SI (and no more). */
3411 newlen
= si
->nonzero_chars
;
3412 full_string_p
= true;
3418 /* Handle memcpy (x, "abcd", 5) or
3419 memcpy (x, "abc\0uvw", 7). */
3420 if (!tree_fits_uhwi_p (len
))
3423 unsigned HOST_WIDE_INT clen
= tree_to_uhwi (len
);
3424 unsigned HOST_WIDE_INT nonzero_chars
= ~idx
;
3425 newlen
= build_int_cst (size_type_node
, MIN (nonzero_chars
, clen
));
3426 full_string_p
= clen
> nonzero_chars
;
3431 && olddsi
->nonzero_chars
3432 && TREE_CODE (olddsi
->nonzero_chars
) == INTEGER_CST
3433 && tree_int_cst_le (newlen
, olddsi
->nonzero_chars
))
3435 /* The SRC substring being written strictly overlaps
3436 a subsequence of the existing string OLDDSI. */
3437 newlen
= olddsi
->nonzero_chars
;
3438 full_string_p
= olddsi
->full_string_p
;
3441 if (olddsi
!= NULL
&& TREE_CODE (len
) == SSA_NAME
)
3442 adjust_last_stmt (olddsi
, stmt
, false);
3446 didx
= new_stridx (dst
);
3453 dsi
= unshare_strinfo (olddsi
);
3454 oldlen
= olddsi
->nonzero_chars
;
3455 dsi
->nonzero_chars
= newlen
;
3456 dsi
->full_string_p
= full_string_p
;
3457 /* Break the chain, so adjust_related_strinfo on later pointers in
3458 the chain won't adjust this one anymore. */
3461 dsi
->endptr
= NULL_TREE
;
3465 dsi
= new_strinfo (dst
, didx
, newlen
, full_string_p
);
3466 set_strinfo (didx
, dsi
);
3467 find_equal_ptrs (dst
, didx
);
3469 dsi
->writable
= true;
3470 dsi
->dont_invalidate
= true;
3473 tree adj
= NULL_TREE
;
3474 location_t loc
= gimple_location (stmt
);
3475 if (oldlen
== NULL_TREE
)
3477 else if (integer_zerop (oldlen
))
3479 else if (TREE_CODE (oldlen
) == INTEGER_CST
3480 || TREE_CODE (newlen
) == INTEGER_CST
)
3481 adj
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (newlen
), newlen
,
3482 fold_convert_loc (loc
, TREE_TYPE (newlen
),
3484 if (adj
!= NULL_TREE
)
3485 adjust_related_strinfos (loc
, dsi
, adj
);
3489 /* memcpy src may not overlap dst, so src doesn't need to be
3490 invalidated either. */
3492 si
->dont_invalidate
= true;
3496 lhs
= gimple_call_lhs (stmt
);
3499 case BUILT_IN_MEMCPY
:
3500 case BUILT_IN_MEMCPY_CHK
:
3501 /* Allow adjust_last_stmt to decrease this memcpy's size. */
3502 laststmt
.stmt
= stmt
;
3503 laststmt
.len
= dsi
->nonzero_chars
;
3504 laststmt
.stridx
= dsi
->idx
;
3506 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
3508 case BUILT_IN_MEMPCPY
:
3509 case BUILT_IN_MEMPCPY_CHK
:
3517 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
3518 If strlen of the second argument is known, strlen of the first argument
3519 is increased by the length of the second argument. Furthermore, attempt
3520 to convert it to memcpy/strcpy if the length of the first argument
3524 strlen_pass::handle_builtin_strcat (built_in_function bcode
)
3527 tree srclen
, args
, type
, fn
, objsz
, endptr
;
3529 gimple
*stmt
= gsi_stmt (m_gsi
);
3531 location_t loc
= gimple_location (stmt
);
3533 tree src
= gimple_call_arg (stmt
, 1);
3534 tree dst
= gimple_call_arg (stmt
, 0);
3536 /* Bail if the source is the same as destination. It will be diagnosed
3538 if (operand_equal_p (src
, dst
, 0))
3541 tree lhs
= gimple_call_lhs (stmt
);
3543 didx
= get_stridx (dst
, stmt
);
3549 dsi
= get_strinfo (didx
);
3553 idx
= get_stridx (src
, stmt
);
3555 srclen
= build_int_cst (size_type_node
, ~idx
);
3558 si
= get_strinfo (idx
);
3560 srclen
= get_string_length (si
);
3563 /* Disable warning for the transformed statement? */
3564 opt_code no_warning_opt
= no_warning
;
3566 if (dsi
== NULL
|| get_string_length (dsi
) == NULL_TREE
)
3569 /* The concatenation always involves copying at least one byte
3570 (the terminating nul), even if the source string is empty.
3571 If the source is unknown assume it's one character long and
3572 used that as both sizes. */
3576 tree type
= TREE_TYPE (slen
);
3577 slen
= fold_build2 (PLUS_EXPR
, type
, slen
, build_int_cst (type
, 1));
3580 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3581 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, NULL_TREE
,
3584 suppress_warning (stmt
, no_warning_opt
);
3587 /* strcat (p, q) can be transformed into
3588 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
3589 with length endptr - p if we need to compute the length
3590 later on. Don't do this transformation if we don't need
3592 if (builtin_decl_implicit_p (BUILT_IN_STPCPY
) && lhs
== NULL_TREE
)
3596 didx
= new_stridx (dst
);
3602 dsi
= new_strinfo (dst
, didx
, NULL_TREE
, false);
3603 set_strinfo (didx
, dsi
);
3604 find_equal_ptrs (dst
, didx
);
3608 dsi
= unshare_strinfo (dsi
);
3609 dsi
->nonzero_chars
= NULL_TREE
;
3610 dsi
->full_string_p
= false;
3612 dsi
->endptr
= NULL_TREE
;
3614 dsi
->writable
= true;
3616 dsi
->dont_invalidate
= true;
3621 tree dstlen
= dsi
->nonzero_chars
;
3622 endptr
= dsi
->endptr
;
3624 dsi
= unshare_strinfo (dsi
);
3625 dsi
->endptr
= NULL_TREE
;
3627 dsi
->writable
= true;
3629 if (srclen
!= NULL_TREE
)
3631 dsi
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
3632 TREE_TYPE (dsi
->nonzero_chars
),
3633 dsi
->nonzero_chars
, srclen
);
3634 gcc_assert (dsi
->full_string_p
);
3635 adjust_related_strinfos (loc
, dsi
, srclen
);
3636 dsi
->dont_invalidate
= true;
3640 dsi
->nonzero_chars
= NULL
;
3641 dsi
->full_string_p
= false;
3642 if (lhs
== NULL_TREE
&& builtin_decl_implicit_p (BUILT_IN_STPCPY
))
3643 dsi
->dont_invalidate
= true;
3647 /* strcat src may not overlap dst, so src doesn't need to be
3648 invalidated either. */
3649 si
->dont_invalidate
= true;
3651 /* For now. Could remove the lhs from the call and add
3652 lhs = dst; afterwards. */
3660 case BUILT_IN_STRCAT
:
3661 if (srclen
!= NULL_TREE
)
3662 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
3664 fn
= builtin_decl_implicit (BUILT_IN_STRCPY
);
3666 case BUILT_IN_STRCAT_CHK
:
3667 if (srclen
!= NULL_TREE
)
3668 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
3670 fn
= builtin_decl_explicit (BUILT_IN_STRCPY_CHK
);
3671 objsz
= gimple_call_arg (stmt
, 2);
3677 if (fn
== NULL_TREE
)
3682 tree type
= TREE_TYPE (dstlen
);
3684 /* Compute the size of the source sequence, including the nul. */
3685 tree srcsize
= srclen
? srclen
: size_zero_node
;
3686 tree one
= build_int_cst (type
, 1);
3687 srcsize
= fold_build2 (PLUS_EXPR
, type
, srcsize
, one
);
3688 tree dstsize
= fold_build2 (PLUS_EXPR
, type
, dstlen
, one
);
3689 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3691 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, dstsize
,
3694 suppress_warning (stmt
, no_warning_opt
);
3697 tree len
= NULL_TREE
;
3698 if (srclen
!= NULL_TREE
)
3700 args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
3701 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
3703 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
3704 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
,
3705 build_int_cst (type
, 1));
3706 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
3710 dst
= fold_convert_loc (loc
, TREE_TYPE (dst
), unshare_expr (endptr
));
3712 dst
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
, TREE_TYPE (dst
), dst
,
3713 fold_convert_loc (loc
, sizetype
,
3714 unshare_expr (dstlen
)));
3715 dst
= force_gimple_operand_gsi (&m_gsi
, dst
, true, NULL_TREE
, true,
3719 objsz
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (objsz
), objsz
,
3720 fold_convert_loc (loc
, TREE_TYPE (objsz
),
3721 unshare_expr (dstlen
)));
3722 objsz
= force_gimple_operand_gsi (&m_gsi
, objsz
, true, NULL_TREE
, true,
3725 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3727 fprintf (dump_file
, "Optimizing: ");
3728 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3730 if (srclen
!= NULL_TREE
)
3731 success
= update_gimple_call (&m_gsi
, fn
, 3 + (objsz
!= NULL_TREE
),
3732 dst
, src
, len
, objsz
);
3734 success
= update_gimple_call (&m_gsi
, fn
, 2 + (objsz
!= NULL_TREE
),
3738 stmt
= gsi_stmt (m_gsi
);
3740 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3742 fprintf (dump_file
, "into: ");
3743 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3745 /* If srclen == NULL, note that current string length can be
3746 computed by transforming this strcpy into stpcpy. */
3747 if (srclen
== NULL_TREE
&& dsi
->dont_invalidate
)
3749 adjust_last_stmt (dsi
, stmt
, true);
3750 if (srclen
!= NULL_TREE
)
3752 laststmt
.stmt
= stmt
;
3753 laststmt
.len
= srclen
;
3754 laststmt
.stridx
= dsi
->idx
;
3757 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3758 fprintf (dump_file
, "not possible.\n");
3761 suppress_warning (stmt
, no_warning_opt
);
3764 /* Handle a call to an allocation function like alloca, malloc or calloc,
3765 or an ordinary allocation function declared with attribute alloc_size. */
3768 strlen_pass::handle_alloc_call (built_in_function bcode
)
3770 gimple
*stmt
= gsi_stmt (m_gsi
);
3771 tree lhs
= gimple_call_lhs (stmt
);
3772 if (lhs
== NULL_TREE
)
3775 gcc_assert (get_stridx (lhs
, stmt
) == 0);
3776 int idx
= new_stridx (lhs
);
3777 tree length
= NULL_TREE
;
3778 if (bcode
== BUILT_IN_CALLOC
)
3779 length
= build_int_cst (size_type_node
, 0);
3780 strinfo
*si
= new_strinfo (lhs
, idx
, length
, length
!= NULL_TREE
);
3781 if (bcode
== BUILT_IN_CALLOC
)
3783 /* Only set STMT for calloc and malloc. */
3785 /* Only set ENDPTR for calloc. */
3788 else if (bcode
== BUILT_IN_MALLOC
)
3791 /* Set ALLOC is set for all allocation functions. */
3793 set_strinfo (idx
, si
);
3794 si
->writable
= true;
3795 si
->dont_invalidate
= true;
3798 /* Handle a call to memset.
3799 After a call to calloc, memset(,0,) is unnecessary.
3800 memset(malloc(n),0,n) is calloc(n,1).
3801 return true when the call is transformed, false otherwise.
3802 When nonnull uses RVALS to determine range information. */
3805 strlen_pass::handle_builtin_memset (bool *zero_write
)
3807 gimple
*memset_stmt
= gsi_stmt (m_gsi
);
3808 tree ptr
= gimple_call_arg (memset_stmt
, 0);
3809 tree memset_val
= gimple_call_arg (memset_stmt
, 1);
3810 tree memset_size
= gimple_call_arg (memset_stmt
, 2);
3812 /* Set to the non-constant offset added to PTR. */
3814 int idx1
= get_stridx (ptr
, memset_stmt
, offrng
, ptr_qry
.rvals
);
3816 && TREE_CODE (memset_val
) == INTEGER_CST
3817 && ((TREE_CODE (memset_size
) == INTEGER_CST
3818 && !integer_zerop (memset_size
))
3819 || TREE_CODE (memset_size
) == SSA_NAME
))
3821 unsigned HOST_WIDE_INT mask
= (HOST_WIDE_INT_1U
<< CHAR_TYPE_SIZE
) - 1;
3822 bool full_string_p
= (wi::to_wide (memset_val
) & mask
) == 0;
3824 /* We only handle symbolic lengths when writing non-zero values. */
3825 if (full_string_p
&& TREE_CODE (memset_size
) != INTEGER_CST
)
3828 idx1
= new_stridx (ptr
);
3833 newlen
= build_int_cst (size_type_node
, 0);
3834 else if (TREE_CODE (memset_size
) == INTEGER_CST
)
3835 newlen
= fold_convert (size_type_node
, memset_size
);
3837 newlen
= memset_size
;
3839 strinfo
*dsi
= new_strinfo (ptr
, idx1
, newlen
, full_string_p
);
3840 set_strinfo (idx1
, dsi
);
3841 find_equal_ptrs (ptr
, idx1
);
3842 dsi
->dont_invalidate
= true;
3843 dsi
->writable
= true;
3849 strinfo
*si1
= get_strinfo (idx1
);
3852 gimple
*alloc_stmt
= si1
->alloc
;
3853 if (!alloc_stmt
|| !is_gimple_call (alloc_stmt
))
3855 tree callee1
= gimple_call_fndecl (alloc_stmt
);
3856 if (!valid_builtin_call (alloc_stmt
))
3858 tree alloc_size
= gimple_call_arg (alloc_stmt
, 0);
3860 /* Check for overflow. */
3861 maybe_warn_overflow (memset_stmt
, false, memset_size
, NULL
, false, true);
3863 /* Bail when there is no statement associated with the destination
3864 (the statement may be null even when SI1->ALLOC is not). */
3868 /* Avoid optimizing if store is at a variable offset from the beginning
3869 of the allocated object. */
3870 if (offrng
[0] != 0 || offrng
[0] != offrng
[1])
3873 /* Bail when the call writes a non-zero value. */
3874 if (!integer_zerop (memset_val
))
3877 /* Let the caller know the memset call cleared the destination. */
3880 enum built_in_function code1
= DECL_FUNCTION_CODE (callee1
);
3881 if (code1
== BUILT_IN_CALLOC
)
3882 /* Not touching alloc_stmt */ ;
3883 else if (code1
== BUILT_IN_MALLOC
3884 && operand_equal_p (memset_size
, alloc_size
, 0))
3886 /* Replace the malloc + memset calls with calloc. */
3887 gimple_stmt_iterator gsi1
= gsi_for_stmt (si1
->stmt
);
3888 update_gimple_call (&gsi1
, builtin_decl_implicit (BUILT_IN_CALLOC
), 2,
3889 alloc_size
, build_one_cst (size_type_node
));
3890 si1
->nonzero_chars
= build_int_cst (size_type_node
, 0);
3891 si1
->full_string_p
= true;
3892 si1
->stmt
= gsi_stmt (gsi1
);
3896 tree lhs
= gimple_call_lhs (memset_stmt
);
3897 unlink_stmt_vdef (memset_stmt
);
3900 gimple
*assign
= gimple_build_assign (lhs
, ptr
);
3901 gsi_replace (&m_gsi
, assign
, false);
3905 gsi_remove (&m_gsi
, true);
3906 release_defs (memset_stmt
);
3912 /* Return first such statement if RES is used in statements testing its
3913 equality to zero, and null otherwise. If EXCLUSIVE is true, return
3914 nonnull if and only RES is used in such expressions exclusively and
3918 use_in_zero_equality (tree res
, bool exclusive
)
3920 gimple
*first_use
= NULL
;
3922 use_operand_p use_p
;
3923 imm_use_iterator iter
;
3925 FOR_EACH_IMM_USE_FAST (use_p
, iter
, res
)
3927 gimple
*use_stmt
= USE_STMT (use_p
);
3929 if (is_gimple_debug (use_stmt
))
3932 if (gimple_code (use_stmt
) == GIMPLE_ASSIGN
)
3934 tree_code code
= gimple_assign_rhs_code (use_stmt
);
3935 if (code
== COND_EXPR
)
3937 tree cond_expr
= gimple_assign_rhs1 (use_stmt
);
3938 if ((TREE_CODE (cond_expr
) != EQ_EXPR
3939 && (TREE_CODE (cond_expr
) != NE_EXPR
))
3940 || !integer_zerop (TREE_OPERAND (cond_expr
, 1)))
3947 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
3949 if (!integer_zerop (gimple_assign_rhs2 (use_stmt
)))
3961 else if (gimple_code (use_stmt
) == GIMPLE_COND
)
3963 tree_code code
= gimple_cond_code (use_stmt
);
3964 if ((code
!= EQ_EXPR
&& code
!= NE_EXPR
)
3965 || !integer_zerop (gimple_cond_rhs (use_stmt
)))
3978 first_use
= use_stmt
;
3984 /* Handle a call to memcmp. We try to handle small comparisons by
3985 converting them to load and compare, and replacing the call to memcmp
3986 with a __builtin_memcmp_eq call where possible.
3987 return true when call is transformed, return false otherwise. */
3990 strlen_pass::handle_builtin_memcmp ()
3992 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
3993 tree res
= gimple_call_lhs (stmt
);
3995 if (!res
|| !use_in_zero_equality (res
))
3998 tree arg1
= gimple_call_arg (stmt
, 0);
3999 tree arg2
= gimple_call_arg (stmt
, 1);
4000 tree len
= gimple_call_arg (stmt
, 2);
4001 unsigned HOST_WIDE_INT leni
;
4003 if (tree_fits_uhwi_p (len
)
4004 && (leni
= tree_to_uhwi (len
)) <= GET_MODE_SIZE (word_mode
)
4005 && pow2p_hwi (leni
))
4007 leni
*= CHAR_TYPE_SIZE
;
4008 unsigned align1
= get_pointer_alignment (arg1
);
4009 unsigned align2
= get_pointer_alignment (arg2
);
4010 unsigned align
= MIN (align1
, align2
);
4011 scalar_int_mode mode
;
4012 if (int_mode_for_size (leni
, 1).exists (&mode
)
4013 && (align
>= leni
|| !targetm
.slow_unaligned_access (mode
, align
)))
4015 location_t loc
= gimple_location (stmt
);
4017 type
= build_nonstandard_integer_type (leni
, 1);
4018 gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type
)), leni
));
4019 tree ptrtype
= build_pointer_type_for_mode (char_type_node
,
4021 off
= build_int_cst (ptrtype
, 0);
4022 arg1
= build2_loc (loc
, MEM_REF
, type
, arg1
, off
);
4023 arg2
= build2_loc (loc
, MEM_REF
, type
, arg2
, off
);
4024 tree tem1
= fold_const_aggregate_ref (arg1
);
4027 tree tem2
= fold_const_aggregate_ref (arg2
);
4030 res
= fold_convert_loc (loc
, TREE_TYPE (res
),
4031 fold_build2_loc (loc
, NE_EXPR
,
4034 gimplify_and_update_call_from_tree (&m_gsi
, res
);
4039 gimple_call_set_fndecl (stmt
, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ
));
4043 /* Given strinfo IDX for ARG, sets LENRNG[] to the range of lengths
4044 of the string(s) referenced by ARG if it can be determined.
4045 If the length cannot be determined, sets *SIZE to the size of
4046 the array the string is stored in, if any. If no such array is
4047 known, sets *SIZE to -1. When the strings are nul-terminated sets
4048 *NULTERM to true, otherwise to false. When nonnull uses RVALS to
4049 determine range information. Returns true on success. */
4052 strlen_pass::get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
4053 unsigned HOST_WIDE_INT lenrng
[2],
4054 unsigned HOST_WIDE_INT
*size
, bool *nulterm
)
4057 *size
= HOST_WIDE_INT_M1U
;
4061 /* IDX is the inverted constant string length. */
4063 lenrng
[1] = lenrng
[0];
4068 /* Set so that both LEN and ~LEN are invalid lengths, i.e., maximum
4069 possible length + 1. */
4070 lenrng
[0] = lenrng
[1] = HOST_WIDE_INT_MAX
;
4072 if (strinfo
*si
= idx
? get_strinfo (idx
) : NULL
)
4074 /* FIXME: Handle all this in_range_strlen_dynamic. */
4075 if (!si
->nonzero_chars
)
4077 else if (tree_fits_uhwi_p (si
->nonzero_chars
))
4079 lenrng
[0] = tree_to_uhwi (si
->nonzero_chars
);
4080 *nulterm
= si
->full_string_p
;
4081 /* Set the upper bound only if the string is known to be
4082 nul-terminated, otherwise leave it at maximum + 1. */
4084 lenrng
[1] = lenrng
[0];
4086 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4089 get_range_query (cfun
)->range_of_expr (r
, si
->nonzero_chars
);
4090 if (r
.kind () == VR_RANGE
)
4092 lenrng
[0] = r
.lower_bound ().to_uhwi ();
4093 lenrng
[1] = r
.upper_bound ().to_uhwi ();
4094 *nulterm
= si
->full_string_p
;
4099 if (lenrng
[0] != HOST_WIDE_INT_MAX
)
4102 /* Compute the minimum and maximum real or possible lengths. */
4103 c_strlen_data lendata
= { };
4104 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
4105 to have it set to the length of the longest string in a PHI. */
4106 lendata
.maxbound
= arg
;
4107 get_range_strlen_dynamic (arg
, stmt
, &lendata
, ptr_qry
);
4109 unsigned HOST_WIDE_INT maxbound
= HOST_WIDE_INT_M1U
;
4110 if (tree_fits_uhwi_p (lendata
.maxbound
)
4111 && !integer_all_onesp (lendata
.maxbound
))
4112 maxbound
= tree_to_uhwi (lendata
.maxbound
);
4114 if (tree_fits_uhwi_p (lendata
.minlen
) && tree_fits_uhwi_p (lendata
.maxlen
))
4116 unsigned HOST_WIDE_INT minlen
= tree_to_uhwi (lendata
.minlen
);
4117 unsigned HOST_WIDE_INT maxlen
= tree_to_uhwi (lendata
.maxlen
);
4119 /* The longest string in this data model. */
4120 const unsigned HOST_WIDE_INT lenmax
4121 = tree_to_uhwi (max_object_size ()) - 2;
4123 if (maxbound
== HOST_WIDE_INT_M1U
)
4127 *nulterm
= minlen
== maxlen
;
4129 else if (maxlen
< lenmax
)
4131 *size
= maxbound
+ 1;
4140 if (maxbound
!= HOST_WIDE_INT_M1U
4142 && !integer_all_onesp (lendata
.maxlen
))
4144 /* Set *SIZE to LENDATA.MAXBOUND which is a conservative estimate
4145 of the longest string based on the sizes of the arrays referenced
4147 *size
= maxbound
+ 1;
4155 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
4156 the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
4157 for a sufficiently large BOUND). If the result is based on the length
4158 of one string being greater than the longest string that would fit in
4159 the array pointer to by the argument, set *PLEN and *PSIZE to
4160 the corresponding length (or its complement when the string is known
4161 to be at least as long and need not be nul-terminated) and size.
4162 Otherwise return null. */
4165 strlen_pass::strxcmp_eqz_result (gimple
*stmt
, tree arg1
, int idx1
,
4166 tree arg2
, int idx2
,
4167 unsigned HOST_WIDE_INT bound
,
4168 unsigned HOST_WIDE_INT len
[2],
4169 unsigned HOST_WIDE_INT
*psize
)
4171 /* Determine the range the length of each string is in and whether it's
4172 known to be nul-terminated, or the size of the array it's stored in. */
4174 unsigned HOST_WIDE_INT siz1
, siz2
;
4175 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4176 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &siz1
, &nul1
)
4177 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &siz2
, &nul2
))
4180 /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
4181 to HWI_MAX when invalid. Adjust the length of each string to consider
4182 to be no more than BOUND. */
4183 if (len1rng
[0] < HOST_WIDE_INT_MAX
&& len1rng
[0] > bound
)
4185 if (len1rng
[1] < HOST_WIDE_INT_MAX
&& len1rng
[1] > bound
)
4187 if (len2rng
[0] < HOST_WIDE_INT_MAX
&& len2rng
[0] > bound
)
4189 if (len2rng
[1] < HOST_WIDE_INT_MAX
&& len2rng
[1] > bound
)
4192 /* Two empty strings are equal. */
4193 if (len1rng
[1] == 0 && len2rng
[1] == 0)
4194 return integer_one_node
;
4196 /* The strings are definitely unequal when the lower bound of the length
4197 of one of them is greater than the length of the longest string that
4198 would fit into the other array. */
4199 if (len1rng
[0] == HOST_WIDE_INT_MAX
4200 && len2rng
[0] != HOST_WIDE_INT_MAX
4201 && ((len2rng
[0] < bound
&& len2rng
[0] >= siz1
)
4202 || len2rng
[0] > siz1
))
4205 len
[0] = len1rng
[0];
4206 /* Set LEN[0] to the lower bound of ARG1's length when it's
4207 nul-terminated or to the complement of its minimum length
4209 len
[1] = nul2
? len2rng
[0] : ~len2rng
[0];
4210 return integer_zero_node
;
4213 if (len2rng
[0] == HOST_WIDE_INT_MAX
4214 && len1rng
[0] != HOST_WIDE_INT_MAX
4215 && ((len1rng
[0] < bound
&& len1rng
[0] >= siz2
)
4216 || len1rng
[0] > siz2
))
4219 len
[0] = nul1
? len1rng
[0] : ~len1rng
[0];
4220 len
[1] = len2rng
[0];
4221 return integer_zero_node
;
4224 /* The strings are also definitely unequal when their lengths are unequal
4225 and at least one is nul-terminated. */
4226 if (len1rng
[0] != HOST_WIDE_INT_MAX
4227 && len2rng
[0] != HOST_WIDE_INT_MAX
4228 && ((len1rng
[1] < len2rng
[0] && nul1
)
4229 || (len2rng
[1] < len1rng
[0] && nul2
)))
4231 if (bound
<= len1rng
[0] || bound
<= len2rng
[0])
4234 *psize
= HOST_WIDE_INT_M1U
;
4236 len
[0] = len1rng
[0];
4237 len
[1] = len2rng
[0];
4238 return integer_zero_node
;
4241 /* The string lengths may be equal or unequal. Even when equal and
4242 both strings nul-terminated, without the string contents there's
4243 no way to determine whether they are equal. */
4247 /* Diagnose pointless calls to strcmp or strncmp STMT with string
4248 arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
4249 whose result is used in equality expressions that evaluate to
4250 a constant due to one argument being longer than the size of
4254 maybe_warn_pointless_strcmp (gimple
*stmt
, HOST_WIDE_INT bound
,
4255 unsigned HOST_WIDE_INT len
[2],
4256 unsigned HOST_WIDE_INT siz
)
4258 tree lhs
= gimple_call_lhs (stmt
);
4259 gimple
*use
= use_in_zero_equality (lhs
, /* exclusive = */ false);
4263 bool at_least
= false;
4265 /* Excessive LEN[i] indicates a lower bound. */
4266 if (len
[0] > HOST_WIDE_INT_MAX
)
4272 if (len
[1] > HOST_WIDE_INT_MAX
)
4278 unsigned HOST_WIDE_INT minlen
= MIN (len
[0], len
[1]);
4280 /* FIXME: Include a note pointing to the declaration of the smaller
4282 location_t stmt_loc
= gimple_or_expr_nonartificial_location (stmt
, lhs
);
4284 tree callee
= gimple_call_fndecl (stmt
);
4285 bool warned
= false;
4286 if (siz
<= minlen
&& bound
== -1)
4287 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4289 ? G_("%qD of a string of length %wu or more and "
4290 "an array of size %wu evaluates to nonzero")
4291 : G_("%qD of a string of length %wu and an array "
4292 "of size %wu evaluates to nonzero")),
4293 callee
, minlen
, siz
);
4294 else if (!at_least
&& siz
<= HOST_WIDE_INT_MAX
)
4296 if (len
[0] != HOST_WIDE_INT_MAX
&& len
[1] != HOST_WIDE_INT_MAX
)
4297 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4298 "%qD of strings of length %wu and %wu "
4299 "and bound of %wu evaluates to nonzero",
4300 callee
, len
[0], len
[1], bound
);
4302 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4303 "%qD of a string of length %wu, an array "
4304 "of size %wu and bound of %wu evaluates to "
4306 callee
, minlen
, siz
, bound
);
4312 location_t use_loc
= gimple_location (use
);
4313 if (LOCATION_LINE (stmt_loc
) != LOCATION_LINE (use_loc
))
4314 inform (use_loc
, "in this expression");
4318 /* Optimize a call to strcmp or strncmp either by folding it to a constant
4319 when possible or by transforming the latter to the former. Warn about
4320 calls where the length of one argument is greater than the size of
4321 the array to which the other argument points if the latter's length
4322 is not known. Return true when the call has been transformed into
4323 another and false otherwise. */
4326 strlen_pass::handle_builtin_string_cmp ()
4328 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
4329 tree lhs
= gimple_call_lhs (stmt
);
4334 tree arg1
= gimple_call_arg (stmt
, 0);
4335 tree arg2
= gimple_call_arg (stmt
, 1);
4336 int idx1
= get_stridx (arg1
, stmt
);
4337 int idx2
= get_stridx (arg2
, stmt
);
4339 /* For strncmp set to the value of the third argument if known. */
4340 HOST_WIDE_INT bound
= -1;
4341 tree len
= NULL_TREE
;
4342 /* Extract the strncmp bound. */
4343 if (gimple_call_num_args (stmt
) == 3)
4345 len
= gimple_call_arg (stmt
, 2);
4346 if (tree_fits_shwi_p (len
))
4347 bound
= tree_to_shwi (len
);
4349 /* If the bound argument is NOT known, do nothing. */
4354 /* Avoid folding if either argument is not a nul-terminated array.
4355 Defer warning until later. */
4356 if (!check_nul_terminated_array (NULL_TREE
, arg1
, len
)
4357 || !check_nul_terminated_array (NULL_TREE
, arg2
, len
))
4361 /* Set to the length of one argument (or its complement if it's
4362 the lower bound of a range) and the size of the array storing
4363 the other if the result is based on the former being equal to
4364 or greater than the latter. */
4365 unsigned HOST_WIDE_INT len
[2] = { HOST_WIDE_INT_MAX
, HOST_WIDE_INT_MAX
};
4366 unsigned HOST_WIDE_INT siz
= HOST_WIDE_INT_M1U
;
4368 /* Try to determine if the two strings are either definitely equal
4369 or definitely unequal and if so, either fold the result to zero
4370 (when equal) or set the range of the result to ~[0, 0] otherwise. */
4371 if (tree eqz
= strxcmp_eqz_result (stmt
, arg1
, idx1
, arg2
, idx2
, bound
,
4374 if (integer_zerop (eqz
))
4376 maybe_warn_pointless_strcmp (stmt
, bound
, len
, siz
);
4378 /* When the lengths of the first two string arguments are
4379 known to be unequal set the range of the result to non-zero.
4380 This allows the call to be eliminated if its result is only
4381 used in tests for equality to zero. */
4383 nz
.set_nonzero (TREE_TYPE (lhs
));
4384 set_range_info (lhs
, nz
);
4387 /* When the two strings are definitely equal (such as when they
4388 are both empty) fold the call to the constant result. */
4389 replace_call_with_value (&m_gsi
, integer_zero_node
);
4394 /* Return if nothing is known about the strings pointed to by ARG1
4396 if (idx1
== 0 && idx2
== 0)
4399 /* Determine either the length or the size of each of the strings,
4400 whichever is available. */
4401 HOST_WIDE_INT cstlen1
= -1, cstlen2
= -1;
4402 HOST_WIDE_INT arysiz1
= -1, arysiz2
= -1;
4405 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4406 unsigned HOST_WIDE_INT arsz1
, arsz2
;
4409 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &arsz1
, nulterm
)
4410 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &arsz2
, nulterm
+ 1))
4413 if (len1rng
[0] == len1rng
[1] && len1rng
[0] < HOST_WIDE_INT_MAX
)
4414 cstlen1
= len1rng
[0];
4415 else if (arsz1
< HOST_WIDE_INT_M1U
)
4418 if (len2rng
[0] == len2rng
[1] && len2rng
[0] < HOST_WIDE_INT_MAX
)
4419 cstlen2
= len2rng
[0];
4420 else if (arsz2
< HOST_WIDE_INT_M1U
)
4424 /* Bail if neither the string length nor the size of the array
4425 it is stored in can be determined. */
4426 if ((cstlen1
< 0 && arysiz1
< 0)
4427 || (cstlen2
< 0 && arysiz2
< 0)
4428 || (cstlen1
< 0 && cstlen2
< 0))
4436 /* The exact number of characters to compare. */
4437 HOST_WIDE_INT cmpsiz
;
4438 if (cstlen1
>= 0 && cstlen2
>= 0)
4439 cmpsiz
= MIN (cstlen1
, cstlen2
);
4440 else if (cstlen1
>= 0)
4445 cmpsiz
= MIN (cmpsiz
, bound
);
4446 /* The size of the array in which the unknown string is stored. */
4447 HOST_WIDE_INT varsiz
= arysiz1
< 0 ? arysiz2
: arysiz1
;
4449 if ((varsiz
< 0 || cmpsiz
< varsiz
) && use_in_zero_equality (lhs
))
4451 /* If the known length is less than the size of the other array
4452 and the strcmp result is only used to test equality to zero,
4453 transform the call to the equivalent _eq call. */
4454 if (tree fn
= builtin_decl_implicit (bound
< 0 ? BUILT_IN_STRCMP_EQ
4455 : BUILT_IN_STRNCMP_EQ
))
4457 tree n
= build_int_cst (size_type_node
, cmpsiz
);
4458 update_gimple_call (&m_gsi
, fn
, 3, arg1
, arg2
, n
);
4466 /* Handle a POINTER_PLUS_EXPR statement.
4467 For p = "abcd" + 2; compute associated length, or if
4468 p = q + off is pointing to a '\0' character of a string, call
4469 zero_length_string on it. */
4472 strlen_pass::handle_pointer_plus ()
4474 gimple
*stmt
= gsi_stmt (m_gsi
);
4475 tree lhs
= gimple_assign_lhs (stmt
), off
;
4476 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
4484 tree off
= gimple_assign_rhs2 (stmt
);
4485 if (tree_fits_uhwi_p (off
)
4486 && tree_to_uhwi (off
) <= (unsigned HOST_WIDE_INT
) ~idx
)
4487 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)]
4488 = ~(~idx
- (int) tree_to_uhwi (off
));
4492 si
= get_strinfo (idx
);
4493 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
4496 off
= gimple_assign_rhs2 (stmt
);
4498 if (si
->full_string_p
&& operand_equal_p (si
->nonzero_chars
, off
, 0))
4499 zsi
= zero_length_string (lhs
, si
);
4500 else if (TREE_CODE (off
) == SSA_NAME
)
4502 gimple
*def_stmt
= SSA_NAME_DEF_STMT (off
);
4503 if (gimple_assign_single_p (def_stmt
)
4504 && si
->full_string_p
4505 && operand_equal_p (si
->nonzero_chars
,
4506 gimple_assign_rhs1 (def_stmt
), 0))
4507 zsi
= zero_length_string (lhs
, si
);
4510 && si
->endptr
!= NULL_TREE
4511 && si
->endptr
!= lhs
4512 && TREE_CODE (si
->endptr
) == SSA_NAME
)
4514 enum tree_code rhs_code
4515 = useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (si
->endptr
))
4516 ? SSA_NAME
: NOP_EXPR
;
4517 gimple_assign_set_rhs_with_ops (&m_gsi
, rhs_code
, si
->endptr
);
4518 gcc_assert (gsi_stmt (m_gsi
) == stmt
);
4523 /* Set LENRANGE to the number of nonzero bytes for a store of TYPE and
4524 clear all flags. Return true on success and false on failure. */
4527 nonzero_bytes_for_type (tree type
, unsigned lenrange
[3],
4528 bool *nulterm
, bool *allnul
, bool *allnonnul
)
4530 /* Use the size of the type of the expression as the size of the store,
4531 and set the upper bound of the length range to that of the size.
4532 Nothing is known about the contents so clear all flags. */
4533 tree typesize
= TYPE_SIZE_UNIT (type
);
4537 if (!tree_fits_uhwi_p (typesize
))
4540 unsigned HOST_WIDE_INT sz
= tree_to_uhwi (typesize
);
4545 lenrange
[1] = lenrange
[2] ? lenrange
[2] - 1 : 0;
4553 /* Recursively determine the minimum and maximum number of leading nonzero
4554 bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
4556 Sets LENRANGE[2] to the total size of the access (which may be less
4557 than LENRANGE[1] when what's being referenced by EXP is a pointer
4558 rather than an array).
4559 Sets *NULTERM if the representation contains a zero byte, sets *ALLNUL
4560 if all the bytes are zero, and *ALLNONNUL is all are nonzero.
4561 OFFSET and NBYTES are the offset into the representation and
4562 the size of the access to it determined from an ADDR_EXPR (i.e.,
4563 a pointer) or MEM_REF or zero for other expressions.
4564 Uses RVALS to determine range information.
4565 Avoids recursing deeper than the limits in SNLIM allow.
4566 Returns true on success and false otherwise. */
4569 strlen_pass::count_nonzero_bytes (tree exp
, gimple
*stmt
,
4570 unsigned HOST_WIDE_INT offset
,
4571 unsigned HOST_WIDE_INT nbytes
,
4572 unsigned lenrange
[3], bool *nulterm
,
4573 bool *allnul
, bool *allnonnul
,
4574 ssa_name_limit_t
&snlim
)
4576 if (TREE_CODE (exp
) == SSA_NAME
)
4578 /* Handle non-zero single-character stores specially. */
4579 tree type
= TREE_TYPE (exp
);
4580 if (TREE_CODE (type
) == INTEGER_TYPE
4581 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
4582 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
)
4583 && tree_expr_nonzero_p (exp
))
4585 /* If the character EXP is known to be non-zero (even if its
4586 exact value is not known) recurse once to set the range
4587 for an arbitrary constant. */
4588 exp
= build_int_cst (type
, 1);
4589 return count_nonzero_bytes (exp
, stmt
,
4590 offset
, 1, lenrange
,
4591 nulterm
, allnul
, allnonnul
, snlim
);
4594 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4595 if (gimple_assign_single_p (stmt
))
4597 exp
= gimple_assign_rhs1 (stmt
);
4599 && TREE_CODE (exp
) != CONSTRUCTOR
4600 && TREE_CODE (exp
) != MEM_REF
)
4602 /* Handle DECLs, CONSTRUCTOR and MEM_REF below. */
4604 else if (gimple_code (stmt
) == GIMPLE_PHI
)
4606 /* Avoid processing an SSA_NAME that has already been visited
4607 or if an SSA_NAME limit has been reached. Indicate success
4608 if the former and failure if the latter. */
4609 if (int res
= snlim
.next_phi (exp
))
4612 /* Determine the minimum and maximum from the PHI arguments. */
4613 unsigned int n
= gimple_phi_num_args (stmt
);
4614 for (unsigned i
= 0; i
!= n
; i
++)
4616 tree def
= gimple_phi_arg_def (stmt
, i
);
4617 if (!count_nonzero_bytes (def
, stmt
,
4618 offset
, nbytes
, lenrange
, nulterm
,
4619 allnul
, allnonnul
, snlim
))
4627 if (TREE_CODE (exp
) == CONSTRUCTOR
)
4630 /* If NBYTES has already been determined by an outer MEM_REF
4631 fail rather than overwriting it (this shouldn't happen). */
4634 tree type
= TREE_TYPE (exp
);
4635 tree size
= TYPE_SIZE_UNIT (type
);
4636 if (!size
|| !tree_fits_uhwi_p (size
))
4639 unsigned HOST_WIDE_INT byte_size
= tree_to_uhwi (size
);
4640 if (byte_size
< offset
)
4643 nbytes
= byte_size
- offset
;
4646 if (TREE_CODE (exp
) == MEM_REF
)
4651 tree arg
= TREE_OPERAND (exp
, 0);
4652 tree off
= TREE_OPERAND (exp
, 1);
4654 if (TREE_CODE (off
) != INTEGER_CST
|| !tree_fits_uhwi_p (off
))
4657 unsigned HOST_WIDE_INT wioff
= tree_to_uhwi (off
);
4658 if (INT_MAX
< wioff
)
4662 if (INT_MAX
< offset
)
4665 /* The size of the MEM_REF access determines the number of bytes. */
4666 tree type
= TREE_TYPE (exp
);
4667 tree typesize
= TYPE_SIZE_UNIT (type
);
4668 if (!typesize
|| !tree_fits_uhwi_p (typesize
))
4670 nbytes
= tree_to_uhwi (typesize
);
4674 /* Handle MEM_REF = SSA_NAME types of assignments. */
4675 return count_nonzero_bytes_addr (arg
, stmt
,
4676 offset
, nbytes
, lenrange
, nulterm
,
4677 allnul
, allnonnul
, snlim
);
4680 if (VAR_P (exp
) || TREE_CODE (exp
) == CONST_DECL
)
4682 /* If EXP can be folded into a constant use the result. Otherwise
4683 proceed to use EXP to determine a range of the result. */
4684 if (tree fold_exp
= ctor_for_folding (exp
))
4685 if (fold_exp
!= error_mark_node
)
4689 const char *prep
= NULL
;
4690 if (TREE_CODE (exp
) == STRING_CST
)
4692 unsigned nchars
= TREE_STRING_LENGTH (exp
);
4693 if (nchars
< offset
)
4697 /* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
4698 (i.e., it's the size of a pointer), or from MEM_REF (as the size
4699 of the access), set it here to the size of the string, including
4700 all internal and trailing nuls if the string has any. */
4701 nbytes
= nchars
- offset
;
4702 else if (nchars
- offset
< nbytes
)
4705 prep
= TREE_STRING_POINTER (exp
) + offset
;
4708 unsigned char buf
[256];
4711 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8)
4713 /* If the pointer to representation hasn't been set above
4714 for STRING_CST point it at the buffer. */
4715 prep
= reinterpret_cast <char *>(buf
);
4716 /* Try to extract the representation of the constant object
4717 or expression starting from the offset. */
4718 unsigned repsize
= native_encode_expr (exp
, buf
, sizeof buf
, offset
);
4719 if (repsize
< nbytes
)
4721 /* This should only happen when REPSIZE is zero because EXP
4722 doesn't denote an object with a known initializer, except
4723 perhaps when the reference reads past its end. */
4729 else if (nbytes
< repsize
)
4734 return nonzero_bytes_for_type (TREE_TYPE (exp
), lenrange
,
4735 nulterm
, allnul
, allnonnul
);
4737 /* Compute the number of leading nonzero bytes in the representation
4738 and update the minimum and maximum. */
4739 unsigned HOST_WIDE_INT n
= prep
? strnlen (prep
, nbytes
) : nbytes
;
4741 if (n
< lenrange
[0])
4743 if (lenrange
[1] < n
)
4746 /* Set the size of the representation. */
4747 if (lenrange
[2] < nbytes
)
4748 lenrange
[2] = nbytes
;
4750 /* Clear NULTERM if none of the bytes is zero. */
4756 /* When the initial number of non-zero bytes N is non-zero, reset
4757 *ALLNUL; if N is less than that the size of the representation
4758 also clear *ALLNONNUL. */
4763 else if (*allnul
|| *allnonnul
)
4769 /* When either ALLNUL is set and N is zero, also determine
4770 whether all subsequent bytes after the first one (which
4771 is nul) are zero or nonzero and clear ALLNUL if not. */
4772 for (const char *p
= prep
; p
!= prep
+ nbytes
; ++p
)
4784 /* Like count_nonzero_bytes, but instead of counting bytes in EXP, count
4785 bytes that are pointed to by EXP, which should be a pointer. */
4788 strlen_pass::count_nonzero_bytes_addr (tree exp
, gimple
*stmt
,
4789 unsigned HOST_WIDE_INT offset
,
4790 unsigned HOST_WIDE_INT nbytes
,
4791 unsigned lenrange
[3], bool *nulterm
,
4792 bool *allnul
, bool *allnonnul
,
4793 ssa_name_limit_t
&snlim
)
4795 int idx
= get_stridx (exp
, stmt
);
4798 strinfo
*si
= get_strinfo (idx
);
4802 /* Handle both constant lengths as well non-constant lengths
4804 unsigned HOST_WIDE_INT minlen
, maxlen
;
4805 if (tree_fits_shwi_p (si
->nonzero_chars
))
4806 minlen
= maxlen
= tree_to_shwi (si
->nonzero_chars
);
4807 else if (si
->nonzero_chars
4808 && TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4811 ptr_qry
.rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
);
4812 if (vr
.kind () != VR_RANGE
)
4815 minlen
= tree_to_uhwi (vr
.min ());
4816 maxlen
= tree_to_uhwi (vr
.max ());
4821 if (maxlen
< offset
)
4824 minlen
= minlen
< offset
? 0 : minlen
- offset
;
4826 if (maxlen
+ 1 < nbytes
)
4829 if (nbytes
<= minlen
)
4832 if (nbytes
< minlen
)
4835 if (nbytes
< maxlen
)
4839 if (minlen
< lenrange
[0])
4840 lenrange
[0] = minlen
;
4841 if (lenrange
[1] < maxlen
)
4842 lenrange
[1] = maxlen
;
4844 if (lenrange
[2] < nbytes
)
4845 lenrange
[2] = nbytes
;
4847 /* Since only the length of the string are known and not its contents,
4848 clear ALLNUL and ALLNONNUL purely on the basis of the length. */
4850 if (minlen
< nbytes
)
4856 if (TREE_CODE (exp
) == ADDR_EXPR
)
4857 return count_nonzero_bytes (TREE_OPERAND (exp
, 0), stmt
,
4859 lenrange
, nulterm
, allnul
, allnonnul
, snlim
);
4861 if (TREE_CODE (exp
) == SSA_NAME
)
4863 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4864 if (gimple_code (stmt
) == GIMPLE_PHI
)
4866 /* Avoid processing an SSA_NAME that has already been visited
4867 or if an SSA_NAME limit has been reached. Indicate success
4868 if the former and failure if the latter. */
4869 if (int res
= snlim
.next_phi (exp
))
4872 /* Determine the minimum and maximum from the PHI arguments. */
4873 unsigned int n
= gimple_phi_num_args (stmt
);
4874 for (unsigned i
= 0; i
!= n
; i
++)
4876 tree def
= gimple_phi_arg_def (stmt
, i
);
4877 if (!count_nonzero_bytes_addr (def
, stmt
,
4878 offset
, nbytes
, lenrange
,
4879 nulterm
, allnul
, allnonnul
,
4888 /* Otherwise we don't know anything. */
4890 if (lenrange
[1] < nbytes
)
4891 lenrange
[1] = nbytes
;
4892 if (lenrange
[2] < nbytes
)
4893 lenrange
[2] = nbytes
;
4900 /* Same as above except with an implicit SSA_NAME limit. When EXPR_OR_TYPE
4901 is a type rather than an expression use its size to compute the range.
4902 RVALS is used to determine ranges of dynamically computed string lengths
4903 (the results of strlen). */
4906 strlen_pass::count_nonzero_bytes (tree expr_or_type
, gimple
*stmt
,
4907 unsigned lenrange
[3], bool *nulterm
,
4908 bool *allnul
, bool *allnonnul
)
4910 if (TYPE_P (expr_or_type
))
4911 return nonzero_bytes_for_type (expr_or_type
, lenrange
,
4912 nulterm
, allnul
, allnonnul
);
4914 /* Set to optimistic values so the caller doesn't have to worry about
4915 initializing these and to what. On success, the function will clear
4916 these if it determines their values are different but being recursive
4917 it never sets either to true. On failure, their values are
4923 ssa_name_limit_t snlim
;
4924 tree expr
= expr_or_type
;
4925 return count_nonzero_bytes (expr
, stmt
,
4926 0, 0, lenrange
, nulterm
, allnul
, allnonnul
,
4930 /* Handle a single or multibyte store other than by a built-in function,
4931 either via a single character assignment or by multi-byte assignment
4932 either via MEM_REF or via a type other than char (such as in
4933 '*(int*)a = 12345'). Return true to let the caller advance *GSI to
4934 the next statement in the basic block and false otherwise. */
4937 strlen_pass::handle_store (bool *zero_write
)
4939 gimple
*stmt
= gsi_stmt (m_gsi
);
4940 /* The LHS and RHS of the store. The RHS is null if STMT is a function
4941 call. STORETYPE is the type of the store (determined from either
4942 the RHS of the assignment statement or the LHS of a function call. */
4943 tree lhs
, rhs
, storetype
;
4944 if (is_gimple_assign (stmt
))
4946 lhs
= gimple_assign_lhs (stmt
);
4947 rhs
= gimple_assign_rhs1 (stmt
);
4948 storetype
= TREE_TYPE (rhs
);
4950 else if (is_gimple_call (stmt
))
4952 lhs
= gimple_call_lhs (stmt
);
4954 storetype
= TREE_TYPE (lhs
);
4959 tree ssaname
= NULL_TREE
;
4963 range_query
*const rvals
= ptr_qry
.rvals
;
4965 /* The offset of the first byte in LHS modified by the store. */
4966 unsigned HOST_WIDE_INT offset
= 0;
4968 if (TREE_CODE (lhs
) == MEM_REF
4969 && TREE_CODE (TREE_OPERAND (lhs
, 0)) == SSA_NAME
)
4971 tree mem_offset
= TREE_OPERAND (lhs
, 1);
4972 if (tree_fits_uhwi_p (mem_offset
))
4974 /* Get the strinfo for the base, and use it if it starts with at
4975 least OFFSET nonzero characters. This is trivially true if
4977 offset
= tree_to_uhwi (mem_offset
);
4978 idx
= get_stridx (TREE_OPERAND (lhs
, 0), stmt
);
4980 si
= get_strinfo (idx
);
4982 ssaname
= TREE_OPERAND (lhs
, 0);
4984 || compare_nonzero_chars (si
, stmt
, offset
, rvals
) < 0)
4986 *zero_write
= rhs
? initializer_zerop (rhs
) : false;
4989 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4990 if (count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
, lenrange
,
4991 &dummy
, &dummy
, &dummy
))
4992 maybe_warn_overflow (stmt
, true, lenrange
[2]);
5000 idx
= get_addr_stridx (lhs
, stmt
, NULL_TREE
, &offset
, rvals
);
5002 si
= get_strinfo (idx
);
5005 /* Minimum and maximum leading non-zero bytes and the size of the store. */
5006 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
5008 /* Set to the minimum length of the string being assigned if known. */
5009 unsigned HOST_WIDE_INT rhs_minlen
;
5011 /* STORING_NONZERO_P is true iff not all stored characters are zero.
5012 STORING_ALL_NONZERO_P is true if all stored characters are zero.
5013 STORING_ALL_ZEROS_P is true iff all stored characters are zero.
5014 Both are false when it's impossible to determine which is true. */
5015 bool storing_nonzero_p
;
5016 bool storing_all_nonzero_p
;
5017 bool storing_all_zeros_p
;
5018 /* FULL_STRING_P is set when the stored sequence of characters form
5019 a nul-terminated string. */
5022 const bool ranges_valid
5023 = count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
,
5024 lenrange
, &full_string_p
,
5025 &storing_all_zeros_p
, &storing_all_nonzero_p
);
5029 rhs_minlen
= lenrange
[0];
5030 storing_nonzero_p
= lenrange
[1] > 0;
5031 *zero_write
= storing_all_zeros_p
;
5033 maybe_warn_overflow (stmt
, true, lenrange
[2]);
5037 rhs_minlen
= HOST_WIDE_INT_M1U
;
5038 full_string_p
= false;
5039 storing_nonzero_p
= false;
5040 storing_all_zeros_p
= false;
5041 storing_all_nonzero_p
= false;
5046 /* The corresponding element is set to 1 if the first and last
5047 element, respectively, of the sequence of characters being
5048 written over the string described by SI ends before
5049 the terminating nul (if it has one), to zero if the nul is
5050 being overwritten but not beyond, or negative otherwise. */
5051 int store_before_nul
[2];
5054 /* The offset of the last stored byte. */
5055 unsigned HOST_WIDE_INT endoff
= offset
+ lenrange
[2] - 1;
5057 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
5058 if (endoff
== offset
)
5059 store_before_nul
[1] = store_before_nul
[0];
5062 = compare_nonzero_chars (si
, stmt
, endoff
, rvals
);
5067 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
5068 store_before_nul
[1] = store_before_nul
[0];
5069 gcc_assert (offset
== 0 || store_before_nul
[0] >= 0);
5072 if (storing_all_zeros_p
5073 && store_before_nul
[0] == 0
5074 && store_before_nul
[1] == 0
5075 && si
->full_string_p
)
5077 /* When overwriting a '\0' with a '\0', the store can be removed
5078 if we know it has been stored in the current function. */
5079 if (!stmt_could_throw_p (cfun
, stmt
) && si
->writable
)
5081 unlink_stmt_vdef (stmt
);
5082 release_defs (stmt
);
5083 gsi_remove (&m_gsi
, true);
5088 si
->writable
= true;
5094 if (store_before_nul
[1] > 0
5095 && storing_nonzero_p
5096 && lenrange
[0] == lenrange
[1]
5097 && lenrange
[0] == lenrange
[2]
5098 && TREE_CODE (storetype
) == INTEGER_TYPE
)
5100 /* Handle a store of one or more non-nul characters that ends
5101 before the terminating nul of the destination and so does
5102 not affect its length
5103 If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
5104 and if we aren't storing '\0', we know that the length of
5105 the string and any other zero terminated string in memory
5106 remains the same. In that case we move to the next gimple
5107 statement and return to signal the caller that it shouldn't
5108 invalidate anything.
5110 This is beneficial for cases like:
5115 strcpy (p, "foobar");
5116 size_t len = strlen (p); // can be folded to 6
5117 size_t len2 = strlen (q); // has to be computed
5119 size_t len3 = strlen (p); // can be folded to 6
5120 size_t len4 = strlen (q); // can be folded to len2
5121 bar (len, len2, len3, len4);
5127 if (storing_nonzero_p
5128 || storing_all_zeros_p
5129 || (full_string_p
&& lenrange
[1] == 0)
5130 || (offset
!= 0 && store_before_nul
[1] > 0))
5132 /* When STORING_NONZERO_P, we know that the string will start
5133 with at least OFFSET + 1 nonzero characters. If storing
5134 a single character, set si->NONZERO_CHARS to the result.
5135 If storing multiple characters, try to determine the number
5136 of leading non-zero characters and set si->NONZERO_CHARS to
5139 When STORING_ALL_ZEROS_P, or the first byte written is zero,
5140 i.e. FULL_STRING_P && LENRANGE[1] == 0, we know that the
5141 string is now OFFSET characters long.
5143 Otherwise, we're storing an unknown value at offset OFFSET,
5144 so need to clip the nonzero_chars to OFFSET.
5145 Use the minimum length of the string (or individual character)
5146 being stored if it's known. Otherwise, STORING_NONZERO_P
5147 guarantees it's at least 1. */
5149 = storing_nonzero_p
&& ranges_valid
? lenrange
[0] : 1;
5150 location_t loc
= gimple_location (stmt
);
5151 tree oldlen
= si
->nonzero_chars
;
5152 if (store_before_nul
[1] == 0 && si
->full_string_p
)
5153 /* We're overwriting the nul terminator with a nonzero or
5154 unknown character. If the previous stmt was a memcpy,
5155 its length may be decreased. */
5156 adjust_last_stmt (si
, stmt
, false);
5157 si
= unshare_strinfo (si
);
5158 if (storing_nonzero_p
)
5160 gcc_assert (len
>= 0);
5161 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
+ len
);
5164 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
);
5166 /* Set FULL_STRING_P only if the length of the strings being
5167 written is the same, and clear it if the strings have
5168 different lengths. In the latter case the length stored
5169 in si->NONZERO_CHARS becomes the lower bound.
5170 FIXME: Handle the upper bound of the length if possible. */
5171 si
->full_string_p
= full_string_p
&& lenrange
[0] == lenrange
[1];
5173 if (storing_all_zeros_p
5175 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5176 si
->endptr
= ssaname
;
5181 si
->writable
= true;
5182 si
->dont_invalidate
= true;
5185 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
5186 si
->nonzero_chars
, oldlen
);
5187 adjust_related_strinfos (loc
, si
, adj
);
5193 else if (idx
== 0 && (storing_all_zeros_p
|| storing_nonzero_p
))
5196 idx
= new_stridx (ssaname
);
5198 idx
= new_addr_stridx (lhs
);
5201 tree ptr
= (ssaname
? ssaname
: build_fold_addr_expr (lhs
));
5204 if (storing_all_zeros_p
)
5206 else if (storing_nonzero_p
&& ranges_valid
)
5208 /* FIXME: Handle the upper bound of the length when
5209 LENRANGE[0] != LENRANGE[1]. */
5211 if (lenrange
[0] != lenrange
[1])
5212 /* Set the minimum length but ignore the maximum
5214 full_string_p
= false;
5219 tree len
= (slen
<= 0
5221 : build_int_cst (size_type_node
, slen
));
5222 si
= new_strinfo (ptr
, idx
, len
, slen
>= 0 && full_string_p
);
5223 set_strinfo (idx
, si
);
5224 if (storing_all_zeros_p
5226 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5227 si
->endptr
= ssaname
;
5228 si
->dont_invalidate
= true;
5229 si
->writable
= true;
5233 && rhs_minlen
< HOST_WIDE_INT_M1U
5234 && ssaname
== NULL_TREE
5235 && TREE_CODE (TREE_TYPE (lhs
)) == ARRAY_TYPE
)
5237 HOST_WIDE_INT a
= int_size_in_bytes (TREE_TYPE (lhs
));
5238 if (a
> 0 && (unsigned HOST_WIDE_INT
) a
> rhs_minlen
)
5240 int idx
= new_addr_stridx (lhs
);
5243 si
= new_strinfo (build_fold_addr_expr (lhs
), idx
,
5244 build_int_cst (size_type_node
, rhs_minlen
),
5246 set_strinfo (idx
, si
);
5247 si
->dont_invalidate
= true;
5252 if (si
!= NULL
&& offset
== 0 && storing_all_zeros_p
&& lenrange
[2] == 1)
5254 /* For single-byte stores only, allow adjust_last_stmt to remove
5255 the statement if the stored '\0' is immediately overwritten. */
5256 laststmt
.stmt
= stmt
;
5257 laststmt
.len
= build_int_cst (size_type_node
, 1);
5258 laststmt
.stridx
= si
->idx
;
5263 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0. */
5266 fold_strstr_to_strncmp (tree rhs1
, tree rhs2
, gimple
*stmt
)
5268 if (TREE_CODE (rhs1
) != SSA_NAME
5269 || TREE_CODE (rhs2
) != SSA_NAME
)
5272 gimple
*call_stmt
= NULL
;
5273 for (int pass
= 0; pass
< 2; pass
++)
5275 gimple
*g
= SSA_NAME_DEF_STMT (rhs1
);
5276 if (gimple_call_builtin_p (g
, BUILT_IN_STRSTR
)
5277 && has_single_use (rhs1
)
5278 && gimple_call_arg (g
, 0) == rhs2
)
5283 std::swap (rhs1
, rhs2
);
5288 tree arg0
= gimple_call_arg (call_stmt
, 0);
5292 tree arg1
= gimple_call_arg (call_stmt
, 1);
5293 tree arg1_len
= NULL_TREE
;
5294 int idx
= get_stridx (arg1
, call_stmt
);
5299 arg1_len
= build_int_cst (size_type_node
, ~idx
);
5302 strinfo
*si
= get_strinfo (idx
);
5304 arg1_len
= get_string_length (si
);
5308 if (arg1_len
!= NULL_TREE
)
5310 gimple_stmt_iterator gsi
= gsi_for_stmt (call_stmt
);
5311 tree strncmp_decl
= builtin_decl_explicit (BUILT_IN_STRNCMP
);
5313 if (!is_gimple_val (arg1_len
))
5315 tree arg1_len_tmp
= make_ssa_name (TREE_TYPE (arg1_len
));
5316 gassign
*arg1_stmt
= gimple_build_assign (arg1_len_tmp
,
5318 gsi_insert_before (&gsi
, arg1_stmt
, GSI_SAME_STMT
);
5319 arg1_len
= arg1_len_tmp
;
5322 gcall
*strncmp_call
= gimple_build_call (strncmp_decl
, 3,
5323 arg0
, arg1
, arg1_len
);
5324 tree strncmp_lhs
= make_ssa_name (integer_type_node
);
5325 gimple_set_vuse (strncmp_call
, gimple_vuse (call_stmt
));
5326 gimple_call_set_lhs (strncmp_call
, strncmp_lhs
);
5327 gsi_remove (&gsi
, true);
5328 gsi_insert_before (&gsi
, strncmp_call
, GSI_SAME_STMT
);
5329 tree zero
= build_zero_cst (TREE_TYPE (strncmp_lhs
));
5331 if (is_gimple_assign (stmt
))
5333 if (gimple_assign_rhs_code (stmt
) == COND_EXPR
)
5335 tree cond
= gimple_assign_rhs1 (stmt
);
5336 TREE_OPERAND (cond
, 0) = strncmp_lhs
;
5337 TREE_OPERAND (cond
, 1) = zero
;
5341 gimple_assign_set_rhs1 (stmt
, strncmp_lhs
);
5342 gimple_assign_set_rhs2 (stmt
, zero
);
5347 gcond
*cond
= as_a
<gcond
*> (stmt
);
5348 gimple_cond_set_lhs (cond
, strncmp_lhs
);
5349 gimple_cond_set_rhs (cond
, zero
);
5357 /* Return true if TYPE corresponds to a narrow character type. */
5360 is_char_type (tree type
)
5362 return (TREE_CODE (type
) == INTEGER_TYPE
5363 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
5364 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
));
5367 /* Check the built-in call at GSI for validity and optimize it.
5368 Uses RVALS to determine range information.
5369 Return true to let the caller advance *GSI to the next statement
5370 in the basic block and false otherwise. */
5373 strlen_pass::check_and_optimize_call (bool *zero_write
)
5375 gimple
*stmt
= gsi_stmt (m_gsi
);
5377 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
5379 tree fntype
= gimple_call_fntype (stmt
);
5383 if (lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype
)))
5385 handle_alloc_call (BUILT_IN_NONE
);
5389 if (tree lhs
= gimple_call_lhs (stmt
))
5390 handle_assign (lhs
, zero_write
);
5392 /* Proceed to handle user-defined formatting functions. */
5395 /* When not optimizing we must be checking printf calls which
5396 we do even for user-defined functions when they are declared
5397 with attribute format. */
5398 if (!flag_optimize_strlen
5400 || !valid_builtin_call (stmt
))
5401 return !handle_printf_call (&m_gsi
, ptr_qry
);
5403 tree callee
= gimple_call_fndecl (stmt
);
5404 switch (DECL_FUNCTION_CODE (callee
))
5406 case BUILT_IN_STRLEN
:
5407 case BUILT_IN_STRNLEN
:
5408 handle_builtin_strlen ();
5410 case BUILT_IN_STRCHR
:
5411 handle_builtin_strchr ();
5413 case BUILT_IN_STRCPY
:
5414 case BUILT_IN_STRCPY_CHK
:
5415 case BUILT_IN_STPCPY
:
5416 case BUILT_IN_STPCPY_CHK
:
5417 handle_builtin_strcpy (DECL_FUNCTION_CODE (callee
));
5420 case BUILT_IN_STRNCAT
:
5421 case BUILT_IN_STRNCAT_CHK
:
5422 handle_builtin_strncat (DECL_FUNCTION_CODE (callee
));
5425 case BUILT_IN_STPNCPY
:
5426 case BUILT_IN_STPNCPY_CHK
:
5427 case BUILT_IN_STRNCPY
:
5428 case BUILT_IN_STRNCPY_CHK
:
5429 handle_builtin_stxncpy_strncat (false);
5432 case BUILT_IN_MEMCPY
:
5433 case BUILT_IN_MEMCPY_CHK
:
5434 case BUILT_IN_MEMPCPY
:
5435 case BUILT_IN_MEMPCPY_CHK
:
5436 handle_builtin_memcpy (DECL_FUNCTION_CODE (callee
));
5438 case BUILT_IN_STRCAT
:
5439 case BUILT_IN_STRCAT_CHK
:
5440 handle_builtin_strcat (DECL_FUNCTION_CODE (callee
));
5442 case BUILT_IN_ALLOCA
:
5443 case BUILT_IN_ALLOCA_WITH_ALIGN
:
5444 case BUILT_IN_MALLOC
:
5445 case BUILT_IN_CALLOC
:
5446 handle_alloc_call (DECL_FUNCTION_CODE (callee
));
5448 case BUILT_IN_MEMSET
:
5449 if (handle_builtin_memset (zero_write
))
5452 case BUILT_IN_MEMCMP
:
5453 if (handle_builtin_memcmp ())
5456 case BUILT_IN_STRCMP
:
5457 case BUILT_IN_STRNCMP
:
5458 if (handle_builtin_string_cmp ())
5462 if (handle_printf_call (&m_gsi
, ptr_qry
))
5470 /* Handle an assignment statement at *GSI to a LHS of integral type.
5471 If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */
5474 strlen_pass::handle_integral_assign (bool *cleanup_eh
)
5476 gimple
*stmt
= gsi_stmt (m_gsi
);
5477 tree lhs
= gimple_assign_lhs (stmt
);
5478 tree lhs_type
= TREE_TYPE (lhs
);
5480 enum tree_code code
= gimple_assign_rhs_code (stmt
);
5481 if (code
== COND_EXPR
)
5483 tree cond
= gimple_assign_rhs1 (stmt
);
5484 enum tree_code cond_code
= TREE_CODE (cond
);
5486 if (cond_code
== EQ_EXPR
|| cond_code
== NE_EXPR
)
5487 fold_strstr_to_strncmp (TREE_OPERAND (cond
, 0),
5488 TREE_OPERAND (cond
, 1), stmt
);
5490 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5491 fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt
),
5492 gimple_assign_rhs2 (stmt
), stmt
);
5493 else if (gimple_assign_load_p (stmt
)
5494 && TREE_CODE (lhs_type
) == INTEGER_TYPE
5495 && TYPE_MODE (lhs_type
) == TYPE_MODE (char_type_node
)
5496 && (TYPE_PRECISION (lhs_type
)
5497 == TYPE_PRECISION (char_type_node
))
5498 && !gimple_has_volatile_ops (stmt
))
5500 tree off
= integer_zero_node
;
5501 unsigned HOST_WIDE_INT coff
= 0;
5503 tree rhs1
= gimple_assign_rhs1 (stmt
);
5504 if (code
== MEM_REF
)
5506 idx
= get_stridx (TREE_OPERAND (rhs1
, 0), stmt
);
5509 strinfo
*si
= get_strinfo (idx
);
5511 && si
->nonzero_chars
5512 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
5513 && (wi::to_widest (si
->nonzero_chars
)
5514 >= wi::to_widest (off
)))
5515 off
= TREE_OPERAND (rhs1
, 1);
5517 /* This case is not useful. See if get_addr_stridx
5518 returns something usable. */
5523 idx
= get_addr_stridx (rhs1
, stmt
, NULL_TREE
, &coff
);
5526 strinfo
*si
= get_strinfo (idx
);
5528 && si
->nonzero_chars
5529 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
5531 widest_int w1
= wi::to_widest (si
->nonzero_chars
);
5532 widest_int w2
= wi::to_widest (off
) + coff
;
5534 && si
->full_string_p
)
5536 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5538 fprintf (dump_file
, "Optimizing: ");
5539 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5542 /* Reading the final '\0' character. */
5543 tree zero
= build_int_cst (lhs_type
, 0);
5544 gimple_set_vuse (stmt
, NULL_TREE
);
5545 gimple_assign_set_rhs_from_tree (&m_gsi
, zero
);
5547 |= maybe_clean_or_replace_eh_stmt (stmt
,
5549 stmt
= gsi_stmt (m_gsi
);
5552 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5554 fprintf (dump_file
, "into: ");
5555 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5560 /* Reading a character before the final '\0'
5561 character. Just set the value range to ~[0, 0]
5562 if we don't have anything better. */
5564 if (!get_range_query (cfun
)->range_of_expr (r
, lhs
)
5567 r
.set_nonzero (lhs_type
);
5568 set_range_info (lhs
, r
);
5574 else if (code
== MEM_REF
&& TREE_CODE (lhs
) == SSA_NAME
)
5576 if (int idx
= new_stridx (lhs
))
5578 /* Record multi-byte assignments from MEM_REFs. */
5579 bool storing_all_nonzero_p
;
5580 bool storing_all_zeros_p
;
5582 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
5583 tree rhs
= gimple_assign_rhs1 (stmt
);
5584 const bool ranges_valid
5585 = count_nonzero_bytes (rhs
, stmt
,
5586 lenrange
, &full_string_p
,
5587 &storing_all_zeros_p
,
5588 &storing_all_nonzero_p
);
5591 tree length
= build_int_cst (sizetype
, lenrange
[0]);
5592 strinfo
*si
= new_strinfo (lhs
, idx
, length
, full_string_p
);
5593 set_strinfo (idx
, si
);
5594 si
->writable
= true;
5595 si
->dont_invalidate
= true;
5600 if (strlen_to_stridx
)
5602 tree rhs1
= gimple_assign_rhs1 (stmt
);
5603 if (stridx_strlenloc
*ps
= strlen_to_stridx
->get (rhs1
))
5604 strlen_to_stridx
->put (lhs
, stridx_strlenloc (*ps
));
5608 /* Handle assignment statement at *GSI to LHS. Set *ZERO_WRITE if
5609 the assignment stores all zero bytes. */
5612 strlen_pass::handle_assign (tree lhs
, bool *zero_write
)
5614 tree type
= TREE_TYPE (lhs
);
5615 if (TREE_CODE (type
) == ARRAY_TYPE
)
5616 type
= TREE_TYPE (type
);
5618 bool is_char_store
= is_char_type (type
);
5619 if (!is_char_store
&& TREE_CODE (lhs
) == MEM_REF
)
5621 /* To consider stores into char objects via integer types other
5622 than char but not those to non-character objects, determine
5623 the type of the destination rather than just the type of
5625 for (int i
= 0; i
!= 2; ++i
)
5627 tree ref
= TREE_OPERAND (lhs
, i
);
5628 type
= TREE_TYPE (ref
);
5629 if (TREE_CODE (type
) == POINTER_TYPE
)
5630 type
= TREE_TYPE (type
);
5631 if (TREE_CODE (type
) == ARRAY_TYPE
)
5632 type
= TREE_TYPE (type
);
5633 if (is_char_type (type
))
5635 is_char_store
= true;
5641 /* Handle a single or multibyte assignment. */
5642 if (is_char_store
&& !handle_store (zero_write
))
5649 /* Attempt to check for validity of the performed access a single statement
5650 at *GSI using string length knowledge, and to optimize it.
5651 If the given basic block needs clean-up of EH, CLEANUP_EH is set to
5652 true. Return true to let the caller advance *GSI to the next statement
5653 in the basic block and false otherwise. */
5656 strlen_pass::check_and_optimize_stmt (bool *cleanup_eh
)
5658 gimple
*stmt
= gsi_stmt (m_gsi
);
5660 /* For statements that modify a string, set to true if the write
5662 bool zero_write
= false;
5664 if (is_gimple_call (stmt
))
5666 if (!check_and_optimize_call (&zero_write
))
5669 else if (!flag_optimize_strlen
|| !strlen_optimize
)
5671 else if (is_gimple_assign (stmt
) && !gimple_clobber_p (stmt
))
5673 /* Handle non-clobbering assignment. */
5674 tree lhs
= gimple_assign_lhs (stmt
);
5675 tree lhs_type
= TREE_TYPE (lhs
);
5677 if (TREE_CODE (lhs
) == SSA_NAME
&& POINTER_TYPE_P (lhs_type
))
5679 if (gimple_assign_single_p (stmt
)
5680 || (gimple_assign_cast_p (stmt
)
5681 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt
)))))
5683 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
5684 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = idx
;
5686 else if (gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
5687 handle_pointer_plus ();
5689 else if (TREE_CODE (lhs
) == SSA_NAME
&& INTEGRAL_TYPE_P (lhs_type
))
5690 /* Handle assignment to a character. */
5691 handle_integral_assign (cleanup_eh
);
5692 else if (TREE_CODE (lhs
) != SSA_NAME
&& !TREE_SIDE_EFFECTS (lhs
))
5693 if (!handle_assign (lhs
, &zero_write
))
5696 else if (gcond
*cond
= dyn_cast
<gcond
*> (stmt
))
5698 enum tree_code code
= gimple_cond_code (cond
);
5699 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5700 fold_strstr_to_strncmp (gimple_cond_lhs (stmt
),
5701 gimple_cond_rhs (stmt
), stmt
);
5704 if (gimple_vdef (stmt
))
5705 maybe_invalidate (stmt
, zero_write
);
5709 /* Recursively call maybe_invalidate on stmts that might be executed
5710 in between dombb and current bb and that contain a vdef. Stop when
5711 *count stmts are inspected, or if the whole strinfo vector has
5712 been invalidated. */
5715 do_invalidate (basic_block dombb
, gimple
*phi
, bitmap visited
, int *count
)
5717 unsigned int i
, n
= gimple_phi_num_args (phi
);
5719 for (i
= 0; i
< n
; i
++)
5721 tree vuse
= gimple_phi_arg_def (phi
, i
);
5722 gimple
*stmt
= SSA_NAME_DEF_STMT (vuse
);
5723 basic_block bb
= gimple_bb (stmt
);
5726 || !bitmap_set_bit (visited
, bb
->index
)
5727 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5731 if (gimple_code (stmt
) == GIMPLE_PHI
)
5733 do_invalidate (dombb
, stmt
, visited
, count
);
5740 if (!maybe_invalidate (stmt
))
5745 vuse
= gimple_vuse (stmt
);
5746 stmt
= SSA_NAME_DEF_STMT (vuse
);
5747 if (gimple_bb (stmt
) != bb
)
5749 bb
= gimple_bb (stmt
);
5752 || !bitmap_set_bit (visited
, bb
->index
)
5753 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5760 /* Release pointer_query cache. */
5762 strlen_pass::~strlen_pass ()
5764 ptr_qry
.flush_cache ();
5767 /* Callback for walk_dominator_tree. Attempt to optimize various
5768 string ops by remembering string lengths pointed by pointer SSA_NAMEs. */
5771 strlen_pass::before_dom_children (basic_block bb
)
5773 basic_block dombb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
5776 stridx_to_strinfo
= NULL
;
5779 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) dombb
->aux
);
5780 if (stridx_to_strinfo
)
5782 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5785 gphi
*phi
= gsi
.phi ();
5786 if (virtual_operand_p (gimple_phi_result (phi
)))
5788 bitmap visited
= BITMAP_ALLOC (NULL
);
5789 int count_vdef
= 100;
5790 do_invalidate (dombb
, phi
, visited
, &count_vdef
);
5791 BITMAP_FREE (visited
);
5792 if (count_vdef
== 0)
5794 /* If there were too many vdefs in between immediate
5795 dominator and current bb, invalidate everything.
5796 If stridx_to_strinfo has been unshared, we need
5797 to free it, otherwise just set it to NULL. */
5798 if (!strinfo_shared ())
5804 vec_safe_iterate (stridx_to_strinfo
, i
, &si
);
5808 (*stridx_to_strinfo
)[i
] = NULL
;
5812 stridx_to_strinfo
= NULL
;
5820 /* If all PHI arguments have the same string index, the PHI result
5822 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5825 gphi
*phi
= gsi
.phi ();
5826 tree result
= gimple_phi_result (phi
);
5827 if (!virtual_operand_p (result
) && POINTER_TYPE_P (TREE_TYPE (result
)))
5829 int idx
= get_stridx (gimple_phi_arg_def (phi
, 0), phi
);
5832 unsigned int i
, n
= gimple_phi_num_args (phi
);
5833 for (i
= 1; i
< n
; i
++)
5834 if (idx
!= get_stridx (gimple_phi_arg_def (phi
, i
), phi
))
5837 ssa_ver_to_stridx
[SSA_NAME_VERSION (result
)] = idx
;
5842 bool cleanup_eh
= false;
5844 /* Attempt to optimize individual statements. */
5845 for (m_gsi
= gsi_start_bb (bb
); !gsi_end_p (m_gsi
); )
5847 /* Reset search depth performance counter. */
5850 if (check_and_optimize_stmt (&cleanup_eh
))
5854 if (cleanup_eh
&& gimple_purge_dead_eh_edges (bb
))
5855 m_cleanup_cfg
= true;
5857 bb
->aux
= stridx_to_strinfo
;
5858 if (vec_safe_length (stridx_to_strinfo
) && !strinfo_shared ())
5859 (*stridx_to_strinfo
)[0] = (strinfo
*) bb
;
5863 /* Callback for walk_dominator_tree. Free strinfo vector if it is
5864 owned by the current bb, clear bb->aux. */
5867 strlen_pass::after_dom_children (basic_block bb
)
5871 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) bb
->aux
);
5872 if (vec_safe_length (stridx_to_strinfo
)
5873 && (*stridx_to_strinfo
)[0] == (strinfo
*) bb
)
5878 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
5880 vec_free (stridx_to_strinfo
);
5889 printf_strlen_execute (function
*fun
, bool warn_only
)
5891 strlen_optimize
= !warn_only
;
5893 calculate_dominance_info (CDI_DOMINATORS
);
5894 loop_optimizer_init (LOOPS_NORMAL
);
5897 gcc_assert (!strlen_to_stridx
);
5898 if (warn_stringop_overflow
|| warn_stringop_truncation
)
5899 strlen_to_stridx
= new hash_map
<tree
, stridx_strlenloc
> ();
5901 /* This has to happen after initializing the loop optimizer
5902 and initializing SCEV as they create new SSA_NAMEs. */
5903 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
5906 /* String length optimization is implemented as a walk of the dominator
5907 tree and a forward walk of statements within each block. */
5908 strlen_pass
walker (CDI_DOMINATORS
);
5909 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));
5911 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5912 walker
.ptr_qry
.dump (dump_file
, true);
5914 ssa_ver_to_stridx
.release ();
5915 strinfo_pool
.release ();
5916 if (decl_to_stridxlist_htab
)
5918 obstack_free (&stridx_obstack
, NULL
);
5919 delete decl_to_stridxlist_htab
;
5920 decl_to_stridxlist_htab
= NULL
;
5922 laststmt
.stmt
= NULL
;
5923 laststmt
.len
= NULL_TREE
;
5924 laststmt
.stridx
= 0;
5926 if (strlen_to_stridx
)
5928 strlen_to_stridx
->empty ();
5929 delete strlen_to_stridx
;
5930 strlen_to_stridx
= NULL
;
5934 loop_optimizer_finalize ();
5936 return walker
.m_cleanup_cfg
? TODO_cleanup_cfg
: 0;
5939 /* This file defines two passes: one for warnings that runs only when
5940 optimization is disabled, and another that implements optimizations
5941 and also issues warnings. */
5943 const pass_data pass_data_warn_printf
=
5945 GIMPLE_PASS
, /* type */
5946 "warn-printf", /* name */
5947 OPTGROUP_NONE
, /* optinfo_flags */
5948 TV_NONE
, /* tv_id */
5949 /* Normally an optimization pass would require PROP_ssa but because
5950 this pass runs early, with no optimization, to do sprintf format
5951 checking, it only requires PROP_cfg. */
5952 PROP_cfg
, /* properties_required */
5953 0, /* properties_provided */
5954 0, /* properties_destroyed */
5955 0, /* todo_flags_start */
5956 0, /* todo_flags_finish */
5959 class pass_warn_printf
: public gimple_opt_pass
5962 pass_warn_printf (gcc::context
*ctxt
)
5963 : gimple_opt_pass (pass_data_warn_printf
, ctxt
)
5966 bool gate (function
*) final override
;
5967 unsigned int execute (function
*fun
) final override
5969 return printf_strlen_execute (fun
, true);
5974 /* Return true to run the warning pass only when not optimizing and
5975 iff either -Wformat-overflow or -Wformat-truncation is specified. */
5978 pass_warn_printf::gate (function
*)
5980 return !optimize
&& (warn_format_overflow
> 0 || warn_format_trunc
> 0);
5983 const pass_data pass_data_strlen
=
5985 GIMPLE_PASS
, /* type */
5986 "strlen", /* name */
5987 OPTGROUP_NONE
, /* optinfo_flags */
5988 TV_TREE_STRLEN
, /* tv_id */
5989 PROP_cfg
| PROP_ssa
, /* properties_required */
5990 0, /* properties_provided */
5991 0, /* properties_destroyed */
5992 0, /* todo_flags_start */
5993 0, /* todo_flags_finish */
5996 class pass_strlen
: public gimple_opt_pass
5999 pass_strlen (gcc::context
*ctxt
)
6000 : gimple_opt_pass (pass_data_strlen
, ctxt
)
6003 opt_pass
* clone () final override
{ return new pass_strlen (m_ctxt
); }
6005 bool gate (function
*) final override
;
6006 unsigned int execute (function
*fun
) final override
6008 return printf_strlen_execute (fun
, false);
6012 /* Return true to run the pass only when the sprintf and/or strlen
6013 optimizations are enabled and -Wformat-overflow or -Wformat-truncation
6017 pass_strlen::gate (function
*)
6019 return ((warn_format_overflow
> 0
6020 || warn_format_trunc
> 0
6021 || warn_restrict
> 0
6022 || flag_optimize_strlen
> 0
6023 || flag_printf_return_value
)
6030 make_pass_warn_printf (gcc::context
*ctxt
)
6032 return new pass_warn_printf (ctxt
);
6036 make_pass_strlen (gcc::context
*ctxt
)
6038 return new pass_strlen (ctxt
);