1 /* String length optimization
2 Copyright (C) 2011-2021 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-fold.h"
40 #include "gimple-iterator.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
*s
, c_strlen_data
*,
197 bitmap
, range_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
),
239 ptr_qry (&m_ranger
, &var_cache
),
241 m_cleanup_cfg (false)
247 virtual edge
before_dom_children (basic_block
);
248 virtual void after_dom_children (basic_block
);
250 bool check_and_optimize_stmt (bool *cleanup_eh
);
251 bool check_and_optimize_call (bool *zero_write
);
252 bool handle_assign (tree lhs
, bool *zero_write
);
253 bool handle_store (bool *zero_write
);
254 void handle_pointer_plus ();
255 void handle_builtin_strlen ();
256 void handle_builtin_strchr ();
257 void handle_builtin_strcpy (built_in_function
);
258 void handle_integral_assign (bool *cleanup_eh
);
259 void handle_builtin_stxncpy_strncat (bool append_p
);
260 void handle_builtin_memcpy (built_in_function bcode
);
261 void handle_builtin_strcat (built_in_function bcode
);
262 void handle_builtin_strncat (built_in_function
);
263 bool handle_builtin_memset (bool *zero_write
);
264 bool handle_builtin_memcmp ();
265 bool handle_builtin_string_cmp ();
266 void handle_alloc_call (built_in_function
);
267 void maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, tree len
,
268 strinfo
*si
= NULL
, bool plus_one
= false,
269 bool rawmem
= false);
270 void maybe_warn_overflow (gimple
*stmt
, bool call_lhs
,
271 unsigned HOST_WIDE_INT len
,
273 bool plus_one
= false, bool rawmem
= false);
274 void adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
);
275 tree
strxcmp_eqz_result (gimple
*stmt
, tree arg1
, int idx1
,
277 unsigned HOST_WIDE_INT bound
,
278 unsigned HOST_WIDE_INT len
[2],
279 unsigned HOST_WIDE_INT
*psize
);
280 bool count_nonzero_bytes (tree expr_or_type
,
282 unsigned lenrange
[3], bool *nulterm
,
283 bool *allnul
, bool *allnonnul
);
284 bool count_nonzero_bytes (tree exp
,
286 unsigned HOST_WIDE_INT offset
,
287 unsigned HOST_WIDE_INT nbytes
,
288 unsigned lenrange
[3], bool *nulterm
,
289 bool *allnul
, bool *allnonnul
,
290 ssa_name_limit_t
&snlim
);
291 bool count_nonzero_bytes_addr (tree exp
,
293 unsigned HOST_WIDE_INT offset
,
294 unsigned HOST_WIDE_INT nbytes
,
295 unsigned lenrange
[3], bool *nulterm
,
296 bool *allnul
, bool *allnonnul
,
297 ssa_name_limit_t
&snlim
);
298 bool get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
299 unsigned HOST_WIDE_INT lenrng
[2],
300 unsigned HOST_WIDE_INT
*size
, bool *nulterm
);
302 gimple_ranger m_ranger
;
304 /* A pointer_query object and its cache to store information about
305 pointers and their targets in. */
306 pointer_query ptr_qry
;
307 pointer_query::cache_type var_cache
;
309 gimple_stmt_iterator m_gsi
;
311 /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
318 * +1 if SI is known to start with more than OFF nonzero characters.
320 * 0 if SI is known to start with exactly OFF nonzero characters.
322 * -1 if SI either does not start with OFF nonzero characters
323 or the relationship between the number of leading nonzero
324 characters in SI and OFF is unknown. */
327 compare_nonzero_chars (strinfo
*si
, unsigned HOST_WIDE_INT off
)
329 if (si
->nonzero_chars
330 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
331 return compare_tree_int (si
->nonzero_chars
, off
);
336 /* Same as above but suitable also for strings with non-constant lengths.
337 Uses RVALS to determine length range. */
340 compare_nonzero_chars (strinfo
*si
, gimple
*stmt
,
341 unsigned HOST_WIDE_INT off
,
344 if (!si
->nonzero_chars
)
347 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
348 return compare_tree_int (si
->nonzero_chars
, off
);
350 if (!rvals
|| TREE_CODE (si
->nonzero_chars
) != SSA_NAME
)
354 if (!rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
))
356 value_range_kind rng
= vr
.kind ();
360 /* If the offset is less than the minimum length or if the bounds
361 of the length range are equal return the result of the comparison
362 same as in the constant case. Otherwise return a conservative
364 int cmpmin
= compare_tree_int (vr
.min (), off
);
365 if (cmpmin
> 0 || tree_int_cst_equal (vr
.min (), vr
.max ()))
371 /* Return true if SI is known to be a zero-length string. */
374 zero_length_string_p (strinfo
*si
)
376 return si
->full_string_p
&& integer_zerop (si
->nonzero_chars
);
379 /* Return strinfo vector entry IDX. */
381 static inline strinfo
*
382 get_strinfo (int idx
)
384 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
386 return (*stridx_to_strinfo
)[idx
];
389 /* Get the next strinfo in the chain after SI, or null if none. */
391 static inline strinfo
*
392 get_next_strinfo (strinfo
*si
)
396 strinfo
*nextsi
= get_strinfo (si
->next
);
397 if (nextsi
== NULL
|| nextsi
->first
!= si
->first
|| nextsi
->prev
!= si
->idx
)
402 /* Helper function for get_stridx. Return the strinfo index of the address
403 of EXP, which is available in PTR if nonnull. If OFFSET_OUT, it is
404 OK to return the index for some X <= &EXP and store &EXP - X in
405 *OFFSET_OUT. When RVALS is nonnull uses it to determine range
409 get_addr_stridx (tree exp
, gimple
*stmt
,
410 tree ptr
, unsigned HOST_WIDE_INT
*offset_out
,
411 range_query
*rvals
= NULL
)
414 struct stridxlist
*list
, *last
= NULL
;
417 if (!decl_to_stridxlist_htab
)
421 base
= get_addr_base_and_unit_offset (exp
, &poff
);
422 if (base
== NULL
|| !DECL_P (base
) || !poff
.is_constant (&off
))
425 list
= decl_to_stridxlist_htab
->get (base
);
431 if (list
->offset
== off
)
437 if (list
->offset
> off
)
444 if ((offset_out
|| ptr
) && last
&& last
->idx
> 0)
446 unsigned HOST_WIDE_INT rel_off
447 = (unsigned HOST_WIDE_INT
) off
- last
->offset
;
448 strinfo
*si
= get_strinfo (last
->idx
);
449 if (si
&& compare_nonzero_chars (si
, stmt
, rel_off
, rvals
) >= 0)
453 *offset_out
= rel_off
;
457 return get_stridx_plus_constant (si
, rel_off
, ptr
);
463 /* Returns string index for EXP. When EXP is an SSA_NAME that refers
464 to a known strinfo with an offset and OFFRNG is non-null, sets
465 both elements of the OFFRNG array to the range of the offset and
466 returns the index of the known strinfo. In this case the result
467 must not be used in for functions that modify the string.
468 When nonnull, uses RVALS to determine range information. */
471 get_stridx (tree exp
, gimple
*stmt
,
472 wide_int offrng
[2] = NULL
, range_query
*rvals
= NULL
)
475 offrng
[0] = offrng
[1] = wi::zero (TYPE_PRECISION (ptrdiff_type_node
));
477 if (TREE_CODE (exp
) == SSA_NAME
)
479 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)])
480 return ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)];
484 HOST_WIDE_INT offset
= 0;
485 /* Follow a chain of at most 5 assignments. */
486 for (int i
= 0; i
< 5; i
++)
488 gimple
*def_stmt
= SSA_NAME_DEF_STMT (e
);
489 if (!is_gimple_assign (def_stmt
))
492 tree_code rhs_code
= gimple_assign_rhs_code (def_stmt
);
495 if (rhs_code
== ADDR_EXPR
)
497 /* Handle indices/offsets into VLAs which are implemented
498 as pointers to arrays. */
499 ptr
= gimple_assign_rhs1 (def_stmt
);
500 ptr
= TREE_OPERAND (ptr
, 0);
502 /* Handle also VLAs of types larger than char. */
503 if (tree eltsize
= TYPE_SIZE_UNIT (TREE_TYPE (ptr
)))
505 if (TREE_CODE (ptr
) == ARRAY_REF
)
507 off
= TREE_OPERAND (ptr
, 1);
508 ptr
= TREE_OPERAND (ptr
, 0);
509 if (!integer_onep (eltsize
))
511 /* Scale the array index by the size of the element
512 type in the rare case that it's greater than
513 the typical 1 for char, making sure both operands
514 have the same type. */
515 eltsize
= fold_convert (ssizetype
, eltsize
);
516 off
= fold_convert (ssizetype
, off
);
517 off
= fold_build2 (MULT_EXPR
, ssizetype
, off
, eltsize
);
521 off
= integer_zero_node
;
526 if (TREE_CODE (ptr
) != MEM_REF
)
529 /* Add the MEM_REF byte offset. */
530 tree mem_off
= TREE_OPERAND (ptr
, 1);
531 off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (off
), off
, mem_off
);
532 ptr
= TREE_OPERAND (ptr
, 0);
534 else if (rhs_code
== POINTER_PLUS_EXPR
)
536 ptr
= gimple_assign_rhs1 (def_stmt
);
537 off
= gimple_assign_rhs2 (def_stmt
);
542 if (TREE_CODE (ptr
) != SSA_NAME
)
545 if (!tree_fits_shwi_p (off
))
547 if (int idx
= ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)])
550 /* Only when requested by setting OFFRNG to non-null,
551 return the index corresponding to the SSA_NAME.
552 Do this irrespective of the whether the offset
554 if (get_range (off
, def_stmt
, offrng
, rvals
))
556 /* When the offset range is known, increment it
557 it by the constant offset computed in prior
558 iterations and store it in the OFFRNG array. */
564 /* When the offset range cannot be determined
565 store [0, SIZE_MAX] and let the caller decide
566 if the offset matters. */
567 offrng
[1] = wi::to_wide (TYPE_MAX_VALUE (sizetype
));
568 offrng
[0] = wi::zero (offrng
[1].get_precision ());
575 HOST_WIDE_INT this_off
= tree_to_shwi (off
);
578 offrng
[0] += wi::shwi (this_off
, offrng
->get_precision ());
579 offrng
[1] += offrng
[0];
585 offset
= (unsigned HOST_WIDE_INT
) offset
+ this_off
;
589 if (int idx
= ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)])
591 strinfo
*si
= get_strinfo (idx
);
594 if (compare_nonzero_chars (si
, offset
) >= 0)
595 return get_stridx_plus_constant (si
, offset
, exp
);
607 if (TREE_CODE (exp
) == ADDR_EXPR
)
609 int idx
= get_addr_stridx (TREE_OPERAND (exp
, 0), stmt
, exp
, NULL
);
614 const char *p
= c_getstr (exp
);
616 return ~(int) strlen (p
);
621 /* Return true if strinfo vector is shared with the immediate dominator. */
624 strinfo_shared (void)
626 return vec_safe_length (stridx_to_strinfo
)
627 && (*stridx_to_strinfo
)[0] != NULL
;
630 /* Unshare strinfo vector that is shared with the immediate dominator. */
633 unshare_strinfo_vec (void)
638 gcc_assert (strinfo_shared ());
639 stridx_to_strinfo
= vec_safe_copy (stridx_to_strinfo
);
640 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
643 (*stridx_to_strinfo
)[0] = NULL
;
646 /* Attempt to create a string index for exp, ADDR_EXPR's operand.
647 Return a pointer to the location where the string index can
648 be stored (if 0) or is stored, or NULL if this can't be tracked. */
651 addr_stridxptr (tree exp
)
656 tree base
= get_addr_base_and_unit_offset (exp
, &poff
);
657 if (base
== NULL_TREE
|| !DECL_P (base
) || !poff
.is_constant (&off
))
660 if (!decl_to_stridxlist_htab
)
662 decl_to_stridxlist_htab
663 = new hash_map
<tree_decl_hash
, stridxlist
> (64);
664 gcc_obstack_init (&stridx_obstack
);
668 stridxlist
*list
= &decl_to_stridxlist_htab
->get_or_insert (base
, &existed
);
672 stridxlist
*before
= NULL
;
673 for (i
= 0; i
< 32; i
++)
675 if (list
->offset
== off
)
677 if (list
->offset
> off
&& before
== NULL
)
679 if (list
->next
== NULL
)
688 before
= XOBNEW (&stridx_obstack
, struct stridxlist
);
695 list
->next
= XOBNEW (&stridx_obstack
, struct stridxlist
);
705 /* Create a new string index, or return 0 if reached limit. */
708 new_stridx (tree exp
)
711 if (max_stridx
>= param_max_tracked_strlens
)
713 if (TREE_CODE (exp
) == SSA_NAME
)
715 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp
))
718 ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)] = idx
;
721 if (TREE_CODE (exp
) == ADDR_EXPR
)
723 int *pidx
= addr_stridxptr (TREE_OPERAND (exp
, 0));
726 gcc_assert (*pidx
== 0);
727 *pidx
= max_stridx
++;
734 /* Like new_stridx, but for ADDR_EXPR's operand instead. */
737 new_addr_stridx (tree exp
)
740 if (max_stridx
>= param_max_tracked_strlens
)
742 pidx
= addr_stridxptr (exp
);
745 gcc_assert (*pidx
== 0);
746 *pidx
= max_stridx
++;
752 /* Create a new strinfo. */
755 new_strinfo (tree ptr
, int idx
, tree nonzero_chars
, bool full_string_p
)
757 strinfo
*si
= strinfo_pool
.allocate ();
758 si
->nonzero_chars
= nonzero_chars
;
759 STRIP_USELESS_TYPE_CONVERSION (ptr
);
763 si
->endptr
= NULL_TREE
;
769 si
->writable
= false;
770 si
->dont_invalidate
= false;
771 si
->full_string_p
= full_string_p
;
775 /* Decrease strinfo refcount and free it if not referenced anymore. */
778 free_strinfo (strinfo
*si
)
780 if (si
&& --si
->refcount
== 0)
781 strinfo_pool
.remove (si
);
784 /* Set strinfo in the vector entry IDX to SI. */
787 set_strinfo (int idx
, strinfo
*si
)
789 if (vec_safe_length (stridx_to_strinfo
) && (*stridx_to_strinfo
)[0])
790 unshare_strinfo_vec ();
791 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
792 vec_safe_grow_cleared (stridx_to_strinfo
, idx
+ 1, true);
793 (*stridx_to_strinfo
)[idx
] = si
;
796 /* Return the first strinfo in the related strinfo chain
797 if all strinfos in between belong to the chain, otherwise NULL. */
800 verify_related_strinfos (strinfo
*origsi
)
802 strinfo
*si
= origsi
, *psi
;
804 if (origsi
->first
== 0)
806 for (; si
->prev
; si
= psi
)
808 if (si
->first
!= origsi
->first
)
810 psi
= get_strinfo (si
->prev
);
813 if (psi
->next
!= si
->idx
)
816 if (si
->idx
!= si
->first
)
821 /* Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
822 Use LOC for folding. */
825 set_endptr_and_length (location_t loc
, strinfo
*si
, tree endptr
)
829 tree start_as_size
= fold_convert_loc (loc
, size_type_node
, si
->ptr
);
830 tree end_as_size
= fold_convert_loc (loc
, size_type_node
, endptr
);
831 si
->nonzero_chars
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
832 end_as_size
, start_as_size
);
833 si
->full_string_p
= true;
836 /* Return the string length, or NULL if it can't be computed.
837 The length may but need not be constant. Instead, it might be
838 the result of a strlen() call. */
841 get_string_length (strinfo
*si
)
843 /* If the length has already been computed return it if it's exact
844 (i.e., the string is nul-terminated at NONZERO_CHARS), or return
846 if (si
->nonzero_chars
)
847 return si
->full_string_p
? si
->nonzero_chars
: NULL
;
849 /* If the string is the result of one of the built-in calls below
850 attempt to compute the length from the call statement. */
853 gimple
*stmt
= si
->stmt
, *lenstmt
;
854 tree callee
, lhs
, fn
, tem
;
856 gimple_stmt_iterator gsi
;
858 gcc_assert (is_gimple_call (stmt
));
859 callee
= gimple_call_fndecl (stmt
);
860 gcc_assert (callee
&& fndecl_built_in_p (callee
, BUILT_IN_NORMAL
));
861 lhs
= gimple_call_lhs (stmt
);
862 /* unshare_strinfo is intentionally not called here. The (delayed)
863 transformation of strcpy or strcat into stpcpy is done at the place
864 of the former strcpy/strcat call and so can affect all the strinfos
865 with the same stmt. If they were unshared before and transformation
866 has been already done, the handling of BUILT_IN_STPCPY{,_CHK} should
867 just compute the right length. */
868 switch (DECL_FUNCTION_CODE (callee
))
870 case BUILT_IN_STRCAT
:
871 case BUILT_IN_STRCAT_CHK
:
872 gsi
= gsi_for_stmt (stmt
);
873 fn
= builtin_decl_implicit (BUILT_IN_STRLEN
);
874 gcc_assert (lhs
== NULL_TREE
);
875 tem
= unshare_expr (gimple_call_arg (stmt
, 0));
876 lenstmt
= gimple_build_call (fn
, 1, tem
);
877 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), lenstmt
);
878 gimple_call_set_lhs (lenstmt
, lhs
);
879 gimple_set_vuse (lenstmt
, gimple_vuse (stmt
));
880 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
881 tem
= gimple_call_arg (stmt
, 0);
882 if (!ptrofftype_p (TREE_TYPE (lhs
)))
884 lhs
= convert_to_ptrofftype (lhs
);
885 lhs
= force_gimple_operand_gsi (&gsi
, lhs
, true, NULL_TREE
,
886 true, GSI_SAME_STMT
);
888 lenstmt
= gimple_build_assign
889 (make_ssa_name (TREE_TYPE (gimple_call_arg (stmt
, 0))),
890 POINTER_PLUS_EXPR
,tem
, lhs
);
891 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
892 gimple_call_set_arg (stmt
, 0, gimple_assign_lhs (lenstmt
));
895 case BUILT_IN_STRCPY
:
896 case BUILT_IN_STRCPY_CHK
:
897 gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY
));
898 if (gimple_call_num_args (stmt
) == 2)
899 fn
= builtin_decl_implicit (BUILT_IN_STPCPY
);
901 fn
= builtin_decl_explicit (BUILT_IN_STPCPY_CHK
);
902 gcc_assert (lhs
== NULL_TREE
);
903 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
905 fprintf (dump_file
, "Optimizing: ");
906 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
908 gimple_call_set_fndecl (stmt
, fn
);
909 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), stmt
);
910 gimple_call_set_lhs (stmt
, lhs
);
912 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
914 fprintf (dump_file
, "into: ");
915 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
918 case BUILT_IN_STPCPY
:
919 case BUILT_IN_STPCPY_CHK
:
920 gcc_assert (lhs
!= NULL_TREE
);
921 loc
= gimple_location (stmt
);
922 set_endptr_and_length (loc
, si
, lhs
);
923 for (strinfo
*chainsi
= verify_related_strinfos (si
);
925 chainsi
= get_next_strinfo (chainsi
))
926 if (chainsi
->nonzero_chars
== NULL
)
927 set_endptr_and_length (loc
, chainsi
, lhs
);
929 case BUILT_IN_ALLOCA
:
930 case BUILT_IN_ALLOCA_WITH_ALIGN
:
931 case BUILT_IN_MALLOC
:
933 /* BUILT_IN_CALLOC always has si->nonzero_chars set. */
940 return si
->nonzero_chars
;
943 /* Dump strlen data to FP for statement STMT. When non-null, RVALS
944 points to the valuation engine used to calculate ranges, and is
945 used to dump strlen range for non-constant results. */
948 dump_strlen_info (FILE *fp
, gimple
*stmt
, range_query
*rvals
)
952 fprintf (fp
, "\nDumping strlen pass data after ");
953 print_gimple_expr (fp
, stmt
, TDF_LINENO
);
957 fprintf (fp
, "\nDumping strlen pass data\n");
959 fprintf (fp
, "max_stridx = %i\n", max_stridx
);
960 fprintf (fp
, "ssa_ver_to_stridx has %u elements\n",
961 ssa_ver_to_stridx
.length ());
962 fprintf (fp
, "stridx_to_strinfo");
963 if (stridx_to_strinfo
)
965 fprintf (fp
, " has %u elements\n", stridx_to_strinfo
->length ());
966 for (unsigned i
= 0; i
!= stridx_to_strinfo
->length (); ++i
)
968 if (strinfo
*si
= (*stridx_to_strinfo
)[i
])
972 fprintf (fp
, " idx = %i", si
->idx
);
975 fprintf (fp
, ", ptr = ");
976 print_generic_expr (fp
, si
->ptr
);
979 if (si
->nonzero_chars
)
981 fprintf (fp
, ", nonzero_chars = ");
982 print_generic_expr (fp
, si
->nonzero_chars
);
983 if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
985 value_range_kind rng
= VR_UNDEFINED
;
990 rvals
->range_of_expr (vr
, si
->nonzero_chars
,
993 if (range_int_cst_p (&vr
))
995 min
= wi::to_wide (vr
.min ());
996 max
= wi::to_wide (vr
.max ());
1004 get_range_query (cfun
)
1005 ->range_of_expr (vr
, si
->nonzero_chars
);
1007 if (!vr
.undefined_p ())
1009 min
= wi::to_wide (vr
.min ());
1010 max
= wi::to_wide (vr
.max ());
1014 if (rng
== VR_RANGE
|| rng
== VR_ANTI_RANGE
)
1016 fprintf (fp
, " %s[%llu, %llu]",
1017 rng
== VR_RANGE
? "" : "~",
1018 (long long) min
.to_uhwi (),
1019 (long long) max
.to_uhwi ());
1024 fprintf (fp
, ", refcount = %i", si
->refcount
);
1027 fprintf (fp
, ", stmt = ");
1028 print_gimple_expr (fp
, si
->stmt
, 0);
1032 fprintf (fp
, ", alloc = ");
1033 print_gimple_expr (fp
, si
->alloc
, 0);
1036 fprintf (fp
, ", writable");
1037 if (si
->dont_invalidate
)
1038 fprintf (fp
, ", dont_invalidate");
1039 if (si
->full_string_p
)
1040 fprintf (fp
, ", full_string_p");
1041 if (strinfo
*next
= get_next_strinfo (si
))
1043 fprintf (fp
, ", {");
1045 fprintf (fp
, "%i%s", next
->idx
, next
->first
? ", " : "");
1046 while ((next
= get_next_strinfo (next
)));
1054 fprintf (fp
, " = null\n");
1056 fprintf (fp
, "decl_to_stridxlist_htab");
1057 if (decl_to_stridxlist_htab
)
1060 typedef decl_to_stridxlist_htab_t::iterator iter_t
;
1061 for (iter_t it
= decl_to_stridxlist_htab
->begin ();
1062 it
!= decl_to_stridxlist_htab
->end (); ++it
)
1064 tree decl
= (*it
).first
;
1065 stridxlist
*list
= &(*it
).second
;
1066 fprintf (fp
, " decl = ");
1067 print_generic_expr (fp
, decl
);
1070 fprintf (fp
, ", offsets = {");
1071 for (; list
; list
= list
->next
)
1072 fprintf (fp
, "%lli%s", (long long) list
->offset
,
1073 list
->next
? ", " : "");
1080 fprintf (fp
, " = null\n");
1084 fprintf (fp
, "laststmt = ");
1085 print_gimple_expr (fp
, laststmt
.stmt
, 0);
1086 fprintf (fp
, ", len = ");
1087 print_generic_expr (fp
, laststmt
.len
);
1088 fprintf (fp
, ", stridx = %i\n", laststmt
.stridx
);
1092 /* Helper of get_range_strlen_dynamic(). See below. */
1095 get_range_strlen_phi (tree src
, gphi
*phi
,
1096 c_strlen_data
*pdata
, bitmap visited
,
1097 range_query
*rvals
, unsigned *pssa_def_max
)
1099 if (!bitmap_set_bit (visited
, SSA_NAME_VERSION (src
)))
1102 if (*pssa_def_max
== 0)
1107 /* Iterate over the PHI arguments and determine the minimum and maximum
1108 length/size of each and incorporate them into the overall result. */
1109 for (unsigned i
= 0; i
!= gimple_phi_num_args (phi
); ++i
)
1111 tree arg
= gimple_phi_arg_def (phi
, i
);
1112 if (arg
== gimple_phi_result (phi
))
1115 c_strlen_data argdata
= { };
1116 if (!get_range_strlen_dynamic (arg
, phi
, &argdata
, visited
, rvals
,
1119 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1123 /* Set the DECL of an unterminated array this argument refers to
1124 if one hasn't been found yet. */
1125 if (!pdata
->decl
&& argdata
.decl
)
1126 pdata
->decl
= argdata
.decl
;
1129 || (integer_zerop (argdata
.minlen
)
1130 && (!argdata
.maxbound
1131 || integer_all_onesp (argdata
.maxbound
))
1132 && integer_all_onesp (argdata
.maxlen
)))
1134 /* Set the upper bound of the length to unbounded. */
1135 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1139 /* Adjust the minimum and maximum length determined so far and
1140 the upper bound on the array size. */
1142 || tree_int_cst_lt (argdata
.minlen
, pdata
->minlen
))
1143 pdata
->minlen
= argdata
.minlen
;
1147 && TREE_CODE (argdata
.maxlen
) == INTEGER_CST
1148 && tree_int_cst_lt (pdata
->maxlen
, argdata
.maxlen
)))
1149 pdata
->maxlen
= argdata
.maxlen
;
1151 if (!pdata
->maxbound
1152 || TREE_CODE (pdata
->maxbound
) != INTEGER_CST
1153 || (argdata
.maxbound
1154 && tree_int_cst_lt (pdata
->maxbound
, argdata
.maxbound
)
1155 && !integer_all_onesp (argdata
.maxbound
)))
1156 pdata
->maxbound
= argdata
.maxbound
;
1162 /* Attempt to determine the length of the string SRC. On success, store
1163 the length in *PDATA and return true. Otherwise, return false.
1164 VISITED is a bitmap of visited PHI nodes. RVALS points to the valuation
1165 engine used to calculate ranges. PSSA_DEF_MAX to an SSA_NAME
1166 assignment limit used to prevent runaway recursion. */
1169 get_range_strlen_dynamic (tree src
, gimple
*stmt
,
1170 c_strlen_data
*pdata
, bitmap visited
,
1171 range_query
*rvals
, unsigned *pssa_def_max
)
1173 int idx
= get_stridx (src
, stmt
);
1176 if (TREE_CODE (src
) == SSA_NAME
)
1178 gimple
*def_stmt
= SSA_NAME_DEF_STMT (src
);
1179 if (gphi
*phi
= dyn_cast
<gphi
*>(def_stmt
))
1180 return get_range_strlen_phi (src
, phi
, pdata
, visited
, rvals
,
1184 /* Return success regardless of the result and handle *PDATA
1186 get_range_strlen (src
, pdata
, 1);
1192 /* SRC is a string of constant length. */
1193 pdata
->minlen
= build_int_cst (size_type_node
, ~idx
);
1194 pdata
->maxlen
= pdata
->minlen
;
1195 pdata
->maxbound
= pdata
->maxlen
;
1199 if (strinfo
*si
= get_strinfo (idx
))
1201 pdata
->minlen
= get_string_length (si
);
1202 if (!pdata
->minlen
&& si
->nonzero_chars
)
1204 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
1205 pdata
->minlen
= si
->nonzero_chars
;
1206 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
1209 rvals
->range_of_expr (vr
, si
->nonzero_chars
, si
->stmt
);
1210 if (range_int_cst_p (&vr
))
1212 pdata
->minlen
= vr
.min ();
1213 pdata
->maxlen
= vr
.max ();
1216 pdata
->minlen
= build_zero_cst (size_type_node
);
1219 pdata
->minlen
= build_zero_cst (size_type_node
);
1221 tree base
= si
->ptr
;
1222 if (TREE_CODE (base
) == ADDR_EXPR
)
1223 base
= TREE_OPERAND (base
, 0);
1227 base
= get_addr_base_and_unit_offset (base
, &poff
);
1230 && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
1231 && TYPE_SIZE_UNIT (TREE_TYPE (base
))
1232 && poff
.is_constant (&off
))
1234 tree basetype
= TREE_TYPE (base
);
1235 tree size
= TYPE_SIZE_UNIT (basetype
);
1236 if (TREE_CODE (size
) == INTEGER_CST
)
1238 ++off
; /* Increment for the terminating nul. */
1239 tree toffset
= build_int_cst (size_type_node
, off
);
1240 pdata
->maxlen
= fold_build2 (MINUS_EXPR
, size_type_node
, size
,
1242 pdata
->maxbound
= pdata
->maxlen
;
1245 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1248 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1250 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == SSA_NAME
)
1253 rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
);
1254 if (range_int_cst_p (&vr
))
1256 pdata
->minlen
= vr
.min ();
1257 pdata
->maxlen
= vr
.max ();
1258 pdata
->maxbound
= pdata
->maxlen
;
1262 pdata
->minlen
= build_zero_cst (size_type_node
);
1263 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1266 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == INTEGER_CST
)
1268 pdata
->maxlen
= pdata
->minlen
;
1269 pdata
->maxbound
= pdata
->minlen
;
1273 /* For PDATA->MINLEN that's a non-constant expression such
1274 as PLUS_EXPR whose value range is unknown, set the bounds
1275 to zero and SIZE_MAX. */
1276 pdata
->minlen
= build_zero_cst (size_type_node
);
1277 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1286 /* Analogous to get_range_strlen but for dynamically created strings,
1287 i.e., those created by calls to strcpy as opposed to just string
1289 Try to obtain the range of the lengths of the string(s) referenced
1290 by SRC, or the size of the largest array SRC refers to if the range
1291 of lengths cannot be determined, and store all in *PDATA. RVALS
1292 points to the valuation engine used to calculate ranges. */
1295 get_range_strlen_dynamic (tree src
, gimple
*stmt
, c_strlen_data
*pdata
,
1298 auto_bitmap visited
;
1299 tree maxbound
= pdata
->maxbound
;
1301 unsigned limit
= param_ssa_name_def_chain_limit
;
1302 if (!get_range_strlen_dynamic (src
, stmt
, pdata
, visited
, rvals
, &limit
))
1304 /* On failure extend the length range to an impossible maximum
1305 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1306 members can stay unchanged regardless. */
1307 pdata
->minlen
= ssize_int (0);
1308 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1310 else if (!pdata
->minlen
)
1311 pdata
->minlen
= ssize_int (0);
1313 /* If it's unchanged from it initial non-null value, set the conservative
1314 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1315 if (maxbound
&& pdata
->maxbound
== maxbound
)
1316 pdata
->maxbound
= build_all_ones_cst (size_type_node
);
1319 /* Invalidate string length information for strings whose length might
1320 change due to stores in STMT, except those marked DONT_INVALIDATE.
1321 For string-modifying statements, ZERO_WRITE is set when the statement
1323 Returns true if any STRIDX_TO_STRINFO entries were considered
1324 for invalidation. */
1327 maybe_invalidate (gimple
*stmt
, bool zero_write
= false)
1329 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1331 fprintf (dump_file
, "%s called for ", __func__
);
1332 print_gimple_stmt (dump_file
, stmt
, TDF_LINENO
);
1336 bool nonempty
= false;
1338 for (unsigned i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
1340 if (si
== NULL
|| !POINTER_TYPE_P (TREE_TYPE (si
->ptr
)))
1345 /* Unconditionally reset DONT_INVALIDATE. */
1346 bool dont_invalidate
= si
->dont_invalidate
;
1347 si
->dont_invalidate
= false;
1349 if (dont_invalidate
)
1353 tree size
= si
->nonzero_chars
;
1354 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, size
);
1355 /* Include the terminating nul in the size of the string
1356 to consider when determining possible clobber. But do not
1357 add it to 'size' since we don't know whether it would
1358 actually fit the allocated area. */
1359 if (known_size_p (r
.size
))
1361 if (known_le (r
.size
, HOST_WIDE_INT_MAX
- BITS_PER_UNIT
))
1362 r
.max_size
+= BITS_PER_UNIT
;
1366 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1368 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1370 fputs (" statement may clobber object ", dump_file
);
1371 print_generic_expr (dump_file
, si
->ptr
);
1372 if (size
&& tree_fits_uhwi_p (size
))
1373 fprintf (dump_file
, " " HOST_WIDE_INT_PRINT_UNSIGNED
1374 " bytes in size", tree_to_uhwi (size
));
1375 fputc ('\n', dump_file
);
1378 set_strinfo (i
, NULL
);
1386 && is_gimple_call (si
->stmt
)
1387 && (DECL_FUNCTION_CODE (gimple_call_fndecl (si
->stmt
))
1388 == BUILT_IN_CALLOC
))
1390 /* If the clobber test above considered the length of
1391 the string (including the nul), then for (potentially)
1392 non-zero writes that might modify storage allocated by
1393 calloc consider the whole object and if it might be
1394 clobbered by the statement reset the statement. */
1395 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, NULL_TREE
);
1396 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1401 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1402 fprintf (dump_file
, "%s returns %i\n", __func__
, nonempty
);
1407 /* Unshare strinfo record SI, if it has refcount > 1 or
1408 if stridx_to_strinfo vector is shared with some other
1412 unshare_strinfo (strinfo
*si
)
1416 if (si
->refcount
== 1 && !strinfo_shared ())
1419 nsi
= new_strinfo (si
->ptr
, si
->idx
, si
->nonzero_chars
, si
->full_string_p
);
1420 nsi
->stmt
= si
->stmt
;
1421 nsi
->alloc
= si
->alloc
;
1422 nsi
->endptr
= si
->endptr
;
1423 nsi
->first
= si
->first
;
1424 nsi
->prev
= si
->prev
;
1425 nsi
->next
= si
->next
;
1426 nsi
->writable
= si
->writable
;
1427 set_strinfo (si
->idx
, nsi
);
1432 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1433 strinfo if there is any. Return it's idx, or 0 if no strinfo has
1437 get_stridx_plus_constant (strinfo
*basesi
, unsigned HOST_WIDE_INT off
,
1440 if (TREE_CODE (ptr
) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1443 if (compare_nonzero_chars (basesi
, off
) < 0
1444 || !tree_fits_uhwi_p (basesi
->nonzero_chars
))
1447 unsigned HOST_WIDE_INT nonzero_chars
1448 = tree_to_uhwi (basesi
->nonzero_chars
) - off
;
1449 strinfo
*si
= basesi
, *chainsi
;
1450 if (si
->first
|| si
->prev
|| si
->next
)
1451 si
= verify_related_strinfos (basesi
);
1453 || si
->nonzero_chars
== NULL_TREE
1454 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1457 if (TREE_CODE (ptr
) == SSA_NAME
1458 && ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1459 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1461 gcc_checking_assert (compare_tree_int (si
->nonzero_chars
, off
) != -1);
1462 for (chainsi
= si
; chainsi
->next
; chainsi
= si
)
1464 si
= get_next_strinfo (chainsi
);
1466 || si
->nonzero_chars
== NULL_TREE
1467 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1469 int r
= compare_tree_int (si
->nonzero_chars
, nonzero_chars
);
1474 if (TREE_CODE (ptr
) == SSA_NAME
)
1475 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = si
->idx
;
1478 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1479 if (pidx
!= NULL
&& *pidx
== 0)
1488 int idx
= new_stridx (ptr
);
1491 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, nonzero_chars
),
1492 basesi
->full_string_p
);
1493 set_strinfo (idx
, si
);
1494 if (strinfo
*nextsi
= get_strinfo (chainsi
->next
))
1496 nextsi
= unshare_strinfo (nextsi
);
1497 si
->next
= nextsi
->idx
;
1500 chainsi
= unshare_strinfo (chainsi
);
1501 if (chainsi
->first
== 0)
1502 chainsi
->first
= chainsi
->idx
;
1503 chainsi
->next
= idx
;
1504 if (chainsi
->endptr
== NULL_TREE
&& zero_length_string_p (si
))
1505 chainsi
->endptr
= ptr
;
1506 si
->endptr
= chainsi
->endptr
;
1507 si
->prev
= chainsi
->idx
;
1508 si
->first
= chainsi
->first
;
1509 si
->writable
= chainsi
->writable
;
1513 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1514 to a zero-length string and if possible chain it to a related strinfo
1515 chain whose part is or might be CHAINSI. */
1518 zero_length_string (tree ptr
, strinfo
*chainsi
)
1522 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1523 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1524 gcc_checking_assert (TREE_CODE (ptr
) == SSA_NAME
1525 && ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] == 0);
1527 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1529 if (chainsi
!= NULL
)
1531 si
= verify_related_strinfos (chainsi
);
1536 /* We shouldn't mix delayed and non-delayed lengths. */
1537 gcc_assert (si
->full_string_p
);
1538 if (si
->endptr
== NULL_TREE
)
1540 si
= unshare_strinfo (si
);
1544 si
= get_next_strinfo (si
);
1547 if (zero_length_string_p (chainsi
))
1551 chainsi
= unshare_strinfo (chainsi
);
1554 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = chainsi
->idx
;
1560 /* We shouldn't mix delayed and non-delayed lengths. */
1561 gcc_assert (chainsi
->full_string_p
);
1562 if (chainsi
->first
|| chainsi
->prev
|| chainsi
->next
)
1564 chainsi
= unshare_strinfo (chainsi
);
1571 idx
= new_stridx (ptr
);
1574 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, 0), true);
1575 set_strinfo (idx
, si
);
1577 if (chainsi
!= NULL
)
1579 chainsi
= unshare_strinfo (chainsi
);
1580 if (chainsi
->first
== 0)
1581 chainsi
->first
= chainsi
->idx
;
1582 chainsi
->next
= idx
;
1583 if (chainsi
->endptr
== NULL_TREE
)
1584 chainsi
->endptr
= ptr
;
1585 si
->prev
= chainsi
->idx
;
1586 si
->first
= chainsi
->first
;
1587 si
->writable
= chainsi
->writable
;
1592 /* For strinfo ORIGSI whose length has been just updated, adjust other
1593 related strinfos so that they match the new ORIGSI. This involves:
1595 - adding ADJ to the nonzero_chars fields
1596 - copying full_string_p from the new ORIGSI. */
1599 adjust_related_strinfos (location_t loc
, strinfo
*origsi
, tree adj
)
1601 strinfo
*si
= verify_related_strinfos (origsi
);
1614 si
= unshare_strinfo (si
);
1615 /* We shouldn't see delayed lengths here; the caller must
1616 have calculated the old length in order to calculate
1618 gcc_assert (si
->nonzero_chars
);
1619 tem
= fold_convert_loc (loc
, TREE_TYPE (si
->nonzero_chars
), adj
);
1620 si
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
1621 TREE_TYPE (si
->nonzero_chars
),
1622 si
->nonzero_chars
, tem
);
1623 si
->full_string_p
= origsi
->full_string_p
;
1625 si
->endptr
= NULL_TREE
;
1626 si
->dont_invalidate
= true;
1628 nsi
= get_next_strinfo (si
);
1635 /* Find if there are other SSA_NAME pointers equal to PTR
1636 for which we don't track their string lengths yet. If so, use
1640 find_equal_ptrs (tree ptr
, int idx
)
1642 if (TREE_CODE (ptr
) != SSA_NAME
)
1646 gimple
*stmt
= SSA_NAME_DEF_STMT (ptr
);
1647 if (!is_gimple_assign (stmt
))
1649 ptr
= gimple_assign_rhs1 (stmt
);
1650 switch (gimple_assign_rhs_code (stmt
))
1655 if (!POINTER_TYPE_P (TREE_TYPE (ptr
)))
1657 if (TREE_CODE (ptr
) == SSA_NAME
)
1659 if (TREE_CODE (ptr
) != ADDR_EXPR
)
1664 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1665 if (pidx
!= NULL
&& *pidx
== 0)
1673 /* We might find an endptr created in this pass. Grow the
1674 vector in that case. */
1675 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1676 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1678 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] != 0)
1680 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = idx
;
1684 /* Return true if STMT is a call to a builtin function with the right
1685 arguments and attributes that should be considered for optimization
1689 valid_builtin_call (gimple
*stmt
)
1691 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
1694 tree callee
= gimple_call_fndecl (stmt
);
1695 tree decl
= builtin_decl_explicit (DECL_FUNCTION_CODE (callee
));
1698 && !gimple_builtin_call_types_compatible_p (stmt
, decl
))
1701 switch (DECL_FUNCTION_CODE (callee
))
1703 case BUILT_IN_MEMCMP
:
1704 case BUILT_IN_MEMCMP_EQ
:
1705 case BUILT_IN_STRCMP
:
1706 case BUILT_IN_STRNCMP
:
1707 case BUILT_IN_STRCHR
:
1708 case BUILT_IN_STRLEN
:
1709 case BUILT_IN_STRNLEN
:
1710 /* The above functions should be pure. Punt if they aren't. */
1711 if (gimple_vdef (stmt
) || gimple_vuse (stmt
) == NULL_TREE
)
1715 case BUILT_IN_ALLOCA
:
1716 case BUILT_IN_ALLOCA_WITH_ALIGN
:
1717 case BUILT_IN_CALLOC
:
1718 case BUILT_IN_MALLOC
:
1719 case BUILT_IN_MEMCPY
:
1720 case BUILT_IN_MEMCPY_CHK
:
1721 case BUILT_IN_MEMPCPY
:
1722 case BUILT_IN_MEMPCPY_CHK
:
1723 case BUILT_IN_MEMSET
:
1724 case BUILT_IN_STPCPY
:
1725 case BUILT_IN_STPCPY_CHK
:
1726 case BUILT_IN_STPNCPY
:
1727 case BUILT_IN_STPNCPY_CHK
:
1728 case BUILT_IN_STRCAT
:
1729 case BUILT_IN_STRCAT_CHK
:
1730 case BUILT_IN_STRCPY
:
1731 case BUILT_IN_STRCPY_CHK
:
1732 case BUILT_IN_STRNCAT
:
1733 case BUILT_IN_STRNCAT_CHK
:
1734 case BUILT_IN_STRNCPY
:
1735 case BUILT_IN_STRNCPY_CHK
:
1736 /* The above functions should be neither const nor pure. Punt if they
1738 if (gimple_vdef (stmt
) == NULL_TREE
|| gimple_vuse (stmt
) == NULL_TREE
)
1749 /* If the last .MEM setter statement before STMT is
1750 memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1751 and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1752 just memcpy (x, y, strlen (y)). SI must be the zero length
1756 strlen_pass::adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
)
1758 tree vuse
, callee
, len
;
1759 struct laststmt_struct last
= laststmt
;
1760 strinfo
*lastsi
, *firstsi
;
1761 unsigned len_arg_no
= 2;
1763 laststmt
.stmt
= NULL
;
1764 laststmt
.len
= NULL_TREE
;
1765 laststmt
.stridx
= 0;
1767 if (last
.stmt
== NULL
)
1770 vuse
= gimple_vuse (stmt
);
1771 if (vuse
== NULL_TREE
1772 || SSA_NAME_DEF_STMT (vuse
) != last
.stmt
1773 || !has_single_use (vuse
))
1776 gcc_assert (last
.stridx
> 0);
1777 lastsi
= get_strinfo (last
.stridx
);
1783 if (lastsi
->first
== 0 || lastsi
->first
!= si
->first
)
1786 firstsi
= verify_related_strinfos (si
);
1787 if (firstsi
== NULL
)
1789 while (firstsi
!= lastsi
)
1791 firstsi
= get_next_strinfo (firstsi
);
1792 if (firstsi
== NULL
)
1797 if (!is_strcat
&& !zero_length_string_p (si
))
1800 if (is_gimple_assign (last
.stmt
))
1802 gimple_stmt_iterator gsi
;
1804 if (!integer_zerop (gimple_assign_rhs1 (last
.stmt
)))
1806 if (stmt_could_throw_p (cfun
, last
.stmt
))
1808 gsi
= gsi_for_stmt (last
.stmt
);
1809 unlink_stmt_vdef (last
.stmt
);
1810 release_defs (last
.stmt
);
1811 gsi_remove (&gsi
, true);
1815 if (!valid_builtin_call (last
.stmt
))
1818 callee
= gimple_call_fndecl (last
.stmt
);
1819 switch (DECL_FUNCTION_CODE (callee
))
1821 case BUILT_IN_MEMCPY
:
1822 case BUILT_IN_MEMCPY_CHK
:
1828 len
= gimple_call_arg (last
.stmt
, len_arg_no
);
1829 if (tree_fits_uhwi_p (len
))
1831 if (!tree_fits_uhwi_p (last
.len
)
1832 || integer_zerop (len
)
1833 || tree_to_uhwi (len
) != tree_to_uhwi (last
.len
) + 1)
1835 /* Don't adjust the length if it is divisible by 4, it is more efficient
1836 to store the extra '\0' in that case. */
1837 if ((tree_to_uhwi (len
) & 3) == 0)
1840 /* Don't fold away an out of bounds access, as this defeats proper
1842 tree dst
= gimple_call_arg (last
.stmt
, 0);
1845 tree size
= compute_objsize (dst
, stmt
, 1, &aref
, &ptr_qry
);
1846 if (size
&& tree_int_cst_lt (size
, len
))
1849 else if (TREE_CODE (len
) == SSA_NAME
)
1851 gimple
*def_stmt
= SSA_NAME_DEF_STMT (len
);
1852 if (!is_gimple_assign (def_stmt
)
1853 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
1854 || gimple_assign_rhs1 (def_stmt
) != last
.len
1855 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
1861 gimple_call_set_arg (last
.stmt
, len_arg_no
, last
.len
);
1862 update_stmt (last
.stmt
);
1865 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1866 call, or when BOUND is non-null, of a strnlen() call, set LHS
1867 range info to [0, min (MAX, BOUND)] when the range includes more
1868 than one value and return LHS. Otherwise, when the range
1869 [MIN, MAX] is such that MIN == MAX, return the tree representation
1870 of (MIN). The latter allows callers to fold suitable strnlen() calls
1874 set_strlen_range (tree lhs
, wide_int min
, wide_int max
,
1875 tree bound
/* = NULL_TREE */)
1877 if (TREE_CODE (lhs
) != SSA_NAME
1878 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1883 /* For strnlen, adjust MIN and MAX as necessary. If the bound
1884 is less than the size of the array set MAX to it. It it's
1885 greater than MAX and MAX is non-zero bump MAX down to account
1886 for the necessary terminating nul. Otherwise leave it alone. */
1887 if (TREE_CODE (bound
) == INTEGER_CST
)
1889 wide_int wibnd
= wi::to_wide (bound
);
1890 int cmp
= wi::cmpu (wibnd
, max
);
1893 else if (cmp
&& wi::ne_p (max
, min
))
1896 else if (TREE_CODE (bound
) == SSA_NAME
)
1899 get_range_query (cfun
)->range_of_expr (r
, bound
);
1900 if (!r
.undefined_p ())
1902 /* For a bound in a known range, adjust the range determined
1903 above as necessary. For a bound in some anti-range or
1904 in an unknown range, use the range determined by callers. */
1905 if (wi::ltu_p (r
.lower_bound (), min
))
1906 min
= r
.lower_bound ();
1907 if (wi::ltu_p (r
.upper_bound (), max
))
1908 max
= r
.upper_bound ();
1914 return wide_int_to_tree (size_type_node
, min
);
1916 set_range_info (lhs
, VR_RANGE
, min
, max
);
1920 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1921 SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1922 a character array A[N] with unknown length bounded by N, and for
1923 strnlen(), by min (N, BOUND). */
1926 maybe_set_strlen_range (tree lhs
, tree src
, tree bound
)
1928 if (TREE_CODE (lhs
) != SSA_NAME
1929 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1932 if (TREE_CODE (src
) == SSA_NAME
)
1934 gimple
*def
= SSA_NAME_DEF_STMT (src
);
1935 if (is_gimple_assign (def
)
1936 && gimple_assign_rhs_code (def
) == ADDR_EXPR
)
1937 src
= gimple_assign_rhs1 (def
);
1940 /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1941 NUL so that the difference between a pointer to just past it and
1942 one to its beginning is positive. */
1943 wide_int max
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
1945 if (TREE_CODE (src
) == ADDR_EXPR
)
1947 /* The last array member of a struct can be bigger than its size
1948 suggests if it's treated as a poor-man's flexible array member. */
1949 src
= TREE_OPERAND (src
, 0);
1950 if (TREE_CODE (src
) != MEM_REF
1951 && !array_at_struct_end_p (src
))
1953 tree type
= TREE_TYPE (src
);
1954 tree size
= TYPE_SIZE_UNIT (type
);
1956 && TREE_CODE (size
) == INTEGER_CST
1957 && !integer_zerop (size
))
1959 /* Even though such uses of strlen would be undefined,
1960 avoid relying on arrays of arrays in case some genius
1961 decides to call strlen on an unterminated array element
1962 that's followed by a terminated one. Likewise, avoid
1963 assuming that a struct array member is necessarily
1964 nul-terminated (the nul may be in the member that
1965 follows). In those cases, assume that the length
1966 of the string stored in such an array is bounded
1967 by the size of the enclosing object if one can be
1969 tree base
= get_base_address (src
);
1972 if (tree size
= DECL_SIZE_UNIT (base
))
1974 && TREE_CODE (size
) == INTEGER_CST
1975 && TREE_CODE (TREE_TYPE (base
)) != POINTER_TYPE
)
1976 max
= wi::to_wide (size
);
1980 /* For strlen() the upper bound above is equal to
1981 the longest string that can be stored in the array
1982 (i.e., it accounts for the terminating nul. For
1983 strnlen() bump up the maximum by one since the array
1984 need not be nul-terminated. */
1985 if (!bound
&& max
!= 0)
1990 wide_int min
= wi::zero (max
.get_precision ());
1991 return set_strlen_range (lhs
, min
, max
, bound
);
1994 /* Diagnose buffer overflow by a STMT writing LEN + PLUS_ONE bytes,
1995 either into a region allocated for the object SI when non-null,
1996 or into an object designated by the LHS of STMT otherwise.
1997 For a call STMT, when CALL_LHS is set use its left hand side
1998 as the destination, otherwise use argument zero.
1999 When nonnull uses RVALS to determine range information.
2000 RAWMEM may be set by memcpy and other raw memory functions
2001 to allow accesses across subobject boundaries. */
2004 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, tree len
,
2005 strinfo
*si
, bool plus_one
, bool rawmem
)
2007 if (!len
|| warning_suppressed_p (stmt
, OPT_Wstringop_overflow_
))
2010 /* The DECL of the function performing the write if it is done
2012 tree writefn
= NULL_TREE
;
2013 /* The destination expression involved in the store or call STMT. */
2014 tree dest
= NULL_TREE
;
2016 if (is_gimple_assign (stmt
))
2017 dest
= gimple_assign_lhs (stmt
);
2018 else if (is_gimple_call (stmt
))
2021 dest
= gimple_call_lhs (stmt
);
2024 gcc_assert (gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
));
2025 dest
= gimple_call_arg (stmt
, 0);
2030 writefn
= gimple_call_fndecl (stmt
);
2035 if (warning_suppressed_p (dest
, OPT_Wstringop_overflow_
))
2038 const int ostype
= rawmem
? 0 : 1;
2040 /* Use maximum precision to avoid overflow in the addition below.
2041 Make sure all operands have the same precision to keep wide_int
2045 /* The size of the destination region (which is smaller than
2046 the destination object for stores at a non-zero offset). */
2047 tree destsize
= compute_objsize (dest
, stmt
, ostype
, &aref
, &ptr_qry
);
2052 aref
.sizrng
[1] = wi::to_offset (max_object_size ());
2055 /* Return early if the DESTSIZE size expression is the same as LEN
2056 and the offset into the destination is zero. This might happen
2057 in the case of a pair of malloc and memset calls to allocate
2058 an object and clear it as if by calloc. */
2059 if (destsize
== len
&& !plus_one
2060 && aref
.offrng
[0] == 0 && aref
.offrng
[0] == aref
.offrng
[1])
2064 if (!get_range (len
, stmt
, rng
, ptr_qry
.rvals
))
2067 widest_int lenrng
[2] =
2068 { widest_int::from (rng
[0], SIGNED
), widest_int::from (rng
[1], SIGNED
) };
2076 /* The size of the remaining space in the destination computed
2077 as the size of the latter minus the offset into it. */
2078 widest_int spcrng
[2];
2080 offset_int remrng
[2];
2081 remrng
[1] = aref
.size_remaining (remrng
);
2082 spcrng
[0] = remrng
[0] == -1 ? 0 : widest_int::from (remrng
[0], UNSIGNED
);
2083 spcrng
[1] = widest_int::from (remrng
[1], UNSIGNED
);
2086 if (wi::leu_p (lenrng
[0], spcrng
[0])
2087 && wi::leu_p (lenrng
[1], spcrng
[1]))
2090 location_t loc
= gimple_or_expr_nonartificial_location (stmt
, dest
);
2091 bool warned
= false;
2092 if (wi::leu_p (lenrng
[0], spcrng
[1]))
2095 && (!si
|| rawmem
|| !is_strlen_related_p (si
->ptr
, len
)))
2099 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2100 "%qD writing one too many bytes into a region "
2101 "of a size that depends on %<strlen%>",
2103 : warning_at (loc
, OPT_Wstringop_overflow_
,
2104 "writing one too many bytes into a region "
2105 "of a size that depends on %<strlen%>"));
2107 else if (lenrng
[0] == lenrng
[1])
2109 if (spcrng
[0] == spcrng
[1])
2111 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2112 lenrng
[0].to_uhwi (),
2113 "%qD writing %wu byte into a region "
2115 "%qD writing %wu bytes into a region "
2117 writefn
, lenrng
[0].to_uhwi (),
2118 spcrng
[0].to_uhwi ())
2119 : warning_n (loc
, OPT_Wstringop_overflow_
,
2120 lenrng
[0].to_uhwi (),
2121 "writing %wu byte into a region "
2123 "writing %wu bytes into a region "
2125 lenrng
[0].to_uhwi (),
2126 spcrng
[0].to_uhwi ()));
2129 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2130 lenrng
[0].to_uhwi (),
2131 "%qD writing %wu byte into a region "
2132 "of size between %wu and %wu",
2133 "%qD writing %wu bytes into a region "
2134 "of size between %wu and %wu",
2135 writefn
, lenrng
[0].to_uhwi (),
2136 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2137 : warning_n (loc
, OPT_Wstringop_overflow_
,
2138 lenrng
[0].to_uhwi (),
2139 "writing %wu byte into a region "
2140 "of size between %wu and %wu",
2141 "writing %wu bytes into a region "
2142 "of size between %wu and %wu",
2143 lenrng
[0].to_uhwi (),
2144 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2146 else if (spcrng
[0] == spcrng
[1])
2148 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2149 "%qD writing between %wu and %wu bytes "
2150 "into a region of size %wu",
2151 writefn
, lenrng
[0].to_uhwi (),
2152 lenrng
[1].to_uhwi (),
2153 spcrng
[0].to_uhwi ())
2154 : warning_at (loc
, OPT_Wstringop_overflow_
,
2155 "writing between %wu and %wu bytes "
2156 "into a region of size %wu",
2157 lenrng
[0].to_uhwi (),
2158 lenrng
[1].to_uhwi (),
2159 spcrng
[0].to_uhwi ()));
2162 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2163 "%qD writing between %wu and %wu bytes "
2164 "into a region of size between %wu and %wu",
2165 writefn
, lenrng
[0].to_uhwi (),
2166 lenrng
[1].to_uhwi (),
2167 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2168 : warning_at (loc
, OPT_Wstringop_overflow_
,
2169 "writing between %wu and %wu bytes "
2170 "into a region of size between %wu and %wu",
2171 lenrng
[0].to_uhwi (),
2172 lenrng
[1].to_uhwi (),
2173 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2178 suppress_warning (stmt
, OPT_Wstringop_overflow_
);
2180 aref
.inform_access (access_write_only
);
2183 /* Convenience wrapper for the above. */
2186 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
,
2187 unsigned HOST_WIDE_INT len
,
2188 strinfo
*si
, bool plus_one
, bool rawmem
)
2190 tree tlen
= build_int_cst (size_type_node
, len
);
2191 maybe_warn_overflow (stmt
, call_lhs
, tlen
, si
, plus_one
, rawmem
);
2194 /* Handle a strlen call. If strlen of the argument is known, replace
2195 the strlen call with the known value, otherwise remember that strlen
2196 of the argument is stored in the lhs SSA_NAME. */
2199 strlen_pass::handle_builtin_strlen ()
2201 gimple
*stmt
= gsi_stmt (m_gsi
);
2202 tree lhs
= gimple_call_lhs (stmt
);
2204 if (lhs
== NULL_TREE
)
2207 location_t loc
= gimple_location (stmt
);
2208 tree callee
= gimple_call_fndecl (stmt
);
2209 tree src
= gimple_call_arg (stmt
, 0);
2210 tree bound
= (DECL_FUNCTION_CODE (callee
) == BUILT_IN_STRNLEN
2211 ? gimple_call_arg (stmt
, 1) : NULL_TREE
);
2212 int idx
= get_stridx (src
, stmt
);
2213 if (idx
|| (bound
&& integer_zerop (bound
)))
2219 rhs
= build_int_cst (TREE_TYPE (lhs
), ~idx
);
2225 si
= get_strinfo (idx
);
2228 rhs
= get_string_length (si
);
2229 /* For strnlen, if bound is constant, even if si is not known
2230 to be zero terminated, if we know at least bound bytes are
2231 not zero, the return value will be bound. */
2232 if (rhs
== NULL_TREE
2233 && bound
!= NULL_TREE
2234 && TREE_CODE (bound
) == INTEGER_CST
2235 && si
->nonzero_chars
!= NULL_TREE
2236 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
2237 && tree_int_cst_le (bound
, si
->nonzero_chars
))
2241 if (rhs
!= NULL_TREE
)
2243 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2245 fprintf (dump_file
, "Optimizing: ");
2246 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2248 rhs
= unshare_expr (rhs
);
2249 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
2250 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2253 rhs
= fold_build2_loc (loc
, MIN_EXPR
, TREE_TYPE (rhs
), rhs
, bound
);
2255 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2256 stmt
= gsi_stmt (m_gsi
);
2258 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2260 fprintf (dump_file
, "into: ");
2261 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2265 /* Don't update anything for strnlen. */
2266 && bound
== NULL_TREE
2267 && TREE_CODE (si
->nonzero_chars
) != SSA_NAME
2268 && TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
2269 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2271 si
= unshare_strinfo (si
);
2272 si
->nonzero_chars
= lhs
;
2273 gcc_assert (si
->full_string_p
);
2276 if (strlen_to_stridx
2277 && (bound
== NULL_TREE
2278 /* For strnlen record this only if the call is proven
2279 to return the same value as strlen would. */
2280 || (TREE_CODE (bound
) == INTEGER_CST
2281 && TREE_CODE (rhs
) == INTEGER_CST
2282 && tree_int_cst_lt (rhs
, bound
))))
2283 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2288 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2292 idx
= new_stridx (src
);
2295 strinfo
*si
= get_strinfo (idx
);
2298 if (!si
->full_string_p
&& !si
->stmt
)
2300 /* Until now we only had a lower bound on the string length.
2301 Install LHS as the actual length. */
2302 si
= unshare_strinfo (si
);
2303 tree old
= si
->nonzero_chars
;
2304 si
->nonzero_chars
= lhs
;
2305 si
->full_string_p
= true;
2306 if (old
&& TREE_CODE (old
) == INTEGER_CST
)
2308 old
= fold_convert_loc (loc
, TREE_TYPE (lhs
), old
);
2309 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2310 TREE_TYPE (lhs
), lhs
, old
);
2311 adjust_related_strinfos (loc
, si
, adj
);
2312 /* Use the constant minimum length as the lower bound
2313 of the non-constant length. */
2314 wide_int min
= wi::to_wide (old
);
2316 = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
2317 set_strlen_range (lhs
, min
, max
);
2333 /* Only store the new length information for calls to strlen(),
2334 not for those to strnlen(). */
2335 strinfo
*si
= new_strinfo (src
, idx
, lhs
, true);
2336 set_strinfo (idx
, si
);
2337 find_equal_ptrs (src
, idx
);
2340 /* For SRC that is an array of N elements, set LHS's range
2341 to [0, min (N, BOUND)]. A constant return value means
2342 the range would have consisted of a single value. In
2343 that case, fold the result into the returned constant. */
2344 if (tree ret
= maybe_set_strlen_range (lhs
, src
, bound
))
2345 if (TREE_CODE (ret
) == INTEGER_CST
)
2347 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2349 fprintf (dump_file
, "Optimizing: ");
2350 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2352 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (ret
)))
2353 ret
= fold_convert_loc (loc
, TREE_TYPE (lhs
), ret
);
2354 gimplify_and_update_call_from_tree (&m_gsi
, ret
);
2355 stmt
= gsi_stmt (m_gsi
);
2357 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2359 fprintf (dump_file
, "into: ");
2360 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2364 if (strlen_to_stridx
&& !bound
)
2365 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2369 /* Handle a strchr call. If strlen of the first argument is known, replace
2370 the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
2371 that lhs of the call is endptr and strlen of the argument is endptr - x. */
2374 strlen_pass::handle_builtin_strchr ()
2376 gimple
*stmt
= gsi_stmt (m_gsi
);
2377 tree lhs
= gimple_call_lhs (stmt
);
2379 if (lhs
== NULL_TREE
)
2382 if (!integer_zerop (gimple_call_arg (stmt
, 1)))
2385 tree src
= gimple_call_arg (stmt
, 0);
2387 /* Avoid folding if the first argument is not a nul-terminated array.
2388 Defer warning until later. */
2389 if (!check_nul_terminated_array (NULL_TREE
, src
))
2392 int idx
= get_stridx (src
, stmt
);
2399 rhs
= build_int_cst (size_type_node
, ~idx
);
2403 si
= get_strinfo (idx
);
2405 rhs
= get_string_length (si
);
2407 if (rhs
!= NULL_TREE
)
2409 location_t loc
= gimple_location (stmt
);
2411 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2413 fprintf (dump_file
, "Optimizing: ");
2414 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2416 if (si
!= NULL
&& si
->endptr
!= NULL_TREE
)
2418 rhs
= unshare_expr (si
->endptr
);
2419 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2421 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2425 rhs
= fold_convert_loc (loc
, sizetype
, unshare_expr (rhs
));
2426 rhs
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
,
2427 TREE_TYPE (src
), src
, rhs
);
2428 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2430 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2432 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2433 stmt
= gsi_stmt (m_gsi
);
2435 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2437 fprintf (dump_file
, "into: ");
2438 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2441 && si
->endptr
== NULL_TREE
2442 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2444 si
= unshare_strinfo (si
);
2447 zero_length_string (lhs
, si
);
2451 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2453 if (TREE_CODE (src
) != SSA_NAME
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src
))
2456 idx
= new_stridx (src
);
2457 else if (get_strinfo (idx
) != NULL
)
2459 zero_length_string (lhs
, NULL
);
2464 location_t loc
= gimple_location (stmt
);
2465 tree lhsu
= fold_convert_loc (loc
, size_type_node
, lhs
);
2466 tree srcu
= fold_convert_loc (loc
, size_type_node
, src
);
2467 tree length
= fold_build2_loc (loc
, MINUS_EXPR
,
2468 size_type_node
, lhsu
, srcu
);
2469 strinfo
*si
= new_strinfo (src
, idx
, length
, true);
2471 set_strinfo (idx
, si
);
2472 find_equal_ptrs (src
, idx
);
2473 zero_length_string (lhs
, si
);
2477 zero_length_string (lhs
, NULL
);
2480 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
2481 If strlen of the second argument is known, strlen of the first argument
2482 is the same after this call. Furthermore, attempt to convert it to
2483 memcpy. Uses RVALS to determine range information. */
2486 strlen_pass::handle_builtin_strcpy (built_in_function bcode
)
2489 tree src
, dst
, srclen
, len
, lhs
, type
, fn
, oldlen
;
2491 gimple
*stmt
= gsi_stmt (m_gsi
);
2492 strinfo
*si
, *dsi
, *olddsi
, *zsi
;
2495 src
= gimple_call_arg (stmt
, 1);
2496 dst
= gimple_call_arg (stmt
, 0);
2497 lhs
= gimple_call_lhs (stmt
);
2498 idx
= get_stridx (src
, stmt
);
2501 si
= get_strinfo (idx
);
2503 didx
= get_stridx (dst
, stmt
);
2507 olddsi
= get_strinfo (didx
);
2512 adjust_last_stmt (olddsi
, stmt
, false);
2516 srclen
= get_string_length (si
);
2518 srclen
= build_int_cst (size_type_node
, ~idx
);
2520 maybe_warn_overflow (stmt
, false, srclen
, olddsi
, true);
2523 adjust_last_stmt (olddsi
, stmt
, false);
2525 loc
= gimple_location (stmt
);
2526 if (srclen
== NULL_TREE
)
2529 case BUILT_IN_STRCPY
:
2530 case BUILT_IN_STRCPY_CHK
:
2531 if (lhs
!= NULL_TREE
|| !builtin_decl_implicit_p (BUILT_IN_STPCPY
))
2534 case BUILT_IN_STPCPY
:
2535 case BUILT_IN_STPCPY_CHK
:
2536 if (lhs
== NULL_TREE
)
2540 tree lhsuint
= fold_convert_loc (loc
, size_type_node
, lhs
);
2541 srclen
= fold_convert_loc (loc
, size_type_node
, dst
);
2542 srclen
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
2552 didx
= new_stridx (dst
);
2558 oldlen
= olddsi
->nonzero_chars
;
2559 dsi
= unshare_strinfo (olddsi
);
2560 dsi
->nonzero_chars
= srclen
;
2561 dsi
->full_string_p
= (srclen
!= NULL_TREE
);
2562 /* Break the chain, so adjust_related_strinfo on later pointers in
2563 the chain won't adjust this one anymore. */
2566 dsi
->endptr
= NULL_TREE
;
2570 dsi
= new_strinfo (dst
, didx
, srclen
, srclen
!= NULL_TREE
);
2571 set_strinfo (didx
, dsi
);
2572 find_equal_ptrs (dst
, didx
);
2574 dsi
->writable
= true;
2575 dsi
->dont_invalidate
= true;
2577 if (dsi
->nonzero_chars
== NULL_TREE
)
2581 /* If string length of src is unknown, use delayed length
2582 computation. If string length of dst will be needed, it
2583 can be computed by transforming this strcpy call into
2584 stpcpy and subtracting dst from the return value. */
2586 /* Look for earlier strings whose length could be determined if
2587 this strcpy is turned into an stpcpy. */
2589 if (dsi
->prev
!= 0 && (chainsi
= verify_related_strinfos (dsi
)) != NULL
)
2591 for (; chainsi
&& chainsi
!= dsi
; chainsi
= get_strinfo (chainsi
->next
))
2593 /* When setting a stmt for delayed length computation
2594 prevent all strinfos through dsi from being
2596 chainsi
= unshare_strinfo (chainsi
);
2597 chainsi
->stmt
= stmt
;
2598 chainsi
->nonzero_chars
= NULL_TREE
;
2599 chainsi
->full_string_p
= false;
2600 chainsi
->endptr
= NULL_TREE
;
2601 chainsi
->dont_invalidate
= true;
2606 /* Try to detect overlap before returning. This catches cases
2607 like strcpy (d, d + n) where n is non-constant whose range
2608 is such that (n <= strlen (d) holds).
2610 OLDDSI->NONZERO_chars may have been reset by this point with
2611 oldlen holding it original value. */
2612 if (olddsi
&& oldlen
)
2614 /* Add 1 for the terminating NUL. */
2615 tree type
= TREE_TYPE (oldlen
);
2616 oldlen
= fold_build2 (PLUS_EXPR
, type
, oldlen
,
2617 build_int_cst (type
, 1));
2618 check_bounds_or_overlap (stmt
, olddsi
->ptr
, src
, oldlen
, NULL_TREE
);
2626 tree adj
= NULL_TREE
;
2627 if (oldlen
== NULL_TREE
)
2629 else if (integer_zerop (oldlen
))
2631 else if (TREE_CODE (oldlen
) == INTEGER_CST
2632 || TREE_CODE (srclen
) == INTEGER_CST
)
2633 adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2634 TREE_TYPE (srclen
), srclen
,
2635 fold_convert_loc (loc
, TREE_TYPE (srclen
),
2637 if (adj
!= NULL_TREE
)
2638 adjust_related_strinfos (loc
, dsi
, adj
);
2642 /* strcpy src may not overlap dst, so src doesn't need to be
2643 invalidated either. */
2645 si
->dont_invalidate
= true;
2651 case BUILT_IN_STRCPY
:
2652 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
2654 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2656 case BUILT_IN_STRCPY_CHK
:
2657 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
2659 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2661 case BUILT_IN_STPCPY
:
2662 /* This would need adjustment of the lhs (subtract one),
2663 or detection that the trailing '\0' doesn't need to be
2664 written, if it will be immediately overwritten.
2665 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); */
2669 zsi
= zero_length_string (lhs
, dsi
);
2672 case BUILT_IN_STPCPY_CHK
:
2673 /* This would need adjustment of the lhs (subtract one),
2674 or detection that the trailing '\0' doesn't need to be
2675 written, if it will be immediately overwritten.
2676 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK); */
2680 zsi
= zero_length_string (lhs
, dsi
);
2687 zsi
->dont_invalidate
= true;
2691 tree args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
2692 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
2695 type
= size_type_node
;
2697 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
2698 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
, build_int_cst (type
, 1));
2700 /* Disable warning for the transformed statement? */
2701 opt_code no_warning_opt
= no_warning
;
2703 if (const strinfo
*chksi
= si
? olddsi
? olddsi
: dsi
: NULL
)
2705 no_warning_opt
= check_bounds_or_overlap (stmt
, chksi
->ptr
, si
->ptr
,
2708 suppress_warning (stmt
, no_warning_opt
);
2711 if (fn
== NULL_TREE
)
2714 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
2716 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2718 fprintf (dump_file
, "Optimizing: ");
2719 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2721 if (gimple_call_num_args (stmt
) == 2)
2722 success
= update_gimple_call (&m_gsi
, fn
, 3, dst
, src
, len
);
2724 success
= update_gimple_call (&m_gsi
, fn
, 4, dst
, src
, len
,
2725 gimple_call_arg (stmt
, 2));
2728 stmt
= gsi_stmt (m_gsi
);
2730 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2732 fprintf (dump_file
, "into: ");
2733 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2735 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2736 laststmt
.stmt
= stmt
;
2737 laststmt
.len
= srclen
;
2738 laststmt
.stridx
= dsi
->idx
;
2740 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2741 fprintf (dump_file
, "not possible.\n");
2744 suppress_warning (stmt
, no_warning_opt
);
2747 /* Check the size argument to the built-in forms of stpncpy and strncpy
2748 for out-of-bounds offsets or overlapping access, and to see if the
2749 size argument is derived from a call to strlen() on the source argument,
2750 and if so, issue an appropriate warning. */
2753 strlen_pass::handle_builtin_strncat (built_in_function
)
2755 /* Same as stxncpy(). */
2756 handle_builtin_stxncpy_strncat (true);
2759 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2760 way. LEN can either be an integer expression, or a pointer (to char).
2761 When it is the latter (such as in recursive calls to self) it is
2762 assumed to be the argument in some call to strlen() whose relationship
2763 to SRC is being ascertained. */
2766 is_strlen_related_p (tree src
, tree len
)
2768 if (TREE_CODE (TREE_TYPE (len
)) == POINTER_TYPE
2769 && operand_equal_p (src
, len
, 0))
2772 if (TREE_CODE (len
) != SSA_NAME
)
2775 if (TREE_CODE (src
) == SSA_NAME
)
2777 gimple
*srcdef
= SSA_NAME_DEF_STMT (src
);
2778 if (is_gimple_assign (srcdef
))
2780 /* Handle bitwise AND used in conversions from wider size_t
2781 to narrower unsigned types. */
2782 tree_code code
= gimple_assign_rhs_code (srcdef
);
2783 if (code
== BIT_AND_EXPR
2784 || code
== NOP_EXPR
)
2785 return is_strlen_related_p (gimple_assign_rhs1 (srcdef
), len
);
2790 if (gimple_call_builtin_p (srcdef
, BUILT_IN_NORMAL
))
2792 /* If SRC is the result of a call to an allocation function
2793 or strlen, use the function's argument instead. */
2794 tree func
= gimple_call_fndecl (srcdef
);
2795 built_in_function code
= DECL_FUNCTION_CODE (func
);
2796 if (code
== BUILT_IN_ALLOCA
2797 || code
== BUILT_IN_ALLOCA_WITH_ALIGN
2798 || code
== BUILT_IN_MALLOC
2799 || code
== BUILT_IN_STRLEN
)
2800 return is_strlen_related_p (gimple_call_arg (srcdef
, 0), len
);
2802 /* FIXME: Handle other functions with attribute alloc_size. */
2807 gimple
*lendef
= SSA_NAME_DEF_STMT (len
);
2811 if (is_gimple_call (lendef
))
2813 tree func
= gimple_call_fndecl (lendef
);
2814 if (!valid_builtin_call (lendef
)
2815 || DECL_FUNCTION_CODE (func
) != BUILT_IN_STRLEN
)
2818 tree arg
= gimple_call_arg (lendef
, 0);
2819 return is_strlen_related_p (src
, arg
);
2822 if (!is_gimple_assign (lendef
))
2825 tree_code code
= gimple_assign_rhs_code (lendef
);
2826 tree rhs1
= gimple_assign_rhs1 (lendef
);
2827 tree rhstype
= TREE_TYPE (rhs1
);
2829 if ((TREE_CODE (rhstype
) == POINTER_TYPE
&& code
== POINTER_PLUS_EXPR
)
2830 || (INTEGRAL_TYPE_P (rhstype
)
2831 && (code
== BIT_AND_EXPR
2832 || code
== NOP_EXPR
)))
2834 /* Pointer plus (an integer), and truncation are considered among
2835 the (potentially) related expressions to strlen. */
2836 return is_strlen_related_p (src
, rhs1
);
2839 if (tree rhs2
= gimple_assign_rhs2 (lendef
))
2841 /* Integer subtraction is considered strlen-related when both
2842 arguments are integers and second one is strlen-related. */
2843 rhstype
= TREE_TYPE (rhs2
);
2844 if (INTEGRAL_TYPE_P (rhstype
) && code
== MINUS_EXPR
)
2845 return is_strlen_related_p (src
, rhs2
);
2851 /* Called by handle_builtin_stxncpy_strncat and by
2852 gimple_fold_builtin_strncpy in gimple-fold.c.
2853 Check to see if the specified bound is a) equal to the size of
2854 the destination DST and if so, b) if it's immediately followed by
2855 DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise,
2856 do nothing. Return true if diagnostic has been issued.
2858 The purpose is to diagnose calls to strncpy and stpncpy that do
2859 not nul-terminate the copy while allowing for the idiom where
2860 such a call is immediately followed by setting the last element
2863 strncpy (a, s, sizeof a);
2864 a[sizeof a - 1] = '\0';
2868 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi
, tree src
, tree cnt
,
2869 pointer_query
*ptr_qry
/* = NULL */)
2871 gimple
*stmt
= gsi_stmt (gsi
);
2872 if (warning_suppressed_p (stmt
, OPT_Wstringop_truncation
))
2875 wide_int cntrange
[2];
2877 if (!get_range_query (cfun
)->range_of_expr (r
, cnt
)
2879 || r
.undefined_p ())
2882 cntrange
[0] = wi::to_wide (r
.min ());
2883 cntrange
[1] = wi::to_wide (r
.max ());
2884 if (r
.kind () == VR_ANTI_RANGE
)
2886 wide_int maxobjsize
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
));
2888 if (wi::ltu_p (cntrange
[1], maxobjsize
))
2890 cntrange
[0] = cntrange
[1] + 1;
2891 cntrange
[1] = maxobjsize
;
2895 cntrange
[1] = cntrange
[0] - 1;
2896 cntrange
[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt
)));
2900 /* Negative value is the constant string length. If it's less than
2901 the lower bound there is no truncation. Avoid calling get_stridx()
2902 when ssa_ver_to_stridx is empty. That implies the caller isn't
2903 running under the control of this pass and ssa_ver_to_stridx hasn't
2904 been created yet. */
2905 int sidx
= ssa_ver_to_stridx
.length () ? get_stridx (src
, stmt
) : 0;
2906 if (sidx
< 0 && wi::gtu_p (cntrange
[0], ~sidx
))
2909 tree dst
= gimple_call_arg (stmt
, 0);
2911 if (TREE_CODE (dstdecl
) == ADDR_EXPR
)
2912 dstdecl
= TREE_OPERAND (dstdecl
, 0);
2914 tree ref
= NULL_TREE
;
2918 /* If the source is a non-string return early to avoid warning
2919 for possible truncation (if the truncation is certain SIDX
2921 tree srcdecl
= gimple_call_arg (stmt
, 1);
2922 if (TREE_CODE (srcdecl
) == ADDR_EXPR
)
2923 srcdecl
= TREE_OPERAND (srcdecl
, 0);
2924 if (get_attr_nonstring_decl (srcdecl
, &ref
))
2928 /* Likewise, if the destination refers to an array/pointer declared
2929 nonstring return early. */
2930 if (get_attr_nonstring_decl (dstdecl
, &ref
))
2933 /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2934 avoid the truncation warning. */
2935 gsi_next_nondebug (&gsi
);
2936 gimple
*next_stmt
= gsi_stmt (gsi
);
2939 /* When there is no statement in the same basic block check
2940 the immediate successor block. */
2941 if (basic_block bb
= gimple_bb (stmt
))
2943 if (single_succ_p (bb
))
2945 /* For simplicity, ignore blocks with multiple outgoing
2946 edges for now and only consider successor blocks along
2948 edge e
= EDGE_SUCC (bb
, 0);
2949 if (!(e
->flags
& EDGE_ABNORMAL
))
2951 gsi
= gsi_start_bb (e
->dest
);
2952 next_stmt
= gsi_stmt (gsi
);
2953 if (next_stmt
&& is_gimple_debug (next_stmt
))
2955 gsi_next_nondebug (&gsi
);
2956 next_stmt
= gsi_stmt (gsi
);
2963 if (next_stmt
&& is_gimple_assign (next_stmt
))
2965 tree lhs
= gimple_assign_lhs (next_stmt
);
2966 tree_code code
= TREE_CODE (lhs
);
2967 if (code
== ARRAY_REF
|| code
== MEM_REF
)
2968 lhs
= TREE_OPERAND (lhs
, 0);
2970 tree func
= gimple_call_fndecl (stmt
);
2971 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STPNCPY
)
2973 tree ret
= gimple_call_lhs (stmt
);
2974 if (ret
&& operand_equal_p (ret
, lhs
, 0))
2978 /* Determine the base address and offset of the reference,
2979 ignoring the innermost array index. */
2980 if (TREE_CODE (ref
) == ARRAY_REF
)
2981 ref
= TREE_OPERAND (ref
, 0);
2984 tree dstbase
= get_addr_base_and_unit_offset (ref
, &dstoff
);
2987 tree lhsbase
= get_addr_base_and_unit_offset (lhs
, &lhsoff
);
2990 && known_eq (dstoff
, lhsoff
)
2991 && operand_equal_p (dstbase
, lhsbase
, 0))
2995 int prec
= TYPE_PRECISION (TREE_TYPE (cnt
));
2996 wide_int lenrange
[2];
2997 if (strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
)
2999 lenrange
[0] = (sisrc
->nonzero_chars
3000 && TREE_CODE (sisrc
->nonzero_chars
) == INTEGER_CST
3001 ? wi::to_wide (sisrc
->nonzero_chars
)
3003 lenrange
[1] = lenrange
[0];
3006 lenrange
[0] = lenrange
[1] = wi::shwi (~sidx
, prec
);
3009 c_strlen_data lendata
= { };
3010 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
3011 to have it set to the length of the longest string in a PHI. */
3012 lendata
.maxbound
= src
;
3013 get_range_strlen (src
, &lendata
, /* eltsize = */1);
3014 if (TREE_CODE (lendata
.minlen
) == INTEGER_CST
3015 && TREE_CODE (lendata
.maxbound
) == INTEGER_CST
)
3017 /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
3018 which stores the length of the shortest known string. */
3019 if (integer_all_onesp (lendata
.maxlen
))
3020 lenrange
[0] = wi::shwi (0, prec
);
3022 lenrange
[0] = wi::to_wide (lendata
.minlen
, prec
);
3023 lenrange
[1] = wi::to_wide (lendata
.maxbound
, prec
);
3027 lenrange
[0] = wi::shwi (0, prec
);
3028 lenrange
[1] = wi::shwi (-1, prec
);
3032 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3033 tree func
= gimple_call_fndecl (stmt
);
3035 if (lenrange
[0] != 0 || !wi::neg_p (lenrange
[1]))
3037 /* If the longest source string is shorter than the lower bound
3038 of the specified count the copy is definitely nul-terminated. */
3039 if (wi::ltu_p (lenrange
[1], cntrange
[0]))
3042 if (wi::neg_p (lenrange
[1]))
3044 /* The length of one of the strings is unknown but at least
3045 one has non-zero length and that length is stored in
3046 LENRANGE[1]. Swap the bounds to force a "may be truncated"
3048 lenrange
[1] = lenrange
[0];
3049 lenrange
[0] = wi::shwi (0, prec
);
3052 /* Set to true for strncat whose bound is derived from the length
3053 of the destination (the expected usage pattern). */
3054 bool cat_dstlen_bounded
= false;
3055 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STRNCAT
)
3056 cat_dstlen_bounded
= is_strlen_related_p (dst
, cnt
);
3058 if (lenrange
[0] == cntrange
[1] && cntrange
[0] == cntrange
[1])
3059 return warning_n (callloc
, OPT_Wstringop_truncation
,
3060 cntrange
[0].to_uhwi (),
3061 "%qD output truncated before terminating "
3062 "nul copying %E byte from a string of the "
3064 "%qD output truncated before terminating nul "
3065 "copying %E bytes from a string of the same "
3068 else if (!cat_dstlen_bounded
)
3070 if (wi::geu_p (lenrange
[0], cntrange
[1]))
3072 /* The shortest string is longer than the upper bound of
3073 the count so the truncation is certain. */
3074 if (cntrange
[0] == cntrange
[1])
3075 return warning_n (callloc
, OPT_Wstringop_truncation
,
3076 cntrange
[0].to_uhwi (),
3077 "%qD output truncated copying %E byte "
3078 "from a string of length %wu",
3079 "%qD output truncated copying %E bytes "
3080 "from a string of length %wu",
3081 func
, cnt
, lenrange
[0].to_uhwi ());
3083 return warning_at (callloc
, OPT_Wstringop_truncation
,
3084 "%qD output truncated copying between %wu "
3085 "and %wu bytes from a string of length %wu",
3086 func
, cntrange
[0].to_uhwi (),
3087 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3089 else if (wi::geu_p (lenrange
[1], cntrange
[1]))
3091 /* The longest string is longer than the upper bound of
3092 the count so the truncation is possible. */
3093 if (cntrange
[0] == cntrange
[1])
3094 return warning_n (callloc
, OPT_Wstringop_truncation
,
3095 cntrange
[0].to_uhwi (),
3096 "%qD output may be truncated copying %E "
3097 "byte from a string of length %wu",
3098 "%qD output may be truncated copying %E "
3099 "bytes from a string of length %wu",
3100 func
, cnt
, lenrange
[1].to_uhwi ());
3102 return warning_at (callloc
, OPT_Wstringop_truncation
,
3103 "%qD output may be truncated copying between "
3104 "%wu and %wu bytes from a string of length %wu",
3105 func
, cntrange
[0].to_uhwi (),
3106 cntrange
[1].to_uhwi (), lenrange
[1].to_uhwi ());
3110 if (!cat_dstlen_bounded
3111 && cntrange
[0] != cntrange
[1]
3112 && wi::leu_p (cntrange
[0], lenrange
[0])
3113 && wi::leu_p (cntrange
[1], lenrange
[0] + 1))
3115 /* If the source (including the terminating nul) is longer than
3116 the lower bound of the specified count but shorter than the
3117 upper bound the copy may (but need not) be truncated. */
3118 return warning_at (callloc
, OPT_Wstringop_truncation
,
3119 "%qD output may be truncated copying between "
3120 "%wu and %wu bytes from a string of length %wu",
3121 func
, cntrange
[0].to_uhwi (),
3122 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3127 if (tree dstsize
= compute_objsize (dst
, stmt
, 1, &aref
, ptr_qry
))
3129 /* The source length is unknown. Try to determine the destination
3130 size and see if it matches the specified bound. If not, bail.
3131 Otherwise go on to see if it should be diagnosed for possible
3136 if (wi::to_wide (dstsize
) != cntrange
[1])
3139 /* Avoid warning for strncpy(a, b, N) calls where the following
3141 N == sizeof a && N == sizeof b */
3142 if (tree srcsize
= compute_objsize (src
, stmt
, 1, &aref
, ptr_qry
))
3143 if (wi::to_wide (srcsize
) == cntrange
[1])
3146 if (cntrange
[0] == cntrange
[1])
3147 return warning_at (callloc
, OPT_Wstringop_truncation
,
3148 "%qD specified bound %E equals destination size",
3155 /* Check the arguments to the built-in forms of stpncpy, strncpy, and
3156 strncat, for out-of-bounds offsets or overlapping access, and to see
3157 if the size is derived from calling strlen() on the source argument,
3158 and if so, issue the appropriate warning.
3159 APPEND_P is true for strncat. */
3162 strlen_pass::handle_builtin_stxncpy_strncat (bool append_p
)
3164 if (!strlen_to_stridx
)
3167 gimple
*stmt
= gsi_stmt (m_gsi
);
3169 tree dst
= gimple_call_arg (stmt
, 0);
3170 tree src
= gimple_call_arg (stmt
, 1);
3171 tree len
= gimple_call_arg (stmt
, 2);
3172 /* An upper bound of the size of the destination. */
3173 tree dstsize
= NULL_TREE
;
3174 /* The length of the destination and source strings (plus 1 for those
3175 whose FULL_STRING_P is set, i.e., whose length is exact rather than
3177 tree dstlenp1
= NULL_TREE
, srclenp1
= NULL_TREE
;;
3179 int didx
= get_stridx (dst
, stmt
);
3180 if (strinfo
*sidst
= didx
> 0 ? get_strinfo (didx
) : NULL
)
3182 /* Compute the size of the destination string including the nul
3183 if it is known to be nul-terminated. */
3184 if (sidst
->nonzero_chars
)
3186 if (sidst
->full_string_p
)
3188 /* String is known to be nul-terminated. */
3189 tree type
= TREE_TYPE (sidst
->nonzero_chars
);
3190 dstlenp1
= fold_build2 (PLUS_EXPR
, type
, sidst
->nonzero_chars
,
3191 build_int_cst (type
, 1));
3194 dstlenp1
= sidst
->nonzero_chars
;
3196 else if (TREE_CODE (sidst
->ptr
) == SSA_NAME
)
3198 gimple
*def_stmt
= SSA_NAME_DEF_STMT (sidst
->ptr
);
3199 dstsize
= gimple_call_alloc_size (def_stmt
);
3205 int sidx
= get_stridx (src
, stmt
);
3206 strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
;
3209 /* strncat() and strncpy() can modify the source string by writing
3210 over the terminating nul so SISRC->DONT_INVALIDATE must be left
3213 /* Compute the size of the source string including the terminating
3214 nul if its known to be nul-terminated. */
3215 if (sisrc
->nonzero_chars
)
3217 if (sisrc
->full_string_p
)
3219 tree type
= TREE_TYPE (sisrc
->nonzero_chars
);
3220 srclenp1
= fold_build2 (PLUS_EXPR
, type
, sisrc
->nonzero_chars
,
3221 build_int_cst (type
, 1));
3224 srclenp1
= sisrc
->nonzero_chars
;
3230 srclenp1
= NULL_TREE
;
3232 opt_code opt
= check_bounds_or_overlap (stmt
, dst
, src
, dstlenp1
, srclenp1
);
3233 if (opt
!= no_warning
)
3235 suppress_warning (stmt
, opt
);
3239 /* If the length argument was computed from strlen(S) for some string
3240 S retrieve the strinfo index for the string (PSS->FIRST) along with
3241 the location of the strlen() call (PSS->SECOND). */
3242 stridx_strlenloc
*pss
= strlen_to_stridx
->get (len
);
3243 if (!pss
|| pss
->first
<= 0)
3245 if (maybe_diag_stxncpy_trunc (m_gsi
, src
, len
))
3246 suppress_warning (stmt
, OPT_Wstringop_truncation
);
3251 /* Retrieve the strinfo data for the string S that LEN was computed
3252 from as some function F of strlen (S) (i.e., LEN need not be equal
3254 strinfo
*silen
= get_strinfo (pss
->first
);
3256 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3258 tree func
= gimple_call_fndecl (stmt
);
3260 bool warned
= false;
3262 /* When -Wstringop-truncation is set, try to determine truncation
3263 before diagnosing possible overflow. Truncation is implied by
3264 the LEN argument being equal to strlen(SRC), regardless of
3265 whether its value is known. Otherwise, when appending, or
3266 when copying into a destination of known size, issue the more
3267 generic -Wstringop-overflow which triggers for LEN arguments
3268 that in any meaningful way depend on strlen(SRC). */
3271 && is_strlen_related_p (src
, len
)
3272 && warning_at (callloc
, OPT_Wstringop_truncation
,
3273 "%qD output truncated before terminating nul "
3274 "copying as many bytes from a string as its length",
3277 else if ((append_p
|| !dstsize
|| len
== dstlenp1
)
3278 && silen
&& is_strlen_related_p (src
, silen
->ptr
))
3280 /* Issue -Wstringop-overflow when appending or when writing into
3281 a destination of a known size. Otherwise, when copying into
3282 a destination of an unknown size, it's truncation. */
3283 opt_code opt
= (append_p
|| dstsize
3284 ? OPT_Wstringop_overflow_
: OPT_Wstringop_truncation
);
3285 warned
= warning_at (callloc
, opt
,
3286 "%qD specified bound depends on the length "
3287 "of the source argument",
3292 location_t strlenloc
= pss
->second
;
3293 if (strlenloc
!= UNKNOWN_LOCATION
&& strlenloc
!= callloc
)
3294 inform (strlenloc
, "length computed here");
3298 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
3299 If strlen of the second argument is known and length of the third argument
3300 is that plus one, strlen of the first argument is the same after this
3301 call. Uses RVALS to determine range information. */
3304 strlen_pass::handle_builtin_memcpy (built_in_function bcode
)
3306 tree lhs
, oldlen
, newlen
;
3307 gimple
*stmt
= gsi_stmt (m_gsi
);
3310 tree len
= gimple_call_arg (stmt
, 2);
3311 tree src
= gimple_call_arg (stmt
, 1);
3312 tree dst
= gimple_call_arg (stmt
, 0);
3314 int didx
= get_stridx (dst
, stmt
);
3315 strinfo
*olddsi
= NULL
;
3317 olddsi
= get_strinfo (didx
);
3322 && !integer_zerop (len
))
3324 maybe_warn_overflow (stmt
, false, len
, olddsi
, false, true);
3325 adjust_last_stmt (olddsi
, stmt
, false);
3328 int idx
= get_stridx (src
, stmt
);
3337 /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
3339 si
= get_strinfo (idx
);
3340 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
3342 if (TREE_CODE (len
) == INTEGER_CST
3343 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
3345 if (tree_int_cst_le (len
, si
->nonzero_chars
))
3347 /* Copying LEN nonzero characters, where LEN is constant. */
3349 full_string_p
= false;
3353 /* Copying the whole of the analyzed part of SI. */
3354 newlen
= si
->nonzero_chars
;
3355 full_string_p
= si
->full_string_p
;
3360 if (!si
->full_string_p
)
3362 if (TREE_CODE (len
) != SSA_NAME
)
3364 def_stmt
= SSA_NAME_DEF_STMT (len
);
3365 if (!is_gimple_assign (def_stmt
)
3366 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
3367 || gimple_assign_rhs1 (def_stmt
) != si
->nonzero_chars
3368 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
3370 /* Copying variable-length string SI (and no more). */
3371 newlen
= si
->nonzero_chars
;
3372 full_string_p
= true;
3378 /* Handle memcpy (x, "abcd", 5) or
3379 memcpy (x, "abc\0uvw", 7). */
3380 if (!tree_fits_uhwi_p (len
))
3383 unsigned HOST_WIDE_INT clen
= tree_to_uhwi (len
);
3384 unsigned HOST_WIDE_INT nonzero_chars
= ~idx
;
3385 newlen
= build_int_cst (size_type_node
, MIN (nonzero_chars
, clen
));
3386 full_string_p
= clen
> nonzero_chars
;
3391 && olddsi
->nonzero_chars
3392 && TREE_CODE (olddsi
->nonzero_chars
) == INTEGER_CST
3393 && tree_int_cst_le (newlen
, olddsi
->nonzero_chars
))
3395 /* The SRC substring being written strictly overlaps
3396 a subsequence of the existing string OLDDSI. */
3397 newlen
= olddsi
->nonzero_chars
;
3398 full_string_p
= olddsi
->full_string_p
;
3401 if (olddsi
!= NULL
&& TREE_CODE (len
) == SSA_NAME
)
3402 adjust_last_stmt (olddsi
, stmt
, false);
3406 didx
= new_stridx (dst
);
3413 dsi
= unshare_strinfo (olddsi
);
3414 oldlen
= olddsi
->nonzero_chars
;
3415 dsi
->nonzero_chars
= newlen
;
3416 dsi
->full_string_p
= full_string_p
;
3417 /* Break the chain, so adjust_related_strinfo on later pointers in
3418 the chain won't adjust this one anymore. */
3421 dsi
->endptr
= NULL_TREE
;
3425 dsi
= new_strinfo (dst
, didx
, newlen
, full_string_p
);
3426 set_strinfo (didx
, dsi
);
3427 find_equal_ptrs (dst
, didx
);
3429 dsi
->writable
= true;
3430 dsi
->dont_invalidate
= true;
3433 tree adj
= NULL_TREE
;
3434 location_t loc
= gimple_location (stmt
);
3435 if (oldlen
== NULL_TREE
)
3437 else if (integer_zerop (oldlen
))
3439 else if (TREE_CODE (oldlen
) == INTEGER_CST
3440 || TREE_CODE (newlen
) == INTEGER_CST
)
3441 adj
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (newlen
), newlen
,
3442 fold_convert_loc (loc
, TREE_TYPE (newlen
),
3444 if (adj
!= NULL_TREE
)
3445 adjust_related_strinfos (loc
, dsi
, adj
);
3449 /* memcpy src may not overlap dst, so src doesn't need to be
3450 invalidated either. */
3452 si
->dont_invalidate
= true;
3456 lhs
= gimple_call_lhs (stmt
);
3459 case BUILT_IN_MEMCPY
:
3460 case BUILT_IN_MEMCPY_CHK
:
3461 /* Allow adjust_last_stmt to decrease this memcpy's size. */
3462 laststmt
.stmt
= stmt
;
3463 laststmt
.len
= dsi
->nonzero_chars
;
3464 laststmt
.stridx
= dsi
->idx
;
3466 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
3468 case BUILT_IN_MEMPCPY
:
3469 case BUILT_IN_MEMPCPY_CHK
:
3477 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
3478 If strlen of the second argument is known, strlen of the first argument
3479 is increased by the length of the second argument. Furthermore, attempt
3480 to convert it to memcpy/strcpy if the length of the first argument
3484 strlen_pass::handle_builtin_strcat (built_in_function bcode
)
3487 tree srclen
, args
, type
, fn
, objsz
, endptr
;
3489 gimple
*stmt
= gsi_stmt (m_gsi
);
3491 location_t loc
= gimple_location (stmt
);
3493 tree src
= gimple_call_arg (stmt
, 1);
3494 tree dst
= gimple_call_arg (stmt
, 0);
3496 /* Bail if the source is the same as destination. It will be diagnosed
3498 if (operand_equal_p (src
, dst
, 0))
3501 tree lhs
= gimple_call_lhs (stmt
);
3503 didx
= get_stridx (dst
, stmt
);
3509 dsi
= get_strinfo (didx
);
3513 idx
= get_stridx (src
, stmt
);
3515 srclen
= build_int_cst (size_type_node
, ~idx
);
3518 si
= get_strinfo (idx
);
3520 srclen
= get_string_length (si
);
3523 /* Disable warning for the transformed statement? */
3524 opt_code no_warning_opt
= no_warning
;
3526 if (dsi
== NULL
|| get_string_length (dsi
) == NULL_TREE
)
3529 /* The concatenation always involves copying at least one byte
3530 (the terminating nul), even if the source string is empty.
3531 If the source is unknown assume it's one character long and
3532 used that as both sizes. */
3536 tree type
= TREE_TYPE (slen
);
3537 slen
= fold_build2 (PLUS_EXPR
, type
, slen
, build_int_cst (type
, 1));
3540 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3541 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, NULL_TREE
,
3544 suppress_warning (stmt
, no_warning_opt
);
3547 /* strcat (p, q) can be transformed into
3548 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
3549 with length endptr - p if we need to compute the length
3550 later on. Don't do this transformation if we don't need
3552 if (builtin_decl_implicit_p (BUILT_IN_STPCPY
) && lhs
== NULL_TREE
)
3556 didx
= new_stridx (dst
);
3562 dsi
= new_strinfo (dst
, didx
, NULL_TREE
, false);
3563 set_strinfo (didx
, dsi
);
3564 find_equal_ptrs (dst
, didx
);
3568 dsi
= unshare_strinfo (dsi
);
3569 dsi
->nonzero_chars
= NULL_TREE
;
3570 dsi
->full_string_p
= false;
3572 dsi
->endptr
= NULL_TREE
;
3574 dsi
->writable
= true;
3576 dsi
->dont_invalidate
= true;
3581 tree dstlen
= dsi
->nonzero_chars
;
3582 endptr
= dsi
->endptr
;
3584 dsi
= unshare_strinfo (dsi
);
3585 dsi
->endptr
= NULL_TREE
;
3587 dsi
->writable
= true;
3589 if (srclen
!= NULL_TREE
)
3591 dsi
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
3592 TREE_TYPE (dsi
->nonzero_chars
),
3593 dsi
->nonzero_chars
, srclen
);
3594 gcc_assert (dsi
->full_string_p
);
3595 adjust_related_strinfos (loc
, dsi
, srclen
);
3596 dsi
->dont_invalidate
= true;
3600 dsi
->nonzero_chars
= NULL
;
3601 dsi
->full_string_p
= false;
3602 if (lhs
== NULL_TREE
&& builtin_decl_implicit_p (BUILT_IN_STPCPY
))
3603 dsi
->dont_invalidate
= true;
3607 /* strcat src may not overlap dst, so src doesn't need to be
3608 invalidated either. */
3609 si
->dont_invalidate
= true;
3611 /* For now. Could remove the lhs from the call and add
3612 lhs = dst; afterwards. */
3620 case BUILT_IN_STRCAT
:
3621 if (srclen
!= NULL_TREE
)
3622 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
3624 fn
= builtin_decl_implicit (BUILT_IN_STRCPY
);
3626 case BUILT_IN_STRCAT_CHK
:
3627 if (srclen
!= NULL_TREE
)
3628 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
3630 fn
= builtin_decl_explicit (BUILT_IN_STRCPY_CHK
);
3631 objsz
= gimple_call_arg (stmt
, 2);
3637 if (fn
== NULL_TREE
)
3642 tree type
= TREE_TYPE (dstlen
);
3644 /* Compute the size of the source sequence, including the nul. */
3645 tree srcsize
= srclen
? srclen
: size_zero_node
;
3646 tree one
= build_int_cst (type
, 1);
3647 srcsize
= fold_build2 (PLUS_EXPR
, type
, srcsize
, one
);
3648 tree dstsize
= fold_build2 (PLUS_EXPR
, type
, dstlen
, one
);
3649 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3651 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, dstsize
,
3654 suppress_warning (stmt
, no_warning_opt
);
3657 tree len
= NULL_TREE
;
3658 if (srclen
!= NULL_TREE
)
3660 args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
3661 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
3663 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
3664 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
,
3665 build_int_cst (type
, 1));
3666 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
3670 dst
= fold_convert_loc (loc
, TREE_TYPE (dst
), unshare_expr (endptr
));
3672 dst
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
, TREE_TYPE (dst
), dst
,
3673 fold_convert_loc (loc
, sizetype
,
3674 unshare_expr (dstlen
)));
3675 dst
= force_gimple_operand_gsi (&m_gsi
, dst
, true, NULL_TREE
, true,
3679 objsz
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (objsz
), objsz
,
3680 fold_convert_loc (loc
, TREE_TYPE (objsz
),
3681 unshare_expr (dstlen
)));
3682 objsz
= force_gimple_operand_gsi (&m_gsi
, objsz
, true, NULL_TREE
, true,
3685 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3687 fprintf (dump_file
, "Optimizing: ");
3688 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3690 if (srclen
!= NULL_TREE
)
3691 success
= update_gimple_call (&m_gsi
, fn
, 3 + (objsz
!= NULL_TREE
),
3692 dst
, src
, len
, objsz
);
3694 success
= update_gimple_call (&m_gsi
, fn
, 2 + (objsz
!= NULL_TREE
),
3698 stmt
= gsi_stmt (m_gsi
);
3700 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3702 fprintf (dump_file
, "into: ");
3703 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3705 /* If srclen == NULL, note that current string length can be
3706 computed by transforming this strcpy into stpcpy. */
3707 if (srclen
== NULL_TREE
&& dsi
->dont_invalidate
)
3709 adjust_last_stmt (dsi
, stmt
, true);
3710 if (srclen
!= NULL_TREE
)
3712 laststmt
.stmt
= stmt
;
3713 laststmt
.len
= srclen
;
3714 laststmt
.stridx
= dsi
->idx
;
3717 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3718 fprintf (dump_file
, "not possible.\n");
3721 suppress_warning (stmt
, no_warning_opt
);
3724 /* Handle a call to an allocation function like alloca, malloc or calloc,
3725 or an ordinary allocation function declared with attribute alloc_size. */
3728 strlen_pass::handle_alloc_call (built_in_function bcode
)
3730 gimple
*stmt
= gsi_stmt (m_gsi
);
3731 tree lhs
= gimple_call_lhs (stmt
);
3732 if (lhs
== NULL_TREE
)
3735 gcc_assert (get_stridx (lhs
, stmt
) == 0);
3736 int idx
= new_stridx (lhs
);
3737 tree length
= NULL_TREE
;
3738 if (bcode
== BUILT_IN_CALLOC
)
3739 length
= build_int_cst (size_type_node
, 0);
3740 strinfo
*si
= new_strinfo (lhs
, idx
, length
, length
!= NULL_TREE
);
3741 if (bcode
== BUILT_IN_CALLOC
)
3743 /* Only set STMT for calloc and malloc. */
3745 /* Only set ENDPTR for calloc. */
3748 else if (bcode
== BUILT_IN_MALLOC
)
3751 /* Set ALLOC is set for all allocation functions. */
3753 set_strinfo (idx
, si
);
3754 si
->writable
= true;
3755 si
->dont_invalidate
= true;
3758 /* Handle a call to memset.
3759 After a call to calloc, memset(,0,) is unnecessary.
3760 memset(malloc(n),0,n) is calloc(n,1).
3761 return true when the call is transformed, false otherwise.
3762 When nonnull uses RVALS to determine range information. */
3765 strlen_pass::handle_builtin_memset (bool *zero_write
)
3767 gimple
*memset_stmt
= gsi_stmt (m_gsi
);
3768 tree ptr
= gimple_call_arg (memset_stmt
, 0);
3769 /* Set to the non-constant offset added to PTR. */
3771 int idx1
= get_stridx (ptr
, memset_stmt
, offrng
, ptr_qry
.rvals
);
3774 strinfo
*si1
= get_strinfo (idx1
);
3777 gimple
*alloc_stmt
= si1
->alloc
;
3778 if (!alloc_stmt
|| !is_gimple_call (alloc_stmt
))
3780 tree callee1
= gimple_call_fndecl (alloc_stmt
);
3781 if (!valid_builtin_call (alloc_stmt
))
3783 tree alloc_size
= gimple_call_arg (alloc_stmt
, 0);
3784 tree memset_size
= gimple_call_arg (memset_stmt
, 2);
3786 /* Check for overflow. */
3787 maybe_warn_overflow (memset_stmt
, false, memset_size
, NULL
, false, true);
3789 /* Bail when there is no statement associated with the destination
3790 (the statement may be null even when SI1->ALLOC is not). */
3794 /* Avoid optimizing if store is at a variable offset from the beginning
3795 of the allocated object. */
3796 if (offrng
[0] != 0 || offrng
[0] != offrng
[1])
3799 /* Bail when the call writes a non-zero value. */
3800 if (!integer_zerop (gimple_call_arg (memset_stmt
, 1)))
3803 /* Let the caller know the memset call cleared the destination. */
3806 enum built_in_function code1
= DECL_FUNCTION_CODE (callee1
);
3807 if (code1
== BUILT_IN_CALLOC
)
3808 /* Not touching alloc_stmt */ ;
3809 else if (code1
== BUILT_IN_MALLOC
3810 && operand_equal_p (memset_size
, alloc_size
, 0))
3812 /* Replace the malloc + memset calls with calloc. */
3813 gimple_stmt_iterator gsi1
= gsi_for_stmt (si1
->stmt
);
3814 update_gimple_call (&gsi1
, builtin_decl_implicit (BUILT_IN_CALLOC
), 2,
3815 alloc_size
, build_one_cst (size_type_node
));
3816 si1
->nonzero_chars
= build_int_cst (size_type_node
, 0);
3817 si1
->full_string_p
= true;
3818 si1
->stmt
= gsi_stmt (gsi1
);
3822 tree lhs
= gimple_call_lhs (memset_stmt
);
3823 unlink_stmt_vdef (memset_stmt
);
3826 gimple
*assign
= gimple_build_assign (lhs
, ptr
);
3827 gsi_replace (&m_gsi
, assign
, false);
3831 gsi_remove (&m_gsi
, true);
3832 release_defs (memset_stmt
);
3838 /* Return first such statement if RES is used in statements testing its
3839 equality to zero, and null otherwise. If EXCLUSIVE is true, return
3840 nonnull if and only RES is used in such expressions exclusively and
3844 use_in_zero_equality (tree res
, bool exclusive
= true)
3846 gimple
*first_use
= NULL
;
3848 use_operand_p use_p
;
3849 imm_use_iterator iter
;
3851 FOR_EACH_IMM_USE_FAST (use_p
, iter
, res
)
3853 gimple
*use_stmt
= USE_STMT (use_p
);
3855 if (is_gimple_debug (use_stmt
))
3858 if (gimple_code (use_stmt
) == GIMPLE_ASSIGN
)
3860 tree_code code
= gimple_assign_rhs_code (use_stmt
);
3861 if (code
== COND_EXPR
)
3863 tree cond_expr
= gimple_assign_rhs1 (use_stmt
);
3864 if ((TREE_CODE (cond_expr
) != EQ_EXPR
3865 && (TREE_CODE (cond_expr
) != NE_EXPR
))
3866 || !integer_zerop (TREE_OPERAND (cond_expr
, 1)))
3873 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
3875 if (!integer_zerop (gimple_assign_rhs2 (use_stmt
)))
3887 else if (gimple_code (use_stmt
) == GIMPLE_COND
)
3889 tree_code code
= gimple_cond_code (use_stmt
);
3890 if ((code
!= EQ_EXPR
&& code
!= NE_EXPR
)
3891 || !integer_zerop (gimple_cond_rhs (use_stmt
)))
3904 first_use
= use_stmt
;
3910 /* Handle a call to memcmp. We try to handle small comparisons by
3911 converting them to load and compare, and replacing the call to memcmp
3912 with a __builtin_memcmp_eq call where possible.
3913 return true when call is transformed, return false otherwise. */
3916 strlen_pass::handle_builtin_memcmp ()
3918 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
3919 tree res
= gimple_call_lhs (stmt
);
3921 if (!res
|| !use_in_zero_equality (res
))
3924 tree arg1
= gimple_call_arg (stmt
, 0);
3925 tree arg2
= gimple_call_arg (stmt
, 1);
3926 tree len
= gimple_call_arg (stmt
, 2);
3927 unsigned HOST_WIDE_INT leni
;
3929 if (tree_fits_uhwi_p (len
)
3930 && (leni
= tree_to_uhwi (len
)) <= GET_MODE_SIZE (word_mode
)
3931 && pow2p_hwi (leni
))
3933 leni
*= CHAR_TYPE_SIZE
;
3934 unsigned align1
= get_pointer_alignment (arg1
);
3935 unsigned align2
= get_pointer_alignment (arg2
);
3936 unsigned align
= MIN (align1
, align2
);
3937 scalar_int_mode mode
;
3938 if (int_mode_for_size (leni
, 1).exists (&mode
)
3939 && (align
>= leni
|| !targetm
.slow_unaligned_access (mode
, align
)))
3941 location_t loc
= gimple_location (stmt
);
3943 type
= build_nonstandard_integer_type (leni
, 1);
3944 gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type
)), leni
));
3945 tree ptrtype
= build_pointer_type_for_mode (char_type_node
,
3947 off
= build_int_cst (ptrtype
, 0);
3948 arg1
= build2_loc (loc
, MEM_REF
, type
, arg1
, off
);
3949 arg2
= build2_loc (loc
, MEM_REF
, type
, arg2
, off
);
3950 tree tem1
= fold_const_aggregate_ref (arg1
);
3953 tree tem2
= fold_const_aggregate_ref (arg2
);
3956 res
= fold_convert_loc (loc
, TREE_TYPE (res
),
3957 fold_build2_loc (loc
, NE_EXPR
,
3960 gimplify_and_update_call_from_tree (&m_gsi
, res
);
3965 gimple_call_set_fndecl (stmt
, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ
));
3969 /* Given strinfo IDX for ARG, sets LENRNG[] to the range of lengths
3970 of the string(s) referenced by ARG if it can be determined.
3971 If the length cannot be determined, sets *SIZE to the size of
3972 the array the string is stored in, if any. If no such array is
3973 known, sets *SIZE to -1. When the strings are nul-terminated sets
3974 *NULTERM to true, otherwise to false. When nonnull uses RVALS to
3975 determine range information. Returns true on success. */
3978 strlen_pass::get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
3979 unsigned HOST_WIDE_INT lenrng
[2],
3980 unsigned HOST_WIDE_INT
*size
, bool *nulterm
)
3983 *size
= HOST_WIDE_INT_M1U
;
3987 /* IDX is the inverted constant string length. */
3989 lenrng
[1] = lenrng
[0];
3994 /* Set so that both LEN and ~LEN are invalid lengths, i.e., maximum
3995 possible length + 1. */
3996 lenrng
[0] = lenrng
[1] = HOST_WIDE_INT_MAX
;
3998 if (strinfo
*si
= idx
? get_strinfo (idx
) : NULL
)
4000 /* FIXME: Handle all this in_range_strlen_dynamic. */
4001 if (!si
->nonzero_chars
)
4003 else if (tree_fits_uhwi_p (si
->nonzero_chars
))
4005 lenrng
[0] = tree_to_uhwi (si
->nonzero_chars
);
4006 *nulterm
= si
->full_string_p
;
4007 /* Set the upper bound only if the string is known to be
4008 nul-terminated, otherwise leave it at maximum + 1. */
4010 lenrng
[1] = lenrng
[0];
4012 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4015 get_range_query (cfun
)->range_of_expr (r
, si
->nonzero_chars
);
4016 if (r
.kind () == VR_RANGE
)
4018 lenrng
[0] = r
.lower_bound ().to_uhwi ();
4019 lenrng
[1] = r
.upper_bound ().to_uhwi ();
4020 *nulterm
= si
->full_string_p
;
4025 if (lenrng
[0] != HOST_WIDE_INT_MAX
)
4028 /* Compute the minimum and maximum real or possible lengths. */
4029 c_strlen_data lendata
= { };
4030 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
4031 to have it set to the length of the longest string in a PHI. */
4032 lendata
.maxbound
= arg
;
4033 get_range_strlen_dynamic (arg
, stmt
, &lendata
, ptr_qry
.rvals
);
4035 unsigned HOST_WIDE_INT maxbound
= HOST_WIDE_INT_M1U
;
4036 if (tree_fits_uhwi_p (lendata
.maxbound
)
4037 && !integer_all_onesp (lendata
.maxbound
))
4038 maxbound
= tree_to_uhwi (lendata
.maxbound
);
4040 if (tree_fits_uhwi_p (lendata
.minlen
) && tree_fits_uhwi_p (lendata
.maxlen
))
4042 unsigned HOST_WIDE_INT minlen
= tree_to_uhwi (lendata
.minlen
);
4043 unsigned HOST_WIDE_INT maxlen
= tree_to_uhwi (lendata
.maxlen
);
4045 /* The longest string in this data model. */
4046 const unsigned HOST_WIDE_INT lenmax
4047 = tree_to_uhwi (max_object_size ()) - 2;
4049 if (maxbound
== HOST_WIDE_INT_M1U
)
4053 *nulterm
= minlen
== maxlen
;
4055 else if (maxlen
< lenmax
)
4057 *size
= maxbound
+ 1;
4066 if (maxbound
!= HOST_WIDE_INT_M1U
4068 && !integer_all_onesp (lendata
.maxlen
))
4070 /* Set *SIZE to LENDATA.MAXBOUND which is a conservative estimate
4071 of the longest string based on the sizes of the arrays referenced
4073 *size
= maxbound
+ 1;
4081 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
4082 the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
4083 for a sufficiently large BOUND). If the result is based on the length
4084 of one string being greater than the longest string that would fit in
4085 the array pointer to by the argument, set *PLEN and *PSIZE to
4086 the corresponding length (or its complement when the string is known
4087 to be at least as long and need not be nul-terminated) and size.
4088 Otherwise return null. */
4091 strlen_pass::strxcmp_eqz_result (gimple
*stmt
, tree arg1
, int idx1
,
4092 tree arg2
, int idx2
,
4093 unsigned HOST_WIDE_INT bound
,
4094 unsigned HOST_WIDE_INT len
[2],
4095 unsigned HOST_WIDE_INT
*psize
)
4097 /* Determine the range the length of each string is in and whether it's
4098 known to be nul-terminated, or the size of the array it's stored in. */
4100 unsigned HOST_WIDE_INT siz1
, siz2
;
4101 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4102 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &siz1
, &nul1
)
4103 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &siz2
, &nul2
))
4106 /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
4107 to HWI_MAX when invalid. Adjust the length of each string to consider
4108 to be no more than BOUND. */
4109 if (len1rng
[0] < HOST_WIDE_INT_MAX
&& len1rng
[0] > bound
)
4111 if (len1rng
[1] < HOST_WIDE_INT_MAX
&& len1rng
[1] > bound
)
4113 if (len2rng
[0] < HOST_WIDE_INT_MAX
&& len2rng
[0] > bound
)
4115 if (len2rng
[1] < HOST_WIDE_INT_MAX
&& len2rng
[1] > bound
)
4118 /* Two empty strings are equal. */
4119 if (len1rng
[1] == 0 && len2rng
[1] == 0)
4120 return integer_one_node
;
4122 /* The strings are definitely unequal when the lower bound of the length
4123 of one of them is greater than the length of the longest string that
4124 would fit into the other array. */
4125 if (len1rng
[0] == HOST_WIDE_INT_MAX
4126 && len2rng
[0] != HOST_WIDE_INT_MAX
4127 && ((len2rng
[0] < bound
&& len2rng
[0] >= siz1
)
4128 || len2rng
[0] > siz1
))
4131 len
[0] = len1rng
[0];
4132 /* Set LEN[0] to the lower bound of ARG1's length when it's
4133 nul-terminated or to the complement of its minimum length
4135 len
[1] = nul2
? len2rng
[0] : ~len2rng
[0];
4136 return integer_zero_node
;
4139 if (len2rng
[0] == HOST_WIDE_INT_MAX
4140 && len1rng
[0] != HOST_WIDE_INT_MAX
4141 && ((len1rng
[0] < bound
&& len1rng
[0] >= siz2
)
4142 || len1rng
[0] > siz2
))
4145 len
[0] = nul1
? len1rng
[0] : ~len1rng
[0];
4146 len
[1] = len2rng
[0];
4147 return integer_zero_node
;
4150 /* The strings are also definitely unequal when their lengths are unequal
4151 and at least one is nul-terminated. */
4152 if (len1rng
[0] != HOST_WIDE_INT_MAX
4153 && len2rng
[0] != HOST_WIDE_INT_MAX
4154 && ((len1rng
[1] < len2rng
[0] && nul1
)
4155 || (len2rng
[1] < len1rng
[0] && nul2
)))
4157 if (bound
<= len1rng
[0] || bound
<= len2rng
[0])
4160 *psize
= HOST_WIDE_INT_M1U
;
4162 len
[0] = len1rng
[0];
4163 len
[1] = len2rng
[0];
4164 return integer_zero_node
;
4167 /* The string lengths may be equal or unequal. Even when equal and
4168 both strings nul-terminated, without the string contents there's
4169 no way to determine whether they are equal. */
4173 /* Diagnose pointless calls to strcmp or strncmp STMT with string
4174 arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
4175 whose result is used in equality expressions that evaluate to
4176 a constant due to one argument being longer than the size of
4180 maybe_warn_pointless_strcmp (gimple
*stmt
, HOST_WIDE_INT bound
,
4181 unsigned HOST_WIDE_INT len
[2],
4182 unsigned HOST_WIDE_INT siz
)
4184 tree lhs
= gimple_call_lhs (stmt
);
4185 gimple
*use
= use_in_zero_equality (lhs
, /* exclusive = */ false);
4189 bool at_least
= false;
4191 /* Excessive LEN[i] indicates a lower bound. */
4192 if (len
[0] > HOST_WIDE_INT_MAX
)
4198 if (len
[1] > HOST_WIDE_INT_MAX
)
4204 unsigned HOST_WIDE_INT minlen
= MIN (len
[0], len
[1]);
4206 /* FIXME: Include a note pointing to the declaration of the smaller
4208 location_t stmt_loc
= gimple_or_expr_nonartificial_location (stmt
, lhs
);
4210 tree callee
= gimple_call_fndecl (stmt
);
4211 bool warned
= false;
4212 if (siz
<= minlen
&& bound
== -1)
4213 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4215 ? G_("%qD of a string of length %wu or more and "
4216 "an array of size %wu evaluates to nonzero")
4217 : G_("%qD of a string of length %wu and an array "
4218 "of size %wu evaluates to nonzero")),
4219 callee
, minlen
, siz
);
4220 else if (!at_least
&& siz
<= HOST_WIDE_INT_MAX
)
4222 if (len
[0] != HOST_WIDE_INT_MAX
&& len
[1] != HOST_WIDE_INT_MAX
)
4223 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4224 "%qD of strings of length %wu and %wu "
4225 "and bound of %wu evaluates to nonzero",
4226 callee
, len
[0], len
[1], bound
);
4228 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4229 "%qD of a string of length %wu, an array "
4230 "of size %wu and bound of %wu evaluates to "
4232 callee
, minlen
, siz
, bound
);
4238 location_t use_loc
= gimple_location (use
);
4239 if (LOCATION_LINE (stmt_loc
) != LOCATION_LINE (use_loc
))
4240 inform (use_loc
, "in this expression");
4244 /* Optimize a call to strcmp or strncmp either by folding it to a constant
4245 when possible or by transforming the latter to the former. Warn about
4246 calls where the length of one argument is greater than the size of
4247 the array to which the other argument points if the latter's length
4248 is not known. Return true when the call has been transformed into
4249 another and false otherwise. */
4252 strlen_pass::handle_builtin_string_cmp ()
4254 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
4255 tree lhs
= gimple_call_lhs (stmt
);
4260 tree arg1
= gimple_call_arg (stmt
, 0);
4261 tree arg2
= gimple_call_arg (stmt
, 1);
4262 int idx1
= get_stridx (arg1
, stmt
);
4263 int idx2
= get_stridx (arg2
, stmt
);
4265 /* For strncmp set to the value of the third argument if known. */
4266 HOST_WIDE_INT bound
= -1;
4267 tree len
= NULL_TREE
;
4268 /* Extract the strncmp bound. */
4269 if (gimple_call_num_args (stmt
) == 3)
4271 len
= gimple_call_arg (stmt
, 2);
4272 if (tree_fits_shwi_p (len
))
4273 bound
= tree_to_shwi (len
);
4275 /* If the bound argument is NOT known, do nothing. */
4280 /* Avoid folding if either argument is not a nul-terminated array.
4281 Defer warning until later. */
4282 if (!check_nul_terminated_array (NULL_TREE
, arg1
, len
)
4283 || !check_nul_terminated_array (NULL_TREE
, arg2
, len
))
4287 /* Set to the length of one argument (or its complement if it's
4288 the lower bound of a range) and the size of the array storing
4289 the other if the result is based on the former being equal to
4290 or greater than the latter. */
4291 unsigned HOST_WIDE_INT len
[2] = { HOST_WIDE_INT_MAX
, HOST_WIDE_INT_MAX
};
4292 unsigned HOST_WIDE_INT siz
= HOST_WIDE_INT_M1U
;
4294 /* Try to determine if the two strings are either definitely equal
4295 or definitely unequal and if so, either fold the result to zero
4296 (when equal) or set the range of the result to ~[0, 0] otherwise. */
4297 if (tree eqz
= strxcmp_eqz_result (stmt
, arg1
, idx1
, arg2
, idx2
, bound
,
4300 if (integer_zerop (eqz
))
4302 maybe_warn_pointless_strcmp (stmt
, bound
, len
, siz
);
4304 /* When the lengths of the first two string arguments are
4305 known to be unequal set the range of the result to non-zero.
4306 This allows the call to be eliminated if its result is only
4307 used in tests for equality to zero. */
4308 wide_int zero
= wi::zero (TYPE_PRECISION (TREE_TYPE (lhs
)));
4309 set_range_info (lhs
, VR_ANTI_RANGE
, zero
, zero
);
4312 /* When the two strings are definitely equal (such as when they
4313 are both empty) fold the call to the constant result. */
4314 replace_call_with_value (&m_gsi
, integer_zero_node
);
4319 /* Return if nothing is known about the strings pointed to by ARG1
4321 if (idx1
== 0 && idx2
== 0)
4324 /* Determine either the length or the size of each of the strings,
4325 whichever is available. */
4326 HOST_WIDE_INT cstlen1
= -1, cstlen2
= -1;
4327 HOST_WIDE_INT arysiz1
= -1, arysiz2
= -1;
4330 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4331 unsigned HOST_WIDE_INT arsz1
, arsz2
;
4334 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &arsz1
, nulterm
)
4335 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &arsz2
, nulterm
+ 1))
4338 if (len1rng
[0] == len1rng
[1] && len1rng
[0] < HOST_WIDE_INT_MAX
)
4339 cstlen1
= len1rng
[0];
4340 else if (arsz1
< HOST_WIDE_INT_M1U
)
4343 if (len2rng
[0] == len2rng
[1] && len2rng
[0] < HOST_WIDE_INT_MAX
)
4344 cstlen2
= len2rng
[0];
4345 else if (arsz2
< HOST_WIDE_INT_M1U
)
4349 /* Bail if neither the string length nor the size of the array
4350 it is stored in can be determined. */
4351 if ((cstlen1
< 0 && arysiz1
< 0)
4352 || (cstlen2
< 0 && arysiz2
< 0)
4353 || (cstlen1
< 0 && cstlen2
< 0))
4361 /* The exact number of characters to compare. */
4362 HOST_WIDE_INT cmpsiz
;
4363 if (cstlen1
>= 0 && cstlen2
>= 0)
4364 cmpsiz
= MIN (cstlen1
, cstlen2
);
4365 else if (cstlen1
>= 0)
4370 cmpsiz
= MIN (cmpsiz
, bound
);
4371 /* The size of the array in which the unknown string is stored. */
4372 HOST_WIDE_INT varsiz
= arysiz1
< 0 ? arysiz2
: arysiz1
;
4374 if ((varsiz
< 0 || cmpsiz
< varsiz
) && use_in_zero_equality (lhs
))
4376 /* If the known length is less than the size of the other array
4377 and the strcmp result is only used to test equality to zero,
4378 transform the call to the equivalent _eq call. */
4379 if (tree fn
= builtin_decl_implicit (bound
< 0 ? BUILT_IN_STRCMP_EQ
4380 : BUILT_IN_STRNCMP_EQ
))
4382 tree n
= build_int_cst (size_type_node
, cmpsiz
);
4383 update_gimple_call (&m_gsi
, fn
, 3, arg1
, arg2
, n
);
4391 /* Handle a POINTER_PLUS_EXPR statement.
4392 For p = "abcd" + 2; compute associated length, or if
4393 p = q + off is pointing to a '\0' character of a string, call
4394 zero_length_string on it. */
4397 strlen_pass::handle_pointer_plus ()
4399 gimple
*stmt
= gsi_stmt (m_gsi
);
4400 tree lhs
= gimple_assign_lhs (stmt
), off
;
4401 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
4409 tree off
= gimple_assign_rhs2 (stmt
);
4410 if (tree_fits_uhwi_p (off
)
4411 && tree_to_uhwi (off
) <= (unsigned HOST_WIDE_INT
) ~idx
)
4412 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)]
4413 = ~(~idx
- (int) tree_to_uhwi (off
));
4417 si
= get_strinfo (idx
);
4418 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
4421 off
= gimple_assign_rhs2 (stmt
);
4423 if (si
->full_string_p
&& operand_equal_p (si
->nonzero_chars
, off
, 0))
4424 zsi
= zero_length_string (lhs
, si
);
4425 else if (TREE_CODE (off
) == SSA_NAME
)
4427 gimple
*def_stmt
= SSA_NAME_DEF_STMT (off
);
4428 if (gimple_assign_single_p (def_stmt
)
4429 && si
->full_string_p
4430 && operand_equal_p (si
->nonzero_chars
,
4431 gimple_assign_rhs1 (def_stmt
), 0))
4432 zsi
= zero_length_string (lhs
, si
);
4435 && si
->endptr
!= NULL_TREE
4436 && si
->endptr
!= lhs
4437 && TREE_CODE (si
->endptr
) == SSA_NAME
)
4439 enum tree_code rhs_code
4440 = useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (si
->endptr
))
4441 ? SSA_NAME
: NOP_EXPR
;
4442 gimple_assign_set_rhs_with_ops (&m_gsi
, rhs_code
, si
->endptr
);
4443 gcc_assert (gsi_stmt (m_gsi
) == stmt
);
4448 /* Set LENRANGE to the number of nonzero bytes for a store of TYPE and
4449 clear all flags. Return true on success and false on failure. */
4452 nonzero_bytes_for_type (tree type
, unsigned lenrange
[3],
4453 bool *nulterm
, bool *allnul
, bool *allnonnul
)
4455 /* Use the size of the type of the expression as the size of the store,
4456 and set the upper bound of the length range to that of the size.
4457 Nothing is known about the contents so clear all flags. */
4458 tree typesize
= TYPE_SIZE_UNIT (type
);
4462 if (!tree_fits_uhwi_p (typesize
))
4465 unsigned HOST_WIDE_INT sz
= tree_to_uhwi (typesize
);
4470 lenrange
[1] = lenrange
[2] ? lenrange
[2] - 1 : 0;
4478 /* Recursively determine the minimum and maximum number of leading nonzero
4479 bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
4481 Sets LENRANGE[2] to the total size of the access (which may be less
4482 than LENRANGE[1] when what's being referenced by EXP is a pointer
4483 rather than an array).
4484 Sets *NULTERM if the representation contains a zero byte, sets *ALLNUL
4485 if all the bytes are zero, and *ALLNONNUL is all are nonzero.
4486 OFFSET and NBYTES are the offset into the representation and
4487 the size of the access to it determined from an ADDR_EXPR (i.e.,
4488 a pointer) or MEM_REF or zero for other expressions.
4489 Uses RVALS to determine range information.
4490 Avoids recursing deeper than the limits in SNLIM allow.
4491 Returns true on success and false otherwise. */
4494 strlen_pass::count_nonzero_bytes (tree exp
, gimple
*stmt
,
4495 unsigned HOST_WIDE_INT offset
,
4496 unsigned HOST_WIDE_INT nbytes
,
4497 unsigned lenrange
[3], bool *nulterm
,
4498 bool *allnul
, bool *allnonnul
,
4499 ssa_name_limit_t
&snlim
)
4501 if (TREE_CODE (exp
) == SSA_NAME
)
4503 /* Handle non-zero single-character stores specially. */
4504 tree type
= TREE_TYPE (exp
);
4505 if (TREE_CODE (type
) == INTEGER_TYPE
4506 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
4507 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
)
4508 && tree_expr_nonzero_p (exp
))
4510 /* If the character EXP is known to be non-zero (even if its
4511 exact value is not known) recurse once to set the range
4512 for an arbitrary constant. */
4513 exp
= build_int_cst (type
, 1);
4514 return count_nonzero_bytes (exp
, stmt
,
4515 offset
, 1, lenrange
,
4516 nulterm
, allnul
, allnonnul
, snlim
);
4519 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4520 if (gimple_assign_single_p (stmt
))
4522 exp
= gimple_assign_rhs1 (stmt
);
4524 && TREE_CODE (exp
) != CONSTRUCTOR
4525 && TREE_CODE (exp
) != MEM_REF
)
4527 /* Handle DECLs, CONSTRUCTOR and MEM_REF below. */
4529 else if (gimple_code (stmt
) == GIMPLE_PHI
)
4531 /* Avoid processing an SSA_NAME that has already been visited
4532 or if an SSA_NAME limit has been reached. Indicate success
4533 if the former and failure if the latter. */
4534 if (int res
= snlim
.next_phi (exp
))
4537 /* Determine the minimum and maximum from the PHI arguments. */
4538 unsigned int n
= gimple_phi_num_args (stmt
);
4539 for (unsigned i
= 0; i
!= n
; i
++)
4541 tree def
= gimple_phi_arg_def (stmt
, i
);
4542 if (!count_nonzero_bytes (def
, stmt
,
4543 offset
, nbytes
, lenrange
, nulterm
,
4544 allnul
, allnonnul
, snlim
))
4552 if (TREE_CODE (exp
) == CONSTRUCTOR
)
4555 /* If NBYTES has already been determined by an outer MEM_REF
4556 fail rather than overwriting it (this shouldn't happen). */
4559 tree type
= TREE_TYPE (exp
);
4560 tree size
= TYPE_SIZE_UNIT (type
);
4561 if (!size
|| !tree_fits_uhwi_p (size
))
4564 unsigned HOST_WIDE_INT byte_size
= tree_to_uhwi (size
);
4565 if (byte_size
< offset
)
4568 nbytes
= byte_size
- offset
;
4571 if (TREE_CODE (exp
) == MEM_REF
)
4576 tree arg
= TREE_OPERAND (exp
, 0);
4577 tree off
= TREE_OPERAND (exp
, 1);
4579 if (TREE_CODE (off
) != INTEGER_CST
|| !tree_fits_uhwi_p (off
))
4582 unsigned HOST_WIDE_INT wioff
= tree_to_uhwi (off
);
4583 if (INT_MAX
< wioff
)
4587 if (INT_MAX
< offset
)
4590 /* The size of the MEM_REF access determines the number of bytes. */
4591 tree type
= TREE_TYPE (exp
);
4592 tree typesize
= TYPE_SIZE_UNIT (type
);
4593 if (!typesize
|| !tree_fits_uhwi_p (typesize
))
4595 nbytes
= tree_to_uhwi (typesize
);
4599 /* Handle MEM_REF = SSA_NAME types of assignments. */
4600 return count_nonzero_bytes_addr (arg
, stmt
,
4601 offset
, nbytes
, lenrange
, nulterm
,
4602 allnul
, allnonnul
, snlim
);
4605 if (VAR_P (exp
) || TREE_CODE (exp
) == CONST_DECL
)
4607 /* If EXP can be folded into a constant use the result. Otherwise
4608 proceed to use EXP to determine a range of the result. */
4609 if (tree fold_exp
= ctor_for_folding (exp
))
4610 if (fold_exp
!= error_mark_node
)
4614 const char *prep
= NULL
;
4615 if (TREE_CODE (exp
) == STRING_CST
)
4617 unsigned nchars
= TREE_STRING_LENGTH (exp
);
4618 if (nchars
< offset
)
4622 /* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
4623 (i.e., it's the size of a pointer), or from MEM_REF (as the size
4624 of the access), set it here to the size of the string, including
4625 all internal and trailing nuls if the string has any. */
4626 nbytes
= nchars
- offset
;
4627 else if (nchars
- offset
< nbytes
)
4630 prep
= TREE_STRING_POINTER (exp
) + offset
;
4633 unsigned char buf
[256];
4636 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8)
4638 /* If the pointer to representation hasn't been set above
4639 for STRING_CST point it at the buffer. */
4640 prep
= reinterpret_cast <char *>(buf
);
4641 /* Try to extract the representation of the constant object
4642 or expression starting from the offset. */
4643 unsigned repsize
= native_encode_expr (exp
, buf
, sizeof buf
, offset
);
4644 if (repsize
< nbytes
)
4646 /* This should only happen when REPSIZE is zero because EXP
4647 doesn't denote an object with a known initializer, except
4648 perhaps when the reference reads past its end. */
4654 else if (nbytes
< repsize
)
4659 return nonzero_bytes_for_type (TREE_TYPE (exp
), lenrange
,
4660 nulterm
, allnul
, allnonnul
);
4662 /* Compute the number of leading nonzero bytes in the representation
4663 and update the minimum and maximum. */
4664 unsigned n
= prep
? strnlen (prep
, nbytes
) : nbytes
;
4666 if (n
< lenrange
[0])
4668 if (lenrange
[1] < n
)
4671 /* Set the size of the representation. */
4672 if (lenrange
[2] < nbytes
)
4673 lenrange
[2] = nbytes
;
4675 /* Clear NULTERM if none of the bytes is zero. */
4681 /* When the initial number of non-zero bytes N is non-zero, reset
4682 *ALLNUL; if N is less than that the size of the representation
4683 also clear *ALLNONNUL. */
4688 else if (*allnul
|| *allnonnul
)
4694 /* When either ALLNUL is set and N is zero, also determine
4695 whether all subsequent bytes after the first one (which
4696 is nul) are zero or nonzero and clear ALLNUL if not. */
4697 for (const char *p
= prep
; p
!= prep
+ nbytes
; ++p
)
4709 /* Like count_nonzero_bytes, but instead of counting bytes in EXP, count
4710 bytes that are pointed to by EXP, which should be a pointer. */
4713 strlen_pass::count_nonzero_bytes_addr (tree exp
, gimple
*stmt
,
4714 unsigned HOST_WIDE_INT offset
,
4715 unsigned HOST_WIDE_INT nbytes
,
4716 unsigned lenrange
[3], bool *nulterm
,
4717 bool *allnul
, bool *allnonnul
,
4718 ssa_name_limit_t
&snlim
)
4720 int idx
= get_stridx (exp
, stmt
);
4723 strinfo
*si
= get_strinfo (idx
);
4727 /* Handle both constant lengths as well non-constant lengths
4729 unsigned HOST_WIDE_INT minlen
, maxlen
;
4730 if (tree_fits_shwi_p (si
->nonzero_chars
))
4731 minlen
= maxlen
= tree_to_shwi (si
->nonzero_chars
);
4732 else if (si
->nonzero_chars
4733 && TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4736 ptr_qry
.rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
);
4737 if (vr
.kind () != VR_RANGE
)
4740 minlen
= tree_to_uhwi (vr
.min ());
4741 maxlen
= tree_to_uhwi (vr
.max ());
4746 if (maxlen
< offset
)
4749 minlen
= minlen
< offset
? 0 : minlen
- offset
;
4751 if (maxlen
+ 1 < nbytes
)
4754 if (nbytes
<= minlen
)
4757 if (nbytes
< minlen
)
4760 if (nbytes
< maxlen
)
4764 if (minlen
< lenrange
[0])
4765 lenrange
[0] = minlen
;
4766 if (lenrange
[1] < maxlen
)
4767 lenrange
[1] = maxlen
;
4769 if (lenrange
[2] < nbytes
)
4770 lenrange
[2] = nbytes
;
4772 /* Since only the length of the string are known and not its contents,
4773 clear ALLNUL and ALLNONNUL purely on the basis of the length. */
4775 if (minlen
< nbytes
)
4781 if (TREE_CODE (exp
) == ADDR_EXPR
)
4782 return count_nonzero_bytes (TREE_OPERAND (exp
, 0), stmt
,
4784 lenrange
, nulterm
, allnul
, allnonnul
, snlim
);
4786 if (TREE_CODE (exp
) == SSA_NAME
)
4788 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4789 if (gimple_code (stmt
) == GIMPLE_PHI
)
4791 /* Avoid processing an SSA_NAME that has already been visited
4792 or if an SSA_NAME limit has been reached. Indicate success
4793 if the former and failure if the latter. */
4794 if (int res
= snlim
.next_phi (exp
))
4797 /* Determine the minimum and maximum from the PHI arguments. */
4798 unsigned int n
= gimple_phi_num_args (stmt
);
4799 for (unsigned i
= 0; i
!= n
; i
++)
4801 tree def
= gimple_phi_arg_def (stmt
, i
);
4802 if (!count_nonzero_bytes_addr (def
, stmt
,
4803 offset
, nbytes
, lenrange
,
4804 nulterm
, allnul
, allnonnul
,
4813 /* Otherwise we don't know anything. */
4815 if (lenrange
[1] < nbytes
)
4816 lenrange
[1] = nbytes
;
4817 if (lenrange
[2] < nbytes
)
4818 lenrange
[2] = nbytes
;
4825 /* Same as above except with an implicit SSA_NAME limit. When EXPR_OR_TYPE
4826 is a type rather than an expression use its size to compute the range.
4827 RVALS is used to determine ranges of dynamically computed string lengths
4828 (the results of strlen). */
4831 strlen_pass::count_nonzero_bytes (tree expr_or_type
, gimple
*stmt
,
4832 unsigned lenrange
[3], bool *nulterm
,
4833 bool *allnul
, bool *allnonnul
)
4835 if (TYPE_P (expr_or_type
))
4836 return nonzero_bytes_for_type (expr_or_type
, lenrange
,
4837 nulterm
, allnul
, allnonnul
);
4839 /* Set to optimistic values so the caller doesn't have to worry about
4840 initializing these and to what. On success, the function will clear
4841 these if it determines their values are different but being recursive
4842 it never sets either to true. On failure, their values are
4848 ssa_name_limit_t snlim
;
4849 tree expr
= expr_or_type
;
4850 return count_nonzero_bytes (expr
, stmt
,
4851 0, 0, lenrange
, nulterm
, allnul
, allnonnul
,
4855 /* Handle a single or multibyte store other than by a built-in function,
4856 either via a single character assignment or by multi-byte assignment
4857 either via MEM_REF or via a type other than char (such as in
4858 '*(int*)a = 12345'). Return true to let the caller advance *GSI to
4859 the next statement in the basic block and false otherwise. */
4862 strlen_pass::handle_store (bool *zero_write
)
4864 gimple
*stmt
= gsi_stmt (m_gsi
);
4865 /* The LHS and RHS of the store. The RHS is null if STMT is a function
4866 call. STORETYPE is the type of the store (determined from either
4867 the RHS of the assignment statement or the LHS of a function call. */
4868 tree lhs
, rhs
, storetype
;
4869 if (is_gimple_assign (stmt
))
4871 lhs
= gimple_assign_lhs (stmt
);
4872 rhs
= gimple_assign_rhs1 (stmt
);
4873 storetype
= TREE_TYPE (rhs
);
4875 else if (is_gimple_call (stmt
))
4877 lhs
= gimple_call_lhs (stmt
);
4879 storetype
= TREE_TYPE (lhs
);
4884 tree ssaname
= NULL_TREE
;
4888 range_query
*const rvals
= ptr_qry
.rvals
;
4890 /* The offset of the first byte in LHS modified by the store. */
4891 unsigned HOST_WIDE_INT offset
= 0;
4893 if (TREE_CODE (lhs
) == MEM_REF
4894 && TREE_CODE (TREE_OPERAND (lhs
, 0)) == SSA_NAME
)
4896 tree mem_offset
= TREE_OPERAND (lhs
, 1);
4897 if (tree_fits_uhwi_p (mem_offset
))
4899 /* Get the strinfo for the base, and use it if it starts with at
4900 least OFFSET nonzero characters. This is trivially true if
4902 offset
= tree_to_uhwi (mem_offset
);
4903 idx
= get_stridx (TREE_OPERAND (lhs
, 0), stmt
);
4905 si
= get_strinfo (idx
);
4907 ssaname
= TREE_OPERAND (lhs
, 0);
4909 || compare_nonzero_chars (si
, stmt
, offset
, rvals
) < 0)
4911 *zero_write
= rhs
? initializer_zerop (rhs
) : false;
4914 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4915 if (count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
, lenrange
,
4916 &dummy
, &dummy
, &dummy
))
4917 maybe_warn_overflow (stmt
, true, lenrange
[2]);
4925 idx
= get_addr_stridx (lhs
, stmt
, NULL_TREE
, &offset
, rvals
);
4927 si
= get_strinfo (idx
);
4930 /* Minimum and maximum leading non-zero bytes and the size of the store. */
4931 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4933 /* Set to the minimum length of the string being assigned if known. */
4934 unsigned HOST_WIDE_INT rhs_minlen
;
4936 /* STORING_NONZERO_P is true iff not all stored characters are zero.
4937 STORING_ALL_NONZERO_P is true if all stored characters are zero.
4938 STORING_ALL_ZEROS_P is true iff all stored characters are zero.
4939 Both are false when it's impossible to determine which is true. */
4940 bool storing_nonzero_p
;
4941 bool storing_all_nonzero_p
;
4942 bool storing_all_zeros_p
;
4943 /* FULL_STRING_P is set when the stored sequence of characters form
4944 a nul-terminated string. */
4947 const bool ranges_valid
4948 = count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
,
4949 lenrange
, &full_string_p
,
4950 &storing_all_zeros_p
, &storing_all_nonzero_p
);
4954 rhs_minlen
= lenrange
[0];
4955 storing_nonzero_p
= lenrange
[1] > 0;
4956 *zero_write
= storing_all_zeros_p
;
4958 maybe_warn_overflow (stmt
, true, lenrange
[2]);
4962 rhs_minlen
= HOST_WIDE_INT_M1U
;
4963 full_string_p
= false;
4964 storing_nonzero_p
= false;
4965 storing_all_zeros_p
= false;
4966 storing_all_nonzero_p
= false;
4971 /* The corresponding element is set to 1 if the first and last
4972 element, respectively, of the sequence of characters being
4973 written over the string described by SI ends before
4974 the terminating nul (if it has one), to zero if the nul is
4975 being overwritten but not beyond, or negative otherwise. */
4976 int store_before_nul
[2];
4979 /* The offset of the last stored byte. */
4980 unsigned HOST_WIDE_INT endoff
= offset
+ lenrange
[2] - 1;
4982 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
4983 if (endoff
== offset
)
4984 store_before_nul
[1] = store_before_nul
[0];
4987 = compare_nonzero_chars (si
, stmt
, endoff
, rvals
);
4992 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
4993 store_before_nul
[1] = store_before_nul
[0];
4994 gcc_assert (offset
== 0 || store_before_nul
[0] >= 0);
4997 if (storing_all_zeros_p
4998 && store_before_nul
[0] == 0
4999 && store_before_nul
[1] == 0
5000 && si
->full_string_p
)
5002 /* When overwriting a '\0' with a '\0', the store can be removed
5003 if we know it has been stored in the current function. */
5004 if (!stmt_could_throw_p (cfun
, stmt
) && si
->writable
)
5006 unlink_stmt_vdef (stmt
);
5007 release_defs (stmt
);
5008 gsi_remove (&m_gsi
, true);
5013 si
->writable
= true;
5019 if (store_before_nul
[1] > 0
5020 && storing_nonzero_p
5021 && lenrange
[0] == lenrange
[1]
5022 && lenrange
[0] == lenrange
[2]
5023 && TREE_CODE (storetype
) == INTEGER_TYPE
)
5025 /* Handle a store of one or more non-nul characters that ends
5026 before the terminating nul of the destination and so does
5027 not affect its length
5028 If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
5029 and if we aren't storing '\0', we know that the length of
5030 the string and any other zero terminated string in memory
5031 remains the same. In that case we move to the next gimple
5032 statement and return to signal the caller that it shouldn't
5033 invalidate anything.
5035 This is beneficial for cases like:
5040 strcpy (p, "foobar");
5041 size_t len = strlen (p); // can be folded to 6
5042 size_t len2 = strlen (q); // has to be computed
5044 size_t len3 = strlen (p); // can be folded to 6
5045 size_t len4 = strlen (q); // can be folded to len2
5046 bar (len, len2, len3, len4);
5052 if (storing_all_zeros_p
5053 || storing_nonzero_p
5054 || (offset
!= 0 && store_before_nul
[1] > 0))
5056 /* When STORING_NONZERO_P, we know that the string will start
5057 with at least OFFSET + 1 nonzero characters. If storing
5058 a single character, set si->NONZERO_CHARS to the result.
5059 If storing multiple characters, try to determine the number
5060 of leading non-zero characters and set si->NONZERO_CHARS to
5063 When STORING_ALL_ZEROS_P, we know that the string is now
5064 OFFSET characters long.
5066 Otherwise, we're storing an unknown value at offset OFFSET,
5067 so need to clip the nonzero_chars to OFFSET.
5068 Use the minimum length of the string (or individual character)
5069 being stored if it's known. Otherwise, STORING_NONZERO_P
5070 guarantees it's at least 1. */
5072 = storing_nonzero_p
&& ranges_valid
? lenrange
[0] : 1;
5073 location_t loc
= gimple_location (stmt
);
5074 tree oldlen
= si
->nonzero_chars
;
5075 if (store_before_nul
[1] == 0 && si
->full_string_p
)
5076 /* We're overwriting the nul terminator with a nonzero or
5077 unknown character. If the previous stmt was a memcpy,
5078 its length may be decreased. */
5079 adjust_last_stmt (si
, stmt
, false);
5080 si
= unshare_strinfo (si
);
5081 if (storing_nonzero_p
)
5083 gcc_assert (len
>= 0);
5084 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
+ len
);
5087 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
);
5089 /* Set FULL_STRING_P only if the length of the strings being
5090 written is the same, and clear it if the strings have
5091 different lengths. In the latter case the length stored
5092 in si->NONZERO_CHARS becomes the lower bound.
5093 FIXME: Handle the upper bound of the length if possible. */
5094 si
->full_string_p
= full_string_p
&& lenrange
[0] == lenrange
[1];
5096 if (storing_all_zeros_p
5098 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5099 si
->endptr
= ssaname
;
5104 si
->writable
= true;
5105 si
->dont_invalidate
= true;
5108 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
5109 si
->nonzero_chars
, oldlen
);
5110 adjust_related_strinfos (loc
, si
, adj
);
5116 else if (idx
== 0 && (storing_all_zeros_p
|| storing_nonzero_p
))
5119 idx
= new_stridx (ssaname
);
5121 idx
= new_addr_stridx (lhs
);
5124 tree ptr
= (ssaname
? ssaname
: build_fold_addr_expr (lhs
));
5127 if (storing_all_zeros_p
)
5129 else if (storing_nonzero_p
&& ranges_valid
)
5131 /* FIXME: Handle the upper bound of the length when
5132 LENRANGE[0] != LENRANGE[1]. */
5134 if (lenrange
[0] != lenrange
[1])
5135 /* Set the minimum length but ignore the maximum
5137 full_string_p
= false;
5142 tree len
= (slen
<= 0
5144 : build_int_cst (size_type_node
, slen
));
5145 si
= new_strinfo (ptr
, idx
, len
, slen
>= 0 && full_string_p
);
5146 set_strinfo (idx
, si
);
5147 if (storing_all_zeros_p
5149 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5150 si
->endptr
= ssaname
;
5151 si
->dont_invalidate
= true;
5152 si
->writable
= true;
5156 && rhs_minlen
< HOST_WIDE_INT_M1U
5157 && ssaname
== NULL_TREE
5158 && TREE_CODE (TREE_TYPE (lhs
)) == ARRAY_TYPE
)
5160 HOST_WIDE_INT a
= int_size_in_bytes (TREE_TYPE (lhs
));
5161 if (a
> 0 && (unsigned HOST_WIDE_INT
) a
> rhs_minlen
)
5163 int idx
= new_addr_stridx (lhs
);
5166 si
= new_strinfo (build_fold_addr_expr (lhs
), idx
,
5167 build_int_cst (size_type_node
, rhs_minlen
),
5169 set_strinfo (idx
, si
);
5170 si
->dont_invalidate
= true;
5175 if (si
!= NULL
&& offset
== 0 && storing_all_zeros_p
&& lenrange
[2] == 1)
5177 /* For single-byte stores only, allow adjust_last_stmt to remove
5178 the statement if the stored '\0' is immediately overwritten. */
5179 laststmt
.stmt
= stmt
;
5180 laststmt
.len
= build_int_cst (size_type_node
, 1);
5181 laststmt
.stridx
= si
->idx
;
5186 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0. */
5189 fold_strstr_to_strncmp (tree rhs1
, tree rhs2
, gimple
*stmt
)
5191 if (TREE_CODE (rhs1
) != SSA_NAME
5192 || TREE_CODE (rhs2
) != SSA_NAME
)
5195 gimple
*call_stmt
= NULL
;
5196 for (int pass
= 0; pass
< 2; pass
++)
5198 gimple
*g
= SSA_NAME_DEF_STMT (rhs1
);
5199 if (gimple_call_builtin_p (g
, BUILT_IN_STRSTR
)
5200 && has_single_use (rhs1
)
5201 && gimple_call_arg (g
, 0) == rhs2
)
5206 std::swap (rhs1
, rhs2
);
5211 tree arg0
= gimple_call_arg (call_stmt
, 0);
5215 tree arg1
= gimple_call_arg (call_stmt
, 1);
5216 tree arg1_len
= NULL_TREE
;
5217 int idx
= get_stridx (arg1
, call_stmt
);
5222 arg1_len
= build_int_cst (size_type_node
, ~idx
);
5225 strinfo
*si
= get_strinfo (idx
);
5227 arg1_len
= get_string_length (si
);
5231 if (arg1_len
!= NULL_TREE
)
5233 gimple_stmt_iterator gsi
= gsi_for_stmt (call_stmt
);
5234 tree strncmp_decl
= builtin_decl_explicit (BUILT_IN_STRNCMP
);
5236 if (!is_gimple_val (arg1_len
))
5238 tree arg1_len_tmp
= make_ssa_name (TREE_TYPE (arg1_len
));
5239 gassign
*arg1_stmt
= gimple_build_assign (arg1_len_tmp
,
5241 gsi_insert_before (&gsi
, arg1_stmt
, GSI_SAME_STMT
);
5242 arg1_len
= arg1_len_tmp
;
5245 gcall
*strncmp_call
= gimple_build_call (strncmp_decl
, 3,
5246 arg0
, arg1
, arg1_len
);
5247 tree strncmp_lhs
= make_ssa_name (integer_type_node
);
5248 gimple_set_vuse (strncmp_call
, gimple_vuse (call_stmt
));
5249 gimple_call_set_lhs (strncmp_call
, strncmp_lhs
);
5250 gsi_remove (&gsi
, true);
5251 gsi_insert_before (&gsi
, strncmp_call
, GSI_SAME_STMT
);
5252 tree zero
= build_zero_cst (TREE_TYPE (strncmp_lhs
));
5254 if (is_gimple_assign (stmt
))
5256 if (gimple_assign_rhs_code (stmt
) == COND_EXPR
)
5258 tree cond
= gimple_assign_rhs1 (stmt
);
5259 TREE_OPERAND (cond
, 0) = strncmp_lhs
;
5260 TREE_OPERAND (cond
, 1) = zero
;
5264 gimple_assign_set_rhs1 (stmt
, strncmp_lhs
);
5265 gimple_assign_set_rhs2 (stmt
, zero
);
5270 gcond
*cond
= as_a
<gcond
*> (stmt
);
5271 gimple_cond_set_lhs (cond
, strncmp_lhs
);
5272 gimple_cond_set_rhs (cond
, zero
);
5280 /* Return true if TYPE corresponds to a narrow character type. */
5283 is_char_type (tree type
)
5285 return (TREE_CODE (type
) == INTEGER_TYPE
5286 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
5287 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
));
5290 /* Check the built-in call at GSI for validity and optimize it.
5291 Uses RVALS to determine range information.
5292 Return true to let the caller advance *GSI to the next statement
5293 in the basic block and false otherwise. */
5296 strlen_pass::check_and_optimize_call (bool *zero_write
)
5298 gimple
*stmt
= gsi_stmt (m_gsi
);
5300 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
5302 tree fntype
= gimple_call_fntype (stmt
);
5306 if (lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype
)))
5308 handle_alloc_call (BUILT_IN_NONE
);
5312 if (tree lhs
= gimple_call_lhs (stmt
))
5313 handle_assign (lhs
, zero_write
);
5315 /* Proceed to handle user-defined formatting functions. */
5318 /* When not optimizing we must be checking printf calls which
5319 we do even for user-defined functions when they are declared
5320 with attribute format. */
5321 if (!flag_optimize_strlen
5323 || !valid_builtin_call (stmt
))
5324 return !handle_printf_call (&m_gsi
, ptr_qry
);
5326 tree callee
= gimple_call_fndecl (stmt
);
5327 switch (DECL_FUNCTION_CODE (callee
))
5329 case BUILT_IN_STRLEN
:
5330 case BUILT_IN_STRNLEN
:
5331 handle_builtin_strlen ();
5333 case BUILT_IN_STRCHR
:
5334 handle_builtin_strchr ();
5336 case BUILT_IN_STRCPY
:
5337 case BUILT_IN_STRCPY_CHK
:
5338 case BUILT_IN_STPCPY
:
5339 case BUILT_IN_STPCPY_CHK
:
5340 handle_builtin_strcpy (DECL_FUNCTION_CODE (callee
));
5343 case BUILT_IN_STRNCAT
:
5344 case BUILT_IN_STRNCAT_CHK
:
5345 handle_builtin_strncat (DECL_FUNCTION_CODE (callee
));
5348 case BUILT_IN_STPNCPY
:
5349 case BUILT_IN_STPNCPY_CHK
:
5350 case BUILT_IN_STRNCPY
:
5351 case BUILT_IN_STRNCPY_CHK
:
5352 handle_builtin_stxncpy_strncat (false);
5355 case BUILT_IN_MEMCPY
:
5356 case BUILT_IN_MEMCPY_CHK
:
5357 case BUILT_IN_MEMPCPY
:
5358 case BUILT_IN_MEMPCPY_CHK
:
5359 handle_builtin_memcpy (DECL_FUNCTION_CODE (callee
));
5361 case BUILT_IN_STRCAT
:
5362 case BUILT_IN_STRCAT_CHK
:
5363 handle_builtin_strcat (DECL_FUNCTION_CODE (callee
));
5365 case BUILT_IN_ALLOCA
:
5366 case BUILT_IN_ALLOCA_WITH_ALIGN
:
5367 case BUILT_IN_MALLOC
:
5368 case BUILT_IN_CALLOC
:
5369 handle_alloc_call (DECL_FUNCTION_CODE (callee
));
5371 case BUILT_IN_MEMSET
:
5372 if (handle_builtin_memset (zero_write
))
5375 case BUILT_IN_MEMCMP
:
5376 if (handle_builtin_memcmp ())
5379 case BUILT_IN_STRCMP
:
5380 case BUILT_IN_STRNCMP
:
5381 if (handle_builtin_string_cmp ())
5385 if (handle_printf_call (&m_gsi
, ptr_qry
))
5393 /* Handle an assignment statement at *GSI to a LHS of integral type.
5394 If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */
5397 strlen_pass::handle_integral_assign (bool *cleanup_eh
)
5399 gimple
*stmt
= gsi_stmt (m_gsi
);
5400 tree lhs
= gimple_assign_lhs (stmt
);
5401 tree lhs_type
= TREE_TYPE (lhs
);
5403 enum tree_code code
= gimple_assign_rhs_code (stmt
);
5404 if (code
== COND_EXPR
)
5406 tree cond
= gimple_assign_rhs1 (stmt
);
5407 enum tree_code cond_code
= TREE_CODE (cond
);
5409 if (cond_code
== EQ_EXPR
|| cond_code
== NE_EXPR
)
5410 fold_strstr_to_strncmp (TREE_OPERAND (cond
, 0),
5411 TREE_OPERAND (cond
, 1), stmt
);
5413 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5414 fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt
),
5415 gimple_assign_rhs2 (stmt
), stmt
);
5416 else if (gimple_assign_load_p (stmt
)
5417 && TREE_CODE (lhs_type
) == INTEGER_TYPE
5418 && TYPE_MODE (lhs_type
) == TYPE_MODE (char_type_node
)
5419 && (TYPE_PRECISION (lhs_type
)
5420 == TYPE_PRECISION (char_type_node
))
5421 && !gimple_has_volatile_ops (stmt
))
5423 tree off
= integer_zero_node
;
5424 unsigned HOST_WIDE_INT coff
= 0;
5426 tree rhs1
= gimple_assign_rhs1 (stmt
);
5427 if (code
== MEM_REF
)
5429 idx
= get_stridx (TREE_OPERAND (rhs1
, 0), stmt
);
5432 strinfo
*si
= get_strinfo (idx
);
5434 && si
->nonzero_chars
5435 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
5436 && (wi::to_widest (si
->nonzero_chars
)
5437 >= wi::to_widest (off
)))
5438 off
= TREE_OPERAND (rhs1
, 1);
5440 /* This case is not useful. See if get_addr_stridx
5441 returns something usable. */
5446 idx
= get_addr_stridx (rhs1
, stmt
, NULL_TREE
, &coff
);
5449 strinfo
*si
= get_strinfo (idx
);
5451 && si
->nonzero_chars
5452 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
5454 widest_int w1
= wi::to_widest (si
->nonzero_chars
);
5455 widest_int w2
= wi::to_widest (off
) + coff
;
5457 && si
->full_string_p
)
5459 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5461 fprintf (dump_file
, "Optimizing: ");
5462 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5465 /* Reading the final '\0' character. */
5466 tree zero
= build_int_cst (lhs_type
, 0);
5467 gimple_set_vuse (stmt
, NULL_TREE
);
5468 gimple_assign_set_rhs_from_tree (&m_gsi
, zero
);
5470 |= maybe_clean_or_replace_eh_stmt (stmt
,
5472 stmt
= gsi_stmt (m_gsi
);
5475 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5477 fprintf (dump_file
, "into: ");
5478 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5483 /* Reading a character before the final '\0'
5484 character. Just set the value range to ~[0, 0]
5485 if we don't have anything better. */
5487 if (!get_range_query (cfun
)->range_of_expr (r
, lhs
)
5490 r
.set_nonzero (lhs_type
);
5491 set_range_info (lhs
, r
);
5497 else if (code
== MEM_REF
&& TREE_CODE (lhs
) == SSA_NAME
)
5499 if (int idx
= new_stridx (lhs
))
5501 /* Record multi-byte assignments from MEM_REFs. */
5502 bool storing_all_nonzero_p
;
5503 bool storing_all_zeros_p
;
5505 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
5506 tree rhs
= gimple_assign_rhs1 (stmt
);
5507 const bool ranges_valid
5508 = count_nonzero_bytes (rhs
, stmt
,
5509 lenrange
, &full_string_p
,
5510 &storing_all_zeros_p
,
5511 &storing_all_nonzero_p
);
5514 tree length
= build_int_cst (sizetype
, lenrange
[0]);
5515 strinfo
*si
= new_strinfo (lhs
, idx
, length
, full_string_p
);
5516 set_strinfo (idx
, si
);
5517 si
->writable
= true;
5518 si
->dont_invalidate
= true;
5523 if (strlen_to_stridx
)
5525 tree rhs1
= gimple_assign_rhs1 (stmt
);
5526 if (stridx_strlenloc
*ps
= strlen_to_stridx
->get (rhs1
))
5527 strlen_to_stridx
->put (lhs
, stridx_strlenloc (*ps
));
5531 /* Handle assignment statement at *GSI to LHS. Set *ZERO_WRITE if
5532 the assignent stores all zero bytes.. */
5535 strlen_pass::handle_assign (tree lhs
, bool *zero_write
)
5537 tree type
= TREE_TYPE (lhs
);
5538 if (TREE_CODE (type
) == ARRAY_TYPE
)
5539 type
= TREE_TYPE (type
);
5541 bool is_char_store
= is_char_type (type
);
5542 if (!is_char_store
&& TREE_CODE (lhs
) == MEM_REF
)
5544 /* To consider stores into char objects via integer types other
5545 than char but not those to non-character objects, determine
5546 the type of the destination rather than just the type of
5548 for (int i
= 0; i
!= 2; ++i
)
5550 tree ref
= TREE_OPERAND (lhs
, i
);
5551 type
= TREE_TYPE (ref
);
5552 if (TREE_CODE (type
) == POINTER_TYPE
)
5553 type
= TREE_TYPE (type
);
5554 if (TREE_CODE (type
) == ARRAY_TYPE
)
5555 type
= TREE_TYPE (type
);
5556 if (is_char_type (type
))
5558 is_char_store
= true;
5564 /* Handle a single or multibyte assignment. */
5565 if (is_char_store
&& !handle_store (zero_write
))
5572 /* Attempt to check for validity of the performed access a single statement
5573 at *GSI using string length knowledge, and to optimize it.
5574 If the given basic block needs clean-up of EH, CLEANUP_EH is set to
5575 true. Return true to let the caller advance *GSI to the next statement
5576 in the basic block and false otherwise. */
5579 strlen_pass::check_and_optimize_stmt (bool *cleanup_eh
)
5581 gimple
*stmt
= gsi_stmt (m_gsi
);
5583 /* For statements that modify a string, set to true if the write
5585 bool zero_write
= false;
5587 if (is_gimple_call (stmt
))
5589 if (!check_and_optimize_call (&zero_write
))
5592 else if (!flag_optimize_strlen
|| !strlen_optimize
)
5594 else if (is_gimple_assign (stmt
) && !gimple_clobber_p (stmt
))
5596 /* Handle non-clobbering assignment. */
5597 tree lhs
= gimple_assign_lhs (stmt
);
5598 tree lhs_type
= TREE_TYPE (lhs
);
5600 if (TREE_CODE (lhs
) == SSA_NAME
&& POINTER_TYPE_P (lhs_type
))
5602 if (gimple_assign_single_p (stmt
)
5603 || (gimple_assign_cast_p (stmt
)
5604 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt
)))))
5606 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
5607 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = idx
;
5609 else if (gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
5610 handle_pointer_plus ();
5612 else if (TREE_CODE (lhs
) == SSA_NAME
&& INTEGRAL_TYPE_P (lhs_type
))
5613 /* Handle assignment to a character. */
5614 handle_integral_assign (cleanup_eh
);
5615 else if (TREE_CODE (lhs
) != SSA_NAME
&& !TREE_SIDE_EFFECTS (lhs
))
5616 if (!handle_assign (lhs
, &zero_write
))
5619 else if (gcond
*cond
= dyn_cast
<gcond
*> (stmt
))
5621 enum tree_code code
= gimple_cond_code (cond
);
5622 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5623 fold_strstr_to_strncmp (gimple_cond_lhs (stmt
),
5624 gimple_cond_rhs (stmt
), stmt
);
5627 if (gimple_vdef (stmt
))
5628 maybe_invalidate (stmt
, zero_write
);
5632 /* Recursively call maybe_invalidate on stmts that might be executed
5633 in between dombb and current bb and that contain a vdef. Stop when
5634 *count stmts are inspected, or if the whole strinfo vector has
5635 been invalidated. */
5638 do_invalidate (basic_block dombb
, gimple
*phi
, bitmap visited
, int *count
)
5640 unsigned int i
, n
= gimple_phi_num_args (phi
);
5642 for (i
= 0; i
< n
; i
++)
5644 tree vuse
= gimple_phi_arg_def (phi
, i
);
5645 gimple
*stmt
= SSA_NAME_DEF_STMT (vuse
);
5646 basic_block bb
= gimple_bb (stmt
);
5649 || !bitmap_set_bit (visited
, bb
->index
)
5650 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5654 if (gimple_code (stmt
) == GIMPLE_PHI
)
5656 do_invalidate (dombb
, stmt
, visited
, count
);
5663 if (!maybe_invalidate (stmt
))
5668 vuse
= gimple_vuse (stmt
);
5669 stmt
= SSA_NAME_DEF_STMT (vuse
);
5670 if (gimple_bb (stmt
) != bb
)
5672 bb
= gimple_bb (stmt
);
5675 || !bitmap_set_bit (visited
, bb
->index
)
5676 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5683 /* Release pointer_query cache. */
5685 strlen_pass::~strlen_pass ()
5687 ptr_qry
.flush_cache ();
5690 /* Callback for walk_dominator_tree. Attempt to optimize various
5691 string ops by remembering string lengths pointed by pointer SSA_NAMEs. */
5694 strlen_pass::before_dom_children (basic_block bb
)
5696 basic_block dombb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
5699 stridx_to_strinfo
= NULL
;
5702 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) dombb
->aux
);
5703 if (stridx_to_strinfo
)
5705 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5708 gphi
*phi
= gsi
.phi ();
5709 if (virtual_operand_p (gimple_phi_result (phi
)))
5711 bitmap visited
= BITMAP_ALLOC (NULL
);
5712 int count_vdef
= 100;
5713 do_invalidate (dombb
, phi
, visited
, &count_vdef
);
5714 BITMAP_FREE (visited
);
5715 if (count_vdef
== 0)
5717 /* If there were too many vdefs in between immediate
5718 dominator and current bb, invalidate everything.
5719 If stridx_to_strinfo has been unshared, we need
5720 to free it, otherwise just set it to NULL. */
5721 if (!strinfo_shared ())
5727 vec_safe_iterate (stridx_to_strinfo
, i
, &si
);
5731 (*stridx_to_strinfo
)[i
] = NULL
;
5735 stridx_to_strinfo
= NULL
;
5743 /* If all PHI arguments have the same string index, the PHI result
5745 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5748 gphi
*phi
= gsi
.phi ();
5749 tree result
= gimple_phi_result (phi
);
5750 if (!virtual_operand_p (result
) && POINTER_TYPE_P (TREE_TYPE (result
)))
5752 int idx
= get_stridx (gimple_phi_arg_def (phi
, 0), phi
);
5755 unsigned int i
, n
= gimple_phi_num_args (phi
);
5756 for (i
= 1; i
< n
; i
++)
5757 if (idx
!= get_stridx (gimple_phi_arg_def (phi
, i
), phi
))
5760 ssa_ver_to_stridx
[SSA_NAME_VERSION (result
)] = idx
;
5765 bool cleanup_eh
= false;
5767 /* Attempt to optimize individual statements. */
5768 for (m_gsi
= gsi_start_bb (bb
); !gsi_end_p (m_gsi
); )
5770 /* Reset search depth preformance counter. */
5773 if (check_and_optimize_stmt (&cleanup_eh
))
5777 if (cleanup_eh
&& gimple_purge_dead_eh_edges (bb
))
5778 m_cleanup_cfg
= true;
5780 bb
->aux
= stridx_to_strinfo
;
5781 if (vec_safe_length (stridx_to_strinfo
) && !strinfo_shared ())
5782 (*stridx_to_strinfo
)[0] = (strinfo
*) bb
;
5786 /* Callback for walk_dominator_tree. Free strinfo vector if it is
5787 owned by the current bb, clear bb->aux. */
5790 strlen_pass::after_dom_children (basic_block bb
)
5794 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) bb
->aux
);
5795 if (vec_safe_length (stridx_to_strinfo
)
5796 && (*stridx_to_strinfo
)[0] == (strinfo
*) bb
)
5801 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
5803 vec_free (stridx_to_strinfo
);
5812 printf_strlen_execute (function
*fun
, bool warn_only
)
5814 strlen_optimize
= !warn_only
;
5816 calculate_dominance_info (CDI_DOMINATORS
);
5818 bool use_scev
= optimize
> 0 && flag_printf_return_value
;
5821 loop_optimizer_init (LOOPS_NORMAL
);
5825 gcc_assert (!strlen_to_stridx
);
5826 if (warn_stringop_overflow
|| warn_stringop_truncation
)
5827 strlen_to_stridx
= new hash_map
<tree
, stridx_strlenloc
> ();
5829 /* This has to happen after initializing the loop optimizer
5830 and initializing SCEV as they create new SSA_NAMEs. */
5831 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
5834 /* String length optimization is implemented as a walk of the dominator
5835 tree and a forward walk of statements within each block. */
5836 strlen_pass
walker (CDI_DOMINATORS
);
5837 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));
5839 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5840 walker
.ptr_qry
.dump (dump_file
, true);
5842 ssa_ver_to_stridx
.release ();
5843 strinfo_pool
.release ();
5844 if (decl_to_stridxlist_htab
)
5846 obstack_free (&stridx_obstack
, NULL
);
5847 delete decl_to_stridxlist_htab
;
5848 decl_to_stridxlist_htab
= NULL
;
5850 laststmt
.stmt
= NULL
;
5851 laststmt
.len
= NULL_TREE
;
5852 laststmt
.stridx
= 0;
5854 if (strlen_to_stridx
)
5856 strlen_to_stridx
->empty ();
5857 delete strlen_to_stridx
;
5858 strlen_to_stridx
= NULL
;
5864 loop_optimizer_finalize ();
5867 return walker
.m_cleanup_cfg
? TODO_cleanup_cfg
: 0;
5870 /* This file defines two passes: one for warnings that runs only when
5871 optimization is disabled, and another that implements optimizations
5872 and also issues warnings. */
5874 const pass_data pass_data_warn_printf
=
5876 GIMPLE_PASS
, /* type */
5877 "warn-printf", /* name */
5878 OPTGROUP_NONE
, /* optinfo_flags */
5879 TV_NONE
, /* tv_id */
5880 /* Normally an optimization pass would require PROP_ssa but because
5881 this pass runs early, with no optimization, to do sprintf format
5882 checking, it only requires PROP_cfg. */
5883 PROP_cfg
, /* properties_required */
5884 0, /* properties_provided */
5885 0, /* properties_destroyed */
5886 0, /* todo_flags_start */
5887 0, /* todo_flags_finish */
5890 class pass_warn_printf
: public gimple_opt_pass
5893 pass_warn_printf (gcc::context
*ctxt
)
5894 : gimple_opt_pass (pass_data_warn_printf
, ctxt
)
5897 virtual bool gate (function
*);
5898 virtual unsigned int execute (function
*fun
)
5900 return printf_strlen_execute (fun
, true);
5905 /* Return true to run the warning pass only when not optimizing and
5906 iff either -Wformat-overflow or -Wformat-truncation is specified. */
5909 pass_warn_printf::gate (function
*)
5911 return !optimize
&& (warn_format_overflow
> 0 || warn_format_trunc
> 0);
5914 const pass_data pass_data_strlen
=
5916 GIMPLE_PASS
, /* type */
5917 "strlen", /* name */
5918 OPTGROUP_NONE
, /* optinfo_flags */
5919 TV_TREE_STRLEN
, /* tv_id */
5920 PROP_cfg
| PROP_ssa
, /* properties_required */
5921 0, /* properties_provided */
5922 0, /* properties_destroyed */
5923 0, /* todo_flags_start */
5924 0, /* todo_flags_finish */
5927 class pass_strlen
: public gimple_opt_pass
5930 pass_strlen (gcc::context
*ctxt
)
5931 : gimple_opt_pass (pass_data_strlen
, ctxt
)
5934 opt_pass
* clone () { return new pass_strlen (m_ctxt
); }
5936 virtual bool gate (function
*);
5937 virtual unsigned int execute (function
*fun
)
5939 return printf_strlen_execute (fun
, false);
5943 /* Return true to run the pass only when the sprintf and/or strlen
5944 optimizations are enabled and -Wformat-overflow or -Wformat-truncation
5948 pass_strlen::gate (function
*)
5950 return ((warn_format_overflow
> 0
5951 || warn_format_trunc
> 0
5952 || warn_restrict
> 0
5953 || flag_optimize_strlen
> 0
5954 || flag_printf_return_value
)
5961 make_pass_warn_printf (gcc::context
*ctxt
)
5963 return new pass_warn_printf (ctxt
);
5967 make_pass_strlen (gcc::context
*ctxt
)
5969 return new pass_strlen (ctxt
);