1 /* String length optimization
2 Copyright (C) 2011-2024 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "alloc-pool.h"
29 #include "tree-pass.h"
32 #include "gimple-pretty-print.h"
33 #include "gimple-ssa-warn-access.h"
34 #include "gimple-ssa-warn-restrict.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "gimple-iterator.h"
38 #include "gimple-fold.h"
41 #include "gimplify-me.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-ssa-propagate.h"
48 #include "tree-ssa-strlen.h"
49 #include "tree-hash-traits.h"
51 #include "pointer-query.h"
53 #include "diagnostic-core.h"
54 #include "diagnostic.h"
59 #include "tree-ssa-loop.h"
60 #include "tree-scalar-evolution.h"
61 #include "vr-values.h"
62 #include "gimple-range.h"
65 /* A vector indexed by SSA_NAME_VERSION. 0 means unknown, positive value
66 is an index into strinfo vector, negative value stands for
67 string length of a string literal (~strlen). */
68 static vec
<int> ssa_ver_to_stridx
;
70 /* Number of currently active string indexes plus one. */
71 static int max_stridx
;
73 /* Set to true to optimize, false when just checking. */
74 static bool strlen_optimize
;
76 /* String information record. */
79 /* Number of leading characters that are known to be nonzero. This is
80 also the length of the string if FULL_STRING_P.
82 The values in a list of related string pointers must be consistent;
83 that is, if strinfo B comes X bytes after strinfo A, it must be
84 the case that A->nonzero_chars == X + B->nonzero_chars. */
86 /* Any of the corresponding pointers for querying alias oracle. */
88 /* STMT is used for two things:
90 - To record the statement that should be used for delayed length
91 computations. We maintain the invariant that all related strinfos
92 have delayed lengths or none do.
94 - To record the malloc or calloc call that produced this result
95 to optimize away malloc/memset sequences. STMT is reset after
96 a calloc-allocated object has been stored a non-zero value into. */
98 /* Set to the dynamic allocation statement for the object (alloca,
99 calloc, malloc, or VLA). Unlike STMT, once set for a strinfo
100 object, ALLOC doesn't change. */
102 /* Pointer to '\0' if known, if NULL, it can be computed as
105 /* Reference count. Any changes to strinfo entry possibly shared
106 with dominating basic blocks need unshare_strinfo first, except
107 for dont_invalidate which affects only the immediately next
110 /* Copy of index. get_strinfo (si->idx) should return si; */
112 /* These 3 fields are for chaining related string pointers together.
114 bl = strlen (b); dl = strlen (d); strcpy (a, b); c = a + bl;
115 strcpy (c, d); e = c + dl;
116 strinfo(a) -> strinfo(c) -> strinfo(e)
117 All have ->first field equal to strinfo(a)->idx and are doubly
118 chained through prev/next fields. The later strinfos are required
119 to point into the same string with zero or more bytes after
120 the previous pointer and all bytes in between the two pointers
121 must be non-zero. Functions like strcpy or memcpy are supposed
122 to adjust all previous strinfo lengths, but not following strinfo
123 lengths (those are uncertain, usually invalidated during
124 maybe_invalidate, except when the alias oracle knows better).
125 Functions like strcat on the other side adjust the whole
126 related strinfo chain.
127 They are updated lazily, so to use the chain the same first fields
128 and si->prev->next == si->idx needs to be verified. */
132 /* A flag whether the string is known to be written in the current
135 /* A flag for the next maybe_invalidate that this strinfo shouldn't
136 be invalidated. Always cleared by maybe_invalidate. */
137 bool dont_invalidate
;
138 /* True if the string is known to be nul-terminated after NONZERO_CHARS
139 characters. False is useful when detecting strings that are built
140 up via successive memcpys. */
144 /* Pool for allocating strinfo_struct entries. */
145 static object_allocator
<strinfo
> strinfo_pool ("strinfo pool");
147 /* Vector mapping positive string indexes to strinfo, for the
148 current basic block. The first pointer in the vector is special,
149 it is either NULL, meaning the vector isn't shared, or it is
150 a basic block pointer to the owner basic_block if shared.
151 If some other bb wants to modify the vector, the vector needs
152 to be unshared first, and only the owner bb is supposed to free it. */
153 static vec
<strinfo
*, va_heap
, vl_embed
> *stridx_to_strinfo
;
155 /* One OFFSET->IDX mapping. */
158 struct stridxlist
*next
;
159 HOST_WIDE_INT offset
;
163 /* Hash table entry, mapping a DECL to a chain of OFFSET->IDX mappings. */
164 struct decl_stridxlist_map
166 struct tree_map_base base
;
167 struct stridxlist list
;
170 /* Hash table for mapping decls to a chained list of offset -> idx
172 typedef hash_map
<tree_decl_hash
, stridxlist
> decl_to_stridxlist_htab_t
;
173 static decl_to_stridxlist_htab_t
*decl_to_stridxlist_htab
;
175 /* Hash table mapping strlen (or strnlen with constant bound and return
176 smaller than bound) calls to stridx instances describing
177 the calls' arguments. Non-null only when warn_stringop_truncation
179 typedef std::pair
<int, location_t
> stridx_strlenloc
;
180 static hash_map
<tree
, stridx_strlenloc
> *strlen_to_stridx
;
182 /* Obstack for struct stridxlist and struct decl_stridxlist_map. */
183 static struct obstack stridx_obstack
;
185 /* Last memcpy statement if it could be adjusted if the trailing
186 '\0' written is immediately overwritten, or
187 *x = '\0' store that could be removed if it is immediately overwritten. */
188 struct laststmt_struct
195 static int get_stridx_plus_constant (strinfo
*, unsigned HOST_WIDE_INT
, tree
);
196 static bool get_range_strlen_dynamic (tree
, gimple
*, c_strlen_data
*,
197 bitmap
, pointer_query
*, unsigned *);
199 /* Sets MINMAX to either the constant value or the range VAL is in
200 and returns either the constant value or VAL on success or null
201 when the range couldn't be determined. Uses RVALS or CFUN for
202 range info, whichever is nonnull. */
205 get_range (tree val
, gimple
*stmt
, wide_int minmax
[2],
206 range_query
*rvals
/* = NULL */)
211 /* When called from front ends for global initializers CFUN
215 rvals
= get_range_query (cfun
);
219 if (!rvals
->range_of_expr (vr
, val
, stmt
))
223 value_range_kind rng
= get_legacy_range (vr
, vrmin
, vrmax
);
226 /* Only handle straight ranges. */
227 minmax
[0] = wi::to_wide (vrmin
);
228 minmax
[1] = wi::to_wide (vrmax
);
235 class strlen_pass
: public dom_walker
238 strlen_pass (cdi_direction direction
)
239 : dom_walker (direction
),
241 m_cleanup_cfg (false)
247 edge
before_dom_children (basic_block
) final override
;
248 void after_dom_children (basic_block
) final override
;
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
, tree vuse
,
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
, tree vuse
,
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 to store information about pointers and
306 pointer_query ptr_qry
;
308 gimple_stmt_iterator m_gsi
;
310 /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
317 * +1 if SI is known to start with more than OFF nonzero characters.
319 * 0 if SI is known to start with exactly OFF nonzero characters.
321 * -1 if SI either does not start with OFF nonzero characters
322 or the relationship between the number of leading nonzero
323 characters in SI and OFF is unknown. */
326 compare_nonzero_chars (strinfo
*si
, unsigned HOST_WIDE_INT off
)
328 if (si
->nonzero_chars
329 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
330 return compare_tree_int (si
->nonzero_chars
, off
);
335 /* Same as above but suitable also for strings with non-constant lengths.
336 Uses RVALS to determine length range. */
339 compare_nonzero_chars (strinfo
*si
, gimple
*stmt
,
340 unsigned HOST_WIDE_INT off
,
343 if (!si
->nonzero_chars
)
346 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
347 return compare_tree_int (si
->nonzero_chars
, off
);
349 if (!rvals
|| TREE_CODE (si
->nonzero_chars
) != SSA_NAME
)
353 if (!rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
)
355 || vr
.undefined_p ())
358 /* If the offset is less than the minimum length or if the bounds
359 of the length range are equal return the result of the comparison
360 same as in the constant case. Otherwise return a conservative
362 signop sign
= TYPE_SIGN (vr
.type ());
363 unsigned prec
= TYPE_PRECISION (vr
.type ());
364 int cmpmin
= wi::cmp (vr
.lower_bound (), wi::uhwi (off
, prec
), sign
);
365 if (cmpmin
> 0 || vr
.singleton_p ())
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
)
987 rvals
->range_of_expr (vr
, si
->nonzero_chars
,
990 get_range_query (cfun
)->range_of_expr (vr
,
996 fprintf (fp
, ", refcount = %i", si
->refcount
);
999 fprintf (fp
, ", stmt = ");
1000 print_gimple_expr (fp
, si
->stmt
, 0);
1004 fprintf (fp
, ", alloc = ");
1005 print_gimple_expr (fp
, si
->alloc
, 0);
1008 fprintf (fp
, ", writable");
1009 if (si
->dont_invalidate
)
1010 fprintf (fp
, ", dont_invalidate");
1011 if (si
->full_string_p
)
1012 fprintf (fp
, ", full_string_p");
1013 if (strinfo
*next
= get_next_strinfo (si
))
1015 fprintf (fp
, ", {");
1017 fprintf (fp
, "%i%s", next
->idx
, next
->first
? ", " : "");
1018 while ((next
= get_next_strinfo (next
)));
1026 fprintf (fp
, " = null\n");
1028 fprintf (fp
, "decl_to_stridxlist_htab");
1029 if (decl_to_stridxlist_htab
)
1032 typedef decl_to_stridxlist_htab_t::iterator iter_t
;
1033 for (iter_t it
= decl_to_stridxlist_htab
->begin ();
1034 it
!= decl_to_stridxlist_htab
->end (); ++it
)
1036 tree decl
= (*it
).first
;
1037 stridxlist
*list
= &(*it
).second
;
1038 fprintf (fp
, " decl = ");
1039 print_generic_expr (fp
, decl
);
1042 fprintf (fp
, ", offsets = {");
1043 for (; list
; list
= list
->next
)
1044 fprintf (fp
, "%lli%s", (long long) list
->offset
,
1045 list
->next
? ", " : "");
1052 fprintf (fp
, " = null\n");
1056 fprintf (fp
, "laststmt = ");
1057 print_gimple_expr (fp
, laststmt
.stmt
, 0);
1058 fprintf (fp
, ", len = ");
1059 print_generic_expr (fp
, laststmt
.len
);
1060 fprintf (fp
, ", stridx = %i\n", laststmt
.stridx
);
1064 /* Helper of get_range_strlen_dynamic(). See below. */
1067 get_range_strlen_phi (tree src
, gphi
*phi
,
1068 c_strlen_data
*pdata
, bitmap visited
,
1069 pointer_query
*ptr_qry
, unsigned *pssa_def_max
)
1071 if (!bitmap_set_bit (visited
, SSA_NAME_VERSION (src
)))
1074 if (*pssa_def_max
== 0)
1079 /* Iterate over the PHI arguments and determine the minimum and maximum
1080 length/size of each and incorporate them into the overall result. */
1081 for (unsigned i
= 0; i
!= gimple_phi_num_args (phi
); ++i
)
1083 tree arg
= gimple_phi_arg_def (phi
, i
);
1084 if (arg
== gimple_phi_result (phi
))
1087 c_strlen_data argdata
= { };
1088 if (!get_range_strlen_dynamic (arg
, phi
, &argdata
, visited
, ptr_qry
,
1091 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1095 /* Set the DECL of an unterminated array this argument refers to
1096 if one hasn't been found yet. */
1097 if (!pdata
->decl
&& argdata
.decl
)
1098 pdata
->decl
= argdata
.decl
;
1101 || (integer_zerop (argdata
.minlen
)
1102 && (!argdata
.maxbound
1103 || integer_all_onesp (argdata
.maxbound
))
1104 && integer_all_onesp (argdata
.maxlen
)))
1106 /* Set the upper bound of the length to unbounded. */
1107 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1111 /* Adjust the minimum and maximum length determined so far and
1112 the upper bound on the array size. */
1113 if (TREE_CODE (argdata
.minlen
) == INTEGER_CST
1115 || tree_int_cst_lt (argdata
.minlen
, pdata
->minlen
)))
1116 pdata
->minlen
= argdata
.minlen
;
1118 if (TREE_CODE (argdata
.maxlen
) == INTEGER_CST
1121 && tree_int_cst_lt (pdata
->maxlen
, argdata
.maxlen
))))
1122 pdata
->maxlen
= argdata
.maxlen
;
1124 if (!pdata
->maxbound
1125 || TREE_CODE (pdata
->maxbound
) != INTEGER_CST
1126 || (argdata
.maxbound
1127 && tree_int_cst_lt (pdata
->maxbound
, argdata
.maxbound
)
1128 && !integer_all_onesp (argdata
.maxbound
)))
1129 pdata
->maxbound
= argdata
.maxbound
;
1135 /* Return the maximum possible length of the string PTR that's less
1136 than MAXLEN given the size of the object of subobject it points
1137 to at the given STMT. MAXLEN is the maximum length of the string
1138 determined so far. Return null when no such maximum can be
1142 get_maxbound (tree ptr
, gimple
*stmt
, offset_int maxlen
,
1143 pointer_query
*ptr_qry
)
1146 if (!ptr_qry
->get_ref (ptr
, stmt
, &aref
))
1149 offset_int sizrem
= aref
.size_remaining ();
1153 if (sizrem
< maxlen
)
1154 maxlen
= sizrem
- 1;
1156 /* Try to determine the maximum from the subobject at the offset.
1157 This handles MEM [&some-struct, member-offset] that's often
1158 the result of folding COMPONENT_REF [some-struct, member]. */
1159 tree reftype
= TREE_TYPE (aref
.ref
);
1160 if (!RECORD_OR_UNION_TYPE_P (reftype
)
1161 || aref
.offrng
[0] != aref
.offrng
[1]
1162 || !wi::fits_shwi_p (aref
.offrng
[0]))
1163 return wide_int_to_tree (size_type_node
, maxlen
);
1165 HOST_WIDE_INT off
= aref
.offrng
[0].to_shwi ();
1166 tree fld
= field_at_offset (reftype
, NULL_TREE
, off
);
1167 if (!fld
|| !DECL_SIZE_UNIT (fld
))
1168 return wide_int_to_tree (size_type_node
, maxlen
);
1170 offset_int size
= wi::to_offset (DECL_SIZE_UNIT (fld
));
1172 return wide_int_to_tree (size_type_node
, maxlen
);
1174 return wide_int_to_tree (size_type_node
, size
- 1);
1177 /* Attempt to determine the length of the string SRC. On success, store
1178 the length in *PDATA and return true. Otherwise, return false.
1179 VISITED is a bitmap of visited PHI nodes. RVALS points to the valuation
1180 engine used to calculate ranges. PSSA_DEF_MAX to an SSA_NAME
1181 assignment limit used to prevent runaway recursion. */
1184 get_range_strlen_dynamic (tree src
, gimple
*stmt
,
1185 c_strlen_data
*pdata
, bitmap visited
,
1186 pointer_query
*ptr_qry
, unsigned *pssa_def_max
)
1188 int idx
= get_stridx (src
, stmt
);
1191 if (TREE_CODE (src
) == SSA_NAME
)
1193 gimple
*def_stmt
= SSA_NAME_DEF_STMT (src
);
1194 if (gphi
*phi
= dyn_cast
<gphi
*>(def_stmt
))
1195 return get_range_strlen_phi (src
, phi
, pdata
, visited
, ptr_qry
,
1199 /* Return success regardless of the result and handle *PDATA
1201 get_range_strlen (src
, pdata
, 1);
1207 /* SRC is a string of constant length. */
1208 pdata
->minlen
= build_int_cst (size_type_node
, ~idx
);
1209 pdata
->maxlen
= pdata
->minlen
;
1210 pdata
->maxbound
= pdata
->maxlen
;
1214 if (strinfo
*si
= get_strinfo (idx
))
1216 pdata
->minlen
= get_string_length (si
);
1217 if (!pdata
->minlen
&& si
->nonzero_chars
)
1219 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
1220 pdata
->minlen
= si
->nonzero_chars
;
1221 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
1224 ptr_qry
->rvals
->range_of_expr (vr
, si
->nonzero_chars
, si
->stmt
);
1225 if (vr
.undefined_p () || vr
.varying_p ())
1226 pdata
->minlen
= build_zero_cst (size_type_node
);
1229 tree type
= vr
.type ();
1230 pdata
->minlen
= wide_int_to_tree (type
, vr
.lower_bound ());
1234 pdata
->minlen
= build_zero_cst (size_type_node
);
1236 tree base
= si
->ptr
;
1237 if (TREE_CODE (base
) == ADDR_EXPR
)
1238 base
= TREE_OPERAND (base
, 0);
1242 base
= get_addr_base_and_unit_offset (base
, &poff
);
1245 && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
1246 && TYPE_SIZE_UNIT (TREE_TYPE (base
))
1247 && poff
.is_constant (&off
))
1249 tree basetype
= TREE_TYPE (base
);
1250 tree size
= TYPE_SIZE_UNIT (basetype
);
1251 if (TREE_CODE (size
) == INTEGER_CST
)
1253 ++off
; /* Increment for the terminating nul. */
1254 tree toffset
= build_int_cst (size_type_node
, off
);
1255 pdata
->maxlen
= fold_build2 (MINUS_EXPR
, size_type_node
,
1257 if (tree_int_cst_lt (pdata
->maxlen
, pdata
->minlen
))
1258 /* This can happen when triggering UB, when base is an
1259 array which is known to be filled with at least size
1260 non-zero bytes. E.g. for
1261 char a[2]; memcpy (a, "12", sizeof a);
1262 We don't want to create an invalid range [2, 1]
1263 where 2 comes from the number of non-zero bytes and
1264 1 from longest valid zero-terminated string that can
1265 be stored in such an array, so pick just one of
1266 those, pdata->minlen. See PR110603. */
1267 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1269 pdata
->maxbound
= pdata
->maxlen
;
1272 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1275 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1277 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == SSA_NAME
)
1280 ptr_qry
->rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
);
1281 if (vr
.varying_p () || vr
.undefined_p ())
1283 pdata
->minlen
= build_zero_cst (size_type_node
);
1284 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1288 tree type
= vr
.type ();
1289 pdata
->minlen
= wide_int_to_tree (type
, vr
.lower_bound ());
1290 pdata
->maxlen
= wide_int_to_tree (type
, vr
.upper_bound ());
1291 offset_int max
= offset_int::from (vr
.upper_bound (0), SIGNED
);
1292 if (tree maxbound
= get_maxbound (si
->ptr
, stmt
, max
, ptr_qry
))
1293 pdata
->maxbound
= maxbound
;
1295 pdata
->maxbound
= pdata
->maxlen
;
1298 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == INTEGER_CST
)
1300 pdata
->maxlen
= pdata
->minlen
;
1301 pdata
->maxbound
= pdata
->minlen
;
1305 /* For PDATA->MINLEN that's a non-constant expression such
1306 as PLUS_EXPR whose value range is unknown, set the bounds
1307 to zero and SIZE_MAX. */
1308 pdata
->minlen
= build_zero_cst (size_type_node
);
1309 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1318 /* Analogous to get_range_strlen but for dynamically created strings,
1319 i.e., those created by calls to strcpy as opposed to just string
1321 Try to obtain the range of the lengths of the string(s) referenced
1322 by SRC, or the size of the largest array SRC refers to if the range
1323 of lengths cannot be determined, and store all in *PDATA. RVALS
1324 points to the valuation engine used to calculate ranges. */
1327 get_range_strlen_dynamic (tree src
, gimple
*stmt
, c_strlen_data
*pdata
,
1328 pointer_query
&ptr_qry
)
1330 auto_bitmap visited
;
1331 tree maxbound
= pdata
->maxbound
;
1333 unsigned limit
= param_ssa_name_def_chain_limit
;
1334 if (!get_range_strlen_dynamic (src
, stmt
, pdata
, visited
, &ptr_qry
, &limit
))
1336 /* On failure extend the length range to an impossible maximum
1337 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1338 members can stay unchanged regardless. */
1339 pdata
->minlen
= ssize_int (0);
1340 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1342 else if (!pdata
->minlen
)
1343 pdata
->minlen
= ssize_int (0);
1345 /* If it's unchanged from it initial non-null value, set the conservative
1346 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1347 if (maxbound
&& pdata
->maxbound
== maxbound
)
1348 pdata
->maxbound
= build_all_ones_cst (size_type_node
);
1351 /* Invalidate string length information for strings whose length might
1352 change due to stores in STMT, except those marked DONT_INVALIDATE.
1353 For string-modifying statements, ZERO_WRITE is set when the statement
1355 Returns true if any STRIDX_TO_STRINFO entries were considered
1356 for invalidation. */
1359 maybe_invalidate (gimple
*stmt
, bool zero_write
= false)
1361 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1363 fprintf (dump_file
, "%s called for ", __func__
);
1364 print_gimple_stmt (dump_file
, stmt
, TDF_LINENO
);
1368 bool nonempty
= false;
1370 for (unsigned i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
1372 if (si
== NULL
|| !POINTER_TYPE_P (TREE_TYPE (si
->ptr
)))
1377 /* Unconditionally reset DONT_INVALIDATE. */
1378 bool dont_invalidate
= si
->dont_invalidate
;
1379 si
->dont_invalidate
= false;
1381 if (dont_invalidate
)
1385 tree size
= si
->nonzero_chars
;
1386 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, size
);
1387 /* Include the terminating nul in the size of the string
1388 to consider when determining possible clobber. But do not
1389 add it to 'size' since we don't know whether it would
1390 actually fit the allocated area. */
1391 if (known_size_p (r
.size
))
1393 if (known_le (r
.size
, HOST_WIDE_INT_MAX
- BITS_PER_UNIT
))
1394 r
.max_size
+= BITS_PER_UNIT
;
1398 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1400 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1402 fputs (" statement may clobber object ", dump_file
);
1403 print_generic_expr (dump_file
, si
->ptr
);
1404 if (size
&& tree_fits_uhwi_p (size
))
1405 fprintf (dump_file
, " " HOST_WIDE_INT_PRINT_UNSIGNED
1406 " bytes in size", tree_to_uhwi (size
));
1407 fputc ('\n', dump_file
);
1410 set_strinfo (i
, NULL
);
1418 && is_gimple_call (si
->stmt
)
1419 && (DECL_FUNCTION_CODE (gimple_call_fndecl (si
->stmt
))
1420 == BUILT_IN_CALLOC
))
1422 /* If the clobber test above considered the length of
1423 the string (including the nul), then for (potentially)
1424 non-zero writes that might modify storage allocated by
1425 calloc consider the whole object and if it might be
1426 clobbered by the statement reset the statement. */
1427 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, NULL_TREE
);
1428 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1433 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1434 fprintf (dump_file
, "%s returns %i\n", __func__
, nonempty
);
1439 /* Unshare strinfo record SI, if it has refcount > 1 or
1440 if stridx_to_strinfo vector is shared with some other
1444 unshare_strinfo (strinfo
*si
)
1448 if (si
->refcount
== 1 && !strinfo_shared ())
1451 nsi
= new_strinfo (si
->ptr
, si
->idx
, si
->nonzero_chars
, si
->full_string_p
);
1452 nsi
->stmt
= si
->stmt
;
1453 nsi
->alloc
= si
->alloc
;
1454 nsi
->endptr
= si
->endptr
;
1455 nsi
->first
= si
->first
;
1456 nsi
->prev
= si
->prev
;
1457 nsi
->next
= si
->next
;
1458 nsi
->writable
= si
->writable
;
1459 set_strinfo (si
->idx
, nsi
);
1464 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1465 strinfo if there is any. Return it's idx, or 0 if no strinfo has
1469 get_stridx_plus_constant (strinfo
*basesi
, unsigned HOST_WIDE_INT off
,
1472 if (TREE_CODE (ptr
) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1475 if (compare_nonzero_chars (basesi
, off
) < 0
1476 || !tree_fits_uhwi_p (basesi
->nonzero_chars
))
1479 unsigned HOST_WIDE_INT nonzero_chars
1480 = tree_to_uhwi (basesi
->nonzero_chars
) - off
;
1481 strinfo
*si
= basesi
, *chainsi
;
1482 if (si
->first
|| si
->prev
|| si
->next
)
1483 si
= verify_related_strinfos (basesi
);
1485 || si
->nonzero_chars
== NULL_TREE
1486 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1489 if (TREE_CODE (ptr
) == SSA_NAME
1490 && ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1491 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1493 gcc_checking_assert (compare_tree_int (si
->nonzero_chars
, off
) != -1);
1494 for (chainsi
= si
; chainsi
->next
; chainsi
= si
)
1496 si
= get_next_strinfo (chainsi
);
1498 || si
->nonzero_chars
== NULL_TREE
1499 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1501 int r
= compare_tree_int (si
->nonzero_chars
, nonzero_chars
);
1506 if (TREE_CODE (ptr
) == SSA_NAME
)
1507 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = si
->idx
;
1510 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1511 if (pidx
!= NULL
&& *pidx
== 0)
1520 int idx
= new_stridx (ptr
);
1523 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, nonzero_chars
),
1524 basesi
->full_string_p
);
1525 set_strinfo (idx
, si
);
1526 if (strinfo
*nextsi
= get_strinfo (chainsi
->next
))
1528 nextsi
= unshare_strinfo (nextsi
);
1529 si
->next
= nextsi
->idx
;
1532 chainsi
= unshare_strinfo (chainsi
);
1533 if (chainsi
->first
== 0)
1534 chainsi
->first
= chainsi
->idx
;
1535 chainsi
->next
= idx
;
1536 if (chainsi
->endptr
== NULL_TREE
&& zero_length_string_p (si
))
1537 chainsi
->endptr
= ptr
;
1538 si
->endptr
= chainsi
->endptr
;
1539 si
->prev
= chainsi
->idx
;
1540 si
->first
= chainsi
->first
;
1541 si
->writable
= chainsi
->writable
;
1545 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1546 to a zero-length string and if possible chain it to a related strinfo
1547 chain whose part is or might be CHAINSI. */
1550 zero_length_string (tree ptr
, strinfo
*chainsi
)
1554 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1555 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1556 gcc_checking_assert (TREE_CODE (ptr
) == SSA_NAME
1557 && ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] == 0);
1559 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1561 if (chainsi
!= NULL
)
1563 si
= verify_related_strinfos (chainsi
);
1568 /* We shouldn't mix delayed and non-delayed lengths. */
1569 gcc_assert (si
->full_string_p
);
1570 if (si
->endptr
== NULL_TREE
)
1572 si
= unshare_strinfo (si
);
1576 si
= get_next_strinfo (si
);
1579 if (zero_length_string_p (chainsi
))
1583 chainsi
= unshare_strinfo (chainsi
);
1586 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = chainsi
->idx
;
1592 /* We shouldn't mix delayed and non-delayed lengths. */
1593 gcc_assert (chainsi
->full_string_p
);
1594 if (chainsi
->first
|| chainsi
->prev
|| chainsi
->next
)
1596 chainsi
= unshare_strinfo (chainsi
);
1603 idx
= new_stridx (ptr
);
1606 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, 0), true);
1607 set_strinfo (idx
, si
);
1609 if (chainsi
!= NULL
)
1611 chainsi
= unshare_strinfo (chainsi
);
1612 if (chainsi
->first
== 0)
1613 chainsi
->first
= chainsi
->idx
;
1614 chainsi
->next
= idx
;
1615 if (chainsi
->endptr
== NULL_TREE
)
1616 chainsi
->endptr
= ptr
;
1617 si
->prev
= chainsi
->idx
;
1618 si
->first
= chainsi
->first
;
1619 si
->writable
= chainsi
->writable
;
1624 /* For strinfo ORIGSI whose length has been just updated, adjust other
1625 related strinfos so that they match the new ORIGSI. This involves:
1627 - adding ADJ to the nonzero_chars fields
1628 - copying full_string_p from the new ORIGSI. */
1631 adjust_related_strinfos (location_t loc
, strinfo
*origsi
, tree adj
)
1633 strinfo
*si
= verify_related_strinfos (origsi
);
1646 si
= unshare_strinfo (si
);
1647 /* We shouldn't see delayed lengths here; the caller must
1648 have calculated the old length in order to calculate
1650 gcc_assert (si
->nonzero_chars
);
1651 tem
= fold_convert_loc (loc
, TREE_TYPE (si
->nonzero_chars
), adj
);
1652 si
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
1653 TREE_TYPE (si
->nonzero_chars
),
1654 si
->nonzero_chars
, tem
);
1655 si
->full_string_p
= origsi
->full_string_p
;
1657 si
->endptr
= NULL_TREE
;
1658 si
->dont_invalidate
= true;
1660 nsi
= get_next_strinfo (si
);
1667 /* Find if there are other SSA_NAME pointers equal to PTR
1668 for which we don't track their string lengths yet. If so, use
1672 find_equal_ptrs (tree ptr
, int idx
)
1674 if (TREE_CODE (ptr
) != SSA_NAME
)
1678 gimple
*stmt
= SSA_NAME_DEF_STMT (ptr
);
1679 if (!is_gimple_assign (stmt
))
1681 ptr
= gimple_assign_rhs1 (stmt
);
1682 switch (gimple_assign_rhs_code (stmt
))
1687 if (!POINTER_TYPE_P (TREE_TYPE (ptr
)))
1689 if (TREE_CODE (ptr
) == SSA_NAME
)
1691 if (TREE_CODE (ptr
) != ADDR_EXPR
)
1696 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1697 if (pidx
!= NULL
&& *pidx
== 0)
1705 /* We might find an endptr created in this pass. Grow the
1706 vector in that case. */
1707 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1708 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1710 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] != 0)
1712 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = idx
;
1716 /* Return true if STMT is a call to a builtin function with the right
1717 arguments and attributes that should be considered for optimization
1721 valid_builtin_call (gimple
*stmt
)
1723 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
1726 tree callee
= gimple_call_fndecl (stmt
);
1727 switch (DECL_FUNCTION_CODE (callee
))
1729 case BUILT_IN_MEMCMP
:
1730 case BUILT_IN_MEMCMP_EQ
:
1731 case BUILT_IN_STRCMP
:
1732 case BUILT_IN_STRNCMP
:
1733 case BUILT_IN_STRCHR
:
1734 case BUILT_IN_STRLEN
:
1735 case BUILT_IN_STRNLEN
:
1736 /* The above functions should be pure. Punt if they aren't. */
1737 if (gimple_vdef (stmt
) || gimple_vuse (stmt
) == NULL_TREE
)
1741 case BUILT_IN_ALLOCA
:
1742 case BUILT_IN_ALLOCA_WITH_ALIGN
:
1743 case BUILT_IN_CALLOC
:
1744 case BUILT_IN_MALLOC
:
1745 case BUILT_IN_MEMCPY
:
1746 case BUILT_IN_MEMCPY_CHK
:
1747 case BUILT_IN_MEMPCPY
:
1748 case BUILT_IN_MEMPCPY_CHK
:
1749 case BUILT_IN_MEMSET
:
1750 case BUILT_IN_STPCPY
:
1751 case BUILT_IN_STPCPY_CHK
:
1752 case BUILT_IN_STPNCPY
:
1753 case BUILT_IN_STPNCPY_CHK
:
1754 case BUILT_IN_STRCAT
:
1755 case BUILT_IN_STRCAT_CHK
:
1756 case BUILT_IN_STRCPY
:
1757 case BUILT_IN_STRCPY_CHK
:
1758 case BUILT_IN_STRNCAT
:
1759 case BUILT_IN_STRNCAT_CHK
:
1760 case BUILT_IN_STRNCPY
:
1761 case BUILT_IN_STRNCPY_CHK
:
1762 /* The above functions should be neither const nor pure. Punt if they
1764 if (gimple_vdef (stmt
) == NULL_TREE
|| gimple_vuse (stmt
) == NULL_TREE
)
1775 /* If the last .MEM setter statement before STMT is
1776 memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1777 and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1778 just memcpy (x, y, strlen (y)). SI must be the zero length
1782 strlen_pass::adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
)
1784 tree vuse
, callee
, len
;
1785 struct laststmt_struct last
= laststmt
;
1786 strinfo
*lastsi
, *firstsi
;
1787 unsigned len_arg_no
= 2;
1789 laststmt
.stmt
= NULL
;
1790 laststmt
.len
= NULL_TREE
;
1791 laststmt
.stridx
= 0;
1793 if (last
.stmt
== NULL
)
1796 vuse
= gimple_vuse (stmt
);
1797 if (vuse
== NULL_TREE
1798 || SSA_NAME_DEF_STMT (vuse
) != last
.stmt
1799 || !has_single_use (vuse
))
1802 gcc_assert (last
.stridx
> 0);
1803 lastsi
= get_strinfo (last
.stridx
);
1809 if (lastsi
->first
== 0 || lastsi
->first
!= si
->first
)
1812 firstsi
= verify_related_strinfos (si
);
1813 if (firstsi
== NULL
)
1815 while (firstsi
!= lastsi
)
1817 firstsi
= get_next_strinfo (firstsi
);
1818 if (firstsi
== NULL
)
1823 if (!is_strcat
&& !zero_length_string_p (si
))
1826 if (is_gimple_assign (last
.stmt
))
1828 gimple_stmt_iterator gsi
;
1830 if (!integer_zerop (gimple_assign_rhs1 (last
.stmt
)))
1832 if (stmt_could_throw_p (cfun
, last
.stmt
))
1834 gsi
= gsi_for_stmt (last
.stmt
);
1835 unlink_stmt_vdef (last
.stmt
);
1836 release_defs (last
.stmt
);
1837 gsi_remove (&gsi
, true);
1841 if (!valid_builtin_call (last
.stmt
))
1844 callee
= gimple_call_fndecl (last
.stmt
);
1845 switch (DECL_FUNCTION_CODE (callee
))
1847 case BUILT_IN_MEMCPY
:
1848 case BUILT_IN_MEMCPY_CHK
:
1854 len
= gimple_call_arg (last
.stmt
, len_arg_no
);
1855 if (tree_fits_uhwi_p (len
))
1857 if (!tree_fits_uhwi_p (last
.len
)
1858 || integer_zerop (len
)
1859 || tree_to_uhwi (len
) != tree_to_uhwi (last
.len
) + 1)
1861 /* Don't adjust the length if it is divisible by 4, it is more efficient
1862 to store the extra '\0' in that case. */
1863 if ((tree_to_uhwi (len
) & 3) == 0)
1866 /* Don't fold away an out of bounds access, as this defeats proper
1868 tree dst
= gimple_call_arg (last
.stmt
, 0);
1871 tree size
= compute_objsize (dst
, stmt
, 1, &aref
, &ptr_qry
);
1872 if (size
&& tree_int_cst_lt (size
, len
))
1875 else if (TREE_CODE (len
) == SSA_NAME
)
1877 gimple
*def_stmt
= SSA_NAME_DEF_STMT (len
);
1878 if (!is_gimple_assign (def_stmt
)
1879 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
1880 || gimple_assign_rhs1 (def_stmt
) != last
.len
1881 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
1887 gimple_call_set_arg (last
.stmt
, len_arg_no
, last
.len
);
1888 update_stmt (last
.stmt
);
1891 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1892 call, or when BOUND is non-null, of a strnlen() call, set LHS
1893 range info to [0, min (MAX, BOUND)] when the range includes more
1894 than one value and return LHS. Otherwise, when the range
1895 [MIN, MAX] is such that MIN == MAX, return the tree representation
1896 of (MIN). The latter allows callers to fold suitable strnlen() calls
1900 set_strlen_range (tree lhs
, wide_int min
, wide_int max
,
1901 tree bound
/* = NULL_TREE */)
1903 if (TREE_CODE (lhs
) != SSA_NAME
1904 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1909 /* For strnlen, adjust MIN and MAX as necessary. If the bound
1910 is less than the size of the array set MAX to it. It it's
1911 greater than MAX and MAX is non-zero bump MAX down to account
1912 for the necessary terminating nul. Otherwise leave it alone. */
1913 if (TREE_CODE (bound
) == INTEGER_CST
)
1915 wide_int wibnd
= wi::to_wide (bound
);
1916 int cmp
= wi::cmpu (wibnd
, max
);
1919 else if (cmp
&& wi::ne_p (max
, min
))
1922 else if (TREE_CODE (bound
) == SSA_NAME
)
1925 get_range_query (cfun
)->range_of_expr (r
, bound
);
1926 if (!r
.undefined_p ())
1928 /* For a bound in a known range, adjust the range determined
1929 above as necessary. For a bound in some anti-range or
1930 in an unknown range, use the range determined by callers. */
1931 if (wi::ltu_p (r
.lower_bound (), min
))
1932 min
= r
.lower_bound ();
1933 if (wi::ltu_p (r
.upper_bound (), max
))
1934 max
= r
.upper_bound ();
1940 return wide_int_to_tree (size_type_node
, min
);
1942 value_range
vr (TREE_TYPE (lhs
), min
, max
);
1943 set_range_info (lhs
, vr
);
1947 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1948 SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1949 a character array A[N] with unknown length bounded by N, and for
1950 strnlen(), by min (N, BOUND). */
1953 maybe_set_strlen_range (tree lhs
, tree src
, tree bound
)
1955 if (TREE_CODE (lhs
) != SSA_NAME
1956 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1959 if (TREE_CODE (src
) == SSA_NAME
)
1961 gimple
*def
= SSA_NAME_DEF_STMT (src
);
1962 if (is_gimple_assign (def
)
1963 && gimple_assign_rhs_code (def
) == ADDR_EXPR
)
1964 src
= gimple_assign_rhs1 (def
);
1967 /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1968 NUL so that the difference between a pointer to just past it and
1969 one to its beginning is positive. */
1970 wide_int max
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
1972 if (TREE_CODE (src
) == ADDR_EXPR
)
1974 /* The last array member of a struct can be bigger than its size
1975 suggests if it's treated as a poor-man's flexible array member. */
1976 src
= TREE_OPERAND (src
, 0);
1977 if (TREE_CODE (src
) != MEM_REF
1978 && !array_ref_flexible_size_p (src
))
1980 tree type
= TREE_TYPE (src
);
1981 tree size
= TYPE_SIZE_UNIT (type
);
1983 && TREE_CODE (size
) == INTEGER_CST
1984 && !integer_zerop (size
))
1986 /* Even though such uses of strlen would be undefined,
1987 avoid relying on arrays of arrays in case some genius
1988 decides to call strlen on an unterminated array element
1989 that's followed by a terminated one. Likewise, avoid
1990 assuming that a struct array member is necessarily
1991 nul-terminated (the nul may be in the member that
1992 follows). In those cases, assume that the length
1993 of the string stored in such an array is bounded
1994 by the size of the enclosing object if one can be
1996 tree base
= get_base_address (src
);
1999 if (tree size
= DECL_SIZE_UNIT (base
))
2001 && TREE_CODE (size
) == INTEGER_CST
2002 && TREE_CODE (TREE_TYPE (base
)) != POINTER_TYPE
)
2003 max
= wi::to_wide (size
);
2007 /* For strlen() the upper bound above is equal to
2008 the longest string that can be stored in the array
2009 (i.e., it accounts for the terminating nul. For
2010 strnlen() bump up the maximum by one since the array
2011 need not be nul-terminated. */
2012 if (!bound
&& max
!= 0)
2017 wide_int min
= wi::zero (max
.get_precision ());
2018 return set_strlen_range (lhs
, min
, max
, bound
);
2021 /* Diagnose buffer overflow by a STMT writing LEN + PLUS_ONE bytes,
2022 either into a region allocated for the object SI when non-null,
2023 or into an object designated by the LHS of STMT otherwise.
2024 For a call STMT, when CALL_LHS is set use its left hand side
2025 as the destination, otherwise use argument zero.
2026 When nonnull uses RVALS to determine range information.
2027 RAWMEM may be set by memcpy and other raw memory functions
2028 to allow accesses across subobject boundaries. */
2031 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, tree len
,
2032 strinfo
*si
, bool plus_one
, bool rawmem
)
2034 if (!len
|| warning_suppressed_p (stmt
, OPT_Wstringop_overflow_
))
2037 /* The DECL of the function performing the write if it is done
2039 tree writefn
= NULL_TREE
;
2040 /* The destination expression involved in the store or call STMT. */
2041 tree dest
= NULL_TREE
;
2043 if (is_gimple_assign (stmt
))
2044 dest
= gimple_assign_lhs (stmt
);
2045 else if (is_gimple_call (stmt
))
2048 dest
= gimple_call_lhs (stmt
);
2051 gcc_assert (gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
));
2052 dest
= gimple_call_arg (stmt
, 0);
2057 writefn
= gimple_call_fndecl (stmt
);
2062 if (warning_suppressed_p (dest
, OPT_Wstringop_overflow_
))
2065 const int ostype
= rawmem
? 0 : 1;
2067 /* Use maximum precision to avoid overflow in the addition below.
2068 Make sure all operands have the same precision to keep wide_int
2072 /* The size of the destination region (which is smaller than
2073 the destination object for stores at a non-zero offset). */
2074 tree destsize
= compute_objsize (dest
, stmt
, ostype
, &aref
, &ptr_qry
);
2079 aref
.sizrng
[1] = wi::to_offset (max_object_size ());
2082 /* Return early if the DESTSIZE size expression is the same as LEN
2083 and the offset into the destination is zero. This might happen
2084 in the case of a pair of malloc and memset calls to allocate
2085 an object and clear it as if by calloc. */
2086 if (destsize
== len
&& !plus_one
2087 && aref
.offrng
[0] == 0 && aref
.offrng
[0] == aref
.offrng
[1])
2091 if (!get_range (len
, stmt
, rng
, ptr_qry
.rvals
))
2094 widest_int lenrng
[2] =
2095 { widest_int::from (rng
[0], SIGNED
), widest_int::from (rng
[1], SIGNED
) };
2103 /* The size of the remaining space in the destination computed
2104 as the size of the latter minus the offset into it. */
2105 widest_int spcrng
[2];
2107 offset_int remrng
[2];
2108 remrng
[1] = aref
.size_remaining (remrng
);
2109 spcrng
[0] = remrng
[0] == -1 ? 0 : widest_int::from (remrng
[0], UNSIGNED
);
2110 spcrng
[1] = widest_int::from (remrng
[1], UNSIGNED
);
2113 if (wi::leu_p (lenrng
[0], spcrng
[0])
2114 && wi::leu_p (lenrng
[1], spcrng
[1]))
2117 location_t loc
= gimple_or_expr_nonartificial_location (stmt
, dest
);
2118 bool warned
= false;
2119 if (wi::leu_p (lenrng
[0], spcrng
[1]))
2122 && (!si
|| rawmem
|| !is_strlen_related_p (si
->ptr
, len
)))
2126 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2127 "%qD writing one too many bytes into a region "
2128 "of a size that depends on %<strlen%>",
2130 : warning_at (loc
, OPT_Wstringop_overflow_
,
2131 "writing one too many bytes into a region "
2132 "of a size that depends on %<strlen%>"));
2134 else if (lenrng
[0] == lenrng
[1])
2136 if (spcrng
[0] == spcrng
[1])
2138 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2139 lenrng
[0].to_uhwi (),
2140 "%qD writing %wu byte into a region "
2142 "%qD writing %wu bytes into a region "
2144 writefn
, lenrng
[0].to_uhwi (),
2145 spcrng
[0].to_uhwi ())
2146 : warning_n (loc
, OPT_Wstringop_overflow_
,
2147 lenrng
[0].to_uhwi (),
2148 "writing %wu byte into a region "
2150 "writing %wu bytes into a region "
2152 lenrng
[0].to_uhwi (),
2153 spcrng
[0].to_uhwi ()));
2156 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2157 lenrng
[0].to_uhwi (),
2158 "%qD writing %wu byte into a region "
2159 "of size between %wu and %wu",
2160 "%qD writing %wu bytes into a region "
2161 "of size between %wu and %wu",
2162 writefn
, lenrng
[0].to_uhwi (),
2163 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2164 : warning_n (loc
, OPT_Wstringop_overflow_
,
2165 lenrng
[0].to_uhwi (),
2166 "writing %wu byte into a region "
2167 "of size between %wu and %wu",
2168 "writing %wu bytes into a region "
2169 "of size between %wu and %wu",
2170 lenrng
[0].to_uhwi (),
2171 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2173 else if (spcrng
[0] == spcrng
[1])
2175 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2176 "%qD writing between %wu and %wu bytes "
2177 "into a region of size %wu",
2178 writefn
, lenrng
[0].to_uhwi (),
2179 lenrng
[1].to_uhwi (),
2180 spcrng
[0].to_uhwi ())
2181 : warning_at (loc
, OPT_Wstringop_overflow_
,
2182 "writing between %wu and %wu bytes "
2183 "into a region of size %wu",
2184 lenrng
[0].to_uhwi (),
2185 lenrng
[1].to_uhwi (),
2186 spcrng
[0].to_uhwi ()));
2189 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2190 "%qD writing between %wu and %wu bytes "
2191 "into a region of size between %wu and %wu",
2192 writefn
, lenrng
[0].to_uhwi (),
2193 lenrng
[1].to_uhwi (),
2194 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2195 : warning_at (loc
, OPT_Wstringop_overflow_
,
2196 "writing between %wu and %wu bytes "
2197 "into a region of size between %wu and %wu",
2198 lenrng
[0].to_uhwi (),
2199 lenrng
[1].to_uhwi (),
2200 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2205 suppress_warning (stmt
, OPT_Wstringop_overflow_
);
2207 aref
.inform_access (access_write_only
);
2210 /* Convenience wrapper for the above. */
2213 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
,
2214 unsigned HOST_WIDE_INT len
,
2215 strinfo
*si
, bool plus_one
, bool rawmem
)
2217 tree tlen
= build_int_cst (size_type_node
, len
);
2218 maybe_warn_overflow (stmt
, call_lhs
, tlen
, si
, plus_one
, rawmem
);
2221 /* Handle a strlen call. If strlen of the argument is known, replace
2222 the strlen call with the known value, otherwise remember that strlen
2223 of the argument is stored in the lhs SSA_NAME. */
2226 strlen_pass::handle_builtin_strlen ()
2228 gimple
*stmt
= gsi_stmt (m_gsi
);
2229 tree lhs
= gimple_call_lhs (stmt
);
2231 if (lhs
== NULL_TREE
)
2234 location_t loc
= gimple_location (stmt
);
2235 tree callee
= gimple_call_fndecl (stmt
);
2236 tree src
= gimple_call_arg (stmt
, 0);
2237 tree bound
= (DECL_FUNCTION_CODE (callee
) == BUILT_IN_STRNLEN
2238 ? gimple_call_arg (stmt
, 1) : NULL_TREE
);
2239 int idx
= get_stridx (src
, stmt
);
2240 if (idx
|| (bound
&& integer_zerop (bound
)))
2246 rhs
= build_int_cst (TREE_TYPE (lhs
), ~idx
);
2252 si
= get_strinfo (idx
);
2255 rhs
= get_string_length (si
);
2256 /* For strnlen, if bound is constant, even if si is not known
2257 to be zero terminated, if we know at least bound bytes are
2258 not zero, the return value will be bound. */
2259 if (rhs
== NULL_TREE
2260 && bound
!= NULL_TREE
2261 && TREE_CODE (bound
) == INTEGER_CST
2262 && si
->nonzero_chars
!= NULL_TREE
2263 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
2264 && tree_int_cst_le (bound
, si
->nonzero_chars
))
2268 if (rhs
!= NULL_TREE
)
2270 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2272 fprintf (dump_file
, "Optimizing: ");
2273 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2275 rhs
= unshare_expr (rhs
);
2276 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
2277 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2280 rhs
= fold_build2_loc (loc
, MIN_EXPR
, TREE_TYPE (rhs
), rhs
, bound
);
2282 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2283 stmt
= gsi_stmt (m_gsi
);
2285 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2287 fprintf (dump_file
, "into: ");
2288 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2292 /* Don't update anything for strnlen. */
2293 && bound
== NULL_TREE
2294 && TREE_CODE (si
->nonzero_chars
) != SSA_NAME
2295 && TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
2296 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2298 si
= unshare_strinfo (si
);
2299 si
->nonzero_chars
= lhs
;
2300 gcc_assert (si
->full_string_p
);
2303 if (strlen_to_stridx
2304 && (bound
== NULL_TREE
2305 /* For strnlen record this only if the call is proven
2306 to return the same value as strlen would. */
2307 || (TREE_CODE (bound
) == INTEGER_CST
2308 && TREE_CODE (rhs
) == INTEGER_CST
2309 && tree_int_cst_lt (rhs
, bound
))))
2310 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2315 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2319 idx
= new_stridx (src
);
2322 strinfo
*si
= get_strinfo (idx
);
2325 if (!si
->full_string_p
&& !si
->stmt
)
2327 /* Until now we only had a lower bound on the string length.
2328 Install LHS as the actual length. */
2329 si
= unshare_strinfo (si
);
2330 tree old
= si
->nonzero_chars
;
2331 si
->nonzero_chars
= lhs
;
2332 si
->full_string_p
= true;
2333 if (old
&& TREE_CODE (old
) == INTEGER_CST
)
2335 old
= fold_convert_loc (loc
, TREE_TYPE (lhs
), old
);
2336 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2337 TREE_TYPE (lhs
), lhs
, old
);
2338 adjust_related_strinfos (loc
, si
, adj
);
2339 /* Use the constant minimum length as the lower bound
2340 of the non-constant length. */
2341 wide_int min
= wi::to_wide (old
);
2343 = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
2344 set_strlen_range (lhs
, min
, max
);
2360 /* Only store the new length information for calls to strlen(),
2361 not for those to strnlen(). */
2362 strinfo
*si
= new_strinfo (src
, idx
, lhs
, true);
2363 set_strinfo (idx
, si
);
2364 find_equal_ptrs (src
, idx
);
2367 /* For SRC that is an array of N elements, set LHS's range
2368 to [0, min (N, BOUND)]. A constant return value means
2369 the range would have consisted of a single value. In
2370 that case, fold the result into the returned constant. */
2371 if (tree ret
= maybe_set_strlen_range (lhs
, src
, bound
))
2372 if (TREE_CODE (ret
) == INTEGER_CST
)
2374 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2376 fprintf (dump_file
, "Optimizing: ");
2377 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2379 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (ret
)))
2380 ret
= fold_convert_loc (loc
, TREE_TYPE (lhs
), ret
);
2381 gimplify_and_update_call_from_tree (&m_gsi
, ret
);
2382 stmt
= gsi_stmt (m_gsi
);
2384 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2386 fprintf (dump_file
, "into: ");
2387 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2391 if (strlen_to_stridx
&& !bound
)
2392 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2396 /* Handle a strchr call. If strlen of the first argument is known, replace
2397 the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
2398 that lhs of the call is endptr and strlen of the argument is endptr - x. */
2401 strlen_pass::handle_builtin_strchr ()
2403 gimple
*stmt
= gsi_stmt (m_gsi
);
2404 tree lhs
= gimple_call_lhs (stmt
);
2406 if (lhs
== NULL_TREE
)
2409 if (!integer_zerop (gimple_call_arg (stmt
, 1)))
2412 tree src
= gimple_call_arg (stmt
, 0);
2414 /* Avoid folding if the first argument is not a nul-terminated array.
2415 Defer warning until later. */
2416 if (!check_nul_terminated_array (NULL_TREE
, src
))
2419 int idx
= get_stridx (src
, stmt
);
2426 rhs
= build_int_cst (size_type_node
, ~idx
);
2430 si
= get_strinfo (idx
);
2432 rhs
= get_string_length (si
);
2434 if (rhs
!= NULL_TREE
)
2436 location_t loc
= gimple_location (stmt
);
2438 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2440 fprintf (dump_file
, "Optimizing: ");
2441 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2443 if (si
!= NULL
&& si
->endptr
!= NULL_TREE
)
2445 rhs
= unshare_expr (si
->endptr
);
2446 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2448 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2452 rhs
= fold_convert_loc (loc
, sizetype
, unshare_expr (rhs
));
2453 rhs
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
,
2454 TREE_TYPE (src
), src
, rhs
);
2455 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2457 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2459 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2460 stmt
= gsi_stmt (m_gsi
);
2462 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2464 fprintf (dump_file
, "into: ");
2465 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2468 && si
->endptr
== NULL_TREE
2469 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2471 si
= unshare_strinfo (si
);
2474 zero_length_string (lhs
, si
);
2478 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2480 if (TREE_CODE (src
) != SSA_NAME
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src
))
2483 idx
= new_stridx (src
);
2484 else if (get_strinfo (idx
) != NULL
)
2486 zero_length_string (lhs
, NULL
);
2491 location_t loc
= gimple_location (stmt
);
2492 tree lhsu
= fold_convert_loc (loc
, size_type_node
, lhs
);
2493 tree srcu
= fold_convert_loc (loc
, size_type_node
, src
);
2494 tree length
= fold_build2_loc (loc
, MINUS_EXPR
,
2495 size_type_node
, lhsu
, srcu
);
2496 strinfo
*si
= new_strinfo (src
, idx
, length
, true);
2498 set_strinfo (idx
, si
);
2499 find_equal_ptrs (src
, idx
);
2500 zero_length_string (lhs
, si
);
2504 zero_length_string (lhs
, NULL
);
2507 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
2508 If strlen of the second argument is known, strlen of the first argument
2509 is the same after this call. Furthermore, attempt to convert it to
2510 memcpy. Uses RVALS to determine range information. */
2513 strlen_pass::handle_builtin_strcpy (built_in_function bcode
)
2516 tree src
, dst
, srclen
, len
, lhs
, type
, fn
, oldlen
;
2518 gimple
*stmt
= gsi_stmt (m_gsi
);
2519 strinfo
*si
, *dsi
, *olddsi
, *zsi
;
2522 src
= gimple_call_arg (stmt
, 1);
2523 dst
= gimple_call_arg (stmt
, 0);
2524 lhs
= gimple_call_lhs (stmt
);
2525 idx
= get_stridx (src
, stmt
);
2528 si
= get_strinfo (idx
);
2530 didx
= get_stridx (dst
, stmt
);
2534 olddsi
= get_strinfo (didx
);
2539 adjust_last_stmt (olddsi
, stmt
, false);
2543 srclen
= get_string_length (si
);
2545 srclen
= build_int_cst (size_type_node
, ~idx
);
2547 maybe_warn_overflow (stmt
, false, srclen
, olddsi
, true);
2550 adjust_last_stmt (olddsi
, stmt
, false);
2552 loc
= gimple_location (stmt
);
2553 if (srclen
== NULL_TREE
)
2556 case BUILT_IN_STRCPY
:
2557 case BUILT_IN_STRCPY_CHK
:
2558 if (lhs
!= NULL_TREE
|| !builtin_decl_implicit_p (BUILT_IN_STPCPY
))
2561 case BUILT_IN_STPCPY
:
2562 case BUILT_IN_STPCPY_CHK
:
2563 if (lhs
== NULL_TREE
)
2567 tree lhsuint
= fold_convert_loc (loc
, size_type_node
, lhs
);
2568 srclen
= fold_convert_loc (loc
, size_type_node
, dst
);
2569 srclen
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
2579 didx
= new_stridx (dst
);
2585 oldlen
= olddsi
->nonzero_chars
;
2586 dsi
= unshare_strinfo (olddsi
);
2587 dsi
->nonzero_chars
= srclen
;
2588 dsi
->full_string_p
= (srclen
!= NULL_TREE
);
2589 /* Break the chain, so adjust_related_strinfo on later pointers in
2590 the chain won't adjust this one anymore. */
2593 dsi
->endptr
= NULL_TREE
;
2597 dsi
= new_strinfo (dst
, didx
, srclen
, srclen
!= NULL_TREE
);
2598 set_strinfo (didx
, dsi
);
2599 find_equal_ptrs (dst
, didx
);
2601 dsi
->writable
= true;
2602 dsi
->dont_invalidate
= true;
2604 if (dsi
->nonzero_chars
== NULL_TREE
)
2608 /* If string length of src is unknown, use delayed length
2609 computation. If string length of dst will be needed, it
2610 can be computed by transforming this strcpy call into
2611 stpcpy and subtracting dst from the return value. */
2613 /* Look for earlier strings whose length could be determined if
2614 this strcpy is turned into an stpcpy. */
2616 if (dsi
->prev
!= 0 && (chainsi
= verify_related_strinfos (dsi
)) != NULL
)
2618 for (; chainsi
&& chainsi
!= dsi
; chainsi
= get_strinfo (chainsi
->next
))
2620 /* When setting a stmt for delayed length computation
2621 prevent all strinfos through dsi from being
2623 chainsi
= unshare_strinfo (chainsi
);
2624 chainsi
->stmt
= stmt
;
2625 chainsi
->nonzero_chars
= NULL_TREE
;
2626 chainsi
->full_string_p
= false;
2627 chainsi
->endptr
= NULL_TREE
;
2628 chainsi
->dont_invalidate
= true;
2633 /* Try to detect overlap before returning. This catches cases
2634 like strcpy (d, d + n) where n is non-constant whose range
2635 is such that (n <= strlen (d) holds).
2637 OLDDSI->NONZERO_chars may have been reset by this point with
2638 oldlen holding it original value. */
2639 if (olddsi
&& oldlen
)
2641 /* Add 1 for the terminating NUL. */
2642 tree type
= TREE_TYPE (oldlen
);
2643 oldlen
= fold_build2 (PLUS_EXPR
, type
, oldlen
,
2644 build_int_cst (type
, 1));
2645 check_bounds_or_overlap (stmt
, olddsi
->ptr
, src
, oldlen
, NULL_TREE
);
2653 tree adj
= NULL_TREE
;
2654 if (oldlen
== NULL_TREE
)
2656 else if (integer_zerop (oldlen
))
2658 else if (TREE_CODE (oldlen
) == INTEGER_CST
2659 || TREE_CODE (srclen
) == INTEGER_CST
)
2660 adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2661 TREE_TYPE (srclen
), srclen
,
2662 fold_convert_loc (loc
, TREE_TYPE (srclen
),
2664 if (adj
!= NULL_TREE
)
2665 adjust_related_strinfos (loc
, dsi
, adj
);
2669 /* strcpy src may not overlap dst, so src doesn't need to be
2670 invalidated either. */
2672 si
->dont_invalidate
= true;
2678 case BUILT_IN_STRCPY
:
2679 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
2681 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2683 case BUILT_IN_STRCPY_CHK
:
2684 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
2686 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2688 case BUILT_IN_STPCPY
:
2689 /* This would need adjustment of the lhs (subtract one),
2690 or detection that the trailing '\0' doesn't need to be
2691 written, if it will be immediately overwritten.
2692 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); */
2696 zsi
= zero_length_string (lhs
, dsi
);
2699 case BUILT_IN_STPCPY_CHK
:
2700 /* This would need adjustment of the lhs (subtract one),
2701 or detection that the trailing '\0' doesn't need to be
2702 written, if it will be immediately overwritten.
2703 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK); */
2707 zsi
= zero_length_string (lhs
, dsi
);
2714 zsi
->dont_invalidate
= true;
2718 tree args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
2719 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
2722 type
= size_type_node
;
2724 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
2725 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
, build_int_cst (type
, 1));
2727 /* Disable warning for the transformed statement? */
2728 opt_code no_warning_opt
= no_warning
;
2730 if (const strinfo
*chksi
= si
? olddsi
? olddsi
: dsi
: NULL
)
2732 no_warning_opt
= check_bounds_or_overlap (stmt
, chksi
->ptr
, si
->ptr
,
2735 suppress_warning (stmt
, no_warning_opt
);
2738 if (fn
== NULL_TREE
)
2741 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
2743 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2745 fprintf (dump_file
, "Optimizing: ");
2746 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2748 if (gimple_call_num_args (stmt
) == 2)
2749 success
= update_gimple_call (&m_gsi
, fn
, 3, dst
, src
, len
);
2751 success
= update_gimple_call (&m_gsi
, fn
, 4, dst
, src
, len
,
2752 gimple_call_arg (stmt
, 2));
2755 stmt
= gsi_stmt (m_gsi
);
2757 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2759 fprintf (dump_file
, "into: ");
2760 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2762 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2763 laststmt
.stmt
= stmt
;
2764 laststmt
.len
= srclen
;
2765 laststmt
.stridx
= dsi
->idx
;
2767 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2768 fprintf (dump_file
, "not possible.\n");
2771 suppress_warning (stmt
, no_warning_opt
);
2774 /* Check the size argument to the built-in forms of stpncpy and strncpy
2775 for out-of-bounds offsets or overlapping access, and to see if the
2776 size argument is derived from a call to strlen() on the source argument,
2777 and if so, issue an appropriate warning. */
2780 strlen_pass::handle_builtin_strncat (built_in_function
)
2782 /* Same as stxncpy(). */
2783 handle_builtin_stxncpy_strncat (true);
2786 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2787 way. LEN can either be an integer expression, or a pointer (to char).
2788 When it is the latter (such as in recursive calls to self) it is
2789 assumed to be the argument in some call to strlen() whose relationship
2790 to SRC is being ascertained. */
2793 is_strlen_related_p (tree src
, tree len
)
2795 if (TREE_CODE (TREE_TYPE (len
)) == POINTER_TYPE
2796 && operand_equal_p (src
, len
, 0))
2799 if (TREE_CODE (len
) != SSA_NAME
)
2802 if (TREE_CODE (src
) == SSA_NAME
)
2804 gimple
*srcdef
= SSA_NAME_DEF_STMT (src
);
2805 if (is_gimple_assign (srcdef
))
2807 /* Handle bitwise AND used in conversions from wider size_t
2808 to narrower unsigned types. */
2809 tree_code code
= gimple_assign_rhs_code (srcdef
);
2810 if (code
== BIT_AND_EXPR
2811 || code
== NOP_EXPR
)
2812 return is_strlen_related_p (gimple_assign_rhs1 (srcdef
), len
);
2817 if (gimple_call_builtin_p (srcdef
, BUILT_IN_NORMAL
))
2819 /* If SRC is the result of a call to an allocation function
2820 or strlen, use the function's argument instead. */
2821 tree func
= gimple_call_fndecl (srcdef
);
2822 built_in_function code
= DECL_FUNCTION_CODE (func
);
2823 if (code
== BUILT_IN_ALLOCA
2824 || code
== BUILT_IN_ALLOCA_WITH_ALIGN
2825 || code
== BUILT_IN_MALLOC
2826 || code
== BUILT_IN_STRLEN
)
2827 return is_strlen_related_p (gimple_call_arg (srcdef
, 0), len
);
2829 /* FIXME: Handle other functions with attribute alloc_size. */
2834 gimple
*lendef
= SSA_NAME_DEF_STMT (len
);
2838 if (is_gimple_call (lendef
))
2840 tree func
= gimple_call_fndecl (lendef
);
2841 if (!valid_builtin_call (lendef
)
2842 || DECL_FUNCTION_CODE (func
) != BUILT_IN_STRLEN
)
2845 tree arg
= gimple_call_arg (lendef
, 0);
2846 return is_strlen_related_p (src
, arg
);
2849 if (!is_gimple_assign (lendef
))
2852 tree_code code
= gimple_assign_rhs_code (lendef
);
2853 tree rhs1
= gimple_assign_rhs1 (lendef
);
2854 tree rhstype
= TREE_TYPE (rhs1
);
2856 if ((TREE_CODE (rhstype
) == POINTER_TYPE
&& code
== POINTER_PLUS_EXPR
)
2857 || (INTEGRAL_TYPE_P (rhstype
)
2858 && (code
== BIT_AND_EXPR
2859 || code
== NOP_EXPR
)))
2861 /* Pointer plus (an integer), and truncation are considered among
2862 the (potentially) related expressions to strlen. */
2863 return is_strlen_related_p (src
, rhs1
);
2866 if (tree rhs2
= gimple_assign_rhs2 (lendef
))
2868 /* Integer subtraction is considered strlen-related when both
2869 arguments are integers and second one is strlen-related. */
2870 rhstype
= TREE_TYPE (rhs2
);
2871 if (INTEGRAL_TYPE_P (rhstype
) && code
== MINUS_EXPR
)
2872 return is_strlen_related_p (src
, rhs2
);
2878 /* Called by handle_builtin_stxncpy_strncat and by
2879 gimple_fold_builtin_strncpy in gimple-fold.cc.
2880 Check to see if the specified bound is a) equal to the size of
2881 the destination DST and if so, b) if it's immediately followed by
2882 DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise,
2883 do nothing. Return true if diagnostic has been issued.
2885 The purpose is to diagnose calls to strncpy and stpncpy that do
2886 not nul-terminate the copy while allowing for the idiom where
2887 such a call is immediately followed by setting the last element
2890 strncpy (a, s, sizeof a);
2891 a[sizeof a - 1] = '\0';
2895 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi
, tree src
, tree cnt
,
2896 pointer_query
*ptr_qry
/* = NULL */)
2898 gimple
*stmt
= gsi_stmt (gsi
);
2899 if (warning_suppressed_p (stmt
, OPT_Wstringop_truncation
))
2902 wide_int cntrange
[2];
2904 if (!get_range_query (cfun
)->range_of_expr (r
, cnt
)
2906 || r
.undefined_p ())
2910 value_range_kind kind
= get_legacy_range (r
, min
, max
);
2911 cntrange
[0] = wi::to_wide (min
);
2912 cntrange
[1] = wi::to_wide (max
);
2913 if (kind
== VR_ANTI_RANGE
)
2915 wide_int maxobjsize
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
));
2917 if (wi::ltu_p (cntrange
[1], maxobjsize
))
2919 cntrange
[0] = cntrange
[1] + 1;
2920 cntrange
[1] = maxobjsize
;
2924 cntrange
[1] = cntrange
[0] - 1;
2925 cntrange
[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt
)));
2929 /* Negative value is the constant string length. If it's less than
2930 the lower bound there is no truncation. Avoid calling get_stridx()
2931 when ssa_ver_to_stridx is empty. That implies the caller isn't
2932 running under the control of this pass and ssa_ver_to_stridx hasn't
2933 been created yet. */
2934 int sidx
= ssa_ver_to_stridx
.length () ? get_stridx (src
, stmt
) : 0;
2935 if (sidx
< 0 && wi::gtu_p (cntrange
[0], ~sidx
))
2938 tree dst
= gimple_call_arg (stmt
, 0);
2940 if (TREE_CODE (dstdecl
) == ADDR_EXPR
)
2941 dstdecl
= TREE_OPERAND (dstdecl
, 0);
2943 tree ref
= NULL_TREE
;
2947 /* If the source is a non-string return early to avoid warning
2948 for possible truncation (if the truncation is certain SIDX
2950 tree srcdecl
= gimple_call_arg (stmt
, 1);
2951 if (TREE_CODE (srcdecl
) == ADDR_EXPR
)
2952 srcdecl
= TREE_OPERAND (srcdecl
, 0);
2953 if (get_attr_nonstring_decl (srcdecl
, &ref
))
2957 /* Likewise, if the destination refers to an array/pointer declared
2958 nonstring return early. */
2959 if (get_attr_nonstring_decl (dstdecl
, &ref
))
2962 /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2963 avoid the truncation warning. */
2964 gsi_next_nondebug (&gsi
);
2965 gimple
*next_stmt
= gsi_stmt (gsi
);
2968 /* When there is no statement in the same basic block check
2969 the immediate successor block. */
2970 if (basic_block bb
= gimple_bb (stmt
))
2972 if (single_succ_p (bb
))
2974 /* For simplicity, ignore blocks with multiple outgoing
2975 edges for now and only consider successor blocks along
2977 edge e
= EDGE_SUCC (bb
, 0);
2978 if (!(e
->flags
& EDGE_ABNORMAL
))
2980 gsi
= gsi_start_bb (e
->dest
);
2981 next_stmt
= gsi_stmt (gsi
);
2982 if (next_stmt
&& is_gimple_debug (next_stmt
))
2984 gsi_next_nondebug (&gsi
);
2985 next_stmt
= gsi_stmt (gsi
);
2992 if (next_stmt
&& is_gimple_assign (next_stmt
))
2994 tree lhs
= gimple_assign_lhs (next_stmt
);
2995 tree_code code
= TREE_CODE (lhs
);
2996 if (code
== ARRAY_REF
|| code
== MEM_REF
)
2997 lhs
= TREE_OPERAND (lhs
, 0);
2999 tree func
= gimple_call_fndecl (stmt
);
3000 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STPNCPY
)
3002 tree ret
= gimple_call_lhs (stmt
);
3003 if (ret
&& operand_equal_p (ret
, lhs
, 0))
3007 /* Determine the base address and offset of the reference,
3008 ignoring the innermost array index. */
3009 if (TREE_CODE (ref
) == ARRAY_REF
)
3010 ref
= TREE_OPERAND (ref
, 0);
3013 tree dstbase
= get_addr_base_and_unit_offset (ref
, &dstoff
);
3016 tree lhsbase
= get_addr_base_and_unit_offset (lhs
, &lhsoff
);
3019 && known_eq (dstoff
, lhsoff
)
3020 && operand_equal_p (dstbase
, lhsbase
, 0))
3024 int prec
= TYPE_PRECISION (TREE_TYPE (cnt
));
3025 wide_int lenrange
[2];
3026 if (strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
)
3028 lenrange
[0] = (sisrc
->nonzero_chars
3029 && TREE_CODE (sisrc
->nonzero_chars
) == INTEGER_CST
3030 ? wi::to_wide (sisrc
->nonzero_chars
)
3032 lenrange
[1] = lenrange
[0];
3035 lenrange
[0] = lenrange
[1] = wi::shwi (~sidx
, prec
);
3038 c_strlen_data lendata
= { };
3039 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
3040 to have it set to the length of the longest string in a PHI. */
3041 lendata
.maxbound
= src
;
3042 get_range_strlen (src
, &lendata
, /* eltsize = */1);
3043 if (TREE_CODE (lendata
.minlen
) == INTEGER_CST
3044 && TREE_CODE (lendata
.maxbound
) == INTEGER_CST
)
3046 /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
3047 which stores the length of the shortest known string. */
3048 if (integer_all_onesp (lendata
.maxlen
))
3049 lenrange
[0] = wi::shwi (0, prec
);
3051 lenrange
[0] = wi::to_wide (lendata
.minlen
, prec
);
3052 lenrange
[1] = wi::to_wide (lendata
.maxbound
, prec
);
3056 lenrange
[0] = wi::shwi (0, prec
);
3057 lenrange
[1] = wi::shwi (-1, prec
);
3061 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3062 tree func
= gimple_call_fndecl (stmt
);
3064 if (lenrange
[0] != 0 || !wi::neg_p (lenrange
[1]))
3066 /* If the longest source string is shorter than the lower bound
3067 of the specified count the copy is definitely nul-terminated. */
3068 if (wi::ltu_p (lenrange
[1], cntrange
[0]))
3071 if (wi::neg_p (lenrange
[1]))
3073 /* The length of one of the strings is unknown but at least
3074 one has non-zero length and that length is stored in
3075 LENRANGE[1]. Swap the bounds to force a "may be truncated"
3077 lenrange
[1] = lenrange
[0];
3078 lenrange
[0] = wi::shwi (0, prec
);
3081 /* Set to true for strncat whose bound is derived from the length
3082 of the destination (the expected usage pattern). */
3083 bool cat_dstlen_bounded
= false;
3084 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STRNCAT
)
3085 cat_dstlen_bounded
= is_strlen_related_p (dst
, cnt
);
3087 if (lenrange
[0] == cntrange
[1] && cntrange
[0] == cntrange
[1])
3088 return warning_n (callloc
, OPT_Wstringop_truncation
,
3089 cntrange
[0].to_uhwi (),
3090 "%qD output truncated before terminating "
3091 "nul copying %E byte from a string of the "
3093 "%qD output truncated before terminating nul "
3094 "copying %E bytes from a string of the same "
3097 else if (!cat_dstlen_bounded
)
3099 if (wi::geu_p (lenrange
[0], cntrange
[1]))
3101 /* The shortest string is longer than the upper bound of
3102 the count so the truncation is certain. */
3103 if (cntrange
[0] == cntrange
[1])
3104 return warning_n (callloc
, OPT_Wstringop_truncation
,
3105 cntrange
[0].to_uhwi (),
3106 "%qD output truncated copying %E byte "
3107 "from a string of length %wu",
3108 "%qD output truncated copying %E bytes "
3109 "from a string of length %wu",
3110 func
, cnt
, lenrange
[0].to_uhwi ());
3112 return warning_at (callloc
, OPT_Wstringop_truncation
,
3113 "%qD output truncated copying between %wu "
3114 "and %wu bytes from a string of length %wu",
3115 func
, cntrange
[0].to_uhwi (),
3116 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3118 else if (wi::geu_p (lenrange
[1], cntrange
[1]))
3120 /* The longest string is longer than the upper bound of
3121 the count so the truncation is possible. */
3122 if (cntrange
[0] == cntrange
[1])
3123 return warning_n (callloc
, OPT_Wstringop_truncation
,
3124 cntrange
[0].to_uhwi (),
3125 "%qD output may be truncated copying %E "
3126 "byte from a string of length %wu",
3127 "%qD output may be truncated copying %E "
3128 "bytes from a string of length %wu",
3129 func
, cnt
, lenrange
[1].to_uhwi ());
3131 return warning_at (callloc
, OPT_Wstringop_truncation
,
3132 "%qD output may be truncated copying between "
3133 "%wu and %wu bytes from a string of length %wu",
3134 func
, cntrange
[0].to_uhwi (),
3135 cntrange
[1].to_uhwi (), lenrange
[1].to_uhwi ());
3139 if (!cat_dstlen_bounded
3140 && cntrange
[0] != cntrange
[1]
3141 && wi::leu_p (cntrange
[0], lenrange
[0])
3142 && wi::leu_p (cntrange
[1], lenrange
[0] + 1))
3144 /* If the source (including the terminating nul) is longer than
3145 the lower bound of the specified count but shorter than the
3146 upper bound the copy may (but need not) be truncated. */
3147 return warning_at (callloc
, OPT_Wstringop_truncation
,
3148 "%qD output may be truncated copying between "
3149 "%wu and %wu bytes from a string of length %wu",
3150 func
, cntrange
[0].to_uhwi (),
3151 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3156 if (tree dstsize
= compute_objsize (dst
, stmt
, 1, &aref
, ptr_qry
))
3158 /* The source length is unknown. Try to determine the destination
3159 size and see if it matches the specified bound. If not, bail.
3160 Otherwise go on to see if it should be diagnosed for possible
3165 if (wi::to_wide (dstsize
) != cntrange
[1])
3168 /* Avoid warning for strncpy(a, b, N) calls where the following
3170 N == sizeof a && N == sizeof b */
3171 if (tree srcsize
= compute_objsize (src
, stmt
, 1, &aref
, ptr_qry
))
3172 if (wi::to_wide (srcsize
) == cntrange
[1])
3175 if (cntrange
[0] == cntrange
[1])
3176 return warning_at (callloc
, OPT_Wstringop_truncation
,
3177 "%qD specified bound %E equals destination size",
3184 /* Check the arguments to the built-in forms of stpncpy, strncpy, and
3185 strncat, for out-of-bounds offsets or overlapping access, and to see
3186 if the size is derived from calling strlen() on the source argument,
3187 and if so, issue the appropriate warning.
3188 APPEND_P is true for strncat. */
3191 strlen_pass::handle_builtin_stxncpy_strncat (bool append_p
)
3193 if (!strlen_to_stridx
)
3196 gimple
*stmt
= gsi_stmt (m_gsi
);
3198 tree dst
= gimple_call_arg (stmt
, 0);
3199 tree src
= gimple_call_arg (stmt
, 1);
3200 tree len
= gimple_call_arg (stmt
, 2);
3201 /* An upper bound of the size of the destination. */
3202 tree dstsize
= NULL_TREE
;
3203 /* The length of the destination and source strings (plus 1 for those
3204 whose FULL_STRING_P is set, i.e., whose length is exact rather than
3206 tree dstlenp1
= NULL_TREE
, srclenp1
= NULL_TREE
;;
3208 int didx
= get_stridx (dst
, stmt
);
3209 if (strinfo
*sidst
= didx
> 0 ? get_strinfo (didx
) : NULL
)
3211 /* Compute the size of the destination string including the nul
3212 if it is known to be nul-terminated. */
3213 if (sidst
->nonzero_chars
)
3215 if (sidst
->full_string_p
)
3217 /* String is known to be nul-terminated. */
3218 tree type
= TREE_TYPE (sidst
->nonzero_chars
);
3219 dstlenp1
= fold_build2 (PLUS_EXPR
, type
, sidst
->nonzero_chars
,
3220 build_int_cst (type
, 1));
3223 dstlenp1
= sidst
->nonzero_chars
;
3225 else if (TREE_CODE (sidst
->ptr
) == SSA_NAME
)
3227 gimple
*def_stmt
= SSA_NAME_DEF_STMT (sidst
->ptr
);
3228 dstsize
= gimple_call_alloc_size (def_stmt
);
3234 int sidx
= get_stridx (src
, stmt
);
3235 strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
;
3238 /* strncat() and strncpy() can modify the source string by writing
3239 over the terminating nul so SISRC->DONT_INVALIDATE must be left
3242 /* Compute the size of the source string including the terminating
3243 nul if its known to be nul-terminated. */
3244 if (sisrc
->nonzero_chars
)
3246 if (sisrc
->full_string_p
)
3248 tree type
= TREE_TYPE (sisrc
->nonzero_chars
);
3249 srclenp1
= fold_build2 (PLUS_EXPR
, type
, sisrc
->nonzero_chars
,
3250 build_int_cst (type
, 1));
3253 srclenp1
= sisrc
->nonzero_chars
;
3259 srclenp1
= NULL_TREE
;
3261 opt_code opt
= check_bounds_or_overlap (stmt
, dst
, src
, dstlenp1
, srclenp1
);
3262 if (opt
!= no_warning
)
3264 suppress_warning (stmt
, opt
);
3268 /* If the length argument was computed from strlen(S) for some string
3269 S retrieve the strinfo index for the string (PSS->FIRST) along with
3270 the location of the strlen() call (PSS->SECOND). */
3271 stridx_strlenloc
*pss
= strlen_to_stridx
->get (len
);
3272 if (!pss
|| pss
->first
<= 0)
3274 if (maybe_diag_stxncpy_trunc (m_gsi
, src
, len
))
3275 suppress_warning (stmt
, OPT_Wstringop_truncation
);
3280 /* Retrieve the strinfo data for the string S that LEN was computed
3281 from as some function F of strlen (S) (i.e., LEN need not be equal
3283 strinfo
*silen
= get_strinfo (pss
->first
);
3285 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3287 tree func
= gimple_call_fndecl (stmt
);
3289 bool warned
= false;
3291 /* When -Wstringop-truncation is set, try to determine truncation
3292 before diagnosing possible overflow. Truncation is implied by
3293 the LEN argument being equal to strlen(SRC), regardless of
3294 whether its value is known. Otherwise, when appending, or
3295 when copying into a destination of known size, issue the more
3296 generic -Wstringop-overflow which triggers for LEN arguments
3297 that in any meaningful way depend on strlen(SRC). */
3300 && is_strlen_related_p (src
, len
)
3301 && warning_at (callloc
, OPT_Wstringop_truncation
,
3302 "%qD output truncated before terminating nul "
3303 "copying as many bytes from a string as its length",
3306 else if ((append_p
|| !dstsize
|| len
== dstlenp1
)
3307 && silen
&& is_strlen_related_p (src
, silen
->ptr
))
3309 /* Issue -Wstringop-overflow when appending or when writing into
3310 a destination of a known size. Otherwise, when copying into
3311 a destination of an unknown size, it's truncation. */
3312 opt_code opt
= (append_p
|| dstsize
3313 ? OPT_Wstringop_overflow_
: OPT_Wstringop_truncation
);
3314 warned
= warning_at (callloc
, opt
,
3315 "%qD specified bound depends on the length "
3316 "of the source argument",
3321 location_t strlenloc
= pss
->second
;
3322 if (strlenloc
!= UNKNOWN_LOCATION
&& strlenloc
!= callloc
)
3323 inform (strlenloc
, "length computed here");
3327 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
3328 If strlen of the second argument is known and length of the third argument
3329 is that plus one, strlen of the first argument is the same after this
3330 call. Uses RVALS to determine range information. */
3333 strlen_pass::handle_builtin_memcpy (built_in_function bcode
)
3335 tree lhs
, oldlen
, newlen
;
3336 gimple
*stmt
= gsi_stmt (m_gsi
);
3339 tree len
= gimple_call_arg (stmt
, 2);
3340 tree src
= gimple_call_arg (stmt
, 1);
3341 tree dst
= gimple_call_arg (stmt
, 0);
3343 int didx
= get_stridx (dst
, stmt
);
3344 strinfo
*olddsi
= NULL
;
3346 olddsi
= get_strinfo (didx
);
3351 && !integer_zerop (len
))
3353 maybe_warn_overflow (stmt
, false, len
, olddsi
, false, true);
3354 if (tree_fits_uhwi_p (len
))
3355 adjust_last_stmt (olddsi
, stmt
, false);
3358 int idx
= get_stridx (src
, stmt
);
3367 /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
3369 si
= get_strinfo (idx
);
3370 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
3372 if (TREE_CODE (len
) == INTEGER_CST
3373 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
3375 if (tree_int_cst_le (len
, si
->nonzero_chars
))
3377 /* Copying LEN nonzero characters, where LEN is constant. */
3379 full_string_p
= false;
3383 /* Copying the whole of the analyzed part of SI. */
3384 newlen
= si
->nonzero_chars
;
3385 full_string_p
= si
->full_string_p
;
3390 if (!si
->full_string_p
)
3392 if (TREE_CODE (len
) != SSA_NAME
)
3394 def_stmt
= SSA_NAME_DEF_STMT (len
);
3395 if (!is_gimple_assign (def_stmt
)
3396 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
3397 || gimple_assign_rhs1 (def_stmt
) != si
->nonzero_chars
3398 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
3400 /* Copying variable-length string SI (and no more). */
3401 newlen
= si
->nonzero_chars
;
3402 full_string_p
= true;
3408 /* Handle memcpy (x, "abcd", 5) or
3409 memcpy (x, "abc\0uvw", 7). */
3410 if (!tree_fits_uhwi_p (len
))
3413 unsigned HOST_WIDE_INT clen
= tree_to_uhwi (len
);
3414 unsigned HOST_WIDE_INT nonzero_chars
= ~idx
;
3415 newlen
= build_int_cst (size_type_node
, MIN (nonzero_chars
, clen
));
3416 full_string_p
= clen
> nonzero_chars
;
3421 && olddsi
->nonzero_chars
3422 && TREE_CODE (olddsi
->nonzero_chars
) == INTEGER_CST
3423 && tree_int_cst_le (newlen
, olddsi
->nonzero_chars
))
3425 /* The SRC substring being written strictly overlaps
3426 a subsequence of the existing string OLDDSI. */
3427 newlen
= olddsi
->nonzero_chars
;
3428 full_string_p
= olddsi
->full_string_p
;
3431 if (olddsi
!= NULL
&& TREE_CODE (len
) == SSA_NAME
)
3432 adjust_last_stmt (olddsi
, stmt
, false);
3436 didx
= new_stridx (dst
);
3443 dsi
= unshare_strinfo (olddsi
);
3444 oldlen
= olddsi
->nonzero_chars
;
3445 dsi
->nonzero_chars
= newlen
;
3446 dsi
->full_string_p
= full_string_p
;
3447 /* Break the chain, so adjust_related_strinfo on later pointers in
3448 the chain won't adjust this one anymore. */
3451 dsi
->endptr
= NULL_TREE
;
3455 dsi
= new_strinfo (dst
, didx
, newlen
, full_string_p
);
3456 set_strinfo (didx
, dsi
);
3457 find_equal_ptrs (dst
, didx
);
3459 dsi
->writable
= true;
3460 dsi
->dont_invalidate
= true;
3463 tree adj
= NULL_TREE
;
3464 location_t loc
= gimple_location (stmt
);
3465 if (oldlen
== NULL_TREE
)
3467 else if (integer_zerop (oldlen
))
3469 else if (TREE_CODE (oldlen
) == INTEGER_CST
3470 || TREE_CODE (newlen
) == INTEGER_CST
)
3471 adj
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (newlen
), newlen
,
3472 fold_convert_loc (loc
, TREE_TYPE (newlen
),
3474 if (adj
!= NULL_TREE
)
3475 adjust_related_strinfos (loc
, dsi
, adj
);
3479 /* memcpy src may not overlap dst, so src doesn't need to be
3480 invalidated either. */
3482 si
->dont_invalidate
= true;
3486 lhs
= gimple_call_lhs (stmt
);
3489 case BUILT_IN_MEMCPY
:
3490 case BUILT_IN_MEMCPY_CHK
:
3491 /* Allow adjust_last_stmt to decrease this memcpy's size. */
3492 laststmt
.stmt
= stmt
;
3493 laststmt
.len
= dsi
->nonzero_chars
;
3494 laststmt
.stridx
= dsi
->idx
;
3496 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
3498 case BUILT_IN_MEMPCPY
:
3499 case BUILT_IN_MEMPCPY_CHK
:
3507 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
3508 If strlen of the second argument is known, strlen of the first argument
3509 is increased by the length of the second argument. Furthermore, attempt
3510 to convert it to memcpy/strcpy if the length of the first argument
3514 strlen_pass::handle_builtin_strcat (built_in_function bcode
)
3517 tree srclen
, args
, type
, fn
, objsz
, endptr
;
3519 gimple
*stmt
= gsi_stmt (m_gsi
);
3521 location_t loc
= gimple_location (stmt
);
3523 tree src
= gimple_call_arg (stmt
, 1);
3524 tree dst
= gimple_call_arg (stmt
, 0);
3526 /* Bail if the source is the same as destination. It will be diagnosed
3528 if (operand_equal_p (src
, dst
, 0))
3531 tree lhs
= gimple_call_lhs (stmt
);
3533 didx
= get_stridx (dst
, stmt
);
3539 dsi
= get_strinfo (didx
);
3543 idx
= get_stridx (src
, stmt
);
3545 srclen
= build_int_cst (size_type_node
, ~idx
);
3548 si
= get_strinfo (idx
);
3550 srclen
= get_string_length (si
);
3553 /* Disable warning for the transformed statement? */
3554 opt_code no_warning_opt
= no_warning
;
3556 if (dsi
== NULL
|| get_string_length (dsi
) == NULL_TREE
)
3559 /* The concatenation always involves copying at least one byte
3560 (the terminating nul), even if the source string is empty.
3561 If the source is unknown assume it's one character long and
3562 used that as both sizes. */
3566 tree type
= TREE_TYPE (slen
);
3567 slen
= fold_build2 (PLUS_EXPR
, type
, slen
, build_int_cst (type
, 1));
3570 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3571 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, NULL_TREE
,
3574 suppress_warning (stmt
, no_warning_opt
);
3577 /* strcat (p, q) can be transformed into
3578 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
3579 with length endptr - p if we need to compute the length
3580 later on. Don't do this transformation if we don't need
3582 if (builtin_decl_implicit_p (BUILT_IN_STPCPY
) && lhs
== NULL_TREE
)
3586 didx
= new_stridx (dst
);
3592 dsi
= new_strinfo (dst
, didx
, NULL_TREE
, false);
3593 set_strinfo (didx
, dsi
);
3594 find_equal_ptrs (dst
, didx
);
3598 dsi
= unshare_strinfo (dsi
);
3599 dsi
->nonzero_chars
= NULL_TREE
;
3600 dsi
->full_string_p
= false;
3602 dsi
->endptr
= NULL_TREE
;
3604 dsi
->writable
= true;
3606 dsi
->dont_invalidate
= true;
3611 tree dstlen
= dsi
->nonzero_chars
;
3612 endptr
= dsi
->endptr
;
3614 dsi
= unshare_strinfo (dsi
);
3615 dsi
->endptr
= NULL_TREE
;
3617 dsi
->writable
= true;
3619 if (srclen
!= NULL_TREE
)
3621 dsi
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
3622 TREE_TYPE (dsi
->nonzero_chars
),
3623 dsi
->nonzero_chars
, srclen
);
3624 gcc_assert (dsi
->full_string_p
);
3625 adjust_related_strinfos (loc
, dsi
, srclen
);
3626 dsi
->dont_invalidate
= true;
3630 dsi
->nonzero_chars
= NULL
;
3631 dsi
->full_string_p
= false;
3632 if (lhs
== NULL_TREE
&& builtin_decl_implicit_p (BUILT_IN_STPCPY
))
3633 dsi
->dont_invalidate
= true;
3637 /* strcat src may not overlap dst, so src doesn't need to be
3638 invalidated either. */
3639 si
->dont_invalidate
= true;
3641 /* For now. Could remove the lhs from the call and add
3642 lhs = dst; afterwards. */
3650 case BUILT_IN_STRCAT
:
3651 if (srclen
!= NULL_TREE
)
3652 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
3654 fn
= builtin_decl_implicit (BUILT_IN_STRCPY
);
3656 case BUILT_IN_STRCAT_CHK
:
3657 if (srclen
!= NULL_TREE
)
3658 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
3660 fn
= builtin_decl_explicit (BUILT_IN_STRCPY_CHK
);
3661 objsz
= gimple_call_arg (stmt
, 2);
3667 if (fn
== NULL_TREE
)
3672 tree type
= TREE_TYPE (dstlen
);
3674 /* Compute the size of the source sequence, including the nul. */
3675 tree srcsize
= srclen
? srclen
: size_zero_node
;
3676 tree one
= build_int_cst (type
, 1);
3677 srcsize
= fold_build2 (PLUS_EXPR
, type
, srcsize
, one
);
3678 tree dstsize
= fold_build2 (PLUS_EXPR
, type
, dstlen
, one
);
3679 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3681 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, dstsize
,
3684 suppress_warning (stmt
, no_warning_opt
);
3687 tree len
= NULL_TREE
;
3688 if (srclen
!= NULL_TREE
)
3690 args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
3691 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
3693 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
3694 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
,
3695 build_int_cst (type
, 1));
3696 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
3700 dst
= fold_convert_loc (loc
, TREE_TYPE (dst
), unshare_expr (endptr
));
3702 dst
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
, TREE_TYPE (dst
), dst
,
3703 fold_convert_loc (loc
, sizetype
,
3704 unshare_expr (dstlen
)));
3705 dst
= force_gimple_operand_gsi (&m_gsi
, dst
, true, NULL_TREE
, true,
3709 objsz
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (objsz
), objsz
,
3710 fold_convert_loc (loc
, TREE_TYPE (objsz
),
3711 unshare_expr (dstlen
)));
3712 objsz
= force_gimple_operand_gsi (&m_gsi
, objsz
, true, NULL_TREE
, true,
3715 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3717 fprintf (dump_file
, "Optimizing: ");
3718 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3720 if (srclen
!= NULL_TREE
)
3721 success
= update_gimple_call (&m_gsi
, fn
, 3 + (objsz
!= NULL_TREE
),
3722 dst
, src
, len
, objsz
);
3724 success
= update_gimple_call (&m_gsi
, fn
, 2 + (objsz
!= NULL_TREE
),
3728 stmt
= gsi_stmt (m_gsi
);
3730 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3732 fprintf (dump_file
, "into: ");
3733 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3735 /* If srclen == NULL, note that current string length can be
3736 computed by transforming this strcpy into stpcpy. */
3737 if (srclen
== NULL_TREE
&& dsi
->dont_invalidate
)
3739 adjust_last_stmt (dsi
, stmt
, true);
3740 if (srclen
!= NULL_TREE
)
3742 laststmt
.stmt
= stmt
;
3743 laststmt
.len
= srclen
;
3744 laststmt
.stridx
= dsi
->idx
;
3747 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3748 fprintf (dump_file
, "not possible.\n");
3751 suppress_warning (stmt
, no_warning_opt
);
3754 /* Handle a call to an allocation function like alloca, malloc or calloc,
3755 or an ordinary allocation function declared with attribute alloc_size. */
3758 strlen_pass::handle_alloc_call (built_in_function bcode
)
3760 gimple
*stmt
= gsi_stmt (m_gsi
);
3761 tree lhs
= gimple_call_lhs (stmt
);
3762 if (lhs
== NULL_TREE
)
3765 gcc_assert (get_stridx (lhs
, stmt
) == 0);
3766 int idx
= new_stridx (lhs
);
3767 tree length
= NULL_TREE
;
3768 if (bcode
== BUILT_IN_CALLOC
)
3769 length
= build_int_cst (size_type_node
, 0);
3770 strinfo
*si
= new_strinfo (lhs
, idx
, length
, length
!= NULL_TREE
);
3771 if (bcode
== BUILT_IN_CALLOC
)
3773 /* Only set STMT for calloc and malloc. */
3775 /* Only set ENDPTR for calloc. */
3778 else if (bcode
== BUILT_IN_MALLOC
)
3781 /* Set ALLOC is set for all allocation functions. */
3783 set_strinfo (idx
, si
);
3784 si
->writable
= true;
3785 si
->dont_invalidate
= true;
3788 /* Handle a call to memset.
3789 After a call to calloc, memset(,0,) is unnecessary.
3790 memset(malloc(n),0,n) is calloc(n,1).
3791 return true when the call is transformed, false otherwise.
3792 When nonnull uses RVALS to determine range information. */
3795 strlen_pass::handle_builtin_memset (bool *zero_write
)
3797 gimple
*memset_stmt
= gsi_stmt (m_gsi
);
3798 tree ptr
= gimple_call_arg (memset_stmt
, 0);
3799 tree memset_val
= gimple_call_arg (memset_stmt
, 1);
3800 tree memset_size
= gimple_call_arg (memset_stmt
, 2);
3802 /* Set to the non-constant offset added to PTR. */
3804 int idx1
= get_stridx (ptr
, memset_stmt
, offrng
, ptr_qry
.rvals
);
3806 && TREE_CODE (memset_val
) == INTEGER_CST
3807 && ((TREE_CODE (memset_size
) == INTEGER_CST
3808 && !integer_zerop (memset_size
))
3809 || TREE_CODE (memset_size
) == SSA_NAME
))
3811 unsigned HOST_WIDE_INT mask
= (HOST_WIDE_INT_1U
<< CHAR_TYPE_SIZE
) - 1;
3812 bool full_string_p
= (wi::to_wide (memset_val
) & mask
) == 0;
3814 /* We only handle symbolic lengths when writing non-zero values. */
3815 if (full_string_p
&& TREE_CODE (memset_size
) != INTEGER_CST
)
3818 idx1
= new_stridx (ptr
);
3823 newlen
= build_int_cst (size_type_node
, 0);
3824 else if (TREE_CODE (memset_size
) == INTEGER_CST
)
3825 newlen
= fold_convert (size_type_node
, memset_size
);
3827 newlen
= memset_size
;
3829 strinfo
*dsi
= new_strinfo (ptr
, idx1
, newlen
, full_string_p
);
3830 set_strinfo (idx1
, dsi
);
3831 find_equal_ptrs (ptr
, idx1
);
3832 dsi
->dont_invalidate
= true;
3833 dsi
->writable
= true;
3839 strinfo
*si1
= get_strinfo (idx1
);
3842 gimple
*alloc_stmt
= si1
->alloc
;
3843 if (!alloc_stmt
|| !is_gimple_call (alloc_stmt
))
3845 tree callee1
= gimple_call_fndecl (alloc_stmt
);
3846 if (!valid_builtin_call (alloc_stmt
))
3848 tree alloc_size
= gimple_call_arg (alloc_stmt
, 0);
3850 /* Check for overflow. */
3851 maybe_warn_overflow (memset_stmt
, false, memset_size
, NULL
, false, true);
3853 /* Bail when there is no statement associated with the destination
3854 (the statement may be null even when SI1->ALLOC is not). */
3858 /* Avoid optimizing if store is at a variable offset from the beginning
3859 of the allocated object. */
3860 if (offrng
[0] != 0 || offrng
[0] != offrng
[1])
3863 /* Bail when the call writes a non-zero value. */
3864 if (!integer_zerop (memset_val
))
3867 /* Let the caller know the memset call cleared the destination. */
3870 enum built_in_function code1
= DECL_FUNCTION_CODE (callee1
);
3871 if (code1
== BUILT_IN_CALLOC
)
3872 /* Not touching alloc_stmt */ ;
3873 else if (code1
== BUILT_IN_MALLOC
3874 && operand_equal_p (memset_size
, alloc_size
, 0))
3876 /* Replace the malloc + memset calls with calloc. */
3877 gimple_stmt_iterator gsi1
= gsi_for_stmt (si1
->stmt
);
3878 update_gimple_call (&gsi1
, builtin_decl_implicit (BUILT_IN_CALLOC
), 2,
3879 alloc_size
, build_one_cst (size_type_node
));
3880 si1
->nonzero_chars
= build_int_cst (size_type_node
, 0);
3881 si1
->full_string_p
= true;
3882 si1
->stmt
= gsi_stmt (gsi1
);
3886 tree lhs
= gimple_call_lhs (memset_stmt
);
3887 unlink_stmt_vdef (memset_stmt
);
3890 gimple
*assign
= gimple_build_assign (lhs
, ptr
);
3891 gsi_replace (&m_gsi
, assign
, false);
3895 gsi_remove (&m_gsi
, true);
3896 release_defs (memset_stmt
);
3902 /* Return first such statement if RES is used in statements testing its
3903 equality to zero, and null otherwise. If EXCLUSIVE is true, return
3904 nonnull if and only RES is used in such expressions exclusively and
3908 use_in_zero_equality (tree res
, bool exclusive
)
3910 gimple
*first_use
= NULL
;
3912 use_operand_p use_p
;
3913 imm_use_iterator iter
;
3915 FOR_EACH_IMM_USE_FAST (use_p
, iter
, res
)
3917 gimple
*use_stmt
= USE_STMT (use_p
);
3919 if (is_gimple_debug (use_stmt
))
3922 if (gimple_code (use_stmt
) == GIMPLE_ASSIGN
)
3924 tree_code code
= gimple_assign_rhs_code (use_stmt
);
3925 if (code
== COND_EXPR
)
3927 tree cond_expr
= gimple_assign_rhs1 (use_stmt
);
3928 if ((TREE_CODE (cond_expr
) != EQ_EXPR
3929 && (TREE_CODE (cond_expr
) != NE_EXPR
))
3930 || !integer_zerop (TREE_OPERAND (cond_expr
, 1)))
3937 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
3939 if (!integer_zerop (gimple_assign_rhs2 (use_stmt
)))
3951 else if (gimple_code (use_stmt
) == GIMPLE_COND
)
3953 tree_code code
= gimple_cond_code (use_stmt
);
3954 if ((code
!= EQ_EXPR
&& code
!= NE_EXPR
)
3955 || !integer_zerop (gimple_cond_rhs (use_stmt
)))
3968 first_use
= use_stmt
;
3974 /* Handle a call to memcmp. We try to handle small comparisons by
3975 converting them to load and compare, and replacing the call to memcmp
3976 with a __builtin_memcmp_eq call where possible.
3977 return true when call is transformed, return false otherwise. */
3980 strlen_pass::handle_builtin_memcmp ()
3982 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
3983 tree res
= gimple_call_lhs (stmt
);
3985 if (!res
|| !use_in_zero_equality (res
))
3988 tree arg1
= gimple_call_arg (stmt
, 0);
3989 tree arg2
= gimple_call_arg (stmt
, 1);
3990 tree len
= gimple_call_arg (stmt
, 2);
3991 unsigned HOST_WIDE_INT leni
;
3993 if (tree_fits_uhwi_p (len
)
3994 && (leni
= tree_to_uhwi (len
)) <= GET_MODE_SIZE (word_mode
)
3995 && pow2p_hwi (leni
))
3997 leni
*= CHAR_TYPE_SIZE
;
3998 unsigned align1
= get_pointer_alignment (arg1
);
3999 unsigned align2
= get_pointer_alignment (arg2
);
4000 unsigned align
= MIN (align1
, align2
);
4001 scalar_int_mode mode
;
4002 if (int_mode_for_size (leni
, 1).exists (&mode
)
4003 && (align
>= leni
|| !targetm
.slow_unaligned_access (mode
, align
)))
4005 location_t loc
= gimple_location (stmt
);
4007 type
= build_nonstandard_integer_type (leni
, 1);
4008 gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type
)), leni
));
4009 tree ptrtype
= build_pointer_type_for_mode (char_type_node
,
4011 off
= build_int_cst (ptrtype
, 0);
4012 arg1
= build2_loc (loc
, MEM_REF
, type
, arg1
, off
);
4013 arg2
= build2_loc (loc
, MEM_REF
, type
, arg2
, off
);
4014 tree tem1
= fold_const_aggregate_ref (arg1
);
4017 tree tem2
= fold_const_aggregate_ref (arg2
);
4020 res
= fold_convert_loc (loc
, TREE_TYPE (res
),
4021 fold_build2_loc (loc
, NE_EXPR
,
4024 gimplify_and_update_call_from_tree (&m_gsi
, res
);
4029 gimple_call_set_fndecl (stmt
, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ
));
4033 /* Given strinfo IDX for ARG, sets LENRNG[] to the range of lengths
4034 of the string(s) referenced by ARG if it can be determined.
4035 If the length cannot be determined, sets *SIZE to the size of
4036 the array the string is stored in, if any. If no such array is
4037 known, sets *SIZE to -1. When the strings are nul-terminated sets
4038 *NULTERM to true, otherwise to false. When nonnull uses RVALS to
4039 determine range information. Returns true on success. */
4042 strlen_pass::get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
4043 unsigned HOST_WIDE_INT lenrng
[2],
4044 unsigned HOST_WIDE_INT
*size
, bool *nulterm
)
4047 *size
= HOST_WIDE_INT_M1U
;
4051 /* IDX is the inverted constant string length. */
4053 lenrng
[1] = lenrng
[0];
4058 /* Set so that both LEN and ~LEN are invalid lengths, i.e., maximum
4059 possible length + 1. */
4060 lenrng
[0] = lenrng
[1] = HOST_WIDE_INT_MAX
;
4062 if (strinfo
*si
= idx
? get_strinfo (idx
) : NULL
)
4064 /* FIXME: Handle all this in_range_strlen_dynamic. */
4065 if (!si
->nonzero_chars
)
4067 else if (tree_fits_uhwi_p (si
->nonzero_chars
))
4069 lenrng
[0] = tree_to_uhwi (si
->nonzero_chars
);
4070 *nulterm
= si
->full_string_p
;
4071 /* Set the upper bound only if the string is known to be
4072 nul-terminated, otherwise leave it at maximum + 1. */
4074 lenrng
[1] = lenrng
[0];
4076 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4079 if (get_range_query (cfun
)->range_of_expr (r
, si
->nonzero_chars
)
4080 && !r
.undefined_p ()
4083 lenrng
[0] = r
.lower_bound ().to_uhwi ();
4084 lenrng
[1] = r
.upper_bound ().to_uhwi ();
4085 *nulterm
= si
->full_string_p
;
4090 if (lenrng
[0] != HOST_WIDE_INT_MAX
)
4093 /* Compute the minimum and maximum real or possible lengths. */
4094 c_strlen_data lendata
= { };
4095 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
4096 to have it set to the length of the longest string in a PHI. */
4097 lendata
.maxbound
= arg
;
4098 get_range_strlen_dynamic (arg
, stmt
, &lendata
, ptr_qry
);
4100 unsigned HOST_WIDE_INT maxbound
= HOST_WIDE_INT_M1U
;
4101 if (tree_fits_uhwi_p (lendata
.maxbound
)
4102 && !integer_all_onesp (lendata
.maxbound
))
4103 maxbound
= tree_to_uhwi (lendata
.maxbound
);
4105 if (tree_fits_uhwi_p (lendata
.minlen
) && tree_fits_uhwi_p (lendata
.maxlen
))
4107 unsigned HOST_WIDE_INT minlen
= tree_to_uhwi (lendata
.minlen
);
4108 unsigned HOST_WIDE_INT maxlen
= tree_to_uhwi (lendata
.maxlen
);
4110 /* The longest string in this data model. */
4111 const unsigned HOST_WIDE_INT lenmax
4112 = tree_to_uhwi (max_object_size ()) - 2;
4114 if (maxbound
== HOST_WIDE_INT_M1U
)
4118 *nulterm
= minlen
== maxlen
;
4120 else if (maxlen
< lenmax
)
4122 *size
= maxbound
+ 1;
4131 if (maxbound
!= HOST_WIDE_INT_M1U
4133 && !integer_all_onesp (lendata
.maxlen
))
4135 /* Set *SIZE to LENDATA.MAXBOUND which is a conservative estimate
4136 of the longest string based on the sizes of the arrays referenced
4138 *size
= maxbound
+ 1;
4146 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
4147 the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
4148 for a sufficiently large BOUND). If the result is based on the length
4149 of one string being greater than the longest string that would fit in
4150 the array pointer to by the argument, set *PLEN and *PSIZE to
4151 the corresponding length (or its complement when the string is known
4152 to be at least as long and need not be nul-terminated) and size.
4153 Otherwise return null. */
4156 strlen_pass::strxcmp_eqz_result (gimple
*stmt
, tree arg1
, int idx1
,
4157 tree arg2
, int idx2
,
4158 unsigned HOST_WIDE_INT bound
,
4159 unsigned HOST_WIDE_INT len
[2],
4160 unsigned HOST_WIDE_INT
*psize
)
4162 /* Determine the range the length of each string is in and whether it's
4163 known to be nul-terminated, or the size of the array it's stored in. */
4165 unsigned HOST_WIDE_INT siz1
, siz2
;
4166 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4167 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &siz1
, &nul1
)
4168 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &siz2
, &nul2
))
4171 /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
4172 to HWI_MAX when invalid. Adjust the length of each string to consider
4173 to be no more than BOUND. */
4174 if (len1rng
[0] < HOST_WIDE_INT_MAX
&& len1rng
[0] > bound
)
4176 if (len1rng
[1] < HOST_WIDE_INT_MAX
&& len1rng
[1] > bound
)
4178 if (len2rng
[0] < HOST_WIDE_INT_MAX
&& len2rng
[0] > bound
)
4180 if (len2rng
[1] < HOST_WIDE_INT_MAX
&& len2rng
[1] > bound
)
4183 /* Two empty strings are equal. */
4184 if (len1rng
[1] == 0 && len2rng
[1] == 0)
4185 return integer_one_node
;
4187 /* The strings are definitely unequal when the lower bound of the length
4188 of one of them is greater than the length of the longest string that
4189 would fit into the other array. */
4190 if (len1rng
[0] == HOST_WIDE_INT_MAX
4191 && len2rng
[0] != HOST_WIDE_INT_MAX
4192 && ((len2rng
[0] < bound
&& len2rng
[0] >= siz1
)
4193 || len2rng
[0] > siz1
))
4196 len
[0] = len1rng
[0];
4197 /* Set LEN[0] to the lower bound of ARG1's length when it's
4198 nul-terminated or to the complement of its minimum length
4200 len
[1] = nul2
? len2rng
[0] : ~len2rng
[0];
4201 return integer_zero_node
;
4204 if (len2rng
[0] == HOST_WIDE_INT_MAX
4205 && len1rng
[0] != HOST_WIDE_INT_MAX
4206 && ((len1rng
[0] < bound
&& len1rng
[0] >= siz2
)
4207 || len1rng
[0] > siz2
))
4210 len
[0] = nul1
? len1rng
[0] : ~len1rng
[0];
4211 len
[1] = len2rng
[0];
4212 return integer_zero_node
;
4215 /* The strings are also definitely unequal when their lengths are unequal
4216 and at least one is nul-terminated. */
4217 if (len1rng
[0] != HOST_WIDE_INT_MAX
4218 && len2rng
[0] != HOST_WIDE_INT_MAX
4219 && ((len1rng
[1] < len2rng
[0] && nul1
)
4220 || (len2rng
[1] < len1rng
[0] && nul2
)))
4222 if (bound
<= len1rng
[0] || bound
<= len2rng
[0])
4225 *psize
= HOST_WIDE_INT_M1U
;
4227 len
[0] = len1rng
[0];
4228 len
[1] = len2rng
[0];
4229 return integer_zero_node
;
4232 /* The string lengths may be equal or unequal. Even when equal and
4233 both strings nul-terminated, without the string contents there's
4234 no way to determine whether they are equal. */
4238 /* Diagnose pointless calls to strcmp or strncmp STMT with string
4239 arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
4240 whose result is used in equality expressions that evaluate to
4241 a constant due to one argument being longer than the size of
4245 maybe_warn_pointless_strcmp (gimple
*stmt
, HOST_WIDE_INT bound
,
4246 unsigned HOST_WIDE_INT len
[2],
4247 unsigned HOST_WIDE_INT siz
)
4249 tree lhs
= gimple_call_lhs (stmt
);
4250 gimple
*use
= use_in_zero_equality (lhs
, /* exclusive = */ false);
4254 bool at_least
= false;
4256 /* Excessive LEN[i] indicates a lower bound. */
4257 if (len
[0] > HOST_WIDE_INT_MAX
)
4263 if (len
[1] > HOST_WIDE_INT_MAX
)
4269 unsigned HOST_WIDE_INT minlen
= MIN (len
[0], len
[1]);
4271 /* FIXME: Include a note pointing to the declaration of the smaller
4273 location_t stmt_loc
= gimple_or_expr_nonartificial_location (stmt
, lhs
);
4275 tree callee
= gimple_call_fndecl (stmt
);
4276 bool warned
= false;
4277 if (siz
<= minlen
&& bound
== -1)
4278 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4280 ? G_("%qD of a string of length %wu or more and "
4281 "an array of size %wu evaluates to nonzero")
4282 : G_("%qD of a string of length %wu and an array "
4283 "of size %wu evaluates to nonzero")),
4284 callee
, minlen
, siz
);
4285 else if (!at_least
&& siz
<= HOST_WIDE_INT_MAX
)
4287 if (len
[0] != HOST_WIDE_INT_MAX
&& len
[1] != HOST_WIDE_INT_MAX
)
4288 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4289 "%qD of strings of length %wu and %wu "
4290 "and bound of %wu evaluates to nonzero",
4291 callee
, len
[0], len
[1], bound
);
4293 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4294 "%qD of a string of length %wu, an array "
4295 "of size %wu and bound of %wu evaluates to "
4297 callee
, minlen
, siz
, bound
);
4303 location_t use_loc
= gimple_location (use
);
4304 if (LOCATION_LINE (stmt_loc
) != LOCATION_LINE (use_loc
))
4305 inform (use_loc
, "in this expression");
4309 /* Optimize a call to strcmp or strncmp either by folding it to a constant
4310 when possible or by transforming the latter to the former. Warn about
4311 calls where the length of one argument is greater than the size of
4312 the array to which the other argument points if the latter's length
4313 is not known. Return true when the call has been transformed into
4314 another and false otherwise. */
4317 strlen_pass::handle_builtin_string_cmp ()
4319 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
4320 tree lhs
= gimple_call_lhs (stmt
);
4325 tree arg1
= gimple_call_arg (stmt
, 0);
4326 tree arg2
= gimple_call_arg (stmt
, 1);
4327 int idx1
= get_stridx (arg1
, stmt
);
4328 int idx2
= get_stridx (arg2
, stmt
);
4330 /* For strncmp set to the value of the third argument if known. */
4331 HOST_WIDE_INT bound
= -1;
4332 tree len
= NULL_TREE
;
4333 /* Extract the strncmp bound. */
4334 if (gimple_call_num_args (stmt
) == 3)
4336 len
= gimple_call_arg (stmt
, 2);
4337 if (tree_fits_shwi_p (len
))
4338 bound
= tree_to_shwi (len
);
4340 /* If the bound argument is NOT known, do nothing. */
4345 /* Avoid folding if either argument is not a nul-terminated array.
4346 Defer warning until later. */
4347 if (!check_nul_terminated_array (NULL_TREE
, arg1
, len
)
4348 || !check_nul_terminated_array (NULL_TREE
, arg2
, len
))
4352 /* Set to the length of one argument (or its complement if it's
4353 the lower bound of a range) and the size of the array storing
4354 the other if the result is based on the former being equal to
4355 or greater than the latter. */
4356 unsigned HOST_WIDE_INT len
[2] = { HOST_WIDE_INT_MAX
, HOST_WIDE_INT_MAX
};
4357 unsigned HOST_WIDE_INT siz
= HOST_WIDE_INT_M1U
;
4359 /* Try to determine if the two strings are either definitely equal
4360 or definitely unequal and if so, either fold the result to zero
4361 (when equal) or set the range of the result to ~[0, 0] otherwise. */
4362 if (tree eqz
= strxcmp_eqz_result (stmt
, arg1
, idx1
, arg2
, idx2
, bound
,
4365 if (integer_zerop (eqz
))
4367 maybe_warn_pointless_strcmp (stmt
, bound
, len
, siz
);
4369 /* When the lengths of the first two string arguments are
4370 known to be unequal set the range of the result to non-zero.
4371 This allows the call to be eliminated if its result is only
4372 used in tests for equality to zero. */
4374 nz
.set_nonzero (TREE_TYPE (lhs
));
4375 set_range_info (lhs
, nz
);
4378 /* When the two strings are definitely equal (such as when they
4379 are both empty) fold the call to the constant result. */
4380 replace_call_with_value (&m_gsi
, integer_zero_node
);
4385 /* Return if nothing is known about the strings pointed to by ARG1
4387 if (idx1
== 0 && idx2
== 0)
4390 /* Determine either the length or the size of each of the strings,
4391 whichever is available. */
4392 HOST_WIDE_INT cstlen1
= -1, cstlen2
= -1;
4393 HOST_WIDE_INT arysiz1
= -1, arysiz2
= -1;
4396 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4397 unsigned HOST_WIDE_INT arsz1
, arsz2
;
4400 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &arsz1
, nulterm
)
4401 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &arsz2
, nulterm
+ 1))
4404 if (len1rng
[0] == len1rng
[1] && len1rng
[0] < HOST_WIDE_INT_MAX
)
4405 cstlen1
= len1rng
[0];
4406 else if (arsz1
< HOST_WIDE_INT_M1U
)
4409 if (len2rng
[0] == len2rng
[1] && len2rng
[0] < HOST_WIDE_INT_MAX
)
4410 cstlen2
= len2rng
[0];
4411 else if (arsz2
< HOST_WIDE_INT_M1U
)
4415 /* Bail if neither the string length nor the size of the array
4416 it is stored in can be determined. */
4417 if ((cstlen1
< 0 && arysiz1
< 0)
4418 || (cstlen2
< 0 && arysiz2
< 0)
4419 || (cstlen1
< 0 && cstlen2
< 0))
4427 /* The exact number of characters to compare. */
4428 HOST_WIDE_INT cmpsiz
;
4429 if (cstlen1
>= 0 && cstlen2
>= 0)
4430 cmpsiz
= MIN (cstlen1
, cstlen2
);
4431 else if (cstlen1
>= 0)
4436 cmpsiz
= MIN (cmpsiz
, bound
);
4437 /* The size of the array in which the unknown string is stored. */
4438 HOST_WIDE_INT varsiz
= arysiz1
< 0 ? arysiz2
: arysiz1
;
4440 if ((varsiz
< 0 || cmpsiz
< varsiz
) && use_in_zero_equality (lhs
))
4442 /* If the known length is less than the size of the other array
4443 and the strcmp result is only used to test equality to zero,
4444 transform the call to the equivalent _eq call. */
4445 if (tree fn
= builtin_decl_implicit (bound
< 0 ? BUILT_IN_STRCMP_EQ
4446 : BUILT_IN_STRNCMP_EQ
))
4448 tree n
= build_int_cst (size_type_node
, cmpsiz
);
4449 update_gimple_call (&m_gsi
, fn
, 3, arg1
, arg2
, n
);
4457 /* Handle a POINTER_PLUS_EXPR statement.
4458 For p = "abcd" + 2; compute associated length, or if
4459 p = q + off is pointing to a '\0' character of a string, call
4460 zero_length_string on it. */
4463 strlen_pass::handle_pointer_plus ()
4465 gimple
*stmt
= gsi_stmt (m_gsi
);
4466 tree lhs
= gimple_assign_lhs (stmt
), off
;
4467 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
4475 tree off
= gimple_assign_rhs2 (stmt
);
4476 if (tree_fits_uhwi_p (off
)
4477 && tree_to_uhwi (off
) <= (unsigned HOST_WIDE_INT
) ~idx
)
4478 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)]
4479 = ~(~idx
- (int) tree_to_uhwi (off
));
4483 si
= get_strinfo (idx
);
4484 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
4487 off
= gimple_assign_rhs2 (stmt
);
4489 if (si
->full_string_p
&& operand_equal_p (si
->nonzero_chars
, off
, 0))
4490 zsi
= zero_length_string (lhs
, si
);
4491 else if (TREE_CODE (off
) == SSA_NAME
)
4493 gimple
*def_stmt
= SSA_NAME_DEF_STMT (off
);
4494 if (gimple_assign_single_p (def_stmt
)
4495 && si
->full_string_p
4496 && operand_equal_p (si
->nonzero_chars
,
4497 gimple_assign_rhs1 (def_stmt
), 0))
4498 zsi
= zero_length_string (lhs
, si
);
4501 && si
->endptr
!= NULL_TREE
4502 && si
->endptr
!= lhs
4503 && TREE_CODE (si
->endptr
) == SSA_NAME
)
4505 enum tree_code rhs_code
4506 = useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (si
->endptr
))
4507 ? SSA_NAME
: NOP_EXPR
;
4508 gimple_assign_set_rhs_with_ops (&m_gsi
, rhs_code
, si
->endptr
);
4509 gcc_assert (gsi_stmt (m_gsi
) == stmt
);
4514 /* Set LENRANGE to the number of nonzero bytes for a store of TYPE and
4515 clear all flags. Return true on success and false on failure. */
4518 nonzero_bytes_for_type (tree type
, unsigned lenrange
[3],
4519 bool *nulterm
, bool *allnul
, bool *allnonnul
)
4521 /* Use the size of the type of the expression as the size of the store,
4522 and set the upper bound of the length range to that of the size.
4523 Nothing is known about the contents so clear all flags. */
4524 tree typesize
= TYPE_SIZE_UNIT (type
);
4528 if (!tree_fits_uhwi_p (typesize
))
4531 unsigned HOST_WIDE_INT sz
= tree_to_uhwi (typesize
);
4536 lenrange
[1] = lenrange
[2] ? lenrange
[2] - 1 : 0;
4544 /* Recursively determine the minimum and maximum number of leading nonzero
4545 bytes in the representation of EXP at memory state VUSE and set
4546 LENRANGE[0] and LENRANGE[1] to each.
4547 Sets LENRANGE[2] to the total size of the access (which may be less
4548 than LENRANGE[1] when what's being referenced by EXP is a pointer
4549 rather than an array).
4550 Sets *NULTERM if the representation contains a zero byte, sets *ALLNUL
4551 if all the bytes are zero, and *ALLNONNUL is all are nonzero.
4552 OFFSET and NBYTES are the offset into the representation and
4553 the size of the access to it determined from an ADDR_EXPR (i.e.,
4554 a pointer) or MEM_REF or zero for other expressions.
4555 Uses RVALS to determine range information.
4556 Avoids recursing deeper than the limits in SNLIM allow.
4557 Returns true on success and false otherwise. */
4560 strlen_pass::count_nonzero_bytes (tree exp
, tree vuse
, gimple
*stmt
,
4561 unsigned HOST_WIDE_INT offset
,
4562 unsigned HOST_WIDE_INT nbytes
,
4563 unsigned lenrange
[3], bool *nulterm
,
4564 bool *allnul
, bool *allnonnul
,
4565 ssa_name_limit_t
&snlim
)
4567 if (TREE_CODE (exp
) == SSA_NAME
)
4569 /* Handle non-zero single-character stores specially. */
4570 tree type
= TREE_TYPE (exp
);
4571 if (TREE_CODE (type
) == INTEGER_TYPE
4572 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
4573 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
)
4574 && tree_expr_nonzero_p (exp
))
4576 /* If the character EXP is known to be non-zero (even if its
4577 exact value is not known) recurse once to set the range
4578 for an arbitrary constant. */
4579 exp
= build_int_cst (type
, 1);
4580 return count_nonzero_bytes (exp
, vuse
, stmt
,
4581 offset
, 1, lenrange
,
4582 nulterm
, allnul
, allnonnul
, snlim
);
4585 gimple
*g
= SSA_NAME_DEF_STMT (exp
);
4586 if (gimple_assign_single_p (g
))
4588 exp
= gimple_assign_rhs1 (g
);
4590 && TREE_CODE (exp
) != CONSTRUCTOR
4591 && TREE_CODE (exp
) != MEM_REF
)
4593 /* Handle DECLs, CONSTRUCTOR and MEM_REF below. */
4596 else if (gimple_code (g
) == GIMPLE_PHI
)
4598 /* Avoid processing an SSA_NAME that has already been visited
4599 or if an SSA_NAME limit has been reached. Indicate success
4600 if the former and failure if the latter. */
4601 if (int res
= snlim
.next_phi (exp
))
4604 /* Determine the minimum and maximum from the PHI arguments. */
4605 unsigned int n
= gimple_phi_num_args (g
);
4606 for (unsigned i
= 0; i
!= n
; i
++)
4608 tree def
= gimple_phi_arg_def (g
, i
);
4609 if (!count_nonzero_bytes (def
, vuse
, g
,
4610 offset
, nbytes
, lenrange
, nulterm
,
4611 allnul
, allnonnul
, snlim
))
4619 if (TREE_CODE (exp
) == CONSTRUCTOR
)
4622 /* If NBYTES has already been determined by an outer MEM_REF
4623 fail rather than overwriting it (this shouldn't happen). */
4626 tree type
= TREE_TYPE (exp
);
4627 tree size
= TYPE_SIZE_UNIT (type
);
4628 if (!size
|| !tree_fits_uhwi_p (size
))
4631 unsigned HOST_WIDE_INT byte_size
= tree_to_uhwi (size
);
4632 if (byte_size
< offset
)
4635 nbytes
= byte_size
- offset
;
4638 if (TREE_CODE (exp
) == MEM_REF
)
4643 tree arg
= TREE_OPERAND (exp
, 0);
4644 tree off
= TREE_OPERAND (exp
, 1);
4646 if (TREE_CODE (off
) != INTEGER_CST
|| !tree_fits_uhwi_p (off
))
4649 unsigned HOST_WIDE_INT wioff
= tree_to_uhwi (off
);
4650 if (INT_MAX
< wioff
)
4654 if (INT_MAX
< offset
)
4657 /* The size of the MEM_REF access determines the number of bytes. */
4658 tree type
= TREE_TYPE (exp
);
4659 tree typesize
= TYPE_SIZE_UNIT (type
);
4660 if (!typesize
|| !tree_fits_uhwi_p (typesize
))
4662 nbytes
= tree_to_uhwi (typesize
);
4666 /* Handle MEM_REF = SSA_NAME types of assignments. */
4667 return count_nonzero_bytes_addr (arg
, vuse
, stmt
,
4668 offset
, nbytes
, lenrange
, nulterm
,
4669 allnul
, allnonnul
, snlim
);
4672 if (VAR_P (exp
) || TREE_CODE (exp
) == CONST_DECL
)
4674 /* If EXP can be folded into a constant use the result. Otherwise
4675 proceed to use EXP to determine a range of the result. */
4676 if (tree fold_exp
= ctor_for_folding (exp
))
4677 if (fold_exp
!= error_mark_node
)
4681 const char *prep
= NULL
;
4682 if (TREE_CODE (exp
) == STRING_CST
)
4684 unsigned nchars
= TREE_STRING_LENGTH (exp
);
4685 if (nchars
< offset
)
4689 /* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
4690 (i.e., it's the size of a pointer), or from MEM_REF (as the size
4691 of the access), set it here to the size of the string, including
4692 all internal and trailing nuls if the string has any. */
4693 nbytes
= nchars
- offset
;
4694 else if (nchars
- offset
< nbytes
)
4697 prep
= TREE_STRING_POINTER (exp
) + offset
;
4700 unsigned char buf
[256];
4703 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8)
4705 /* If the pointer to representation hasn't been set above
4706 for STRING_CST point it at the buffer. */
4707 prep
= reinterpret_cast <char *>(buf
);
4708 /* Try to extract the representation of the constant object
4709 or expression starting from the offset. */
4710 unsigned repsize
= native_encode_expr (exp
, buf
, sizeof buf
, offset
);
4711 if (repsize
< nbytes
)
4713 /* This should only happen when REPSIZE is zero because EXP
4714 doesn't denote an object with a known initializer, except
4715 perhaps when the reference reads past its end. */
4721 else if (nbytes
< repsize
)
4726 return nonzero_bytes_for_type (TREE_TYPE (exp
), lenrange
,
4727 nulterm
, allnul
, allnonnul
);
4729 /* Compute the number of leading nonzero bytes in the representation
4730 and update the minimum and maximum. */
4731 unsigned HOST_WIDE_INT n
= prep
? strnlen (prep
, nbytes
) : nbytes
;
4733 if (n
< lenrange
[0])
4735 if (lenrange
[1] < n
)
4738 /* Set the size of the representation. */
4739 if (lenrange
[2] < nbytes
)
4740 lenrange
[2] = nbytes
;
4742 /* Clear NULTERM if none of the bytes is zero. */
4748 /* When the initial number of non-zero bytes N is non-zero, reset
4749 *ALLNUL; if N is less than that the size of the representation
4750 also clear *ALLNONNUL. */
4755 else if (*allnul
|| *allnonnul
)
4761 /* When either ALLNUL is set and N is zero, also determine
4762 whether all subsequent bytes after the first one (which
4763 is nul) are zero or nonzero and clear ALLNUL if not. */
4764 for (const char *p
= prep
; p
!= prep
+ nbytes
; ++p
)
4776 /* Like count_nonzero_bytes, but instead of counting bytes in EXP, count
4777 bytes that are pointed to by EXP, which should be a pointer. */
4780 strlen_pass::count_nonzero_bytes_addr (tree exp
, tree vuse
, gimple
*stmt
,
4781 unsigned HOST_WIDE_INT offset
,
4782 unsigned HOST_WIDE_INT nbytes
,
4783 unsigned lenrange
[3], bool *nulterm
,
4784 bool *allnul
, bool *allnonnul
,
4785 ssa_name_limit_t
&snlim
)
4787 int idx
= get_stridx (exp
, stmt
);
4790 /* get_strinfo reflects string lengths before the current statement,
4791 where the current statement is the outermost count_nonzero_bytes
4792 stmt. If there are any stores in between stmt and that
4793 current statement, the string length information might describe
4794 something significantly different. */
4795 if (gimple_vuse (stmt
) != vuse
)
4798 strinfo
*si
= get_strinfo (idx
);
4802 /* Handle both constant lengths as well non-constant lengths
4804 unsigned HOST_WIDE_INT minlen
, maxlen
;
4805 if (tree_fits_shwi_p (si
->nonzero_chars
))
4806 minlen
= maxlen
= tree_to_shwi (si
->nonzero_chars
);
4807 else if (si
->nonzero_chars
4808 && TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4811 if (!ptr_qry
.rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
)
4812 || vr
.undefined_p ()
4816 minlen
= vr
.lower_bound ().to_uhwi ();
4817 maxlen
= vr
.upper_bound ().to_uhwi ();
4822 if (maxlen
< offset
)
4825 minlen
= minlen
< offset
? 0 : minlen
- offset
;
4827 if (maxlen
+ 1 < nbytes
)
4830 if (nbytes
<= minlen
)
4833 if (nbytes
< minlen
)
4836 if (nbytes
< maxlen
)
4840 if (minlen
< lenrange
[0])
4841 lenrange
[0] = minlen
;
4842 if (lenrange
[1] < maxlen
)
4843 lenrange
[1] = maxlen
;
4845 if (lenrange
[2] < nbytes
)
4846 lenrange
[2] = nbytes
;
4848 /* Since only the length of the string are known and not its contents,
4849 clear ALLNUL and ALLNONNUL purely on the basis of the length. */
4851 if (minlen
< nbytes
)
4857 if (TREE_CODE (exp
) == ADDR_EXPR
)
4858 return count_nonzero_bytes (TREE_OPERAND (exp
, 0), vuse
, stmt
,
4860 lenrange
, nulterm
, allnul
, allnonnul
, snlim
);
4862 if (TREE_CODE (exp
) == SSA_NAME
)
4864 gimple
*g
= SSA_NAME_DEF_STMT (exp
);
4865 if (gimple_code (g
) == GIMPLE_PHI
)
4867 /* Avoid processing an SSA_NAME that has already been visited
4868 or if an SSA_NAME limit has been reached. Indicate success
4869 if the former and failure if the latter. */
4870 if (int res
= snlim
.next_phi (exp
))
4873 /* Determine the minimum and maximum from the PHI arguments. */
4874 unsigned int n
= gimple_phi_num_args (g
);
4875 for (unsigned i
= 0; i
!= n
; i
++)
4877 tree def
= gimple_phi_arg_def (g
, i
);
4878 if (!count_nonzero_bytes_addr (def
, vuse
, g
,
4879 offset
, nbytes
, lenrange
,
4880 nulterm
, allnul
, allnonnul
,
4889 /* Otherwise we don't know anything. */
4891 if (lenrange
[1] < nbytes
)
4892 lenrange
[1] = nbytes
;
4893 if (lenrange
[2] < nbytes
)
4894 lenrange
[2] = nbytes
;
4901 /* Same as above except with an implicit SSA_NAME limit. When EXPR_OR_TYPE
4902 is a type rather than an expression use its size to compute the range.
4903 RVALS is used to determine ranges of dynamically computed string lengths
4904 (the results of strlen). */
4907 strlen_pass::count_nonzero_bytes (tree expr_or_type
, gimple
*stmt
,
4908 unsigned lenrange
[3], bool *nulterm
,
4909 bool *allnul
, bool *allnonnul
)
4911 if (TYPE_P (expr_or_type
))
4912 return nonzero_bytes_for_type (expr_or_type
, lenrange
,
4913 nulterm
, allnul
, allnonnul
);
4915 /* Set to optimistic values so the caller doesn't have to worry about
4916 initializing these and to what. On success, the function will clear
4917 these if it determines their values are different but being recursive
4918 it never sets either to true. On failure, their values are
4924 ssa_name_limit_t snlim
;
4925 tree expr
= expr_or_type
;
4926 return count_nonzero_bytes (expr
, gimple_vuse (stmt
), stmt
,
4927 0, 0, lenrange
, nulterm
, allnul
, allnonnul
,
4931 /* Handle a single or multibyte store other than by a built-in function,
4932 either via a single character assignment or by multi-byte assignment
4933 either via MEM_REF or via a type other than char (such as in
4934 '*(int*)a = 12345'). Return true to let the caller advance *GSI to
4935 the next statement in the basic block and false otherwise. */
4938 strlen_pass::handle_store (bool *zero_write
)
4940 gimple
*stmt
= gsi_stmt (m_gsi
);
4941 /* The LHS and RHS of the store. The RHS is null if STMT is a function
4942 call. STORETYPE is the type of the store (determined from either
4943 the RHS of the assignment statement or the LHS of a function call. */
4944 tree lhs
, rhs
, storetype
;
4945 if (is_gimple_assign (stmt
))
4947 lhs
= gimple_assign_lhs (stmt
);
4948 rhs
= gimple_assign_rhs1 (stmt
);
4949 storetype
= TREE_TYPE (rhs
);
4951 else if (is_gimple_call (stmt
))
4953 lhs
= gimple_call_lhs (stmt
);
4955 storetype
= TREE_TYPE (lhs
);
4960 tree ssaname
= NULL_TREE
;
4964 range_query
*const rvals
= ptr_qry
.rvals
;
4966 /* The offset of the first byte in LHS modified by the store. */
4967 unsigned HOST_WIDE_INT offset
= 0;
4969 if (TREE_CODE (lhs
) == MEM_REF
4970 && TREE_CODE (TREE_OPERAND (lhs
, 0)) == SSA_NAME
)
4972 tree mem_offset
= TREE_OPERAND (lhs
, 1);
4973 if (tree_fits_uhwi_p (mem_offset
))
4975 /* Get the strinfo for the base, and use it if it starts with at
4976 least OFFSET nonzero characters. This is trivially true if
4978 offset
= tree_to_uhwi (mem_offset
);
4979 idx
= get_stridx (TREE_OPERAND (lhs
, 0), stmt
);
4981 si
= get_strinfo (idx
);
4983 ssaname
= TREE_OPERAND (lhs
, 0);
4985 || compare_nonzero_chars (si
, stmt
, offset
, rvals
) < 0)
4987 *zero_write
= rhs
? initializer_zerop (rhs
) : false;
4990 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4991 if (count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
, lenrange
,
4992 &dummy
, &dummy
, &dummy
))
4993 maybe_warn_overflow (stmt
, true, lenrange
[2]);
5001 idx
= get_addr_stridx (lhs
, stmt
, NULL_TREE
, &offset
, rvals
);
5003 si
= get_strinfo (idx
);
5006 /* Minimum and maximum leading non-zero bytes and the size of the store. */
5007 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
5009 /* Set to the minimum length of the string being assigned if known. */
5010 unsigned HOST_WIDE_INT rhs_minlen
;
5012 /* STORING_NONZERO_P is true iff not all stored characters are zero.
5013 STORING_ALL_NONZERO_P is true if all stored characters are zero.
5014 STORING_ALL_ZEROS_P is true iff all stored characters are zero.
5015 Both are false when it's impossible to determine which is true. */
5016 bool storing_nonzero_p
;
5017 bool storing_all_nonzero_p
;
5018 bool storing_all_zeros_p
;
5019 /* FULL_STRING_P is set when the stored sequence of characters form
5020 a nul-terminated string. */
5023 const bool ranges_valid
5024 = count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
,
5025 lenrange
, &full_string_p
,
5026 &storing_all_zeros_p
, &storing_all_nonzero_p
);
5030 rhs_minlen
= lenrange
[0];
5031 storing_nonzero_p
= lenrange
[1] > 0;
5032 *zero_write
= storing_all_zeros_p
;
5034 maybe_warn_overflow (stmt
, true, lenrange
[2]);
5038 rhs_minlen
= HOST_WIDE_INT_M1U
;
5039 full_string_p
= false;
5040 storing_nonzero_p
= false;
5041 storing_all_zeros_p
= false;
5042 storing_all_nonzero_p
= false;
5047 /* The count_nonzero_bytes call above might have unshared si.
5048 Fetch it again from the vector. */
5049 si
= get_strinfo (idx
);
5050 /* The corresponding element is set to 1 if the first and last
5051 element, respectively, of the sequence of characters being
5052 written over the string described by SI ends before
5053 the terminating nul (if it has one), to zero if the nul is
5054 being overwritten but not beyond, or negative otherwise. */
5055 int store_before_nul
[2];
5058 /* The offset of the last stored byte. */
5059 unsigned HOST_WIDE_INT endoff
= offset
+ lenrange
[2] - 1;
5061 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
5062 if (endoff
== offset
)
5063 store_before_nul
[1] = store_before_nul
[0];
5066 = compare_nonzero_chars (si
, stmt
, endoff
, rvals
);
5071 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
5072 store_before_nul
[1] = store_before_nul
[0];
5073 gcc_assert (offset
== 0 || store_before_nul
[0] >= 0);
5076 if (storing_all_zeros_p
5077 && store_before_nul
[0] == 0
5078 && store_before_nul
[1] == 0
5079 && si
->full_string_p
)
5081 /* When overwriting a '\0' with a '\0', the store can be removed
5082 if we know it has been stored in the current function. */
5083 if (!stmt_could_throw_p (cfun
, stmt
) && si
->writable
)
5085 unlink_stmt_vdef (stmt
);
5086 release_defs (stmt
);
5087 gsi_remove (&m_gsi
, true);
5092 si
->writable
= true;
5098 if (store_before_nul
[1] > 0
5099 && storing_nonzero_p
5100 && lenrange
[0] == lenrange
[1]
5101 && lenrange
[0] == lenrange
[2]
5102 && TREE_CODE (storetype
) == INTEGER_TYPE
)
5104 /* Handle a store of one or more non-nul characters that ends
5105 before the terminating nul of the destination and so does
5106 not affect its length
5107 If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
5108 and if we aren't storing '\0', we know that the length of
5109 the string and any other zero terminated string in memory
5110 remains the same. In that case we move to the next gimple
5111 statement and return to signal the caller that it shouldn't
5112 invalidate anything.
5114 This is beneficial for cases like:
5119 strcpy (p, "foobar");
5120 size_t len = strlen (p); // can be folded to 6
5121 size_t len2 = strlen (q); // has to be computed
5123 size_t len3 = strlen (p); // can be folded to 6
5124 size_t len4 = strlen (q); // can be folded to len2
5125 bar (len, len2, len3, len4);
5131 if (storing_nonzero_p
5132 || storing_all_zeros_p
5133 || (full_string_p
&& lenrange
[1] == 0)
5134 || (offset
!= 0 && store_before_nul
[1] > 0))
5136 /* When STORING_NONZERO_P, we know that the string will start
5137 with at least OFFSET + 1 nonzero characters. If storing
5138 a single character, set si->NONZERO_CHARS to the result.
5139 If storing multiple characters, try to determine the number
5140 of leading non-zero characters and set si->NONZERO_CHARS to
5143 When STORING_ALL_ZEROS_P, or the first byte written is zero,
5144 i.e. FULL_STRING_P && LENRANGE[1] == 0, we know that the
5145 string is now OFFSET characters long.
5147 Otherwise, we're storing an unknown value at offset OFFSET,
5148 so need to clip the nonzero_chars to OFFSET.
5149 Use the minimum length of the string (or individual character)
5150 being stored if it's known. Otherwise, STORING_NONZERO_P
5151 guarantees it's at least 1. */
5153 = storing_nonzero_p
&& ranges_valid
? lenrange
[0] : 1;
5154 location_t loc
= gimple_location (stmt
);
5155 tree oldlen
= si
->nonzero_chars
;
5156 if (store_before_nul
[1] == 0 && si
->full_string_p
)
5157 /* We're overwriting the nul terminator with a nonzero or
5158 unknown character. If the previous stmt was a memcpy,
5159 its length may be decreased. */
5160 adjust_last_stmt (si
, stmt
, false);
5161 si
= unshare_strinfo (si
);
5162 if (storing_nonzero_p
)
5164 gcc_assert (len
>= 0);
5165 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
+ len
);
5168 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
);
5170 /* Set FULL_STRING_P only if the length of the strings being
5171 written is the same, and clear it if the strings have
5172 different lengths. In the latter case the length stored
5173 in si->NONZERO_CHARS becomes the lower bound.
5174 FIXME: Handle the upper bound of the length if possible. */
5175 si
->full_string_p
= full_string_p
&& lenrange
[0] == lenrange
[1];
5177 if (storing_all_zeros_p
5179 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5180 si
->endptr
= ssaname
;
5185 si
->writable
= true;
5186 si
->dont_invalidate
= true;
5189 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
5190 si
->nonzero_chars
, oldlen
);
5191 adjust_related_strinfos (loc
, si
, adj
);
5197 else if (idx
== 0 && (storing_all_zeros_p
|| storing_nonzero_p
))
5200 idx
= new_stridx (ssaname
);
5202 idx
= new_addr_stridx (lhs
);
5205 tree ptr
= (ssaname
? ssaname
: build_fold_addr_expr (lhs
));
5208 if (storing_all_zeros_p
)
5210 else if (storing_nonzero_p
&& ranges_valid
)
5212 /* FIXME: Handle the upper bound of the length when
5213 LENRANGE[0] != LENRANGE[1]. */
5215 if (lenrange
[0] != lenrange
[1])
5216 /* Set the minimum length but ignore the maximum
5218 full_string_p
= false;
5223 tree len
= (slen
<= 0
5225 : build_int_cst (size_type_node
, slen
));
5226 si
= new_strinfo (ptr
, idx
, len
, slen
>= 0 && full_string_p
);
5227 set_strinfo (idx
, si
);
5228 if (storing_all_zeros_p
5230 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5231 si
->endptr
= ssaname
;
5232 si
->dont_invalidate
= true;
5233 si
->writable
= true;
5237 && rhs_minlen
< HOST_WIDE_INT_M1U
5238 && ssaname
== NULL_TREE
5239 && TREE_CODE (TREE_TYPE (lhs
)) == ARRAY_TYPE
)
5241 HOST_WIDE_INT a
= int_size_in_bytes (TREE_TYPE (lhs
));
5242 if (a
> 0 && (unsigned HOST_WIDE_INT
) a
> rhs_minlen
)
5244 int idx
= new_addr_stridx (lhs
);
5247 si
= new_strinfo (build_fold_addr_expr (lhs
), idx
,
5248 build_int_cst (size_type_node
, rhs_minlen
),
5250 set_strinfo (idx
, si
);
5251 si
->dont_invalidate
= true;
5256 if (si
!= NULL
&& offset
== 0 && storing_all_zeros_p
&& lenrange
[2] == 1)
5258 /* For single-byte stores only, allow adjust_last_stmt to remove
5259 the statement if the stored '\0' is immediately overwritten. */
5260 laststmt
.stmt
= stmt
;
5261 laststmt
.len
= build_int_cst (size_type_node
, 1);
5262 laststmt
.stridx
= si
->idx
;
5267 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0. */
5270 fold_strstr_to_strncmp (tree rhs1
, tree rhs2
, gimple
*stmt
)
5272 if (TREE_CODE (rhs1
) != SSA_NAME
5273 || TREE_CODE (rhs2
) != SSA_NAME
)
5276 gimple
*call_stmt
= NULL
;
5277 for (int pass
= 0; pass
< 2; pass
++)
5279 gimple
*g
= SSA_NAME_DEF_STMT (rhs1
);
5280 if (gimple_call_builtin_p (g
, BUILT_IN_STRSTR
)
5281 && has_single_use (rhs1
)
5282 && gimple_call_arg (g
, 0) == rhs2
)
5287 std::swap (rhs1
, rhs2
);
5292 tree arg0
= gimple_call_arg (call_stmt
, 0);
5296 tree arg1
= gimple_call_arg (call_stmt
, 1);
5297 tree arg1_len
= NULL_TREE
;
5298 int idx
= get_stridx (arg1
, call_stmt
);
5303 arg1_len
= build_int_cst (size_type_node
, ~idx
);
5306 strinfo
*si
= get_strinfo (idx
);
5308 arg1_len
= get_string_length (si
);
5312 if (arg1_len
!= NULL_TREE
)
5314 gimple_stmt_iterator gsi
= gsi_for_stmt (call_stmt
);
5315 tree strncmp_decl
= builtin_decl_explicit (BUILT_IN_STRNCMP
);
5317 if (!is_gimple_val (arg1_len
))
5319 tree arg1_len_tmp
= make_ssa_name (TREE_TYPE (arg1_len
));
5320 gassign
*arg1_stmt
= gimple_build_assign (arg1_len_tmp
,
5322 gsi_insert_before (&gsi
, arg1_stmt
, GSI_SAME_STMT
);
5323 arg1_len
= arg1_len_tmp
;
5326 gcall
*strncmp_call
= gimple_build_call (strncmp_decl
, 3,
5327 arg0
, arg1
, arg1_len
);
5328 tree strncmp_lhs
= make_ssa_name (integer_type_node
);
5329 gimple_set_vuse (strncmp_call
, gimple_vuse (call_stmt
));
5330 gimple_call_set_lhs (strncmp_call
, strncmp_lhs
);
5331 gsi_remove (&gsi
, true);
5332 gsi_insert_before (&gsi
, strncmp_call
, GSI_SAME_STMT
);
5333 tree zero
= build_zero_cst (TREE_TYPE (strncmp_lhs
));
5335 if (is_gimple_assign (stmt
))
5337 if (gimple_assign_rhs_code (stmt
) == COND_EXPR
)
5339 tree cond
= gimple_assign_rhs1 (stmt
);
5340 TREE_OPERAND (cond
, 0) = strncmp_lhs
;
5341 TREE_OPERAND (cond
, 1) = zero
;
5345 gimple_assign_set_rhs1 (stmt
, strncmp_lhs
);
5346 gimple_assign_set_rhs2 (stmt
, zero
);
5351 gcond
*cond
= as_a
<gcond
*> (stmt
);
5352 gimple_cond_set_lhs (cond
, strncmp_lhs
);
5353 gimple_cond_set_rhs (cond
, zero
);
5361 /* Return true if TYPE corresponds to a narrow character type. */
5364 is_char_type (tree type
)
5366 return (TREE_CODE (type
) == INTEGER_TYPE
5367 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
5368 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
));
5371 /* Check the built-in call at GSI for validity and optimize it.
5372 Uses RVALS to determine range information.
5373 Return true to let the caller advance *GSI to the next statement
5374 in the basic block and false otherwise. */
5377 strlen_pass::check_and_optimize_call (bool *zero_write
)
5379 gimple
*stmt
= gsi_stmt (m_gsi
);
5381 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
5383 tree fntype
= gimple_call_fntype (stmt
);
5387 if (lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype
)))
5389 handle_alloc_call (BUILT_IN_NONE
);
5393 if (tree lhs
= gimple_call_lhs (stmt
))
5394 handle_assign (lhs
, zero_write
);
5396 /* Proceed to handle user-defined formatting functions. */
5399 /* When not optimizing we must be checking printf calls which
5400 we do even for user-defined functions when they are declared
5401 with attribute format. */
5402 if (!flag_optimize_strlen
5404 || !valid_builtin_call (stmt
))
5405 return !handle_printf_call (&m_gsi
, ptr_qry
);
5407 tree callee
= gimple_call_fndecl (stmt
);
5408 switch (DECL_FUNCTION_CODE (callee
))
5410 case BUILT_IN_STRLEN
:
5411 case BUILT_IN_STRNLEN
:
5412 handle_builtin_strlen ();
5414 case BUILT_IN_STRCHR
:
5415 handle_builtin_strchr ();
5417 case BUILT_IN_STRCPY
:
5418 case BUILT_IN_STRCPY_CHK
:
5419 case BUILT_IN_STPCPY
:
5420 case BUILT_IN_STPCPY_CHK
:
5421 handle_builtin_strcpy (DECL_FUNCTION_CODE (callee
));
5424 case BUILT_IN_STRNCAT
:
5425 case BUILT_IN_STRNCAT_CHK
:
5426 handle_builtin_strncat (DECL_FUNCTION_CODE (callee
));
5429 case BUILT_IN_STPNCPY
:
5430 case BUILT_IN_STPNCPY_CHK
:
5431 case BUILT_IN_STRNCPY
:
5432 case BUILT_IN_STRNCPY_CHK
:
5433 handle_builtin_stxncpy_strncat (false);
5436 case BUILT_IN_MEMCPY
:
5437 case BUILT_IN_MEMCPY_CHK
:
5438 case BUILT_IN_MEMPCPY
:
5439 case BUILT_IN_MEMPCPY_CHK
:
5440 handle_builtin_memcpy (DECL_FUNCTION_CODE (callee
));
5442 case BUILT_IN_STRCAT
:
5443 case BUILT_IN_STRCAT_CHK
:
5444 handle_builtin_strcat (DECL_FUNCTION_CODE (callee
));
5446 case BUILT_IN_ALLOCA
:
5447 case BUILT_IN_ALLOCA_WITH_ALIGN
:
5448 case BUILT_IN_MALLOC
:
5449 case BUILT_IN_CALLOC
:
5450 handle_alloc_call (DECL_FUNCTION_CODE (callee
));
5452 case BUILT_IN_MEMSET
:
5453 if (handle_builtin_memset (zero_write
))
5456 case BUILT_IN_MEMCMP
:
5457 if (handle_builtin_memcmp ())
5460 case BUILT_IN_STRCMP
:
5461 case BUILT_IN_STRNCMP
:
5462 if (handle_builtin_string_cmp ())
5466 if (handle_printf_call (&m_gsi
, ptr_qry
))
5474 /* Handle an assignment statement at *GSI to a LHS of integral type.
5475 If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */
5478 strlen_pass::handle_integral_assign (bool *cleanup_eh
)
5480 gimple
*stmt
= gsi_stmt (m_gsi
);
5481 tree lhs
= gimple_assign_lhs (stmt
);
5482 tree lhs_type
= TREE_TYPE (lhs
);
5484 enum tree_code code
= gimple_assign_rhs_code (stmt
);
5485 if (code
== COND_EXPR
)
5487 tree cond
= gimple_assign_rhs1 (stmt
);
5488 enum tree_code cond_code
= TREE_CODE (cond
);
5490 if (cond_code
== EQ_EXPR
|| cond_code
== NE_EXPR
)
5491 fold_strstr_to_strncmp (TREE_OPERAND (cond
, 0),
5492 TREE_OPERAND (cond
, 1), stmt
);
5494 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5495 fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt
),
5496 gimple_assign_rhs2 (stmt
), stmt
);
5497 else if (gimple_assign_load_p (stmt
)
5498 && TREE_CODE (lhs_type
) == INTEGER_TYPE
5499 && TYPE_MODE (lhs_type
) == TYPE_MODE (char_type_node
)
5500 && (TYPE_PRECISION (lhs_type
)
5501 == TYPE_PRECISION (char_type_node
))
5502 && !gimple_has_volatile_ops (stmt
))
5504 tree off
= integer_zero_node
;
5505 unsigned HOST_WIDE_INT coff
= 0;
5507 tree rhs1
= gimple_assign_rhs1 (stmt
);
5508 if (code
== MEM_REF
)
5510 idx
= get_stridx (TREE_OPERAND (rhs1
, 0), stmt
);
5513 strinfo
*si
= get_strinfo (idx
);
5515 && si
->nonzero_chars
5516 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
5517 && (wi::to_widest (si
->nonzero_chars
)
5518 >= wi::to_widest (off
)))
5519 off
= TREE_OPERAND (rhs1
, 1);
5521 /* This case is not useful. See if get_addr_stridx
5522 returns something usable. */
5527 idx
= get_addr_stridx (rhs1
, stmt
, NULL_TREE
, &coff
);
5530 strinfo
*si
= get_strinfo (idx
);
5532 && si
->nonzero_chars
5533 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
5535 widest_int w1
= wi::to_widest (si
->nonzero_chars
);
5536 widest_int w2
= wi::to_widest (off
) + coff
;
5538 && si
->full_string_p
)
5540 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5542 fprintf (dump_file
, "Optimizing: ");
5543 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5546 /* Reading the final '\0' character. */
5547 tree zero
= build_int_cst (lhs_type
, 0);
5548 gimple_set_vuse (stmt
, NULL_TREE
);
5549 gimple_assign_set_rhs_from_tree (&m_gsi
, zero
);
5551 |= maybe_clean_or_replace_eh_stmt (stmt
,
5553 stmt
= gsi_stmt (m_gsi
);
5556 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5558 fprintf (dump_file
, "into: ");
5559 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5564 /* Reading a character before the final '\0'
5565 character. Just set the value range to ~[0, 0]
5566 if we don't have anything better. */
5568 if (!get_range_query (cfun
)->range_of_expr (r
, lhs
)
5571 r
.set_nonzero (lhs_type
);
5572 set_range_info (lhs
, r
);
5578 else if (code
== MEM_REF
&& TREE_CODE (lhs
) == SSA_NAME
)
5580 if (int idx
= new_stridx (lhs
))
5582 /* Record multi-byte assignments from MEM_REFs. */
5583 bool storing_all_nonzero_p
;
5584 bool storing_all_zeros_p
;
5586 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
5587 tree rhs
= gimple_assign_rhs1 (stmt
);
5588 const bool ranges_valid
5589 = count_nonzero_bytes (rhs
, stmt
,
5590 lenrange
, &full_string_p
,
5591 &storing_all_zeros_p
,
5592 &storing_all_nonzero_p
);
5595 tree length
= build_int_cst (sizetype
, lenrange
[0]);
5596 strinfo
*si
= new_strinfo (lhs
, idx
, length
, full_string_p
);
5597 set_strinfo (idx
, si
);
5598 si
->writable
= true;
5599 si
->dont_invalidate
= true;
5604 if (strlen_to_stridx
)
5606 tree rhs1
= gimple_assign_rhs1 (stmt
);
5607 if (stridx_strlenloc
*ps
= strlen_to_stridx
->get (rhs1
))
5608 strlen_to_stridx
->put (lhs
, stridx_strlenloc (*ps
));
5612 /* Handle assignment statement at *GSI to LHS. Set *ZERO_WRITE if
5613 the assignment stores all zero bytes. */
5616 strlen_pass::handle_assign (tree lhs
, bool *zero_write
)
5618 tree type
= TREE_TYPE (lhs
);
5619 if (TREE_CODE (type
) == ARRAY_TYPE
)
5620 type
= TREE_TYPE (type
);
5622 bool is_char_store
= is_char_type (type
);
5623 if (!is_char_store
&& TREE_CODE (lhs
) == MEM_REF
)
5625 /* To consider stores into char objects via integer types other
5626 than char but not those to non-character objects, determine
5627 the type of the destination rather than just the type of
5629 for (int i
= 0; i
!= 2; ++i
)
5631 tree ref
= TREE_OPERAND (lhs
, i
);
5632 type
= TREE_TYPE (ref
);
5633 if (TREE_CODE (type
) == POINTER_TYPE
)
5634 type
= TREE_TYPE (type
);
5635 if (TREE_CODE (type
) == ARRAY_TYPE
)
5636 type
= TREE_TYPE (type
);
5637 if (is_char_type (type
))
5639 is_char_store
= true;
5645 /* Handle a single or multibyte assignment. */
5646 if (is_char_store
&& !handle_store (zero_write
))
5653 /* Attempt to check for validity of the performed access a single statement
5654 at *GSI using string length knowledge, and to optimize it.
5655 If the given basic block needs clean-up of EH, CLEANUP_EH is set to
5656 true. Return true to let the caller advance *GSI to the next statement
5657 in the basic block and false otherwise. */
5660 strlen_pass::check_and_optimize_stmt (bool *cleanup_eh
)
5662 gimple
*stmt
= gsi_stmt (m_gsi
);
5664 /* For statements that modify a string, set to true if the write
5666 bool zero_write
= false;
5668 if (is_gimple_call (stmt
))
5670 if (!check_and_optimize_call (&zero_write
))
5673 else if (!flag_optimize_strlen
|| !strlen_optimize
)
5675 else if (is_gimple_assign (stmt
) && !gimple_clobber_p (stmt
))
5677 /* Handle non-clobbering assignment. */
5678 tree lhs
= gimple_assign_lhs (stmt
);
5679 tree lhs_type
= TREE_TYPE (lhs
);
5681 if (TREE_CODE (lhs
) == SSA_NAME
&& POINTER_TYPE_P (lhs_type
))
5683 if (gimple_assign_single_p (stmt
)
5684 || (gimple_assign_cast_p (stmt
)
5685 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt
)))))
5687 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
5688 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = idx
;
5690 else if (gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
5691 handle_pointer_plus ();
5693 else if (TREE_CODE (lhs
) == SSA_NAME
&& INTEGRAL_TYPE_P (lhs_type
))
5694 /* Handle assignment to a character. */
5695 handle_integral_assign (cleanup_eh
);
5696 else if (TREE_CODE (lhs
) != SSA_NAME
&& !TREE_SIDE_EFFECTS (lhs
))
5697 if (!handle_assign (lhs
, &zero_write
))
5700 else if (gcond
*cond
= dyn_cast
<gcond
*> (stmt
))
5702 enum tree_code code
= gimple_cond_code (cond
);
5703 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5704 fold_strstr_to_strncmp (gimple_cond_lhs (stmt
),
5705 gimple_cond_rhs (stmt
), stmt
);
5708 if (gimple_vdef (stmt
))
5709 maybe_invalidate (stmt
, zero_write
);
5713 /* Recursively call maybe_invalidate on stmts that might be executed
5714 in between dombb and current bb and that contain a vdef. Stop when
5715 *count stmts are inspected, or if the whole strinfo vector has
5716 been invalidated. */
5719 do_invalidate (basic_block dombb
, gimple
*phi
, bitmap visited
, int *count
)
5721 unsigned int i
, n
= gimple_phi_num_args (phi
);
5723 for (i
= 0; i
< n
; i
++)
5725 tree vuse
= gimple_phi_arg_def (phi
, i
);
5726 gimple
*stmt
= SSA_NAME_DEF_STMT (vuse
);
5727 basic_block bb
= gimple_bb (stmt
);
5730 || !bitmap_set_bit (visited
, bb
->index
)
5731 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5735 if (gimple_code (stmt
) == GIMPLE_PHI
)
5737 do_invalidate (dombb
, stmt
, visited
, count
);
5744 if (!maybe_invalidate (stmt
))
5749 vuse
= gimple_vuse (stmt
);
5750 stmt
= SSA_NAME_DEF_STMT (vuse
);
5751 if (gimple_bb (stmt
) != bb
)
5753 bb
= gimple_bb (stmt
);
5756 || !bitmap_set_bit (visited
, bb
->index
)
5757 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5764 /* Release pointer_query cache. */
5766 strlen_pass::~strlen_pass ()
5768 ptr_qry
.flush_cache ();
5771 /* Callback for walk_dominator_tree. Attempt to optimize various
5772 string ops by remembering string lengths pointed by pointer SSA_NAMEs. */
5775 strlen_pass::before_dom_children (basic_block bb
)
5777 basic_block dombb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
5780 stridx_to_strinfo
= NULL
;
5783 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) dombb
->aux
);
5784 if (stridx_to_strinfo
)
5786 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5789 gphi
*phi
= gsi
.phi ();
5790 if (virtual_operand_p (gimple_phi_result (phi
)))
5792 bitmap visited
= BITMAP_ALLOC (NULL
);
5793 int count_vdef
= 100;
5794 do_invalidate (dombb
, phi
, visited
, &count_vdef
);
5795 BITMAP_FREE (visited
);
5796 if (count_vdef
== 0)
5798 /* If there were too many vdefs in between immediate
5799 dominator and current bb, invalidate everything.
5800 If stridx_to_strinfo has been unshared, we need
5801 to free it, otherwise just set it to NULL. */
5802 if (!strinfo_shared ())
5808 vec_safe_iterate (stridx_to_strinfo
, i
, &si
);
5812 (*stridx_to_strinfo
)[i
] = NULL
;
5816 stridx_to_strinfo
= NULL
;
5824 /* If all PHI arguments have the same string index, the PHI result
5826 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5829 gphi
*phi
= gsi
.phi ();
5830 tree result
= gimple_phi_result (phi
);
5831 if (!virtual_operand_p (result
) && POINTER_TYPE_P (TREE_TYPE (result
)))
5833 int idx
= get_stridx (gimple_phi_arg_def (phi
, 0), phi
);
5836 unsigned int i
, n
= gimple_phi_num_args (phi
);
5837 for (i
= 1; i
< n
; i
++)
5838 if (idx
!= get_stridx (gimple_phi_arg_def (phi
, i
), phi
))
5841 ssa_ver_to_stridx
[SSA_NAME_VERSION (result
)] = idx
;
5846 bool cleanup_eh
= false;
5848 /* Attempt to optimize individual statements. */
5849 for (m_gsi
= gsi_start_bb (bb
); !gsi_end_p (m_gsi
); )
5851 /* Reset search depth performance counter. */
5854 if (check_and_optimize_stmt (&cleanup_eh
))
5858 if (cleanup_eh
&& gimple_purge_dead_eh_edges (bb
))
5859 m_cleanup_cfg
= true;
5861 bb
->aux
= stridx_to_strinfo
;
5862 if (vec_safe_length (stridx_to_strinfo
) && !strinfo_shared ())
5863 (*stridx_to_strinfo
)[0] = (strinfo
*) bb
;
5867 /* Callback for walk_dominator_tree. Free strinfo vector if it is
5868 owned by the current bb, clear bb->aux. */
5871 strlen_pass::after_dom_children (basic_block bb
)
5875 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) bb
->aux
);
5876 if (vec_safe_length (stridx_to_strinfo
)
5877 && (*stridx_to_strinfo
)[0] == (strinfo
*) bb
)
5882 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
5884 vec_free (stridx_to_strinfo
);
5893 printf_strlen_execute (function
*fun
, bool warn_only
)
5895 strlen_optimize
= !warn_only
;
5897 calculate_dominance_info (CDI_DOMINATORS
);
5898 loop_optimizer_init (LOOPS_NORMAL
);
5901 gcc_assert (!strlen_to_stridx
);
5902 if (warn_stringop_overflow
|| warn_stringop_truncation
)
5903 strlen_to_stridx
= new hash_map
<tree
, stridx_strlenloc
> ();
5905 /* This has to happen after initializing the loop optimizer
5906 and initializing SCEV as they create new SSA_NAMEs. */
5907 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
5910 /* String length optimization is implemented as a walk of the dominator
5911 tree and a forward walk of statements within each block. */
5912 strlen_pass
walker (CDI_DOMINATORS
);
5913 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));
5915 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5916 walker
.ptr_qry
.dump (dump_file
, true);
5918 ssa_ver_to_stridx
.release ();
5919 strinfo_pool
.release ();
5920 if (decl_to_stridxlist_htab
)
5922 obstack_free (&stridx_obstack
, NULL
);
5923 delete decl_to_stridxlist_htab
;
5924 decl_to_stridxlist_htab
= NULL
;
5926 laststmt
.stmt
= NULL
;
5927 laststmt
.len
= NULL_TREE
;
5928 laststmt
.stridx
= 0;
5930 if (strlen_to_stridx
)
5932 strlen_to_stridx
->empty ();
5933 delete strlen_to_stridx
;
5934 strlen_to_stridx
= NULL
;
5938 loop_optimizer_finalize ();
5940 return walker
.m_cleanup_cfg
? TODO_cleanup_cfg
: 0;
5943 /* This file defines two passes: one for warnings that runs only when
5944 optimization is disabled, and another that implements optimizations
5945 and also issues warnings. */
5947 const pass_data pass_data_warn_printf
=
5949 GIMPLE_PASS
, /* type */
5950 "warn-printf", /* name */
5951 OPTGROUP_NONE
, /* optinfo_flags */
5952 TV_NONE
, /* tv_id */
5953 /* Normally an optimization pass would require PROP_ssa but because
5954 this pass runs early, with no optimization, to do sprintf format
5955 checking, it only requires PROP_cfg. */
5956 PROP_cfg
, /* properties_required */
5957 0, /* properties_provided */
5958 0, /* properties_destroyed */
5959 0, /* todo_flags_start */
5960 0, /* todo_flags_finish */
5963 class pass_warn_printf
: public gimple_opt_pass
5966 pass_warn_printf (gcc::context
*ctxt
)
5967 : gimple_opt_pass (pass_data_warn_printf
, ctxt
)
5970 bool gate (function
*) final override
;
5971 unsigned int execute (function
*fun
) final override
5973 return printf_strlen_execute (fun
, true);
5978 /* Return true to run the warning pass only when not optimizing and
5979 iff either -Wformat-overflow or -Wformat-truncation is specified. */
5982 pass_warn_printf::gate (function
*)
5984 return !optimize
&& (warn_format_overflow
> 0 || warn_format_trunc
> 0);
5987 const pass_data pass_data_strlen
=
5989 GIMPLE_PASS
, /* type */
5990 "strlen", /* name */
5991 OPTGROUP_NONE
, /* optinfo_flags */
5992 TV_TREE_STRLEN
, /* tv_id */
5993 PROP_cfg
| PROP_ssa
, /* properties_required */
5994 0, /* properties_provided */
5995 0, /* properties_destroyed */
5996 0, /* todo_flags_start */
5997 0, /* todo_flags_finish */
6000 class pass_strlen
: public gimple_opt_pass
6003 pass_strlen (gcc::context
*ctxt
)
6004 : gimple_opt_pass (pass_data_strlen
, ctxt
)
6007 opt_pass
* clone () final override
{ return new pass_strlen (m_ctxt
); }
6009 bool gate (function
*) final override
;
6010 unsigned int execute (function
*fun
) final override
6012 return printf_strlen_execute (fun
, false);
6016 /* Return true to run the pass only when the sprintf and/or strlen
6017 optimizations are enabled and -Wformat-overflow or -Wformat-truncation
6021 pass_strlen::gate (function
*)
6023 return ((warn_format_overflow
> 0
6024 || warn_format_trunc
> 0
6025 || warn_restrict
> 0
6026 || flag_optimize_strlen
> 0
6027 || flag_printf_return_value
)
6034 make_pass_warn_printf (gcc::context
*ctxt
)
6036 return new pass_warn_printf (ctxt
);
6040 make_pass_strlen (gcc::context
*ctxt
)
6042 return new pass_strlen (ctxt
);