1 /* String length optimization
2 Copyright (C) 2011-2023 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "alloc-pool.h"
29 #include "tree-pass.h"
32 #include "gimple-pretty-print.h"
33 #include "gimple-ssa-warn-access.h"
34 #include "gimple-ssa-warn-restrict.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "gimple-iterator.h"
38 #include "gimple-fold.h"
41 #include "gimplify-me.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-ssa-propagate.h"
48 #include "tree-ssa-strlen.h"
49 #include "tree-hash-traits.h"
51 #include "pointer-query.h"
53 #include "diagnostic-core.h"
54 #include "diagnostic.h"
59 #include "tree-ssa-loop.h"
60 #include "tree-scalar-evolution.h"
61 #include "vr-values.h"
62 #include "gimple-range.h"
65 /* A vector indexed by SSA_NAME_VERSION. 0 means unknown, positive value
66 is an index into strinfo vector, negative value stands for
67 string length of a string literal (~strlen). */
68 static vec
<int> ssa_ver_to_stridx
;
70 /* Number of currently active string indexes plus one. */
71 static int max_stridx
;
73 /* Set to true to optimize, false when just checking. */
74 static bool strlen_optimize
;
76 /* String information record. */
79 /* Number of leading characters that are known to be nonzero. This is
80 also the length of the string if FULL_STRING_P.
82 The values in a list of related string pointers must be consistent;
83 that is, if strinfo B comes X bytes after strinfo A, it must be
84 the case that A->nonzero_chars == X + B->nonzero_chars. */
86 /* Any of the corresponding pointers for querying alias oracle. */
88 /* STMT is used for two things:
90 - To record the statement that should be used for delayed length
91 computations. We maintain the invariant that all related strinfos
92 have delayed lengths or none do.
94 - To record the malloc or calloc call that produced this result
95 to optimize away malloc/memset sequences. STMT is reset after
96 a calloc-allocated object has been stored a non-zero value into. */
98 /* Set to the dynamic allocation statement for the object (alloca,
99 calloc, malloc, or VLA). Unlike STMT, once set for a strinfo
100 object, ALLOC doesn't change. */
102 /* Pointer to '\0' if known, if NULL, it can be computed as
105 /* Reference count. Any changes to strinfo entry possibly shared
106 with dominating basic blocks need unshare_strinfo first, except
107 for dont_invalidate which affects only the immediately next
110 /* Copy of index. get_strinfo (si->idx) should return si; */
112 /* These 3 fields are for chaining related string pointers together.
114 bl = strlen (b); dl = strlen (d); strcpy (a, b); c = a + bl;
115 strcpy (c, d); e = c + dl;
116 strinfo(a) -> strinfo(c) -> strinfo(e)
117 All have ->first field equal to strinfo(a)->idx and are doubly
118 chained through prev/next fields. The later strinfos are required
119 to point into the same string with zero or more bytes after
120 the previous pointer and all bytes in between the two pointers
121 must be non-zero. Functions like strcpy or memcpy are supposed
122 to adjust all previous strinfo lengths, but not following strinfo
123 lengths (those are uncertain, usually invalidated during
124 maybe_invalidate, except when the alias oracle knows better).
125 Functions like strcat on the other side adjust the whole
126 related strinfo chain.
127 They are updated lazily, so to use the chain the same first fields
128 and si->prev->next == si->idx needs to be verified. */
132 /* A flag whether the string is known to be written in the current
135 /* A flag for the next maybe_invalidate that this strinfo shouldn't
136 be invalidated. Always cleared by maybe_invalidate. */
137 bool dont_invalidate
;
138 /* True if the string is known to be nul-terminated after NONZERO_CHARS
139 characters. False is useful when detecting strings that are built
140 up via successive memcpys. */
144 /* Pool for allocating strinfo_struct entries. */
145 static object_allocator
<strinfo
> strinfo_pool ("strinfo pool");
147 /* Vector mapping positive string indexes to strinfo, for the
148 current basic block. The first pointer in the vector is special,
149 it is either NULL, meaning the vector isn't shared, or it is
150 a basic block pointer to the owner basic_block if shared.
151 If some other bb wants to modify the vector, the vector needs
152 to be unshared first, and only the owner bb is supposed to free it. */
153 static vec
<strinfo
*, va_heap
, vl_embed
> *stridx_to_strinfo
;
155 /* One OFFSET->IDX mapping. */
158 struct stridxlist
*next
;
159 HOST_WIDE_INT offset
;
163 /* Hash table entry, mapping a DECL to a chain of OFFSET->IDX mappings. */
164 struct decl_stridxlist_map
166 struct tree_map_base base
;
167 struct stridxlist list
;
170 /* Hash table for mapping decls to a chained list of offset -> idx
172 typedef hash_map
<tree_decl_hash
, stridxlist
> decl_to_stridxlist_htab_t
;
173 static decl_to_stridxlist_htab_t
*decl_to_stridxlist_htab
;
175 /* Hash table mapping strlen (or strnlen with constant bound and return
176 smaller than bound) calls to stridx instances describing
177 the calls' arguments. Non-null only when warn_stringop_truncation
179 typedef std::pair
<int, location_t
> stridx_strlenloc
;
180 static hash_map
<tree
, stridx_strlenloc
> *strlen_to_stridx
;
182 /* Obstack for struct stridxlist and struct decl_stridxlist_map. */
183 static struct obstack stridx_obstack
;
185 /* Last memcpy statement if it could be adjusted if the trailing
186 '\0' written is immediately overwritten, or
187 *x = '\0' store that could be removed if it is immediately overwritten. */
188 struct laststmt_struct
195 static int get_stridx_plus_constant (strinfo
*, unsigned HOST_WIDE_INT
, tree
);
196 static bool get_range_strlen_dynamic (tree
, gimple
*, c_strlen_data
*,
197 bitmap
, pointer_query
*, unsigned *);
199 /* Sets MINMAX to either the constant value or the range VAL is in
200 and returns either the constant value or VAL on success or null
201 when the range couldn't be determined. Uses RVALS or CFUN for
202 range info, whichever is nonnull. */
205 get_range (tree val
, gimple
*stmt
, wide_int minmax
[2],
206 range_query
*rvals
/* = NULL */)
211 /* When called from front ends for global initializers CFUN
215 rvals
= get_range_query (cfun
);
219 if (!rvals
->range_of_expr (vr
, val
, stmt
))
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
,
286 unsigned HOST_WIDE_INT offset
,
287 unsigned HOST_WIDE_INT nbytes
,
288 unsigned lenrange
[3], bool *nulterm
,
289 bool *allnul
, bool *allnonnul
,
290 ssa_name_limit_t
&snlim
);
291 bool count_nonzero_bytes_addr (tree exp
,
293 unsigned HOST_WIDE_INT offset
,
294 unsigned HOST_WIDE_INT nbytes
,
295 unsigned lenrange
[3], bool *nulterm
,
296 bool *allnul
, bool *allnonnul
,
297 ssa_name_limit_t
&snlim
);
298 bool get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
299 unsigned HOST_WIDE_INT lenrng
[2],
300 unsigned HOST_WIDE_INT
*size
, bool *nulterm
);
302 gimple_ranger m_ranger
;
304 /* A pointer_query object 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 ());
1231 pdata
->maxlen
= wide_int_to_tree (type
, vr
.upper_bound ());
1235 pdata
->minlen
= build_zero_cst (size_type_node
);
1237 tree base
= si
->ptr
;
1238 if (TREE_CODE (base
) == ADDR_EXPR
)
1239 base
= TREE_OPERAND (base
, 0);
1243 base
= get_addr_base_and_unit_offset (base
, &poff
);
1246 && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
1247 && TYPE_SIZE_UNIT (TREE_TYPE (base
))
1248 && poff
.is_constant (&off
))
1250 tree basetype
= TREE_TYPE (base
);
1251 tree size
= TYPE_SIZE_UNIT (basetype
);
1252 if (TREE_CODE (size
) == INTEGER_CST
)
1254 ++off
; /* Increment for the terminating nul. */
1255 tree toffset
= build_int_cst (size_type_node
, off
);
1256 pdata
->maxlen
= fold_build2 (MINUS_EXPR
, size_type_node
, size
,
1258 pdata
->maxbound
= pdata
->maxlen
;
1261 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1264 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1266 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == SSA_NAME
)
1269 ptr_qry
->rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
);
1270 if (vr
.varying_p () || vr
.undefined_p ())
1272 pdata
->minlen
= build_zero_cst (size_type_node
);
1273 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1277 tree type
= vr
.type ();
1278 pdata
->minlen
= wide_int_to_tree (type
, vr
.lower_bound ());
1279 pdata
->maxlen
= wide_int_to_tree (type
, vr
.upper_bound ());
1280 offset_int max
= offset_int::from (vr
.upper_bound (0), SIGNED
);
1281 if (tree maxbound
= get_maxbound (si
->ptr
, stmt
, max
, ptr_qry
))
1282 pdata
->maxbound
= maxbound
;
1284 pdata
->maxbound
= pdata
->maxlen
;
1287 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == INTEGER_CST
)
1289 pdata
->maxlen
= pdata
->minlen
;
1290 pdata
->maxbound
= pdata
->minlen
;
1294 /* For PDATA->MINLEN that's a non-constant expression such
1295 as PLUS_EXPR whose value range is unknown, set the bounds
1296 to zero and SIZE_MAX. */
1297 pdata
->minlen
= build_zero_cst (size_type_node
);
1298 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1307 /* Analogous to get_range_strlen but for dynamically created strings,
1308 i.e., those created by calls to strcpy as opposed to just string
1310 Try to obtain the range of the lengths of the string(s) referenced
1311 by SRC, or the size of the largest array SRC refers to if the range
1312 of lengths cannot be determined, and store all in *PDATA. RVALS
1313 points to the valuation engine used to calculate ranges. */
1316 get_range_strlen_dynamic (tree src
, gimple
*stmt
, c_strlen_data
*pdata
,
1317 pointer_query
&ptr_qry
)
1319 auto_bitmap visited
;
1320 tree maxbound
= pdata
->maxbound
;
1322 unsigned limit
= param_ssa_name_def_chain_limit
;
1323 if (!get_range_strlen_dynamic (src
, stmt
, pdata
, visited
, &ptr_qry
, &limit
))
1325 /* On failure extend the length range to an impossible maximum
1326 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1327 members can stay unchanged regardless. */
1328 pdata
->minlen
= ssize_int (0);
1329 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1331 else if (!pdata
->minlen
)
1332 pdata
->minlen
= ssize_int (0);
1334 /* If it's unchanged from it initial non-null value, set the conservative
1335 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1336 if (maxbound
&& pdata
->maxbound
== maxbound
)
1337 pdata
->maxbound
= build_all_ones_cst (size_type_node
);
1340 /* Invalidate string length information for strings whose length might
1341 change due to stores in STMT, except those marked DONT_INVALIDATE.
1342 For string-modifying statements, ZERO_WRITE is set when the statement
1344 Returns true if any STRIDX_TO_STRINFO entries were considered
1345 for invalidation. */
1348 maybe_invalidate (gimple
*stmt
, bool zero_write
= false)
1350 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1352 fprintf (dump_file
, "%s called for ", __func__
);
1353 print_gimple_stmt (dump_file
, stmt
, TDF_LINENO
);
1357 bool nonempty
= false;
1359 for (unsigned i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
1361 if (si
== NULL
|| !POINTER_TYPE_P (TREE_TYPE (si
->ptr
)))
1366 /* Unconditionally reset DONT_INVALIDATE. */
1367 bool dont_invalidate
= si
->dont_invalidate
;
1368 si
->dont_invalidate
= false;
1370 if (dont_invalidate
)
1374 tree size
= si
->nonzero_chars
;
1375 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, size
);
1376 /* Include the terminating nul in the size of the string
1377 to consider when determining possible clobber. But do not
1378 add it to 'size' since we don't know whether it would
1379 actually fit the allocated area. */
1380 if (known_size_p (r
.size
))
1382 if (known_le (r
.size
, HOST_WIDE_INT_MAX
- BITS_PER_UNIT
))
1383 r
.max_size
+= BITS_PER_UNIT
;
1387 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1389 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1391 fputs (" statement may clobber object ", dump_file
);
1392 print_generic_expr (dump_file
, si
->ptr
);
1393 if (size
&& tree_fits_uhwi_p (size
))
1394 fprintf (dump_file
, " " HOST_WIDE_INT_PRINT_UNSIGNED
1395 " bytes in size", tree_to_uhwi (size
));
1396 fputc ('\n', dump_file
);
1399 set_strinfo (i
, NULL
);
1407 && is_gimple_call (si
->stmt
)
1408 && (DECL_FUNCTION_CODE (gimple_call_fndecl (si
->stmt
))
1409 == BUILT_IN_CALLOC
))
1411 /* If the clobber test above considered the length of
1412 the string (including the nul), then for (potentially)
1413 non-zero writes that might modify storage allocated by
1414 calloc consider the whole object and if it might be
1415 clobbered by the statement reset the statement. */
1416 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, NULL_TREE
);
1417 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1422 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1423 fprintf (dump_file
, "%s returns %i\n", __func__
, nonempty
);
1428 /* Unshare strinfo record SI, if it has refcount > 1 or
1429 if stridx_to_strinfo vector is shared with some other
1433 unshare_strinfo (strinfo
*si
)
1437 if (si
->refcount
== 1 && !strinfo_shared ())
1440 nsi
= new_strinfo (si
->ptr
, si
->idx
, si
->nonzero_chars
, si
->full_string_p
);
1441 nsi
->stmt
= si
->stmt
;
1442 nsi
->alloc
= si
->alloc
;
1443 nsi
->endptr
= si
->endptr
;
1444 nsi
->first
= si
->first
;
1445 nsi
->prev
= si
->prev
;
1446 nsi
->next
= si
->next
;
1447 nsi
->writable
= si
->writable
;
1448 set_strinfo (si
->idx
, nsi
);
1453 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1454 strinfo if there is any. Return it's idx, or 0 if no strinfo has
1458 get_stridx_plus_constant (strinfo
*basesi
, unsigned HOST_WIDE_INT off
,
1461 if (TREE_CODE (ptr
) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1464 if (compare_nonzero_chars (basesi
, off
) < 0
1465 || !tree_fits_uhwi_p (basesi
->nonzero_chars
))
1468 unsigned HOST_WIDE_INT nonzero_chars
1469 = tree_to_uhwi (basesi
->nonzero_chars
) - off
;
1470 strinfo
*si
= basesi
, *chainsi
;
1471 if (si
->first
|| si
->prev
|| si
->next
)
1472 si
= verify_related_strinfos (basesi
);
1474 || si
->nonzero_chars
== NULL_TREE
1475 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1478 if (TREE_CODE (ptr
) == SSA_NAME
1479 && ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1480 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1482 gcc_checking_assert (compare_tree_int (si
->nonzero_chars
, off
) != -1);
1483 for (chainsi
= si
; chainsi
->next
; chainsi
= si
)
1485 si
= get_next_strinfo (chainsi
);
1487 || si
->nonzero_chars
== NULL_TREE
1488 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1490 int r
= compare_tree_int (si
->nonzero_chars
, nonzero_chars
);
1495 if (TREE_CODE (ptr
) == SSA_NAME
)
1496 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = si
->idx
;
1499 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1500 if (pidx
!= NULL
&& *pidx
== 0)
1509 int idx
= new_stridx (ptr
);
1512 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, nonzero_chars
),
1513 basesi
->full_string_p
);
1514 set_strinfo (idx
, si
);
1515 if (strinfo
*nextsi
= get_strinfo (chainsi
->next
))
1517 nextsi
= unshare_strinfo (nextsi
);
1518 si
->next
= nextsi
->idx
;
1521 chainsi
= unshare_strinfo (chainsi
);
1522 if (chainsi
->first
== 0)
1523 chainsi
->first
= chainsi
->idx
;
1524 chainsi
->next
= idx
;
1525 if (chainsi
->endptr
== NULL_TREE
&& zero_length_string_p (si
))
1526 chainsi
->endptr
= ptr
;
1527 si
->endptr
= chainsi
->endptr
;
1528 si
->prev
= chainsi
->idx
;
1529 si
->first
= chainsi
->first
;
1530 si
->writable
= chainsi
->writable
;
1534 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1535 to a zero-length string and if possible chain it to a related strinfo
1536 chain whose part is or might be CHAINSI. */
1539 zero_length_string (tree ptr
, strinfo
*chainsi
)
1543 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1544 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1545 gcc_checking_assert (TREE_CODE (ptr
) == SSA_NAME
1546 && ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] == 0);
1548 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1550 if (chainsi
!= NULL
)
1552 si
= verify_related_strinfos (chainsi
);
1557 /* We shouldn't mix delayed and non-delayed lengths. */
1558 gcc_assert (si
->full_string_p
);
1559 if (si
->endptr
== NULL_TREE
)
1561 si
= unshare_strinfo (si
);
1565 si
= get_next_strinfo (si
);
1568 if (zero_length_string_p (chainsi
))
1572 chainsi
= unshare_strinfo (chainsi
);
1575 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = chainsi
->idx
;
1581 /* We shouldn't mix delayed and non-delayed lengths. */
1582 gcc_assert (chainsi
->full_string_p
);
1583 if (chainsi
->first
|| chainsi
->prev
|| chainsi
->next
)
1585 chainsi
= unshare_strinfo (chainsi
);
1592 idx
= new_stridx (ptr
);
1595 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, 0), true);
1596 set_strinfo (idx
, si
);
1598 if (chainsi
!= NULL
)
1600 chainsi
= unshare_strinfo (chainsi
);
1601 if (chainsi
->first
== 0)
1602 chainsi
->first
= chainsi
->idx
;
1603 chainsi
->next
= idx
;
1604 if (chainsi
->endptr
== NULL_TREE
)
1605 chainsi
->endptr
= ptr
;
1606 si
->prev
= chainsi
->idx
;
1607 si
->first
= chainsi
->first
;
1608 si
->writable
= chainsi
->writable
;
1613 /* For strinfo ORIGSI whose length has been just updated, adjust other
1614 related strinfos so that they match the new ORIGSI. This involves:
1616 - adding ADJ to the nonzero_chars fields
1617 - copying full_string_p from the new ORIGSI. */
1620 adjust_related_strinfos (location_t loc
, strinfo
*origsi
, tree adj
)
1622 strinfo
*si
= verify_related_strinfos (origsi
);
1635 si
= unshare_strinfo (si
);
1636 /* We shouldn't see delayed lengths here; the caller must
1637 have calculated the old length in order to calculate
1639 gcc_assert (si
->nonzero_chars
);
1640 tem
= fold_convert_loc (loc
, TREE_TYPE (si
->nonzero_chars
), adj
);
1641 si
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
1642 TREE_TYPE (si
->nonzero_chars
),
1643 si
->nonzero_chars
, tem
);
1644 si
->full_string_p
= origsi
->full_string_p
;
1646 si
->endptr
= NULL_TREE
;
1647 si
->dont_invalidate
= true;
1649 nsi
= get_next_strinfo (si
);
1656 /* Find if there are other SSA_NAME pointers equal to PTR
1657 for which we don't track their string lengths yet. If so, use
1661 find_equal_ptrs (tree ptr
, int idx
)
1663 if (TREE_CODE (ptr
) != SSA_NAME
)
1667 gimple
*stmt
= SSA_NAME_DEF_STMT (ptr
);
1668 if (!is_gimple_assign (stmt
))
1670 ptr
= gimple_assign_rhs1 (stmt
);
1671 switch (gimple_assign_rhs_code (stmt
))
1676 if (!POINTER_TYPE_P (TREE_TYPE (ptr
)))
1678 if (TREE_CODE (ptr
) == SSA_NAME
)
1680 if (TREE_CODE (ptr
) != ADDR_EXPR
)
1685 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1686 if (pidx
!= NULL
&& *pidx
== 0)
1694 /* We might find an endptr created in this pass. Grow the
1695 vector in that case. */
1696 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1697 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1699 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] != 0)
1701 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = idx
;
1705 /* Return true if STMT is a call to a builtin function with the right
1706 arguments and attributes that should be considered for optimization
1710 valid_builtin_call (gimple
*stmt
)
1712 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
1715 tree callee
= gimple_call_fndecl (stmt
);
1716 switch (DECL_FUNCTION_CODE (callee
))
1718 case BUILT_IN_MEMCMP
:
1719 case BUILT_IN_MEMCMP_EQ
:
1720 case BUILT_IN_STRCMP
:
1721 case BUILT_IN_STRNCMP
:
1722 case BUILT_IN_STRCHR
:
1723 case BUILT_IN_STRLEN
:
1724 case BUILT_IN_STRNLEN
:
1725 /* The above functions should be pure. Punt if they aren't. */
1726 if (gimple_vdef (stmt
) || gimple_vuse (stmt
) == NULL_TREE
)
1730 case BUILT_IN_ALLOCA
:
1731 case BUILT_IN_ALLOCA_WITH_ALIGN
:
1732 case BUILT_IN_CALLOC
:
1733 case BUILT_IN_MALLOC
:
1734 case BUILT_IN_MEMCPY
:
1735 case BUILT_IN_MEMCPY_CHK
:
1736 case BUILT_IN_MEMPCPY
:
1737 case BUILT_IN_MEMPCPY_CHK
:
1738 case BUILT_IN_MEMSET
:
1739 case BUILT_IN_STPCPY
:
1740 case BUILT_IN_STPCPY_CHK
:
1741 case BUILT_IN_STPNCPY
:
1742 case BUILT_IN_STPNCPY_CHK
:
1743 case BUILT_IN_STRCAT
:
1744 case BUILT_IN_STRCAT_CHK
:
1745 case BUILT_IN_STRCPY
:
1746 case BUILT_IN_STRCPY_CHK
:
1747 case BUILT_IN_STRNCAT
:
1748 case BUILT_IN_STRNCAT_CHK
:
1749 case BUILT_IN_STRNCPY
:
1750 case BUILT_IN_STRNCPY_CHK
:
1751 /* The above functions should be neither const nor pure. Punt if they
1753 if (gimple_vdef (stmt
) == NULL_TREE
|| gimple_vuse (stmt
) == NULL_TREE
)
1764 /* If the last .MEM setter statement before STMT is
1765 memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1766 and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1767 just memcpy (x, y, strlen (y)). SI must be the zero length
1771 strlen_pass::adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
)
1773 tree vuse
, callee
, len
;
1774 struct laststmt_struct last
= laststmt
;
1775 strinfo
*lastsi
, *firstsi
;
1776 unsigned len_arg_no
= 2;
1778 laststmt
.stmt
= NULL
;
1779 laststmt
.len
= NULL_TREE
;
1780 laststmt
.stridx
= 0;
1782 if (last
.stmt
== NULL
)
1785 vuse
= gimple_vuse (stmt
);
1786 if (vuse
== NULL_TREE
1787 || SSA_NAME_DEF_STMT (vuse
) != last
.stmt
1788 || !has_single_use (vuse
))
1791 gcc_assert (last
.stridx
> 0);
1792 lastsi
= get_strinfo (last
.stridx
);
1798 if (lastsi
->first
== 0 || lastsi
->first
!= si
->first
)
1801 firstsi
= verify_related_strinfos (si
);
1802 if (firstsi
== NULL
)
1804 while (firstsi
!= lastsi
)
1806 firstsi
= get_next_strinfo (firstsi
);
1807 if (firstsi
== NULL
)
1812 if (!is_strcat
&& !zero_length_string_p (si
))
1815 if (is_gimple_assign (last
.stmt
))
1817 gimple_stmt_iterator gsi
;
1819 if (!integer_zerop (gimple_assign_rhs1 (last
.stmt
)))
1821 if (stmt_could_throw_p (cfun
, last
.stmt
))
1823 gsi
= gsi_for_stmt (last
.stmt
);
1824 unlink_stmt_vdef (last
.stmt
);
1825 release_defs (last
.stmt
);
1826 gsi_remove (&gsi
, true);
1830 if (!valid_builtin_call (last
.stmt
))
1833 callee
= gimple_call_fndecl (last
.stmt
);
1834 switch (DECL_FUNCTION_CODE (callee
))
1836 case BUILT_IN_MEMCPY
:
1837 case BUILT_IN_MEMCPY_CHK
:
1843 len
= gimple_call_arg (last
.stmt
, len_arg_no
);
1844 if (tree_fits_uhwi_p (len
))
1846 if (!tree_fits_uhwi_p (last
.len
)
1847 || integer_zerop (len
)
1848 || tree_to_uhwi (len
) != tree_to_uhwi (last
.len
) + 1)
1850 /* Don't adjust the length if it is divisible by 4, it is more efficient
1851 to store the extra '\0' in that case. */
1852 if ((tree_to_uhwi (len
) & 3) == 0)
1855 /* Don't fold away an out of bounds access, as this defeats proper
1857 tree dst
= gimple_call_arg (last
.stmt
, 0);
1860 tree size
= compute_objsize (dst
, stmt
, 1, &aref
, &ptr_qry
);
1861 if (size
&& tree_int_cst_lt (size
, len
))
1864 else if (TREE_CODE (len
) == SSA_NAME
)
1866 gimple
*def_stmt
= SSA_NAME_DEF_STMT (len
);
1867 if (!is_gimple_assign (def_stmt
)
1868 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
1869 || gimple_assign_rhs1 (def_stmt
) != last
.len
1870 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
1876 gimple_call_set_arg (last
.stmt
, len_arg_no
, last
.len
);
1877 update_stmt (last
.stmt
);
1880 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1881 call, or when BOUND is non-null, of a strnlen() call, set LHS
1882 range info to [0, min (MAX, BOUND)] when the range includes more
1883 than one value and return LHS. Otherwise, when the range
1884 [MIN, MAX] is such that MIN == MAX, return the tree representation
1885 of (MIN). The latter allows callers to fold suitable strnlen() calls
1889 set_strlen_range (tree lhs
, wide_int min
, wide_int max
,
1890 tree bound
/* = NULL_TREE */)
1892 if (TREE_CODE (lhs
) != SSA_NAME
1893 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1898 /* For strnlen, adjust MIN and MAX as necessary. If the bound
1899 is less than the size of the array set MAX to it. It it's
1900 greater than MAX and MAX is non-zero bump MAX down to account
1901 for the necessary terminating nul. Otherwise leave it alone. */
1902 if (TREE_CODE (bound
) == INTEGER_CST
)
1904 wide_int wibnd
= wi::to_wide (bound
);
1905 int cmp
= wi::cmpu (wibnd
, max
);
1908 else if (cmp
&& wi::ne_p (max
, min
))
1911 else if (TREE_CODE (bound
) == SSA_NAME
)
1914 get_range_query (cfun
)->range_of_expr (r
, bound
);
1915 if (!r
.undefined_p ())
1917 /* For a bound in a known range, adjust the range determined
1918 above as necessary. For a bound in some anti-range or
1919 in an unknown range, use the range determined by callers. */
1920 if (wi::ltu_p (r
.lower_bound (), min
))
1921 min
= r
.lower_bound ();
1922 if (wi::ltu_p (r
.upper_bound (), max
))
1923 max
= r
.upper_bound ();
1929 return wide_int_to_tree (size_type_node
, min
);
1931 value_range
vr (TREE_TYPE (lhs
), min
, max
);
1932 set_range_info (lhs
, vr
);
1936 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1937 SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1938 a character array A[N] with unknown length bounded by N, and for
1939 strnlen(), by min (N, BOUND). */
1942 maybe_set_strlen_range (tree lhs
, tree src
, tree bound
)
1944 if (TREE_CODE (lhs
) != SSA_NAME
1945 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1948 if (TREE_CODE (src
) == SSA_NAME
)
1950 gimple
*def
= SSA_NAME_DEF_STMT (src
);
1951 if (is_gimple_assign (def
)
1952 && gimple_assign_rhs_code (def
) == ADDR_EXPR
)
1953 src
= gimple_assign_rhs1 (def
);
1956 /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1957 NUL so that the difference between a pointer to just past it and
1958 one to its beginning is positive. */
1959 wide_int max
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
1961 if (TREE_CODE (src
) == ADDR_EXPR
)
1963 /* The last array member of a struct can be bigger than its size
1964 suggests if it's treated as a poor-man's flexible array member. */
1965 src
= TREE_OPERAND (src
, 0);
1966 if (TREE_CODE (src
) != MEM_REF
1967 && !array_ref_flexible_size_p (src
))
1969 tree type
= TREE_TYPE (src
);
1970 tree size
= TYPE_SIZE_UNIT (type
);
1972 && TREE_CODE (size
) == INTEGER_CST
1973 && !integer_zerop (size
))
1975 /* Even though such uses of strlen would be undefined,
1976 avoid relying on arrays of arrays in case some genius
1977 decides to call strlen on an unterminated array element
1978 that's followed by a terminated one. Likewise, avoid
1979 assuming that a struct array member is necessarily
1980 nul-terminated (the nul may be in the member that
1981 follows). In those cases, assume that the length
1982 of the string stored in such an array is bounded
1983 by the size of the enclosing object if one can be
1985 tree base
= get_base_address (src
);
1988 if (tree size
= DECL_SIZE_UNIT (base
))
1990 && TREE_CODE (size
) == INTEGER_CST
1991 && TREE_CODE (TREE_TYPE (base
)) != POINTER_TYPE
)
1992 max
= wi::to_wide (size
);
1996 /* For strlen() the upper bound above is equal to
1997 the longest string that can be stored in the array
1998 (i.e., it accounts for the terminating nul. For
1999 strnlen() bump up the maximum by one since the array
2000 need not be nul-terminated. */
2001 if (!bound
&& max
!= 0)
2006 wide_int min
= wi::zero (max
.get_precision ());
2007 return set_strlen_range (lhs
, min
, max
, bound
);
2010 /* Diagnose buffer overflow by a STMT writing LEN + PLUS_ONE bytes,
2011 either into a region allocated for the object SI when non-null,
2012 or into an object designated by the LHS of STMT otherwise.
2013 For a call STMT, when CALL_LHS is set use its left hand side
2014 as the destination, otherwise use argument zero.
2015 When nonnull uses RVALS to determine range information.
2016 RAWMEM may be set by memcpy and other raw memory functions
2017 to allow accesses across subobject boundaries. */
2020 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, tree len
,
2021 strinfo
*si
, bool plus_one
, bool rawmem
)
2023 if (!len
|| warning_suppressed_p (stmt
, OPT_Wstringop_overflow_
))
2026 /* The DECL of the function performing the write if it is done
2028 tree writefn
= NULL_TREE
;
2029 /* The destination expression involved in the store or call STMT. */
2030 tree dest
= NULL_TREE
;
2032 if (is_gimple_assign (stmt
))
2033 dest
= gimple_assign_lhs (stmt
);
2034 else if (is_gimple_call (stmt
))
2037 dest
= gimple_call_lhs (stmt
);
2040 gcc_assert (gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
));
2041 dest
= gimple_call_arg (stmt
, 0);
2046 writefn
= gimple_call_fndecl (stmt
);
2051 if (warning_suppressed_p (dest
, OPT_Wstringop_overflow_
))
2054 const int ostype
= rawmem
? 0 : 1;
2056 /* Use maximum precision to avoid overflow in the addition below.
2057 Make sure all operands have the same precision to keep wide_int
2061 /* The size of the destination region (which is smaller than
2062 the destination object for stores at a non-zero offset). */
2063 tree destsize
= compute_objsize (dest
, stmt
, ostype
, &aref
, &ptr_qry
);
2068 aref
.sizrng
[1] = wi::to_offset (max_object_size ());
2071 /* Return early if the DESTSIZE size expression is the same as LEN
2072 and the offset into the destination is zero. This might happen
2073 in the case of a pair of malloc and memset calls to allocate
2074 an object and clear it as if by calloc. */
2075 if (destsize
== len
&& !plus_one
2076 && aref
.offrng
[0] == 0 && aref
.offrng
[0] == aref
.offrng
[1])
2080 if (!get_range (len
, stmt
, rng
, ptr_qry
.rvals
))
2083 widest_int lenrng
[2] =
2084 { widest_int::from (rng
[0], SIGNED
), widest_int::from (rng
[1], SIGNED
) };
2092 /* The size of the remaining space in the destination computed
2093 as the size of the latter minus the offset into it. */
2094 widest_int spcrng
[2];
2096 offset_int remrng
[2];
2097 remrng
[1] = aref
.size_remaining (remrng
);
2098 spcrng
[0] = remrng
[0] == -1 ? 0 : widest_int::from (remrng
[0], UNSIGNED
);
2099 spcrng
[1] = widest_int::from (remrng
[1], UNSIGNED
);
2102 if (wi::leu_p (lenrng
[0], spcrng
[0])
2103 && wi::leu_p (lenrng
[1], spcrng
[1]))
2106 location_t loc
= gimple_or_expr_nonartificial_location (stmt
, dest
);
2107 bool warned
= false;
2108 if (wi::leu_p (lenrng
[0], spcrng
[1]))
2111 && (!si
|| rawmem
|| !is_strlen_related_p (si
->ptr
, len
)))
2115 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2116 "%qD writing one too many bytes into a region "
2117 "of a size that depends on %<strlen%>",
2119 : warning_at (loc
, OPT_Wstringop_overflow_
,
2120 "writing one too many bytes into a region "
2121 "of a size that depends on %<strlen%>"));
2123 else if (lenrng
[0] == lenrng
[1])
2125 if (spcrng
[0] == spcrng
[1])
2127 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2128 lenrng
[0].to_uhwi (),
2129 "%qD writing %wu byte into a region "
2131 "%qD writing %wu bytes into a region "
2133 writefn
, lenrng
[0].to_uhwi (),
2134 spcrng
[0].to_uhwi ())
2135 : warning_n (loc
, OPT_Wstringop_overflow_
,
2136 lenrng
[0].to_uhwi (),
2137 "writing %wu byte into a region "
2139 "writing %wu bytes into a region "
2141 lenrng
[0].to_uhwi (),
2142 spcrng
[0].to_uhwi ()));
2145 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2146 lenrng
[0].to_uhwi (),
2147 "%qD writing %wu byte into a region "
2148 "of size between %wu and %wu",
2149 "%qD writing %wu bytes into a region "
2150 "of size between %wu and %wu",
2151 writefn
, lenrng
[0].to_uhwi (),
2152 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2153 : warning_n (loc
, OPT_Wstringop_overflow_
,
2154 lenrng
[0].to_uhwi (),
2155 "writing %wu byte into a region "
2156 "of size between %wu and %wu",
2157 "writing %wu bytes into a region "
2158 "of size between %wu and %wu",
2159 lenrng
[0].to_uhwi (),
2160 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2162 else if (spcrng
[0] == spcrng
[1])
2164 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2165 "%qD writing between %wu and %wu bytes "
2166 "into a region of size %wu",
2167 writefn
, lenrng
[0].to_uhwi (),
2168 lenrng
[1].to_uhwi (),
2169 spcrng
[0].to_uhwi ())
2170 : warning_at (loc
, OPT_Wstringop_overflow_
,
2171 "writing between %wu and %wu bytes "
2172 "into a region of size %wu",
2173 lenrng
[0].to_uhwi (),
2174 lenrng
[1].to_uhwi (),
2175 spcrng
[0].to_uhwi ()));
2178 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2179 "%qD writing between %wu and %wu bytes "
2180 "into a region of size between %wu and %wu",
2181 writefn
, lenrng
[0].to_uhwi (),
2182 lenrng
[1].to_uhwi (),
2183 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2184 : warning_at (loc
, OPT_Wstringop_overflow_
,
2185 "writing between %wu and %wu bytes "
2186 "into a region of size between %wu and %wu",
2187 lenrng
[0].to_uhwi (),
2188 lenrng
[1].to_uhwi (),
2189 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2194 suppress_warning (stmt
, OPT_Wstringop_overflow_
);
2196 aref
.inform_access (access_write_only
);
2199 /* Convenience wrapper for the above. */
2202 strlen_pass::maybe_warn_overflow (gimple
*stmt
, bool call_lhs
,
2203 unsigned HOST_WIDE_INT len
,
2204 strinfo
*si
, bool plus_one
, bool rawmem
)
2206 tree tlen
= build_int_cst (size_type_node
, len
);
2207 maybe_warn_overflow (stmt
, call_lhs
, tlen
, si
, plus_one
, rawmem
);
2210 /* Handle a strlen call. If strlen of the argument is known, replace
2211 the strlen call with the known value, otherwise remember that strlen
2212 of the argument is stored in the lhs SSA_NAME. */
2215 strlen_pass::handle_builtin_strlen ()
2217 gimple
*stmt
= gsi_stmt (m_gsi
);
2218 tree lhs
= gimple_call_lhs (stmt
);
2220 if (lhs
== NULL_TREE
)
2223 location_t loc
= gimple_location (stmt
);
2224 tree callee
= gimple_call_fndecl (stmt
);
2225 tree src
= gimple_call_arg (stmt
, 0);
2226 tree bound
= (DECL_FUNCTION_CODE (callee
) == BUILT_IN_STRNLEN
2227 ? gimple_call_arg (stmt
, 1) : NULL_TREE
);
2228 int idx
= get_stridx (src
, stmt
);
2229 if (idx
|| (bound
&& integer_zerop (bound
)))
2235 rhs
= build_int_cst (TREE_TYPE (lhs
), ~idx
);
2241 si
= get_strinfo (idx
);
2244 rhs
= get_string_length (si
);
2245 /* For strnlen, if bound is constant, even if si is not known
2246 to be zero terminated, if we know at least bound bytes are
2247 not zero, the return value will be bound. */
2248 if (rhs
== NULL_TREE
2249 && bound
!= NULL_TREE
2250 && TREE_CODE (bound
) == INTEGER_CST
2251 && si
->nonzero_chars
!= NULL_TREE
2252 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
2253 && tree_int_cst_le (bound
, si
->nonzero_chars
))
2257 if (rhs
!= NULL_TREE
)
2259 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2261 fprintf (dump_file
, "Optimizing: ");
2262 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2264 rhs
= unshare_expr (rhs
);
2265 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
2266 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2269 rhs
= fold_build2_loc (loc
, MIN_EXPR
, TREE_TYPE (rhs
), rhs
, bound
);
2271 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2272 stmt
= gsi_stmt (m_gsi
);
2274 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2276 fprintf (dump_file
, "into: ");
2277 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2281 /* Don't update anything for strnlen. */
2282 && bound
== NULL_TREE
2283 && TREE_CODE (si
->nonzero_chars
) != SSA_NAME
2284 && TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
2285 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2287 si
= unshare_strinfo (si
);
2288 si
->nonzero_chars
= lhs
;
2289 gcc_assert (si
->full_string_p
);
2292 if (strlen_to_stridx
2293 && (bound
== NULL_TREE
2294 /* For strnlen record this only if the call is proven
2295 to return the same value as strlen would. */
2296 || (TREE_CODE (bound
) == INTEGER_CST
2297 && TREE_CODE (rhs
) == INTEGER_CST
2298 && tree_int_cst_lt (rhs
, bound
))))
2299 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2304 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2308 idx
= new_stridx (src
);
2311 strinfo
*si
= get_strinfo (idx
);
2314 if (!si
->full_string_p
&& !si
->stmt
)
2316 /* Until now we only had a lower bound on the string length.
2317 Install LHS as the actual length. */
2318 si
= unshare_strinfo (si
);
2319 tree old
= si
->nonzero_chars
;
2320 si
->nonzero_chars
= lhs
;
2321 si
->full_string_p
= true;
2322 if (old
&& TREE_CODE (old
) == INTEGER_CST
)
2324 old
= fold_convert_loc (loc
, TREE_TYPE (lhs
), old
);
2325 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2326 TREE_TYPE (lhs
), lhs
, old
);
2327 adjust_related_strinfos (loc
, si
, adj
);
2328 /* Use the constant minimum length as the lower bound
2329 of the non-constant length. */
2330 wide_int min
= wi::to_wide (old
);
2332 = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
2333 set_strlen_range (lhs
, min
, max
);
2349 /* Only store the new length information for calls to strlen(),
2350 not for those to strnlen(). */
2351 strinfo
*si
= new_strinfo (src
, idx
, lhs
, true);
2352 set_strinfo (idx
, si
);
2353 find_equal_ptrs (src
, idx
);
2356 /* For SRC that is an array of N elements, set LHS's range
2357 to [0, min (N, BOUND)]. A constant return value means
2358 the range would have consisted of a single value. In
2359 that case, fold the result into the returned constant. */
2360 if (tree ret
= maybe_set_strlen_range (lhs
, src
, bound
))
2361 if (TREE_CODE (ret
) == INTEGER_CST
)
2363 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2365 fprintf (dump_file
, "Optimizing: ");
2366 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2368 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (ret
)))
2369 ret
= fold_convert_loc (loc
, TREE_TYPE (lhs
), ret
);
2370 gimplify_and_update_call_from_tree (&m_gsi
, ret
);
2371 stmt
= gsi_stmt (m_gsi
);
2373 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2375 fprintf (dump_file
, "into: ");
2376 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2380 if (strlen_to_stridx
&& !bound
)
2381 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2385 /* Handle a strchr call. If strlen of the first argument is known, replace
2386 the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
2387 that lhs of the call is endptr and strlen of the argument is endptr - x. */
2390 strlen_pass::handle_builtin_strchr ()
2392 gimple
*stmt
= gsi_stmt (m_gsi
);
2393 tree lhs
= gimple_call_lhs (stmt
);
2395 if (lhs
== NULL_TREE
)
2398 if (!integer_zerop (gimple_call_arg (stmt
, 1)))
2401 tree src
= gimple_call_arg (stmt
, 0);
2403 /* Avoid folding if the first argument is not a nul-terminated array.
2404 Defer warning until later. */
2405 if (!check_nul_terminated_array (NULL_TREE
, src
))
2408 int idx
= get_stridx (src
, stmt
);
2415 rhs
= build_int_cst (size_type_node
, ~idx
);
2419 si
= get_strinfo (idx
);
2421 rhs
= get_string_length (si
);
2423 if (rhs
!= NULL_TREE
)
2425 location_t loc
= gimple_location (stmt
);
2427 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2429 fprintf (dump_file
, "Optimizing: ");
2430 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2432 if (si
!= NULL
&& si
->endptr
!= NULL_TREE
)
2434 rhs
= unshare_expr (si
->endptr
);
2435 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2437 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2441 rhs
= fold_convert_loc (loc
, sizetype
, unshare_expr (rhs
));
2442 rhs
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
,
2443 TREE_TYPE (src
), src
, rhs
);
2444 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2446 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2448 gimplify_and_update_call_from_tree (&m_gsi
, rhs
);
2449 stmt
= gsi_stmt (m_gsi
);
2451 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2453 fprintf (dump_file
, "into: ");
2454 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2457 && si
->endptr
== NULL_TREE
2458 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2460 si
= unshare_strinfo (si
);
2463 zero_length_string (lhs
, si
);
2467 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2469 if (TREE_CODE (src
) != SSA_NAME
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src
))
2472 idx
= new_stridx (src
);
2473 else if (get_strinfo (idx
) != NULL
)
2475 zero_length_string (lhs
, NULL
);
2480 location_t loc
= gimple_location (stmt
);
2481 tree lhsu
= fold_convert_loc (loc
, size_type_node
, lhs
);
2482 tree srcu
= fold_convert_loc (loc
, size_type_node
, src
);
2483 tree length
= fold_build2_loc (loc
, MINUS_EXPR
,
2484 size_type_node
, lhsu
, srcu
);
2485 strinfo
*si
= new_strinfo (src
, idx
, length
, true);
2487 set_strinfo (idx
, si
);
2488 find_equal_ptrs (src
, idx
);
2489 zero_length_string (lhs
, si
);
2493 zero_length_string (lhs
, NULL
);
2496 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
2497 If strlen of the second argument is known, strlen of the first argument
2498 is the same after this call. Furthermore, attempt to convert it to
2499 memcpy. Uses RVALS to determine range information. */
2502 strlen_pass::handle_builtin_strcpy (built_in_function bcode
)
2505 tree src
, dst
, srclen
, len
, lhs
, type
, fn
, oldlen
;
2507 gimple
*stmt
= gsi_stmt (m_gsi
);
2508 strinfo
*si
, *dsi
, *olddsi
, *zsi
;
2511 src
= gimple_call_arg (stmt
, 1);
2512 dst
= gimple_call_arg (stmt
, 0);
2513 lhs
= gimple_call_lhs (stmt
);
2514 idx
= get_stridx (src
, stmt
);
2517 si
= get_strinfo (idx
);
2519 didx
= get_stridx (dst
, stmt
);
2523 olddsi
= get_strinfo (didx
);
2528 adjust_last_stmt (olddsi
, stmt
, false);
2532 srclen
= get_string_length (si
);
2534 srclen
= build_int_cst (size_type_node
, ~idx
);
2536 maybe_warn_overflow (stmt
, false, srclen
, olddsi
, true);
2539 adjust_last_stmt (olddsi
, stmt
, false);
2541 loc
= gimple_location (stmt
);
2542 if (srclen
== NULL_TREE
)
2545 case BUILT_IN_STRCPY
:
2546 case BUILT_IN_STRCPY_CHK
:
2547 if (lhs
!= NULL_TREE
|| !builtin_decl_implicit_p (BUILT_IN_STPCPY
))
2550 case BUILT_IN_STPCPY
:
2551 case BUILT_IN_STPCPY_CHK
:
2552 if (lhs
== NULL_TREE
)
2556 tree lhsuint
= fold_convert_loc (loc
, size_type_node
, lhs
);
2557 srclen
= fold_convert_loc (loc
, size_type_node
, dst
);
2558 srclen
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
2568 didx
= new_stridx (dst
);
2574 oldlen
= olddsi
->nonzero_chars
;
2575 dsi
= unshare_strinfo (olddsi
);
2576 dsi
->nonzero_chars
= srclen
;
2577 dsi
->full_string_p
= (srclen
!= NULL_TREE
);
2578 /* Break the chain, so adjust_related_strinfo on later pointers in
2579 the chain won't adjust this one anymore. */
2582 dsi
->endptr
= NULL_TREE
;
2586 dsi
= new_strinfo (dst
, didx
, srclen
, srclen
!= NULL_TREE
);
2587 set_strinfo (didx
, dsi
);
2588 find_equal_ptrs (dst
, didx
);
2590 dsi
->writable
= true;
2591 dsi
->dont_invalidate
= true;
2593 if (dsi
->nonzero_chars
== NULL_TREE
)
2597 /* If string length of src is unknown, use delayed length
2598 computation. If string length of dst will be needed, it
2599 can be computed by transforming this strcpy call into
2600 stpcpy and subtracting dst from the return value. */
2602 /* Look for earlier strings whose length could be determined if
2603 this strcpy is turned into an stpcpy. */
2605 if (dsi
->prev
!= 0 && (chainsi
= verify_related_strinfos (dsi
)) != NULL
)
2607 for (; chainsi
&& chainsi
!= dsi
; chainsi
= get_strinfo (chainsi
->next
))
2609 /* When setting a stmt for delayed length computation
2610 prevent all strinfos through dsi from being
2612 chainsi
= unshare_strinfo (chainsi
);
2613 chainsi
->stmt
= stmt
;
2614 chainsi
->nonzero_chars
= NULL_TREE
;
2615 chainsi
->full_string_p
= false;
2616 chainsi
->endptr
= NULL_TREE
;
2617 chainsi
->dont_invalidate
= true;
2622 /* Try to detect overlap before returning. This catches cases
2623 like strcpy (d, d + n) where n is non-constant whose range
2624 is such that (n <= strlen (d) holds).
2626 OLDDSI->NONZERO_chars may have been reset by this point with
2627 oldlen holding it original value. */
2628 if (olddsi
&& oldlen
)
2630 /* Add 1 for the terminating NUL. */
2631 tree type
= TREE_TYPE (oldlen
);
2632 oldlen
= fold_build2 (PLUS_EXPR
, type
, oldlen
,
2633 build_int_cst (type
, 1));
2634 check_bounds_or_overlap (stmt
, olddsi
->ptr
, src
, oldlen
, NULL_TREE
);
2642 tree adj
= NULL_TREE
;
2643 if (oldlen
== NULL_TREE
)
2645 else if (integer_zerop (oldlen
))
2647 else if (TREE_CODE (oldlen
) == INTEGER_CST
2648 || TREE_CODE (srclen
) == INTEGER_CST
)
2649 adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2650 TREE_TYPE (srclen
), srclen
,
2651 fold_convert_loc (loc
, TREE_TYPE (srclen
),
2653 if (adj
!= NULL_TREE
)
2654 adjust_related_strinfos (loc
, dsi
, adj
);
2658 /* strcpy src may not overlap dst, so src doesn't need to be
2659 invalidated either. */
2661 si
->dont_invalidate
= true;
2667 case BUILT_IN_STRCPY
:
2668 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
2670 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2672 case BUILT_IN_STRCPY_CHK
:
2673 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
2675 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2677 case BUILT_IN_STPCPY
:
2678 /* This would need adjustment of the lhs (subtract one),
2679 or detection that the trailing '\0' doesn't need to be
2680 written, if it will be immediately overwritten.
2681 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); */
2685 zsi
= zero_length_string (lhs
, dsi
);
2688 case BUILT_IN_STPCPY_CHK
:
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_CHK); */
2696 zsi
= zero_length_string (lhs
, dsi
);
2703 zsi
->dont_invalidate
= true;
2707 tree args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
2708 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
2711 type
= size_type_node
;
2713 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
2714 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
, build_int_cst (type
, 1));
2716 /* Disable warning for the transformed statement? */
2717 opt_code no_warning_opt
= no_warning
;
2719 if (const strinfo
*chksi
= si
? olddsi
? olddsi
: dsi
: NULL
)
2721 no_warning_opt
= check_bounds_or_overlap (stmt
, chksi
->ptr
, si
->ptr
,
2724 suppress_warning (stmt
, no_warning_opt
);
2727 if (fn
== NULL_TREE
)
2730 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
2732 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2734 fprintf (dump_file
, "Optimizing: ");
2735 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2737 if (gimple_call_num_args (stmt
) == 2)
2738 success
= update_gimple_call (&m_gsi
, fn
, 3, dst
, src
, len
);
2740 success
= update_gimple_call (&m_gsi
, fn
, 4, dst
, src
, len
,
2741 gimple_call_arg (stmt
, 2));
2744 stmt
= gsi_stmt (m_gsi
);
2746 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2748 fprintf (dump_file
, "into: ");
2749 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2751 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2752 laststmt
.stmt
= stmt
;
2753 laststmt
.len
= srclen
;
2754 laststmt
.stridx
= dsi
->idx
;
2756 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2757 fprintf (dump_file
, "not possible.\n");
2760 suppress_warning (stmt
, no_warning_opt
);
2763 /* Check the size argument to the built-in forms of stpncpy and strncpy
2764 for out-of-bounds offsets or overlapping access, and to see if the
2765 size argument is derived from a call to strlen() on the source argument,
2766 and if so, issue an appropriate warning. */
2769 strlen_pass::handle_builtin_strncat (built_in_function
)
2771 /* Same as stxncpy(). */
2772 handle_builtin_stxncpy_strncat (true);
2775 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2776 way. LEN can either be an integer expression, or a pointer (to char).
2777 When it is the latter (such as in recursive calls to self) it is
2778 assumed to be the argument in some call to strlen() whose relationship
2779 to SRC is being ascertained. */
2782 is_strlen_related_p (tree src
, tree len
)
2784 if (TREE_CODE (TREE_TYPE (len
)) == POINTER_TYPE
2785 && operand_equal_p (src
, len
, 0))
2788 if (TREE_CODE (len
) != SSA_NAME
)
2791 if (TREE_CODE (src
) == SSA_NAME
)
2793 gimple
*srcdef
= SSA_NAME_DEF_STMT (src
);
2794 if (is_gimple_assign (srcdef
))
2796 /* Handle bitwise AND used in conversions from wider size_t
2797 to narrower unsigned types. */
2798 tree_code code
= gimple_assign_rhs_code (srcdef
);
2799 if (code
== BIT_AND_EXPR
2800 || code
== NOP_EXPR
)
2801 return is_strlen_related_p (gimple_assign_rhs1 (srcdef
), len
);
2806 if (gimple_call_builtin_p (srcdef
, BUILT_IN_NORMAL
))
2808 /* If SRC is the result of a call to an allocation function
2809 or strlen, use the function's argument instead. */
2810 tree func
= gimple_call_fndecl (srcdef
);
2811 built_in_function code
= DECL_FUNCTION_CODE (func
);
2812 if (code
== BUILT_IN_ALLOCA
2813 || code
== BUILT_IN_ALLOCA_WITH_ALIGN
2814 || code
== BUILT_IN_MALLOC
2815 || code
== BUILT_IN_STRLEN
)
2816 return is_strlen_related_p (gimple_call_arg (srcdef
, 0), len
);
2818 /* FIXME: Handle other functions with attribute alloc_size. */
2823 gimple
*lendef
= SSA_NAME_DEF_STMT (len
);
2827 if (is_gimple_call (lendef
))
2829 tree func
= gimple_call_fndecl (lendef
);
2830 if (!valid_builtin_call (lendef
)
2831 || DECL_FUNCTION_CODE (func
) != BUILT_IN_STRLEN
)
2834 tree arg
= gimple_call_arg (lendef
, 0);
2835 return is_strlen_related_p (src
, arg
);
2838 if (!is_gimple_assign (lendef
))
2841 tree_code code
= gimple_assign_rhs_code (lendef
);
2842 tree rhs1
= gimple_assign_rhs1 (lendef
);
2843 tree rhstype
= TREE_TYPE (rhs1
);
2845 if ((TREE_CODE (rhstype
) == POINTER_TYPE
&& code
== POINTER_PLUS_EXPR
)
2846 || (INTEGRAL_TYPE_P (rhstype
)
2847 && (code
== BIT_AND_EXPR
2848 || code
== NOP_EXPR
)))
2850 /* Pointer plus (an integer), and truncation are considered among
2851 the (potentially) related expressions to strlen. */
2852 return is_strlen_related_p (src
, rhs1
);
2855 if (tree rhs2
= gimple_assign_rhs2 (lendef
))
2857 /* Integer subtraction is considered strlen-related when both
2858 arguments are integers and second one is strlen-related. */
2859 rhstype
= TREE_TYPE (rhs2
);
2860 if (INTEGRAL_TYPE_P (rhstype
) && code
== MINUS_EXPR
)
2861 return is_strlen_related_p (src
, rhs2
);
2867 /* Called by handle_builtin_stxncpy_strncat and by
2868 gimple_fold_builtin_strncpy in gimple-fold.cc.
2869 Check to see if the specified bound is a) equal to the size of
2870 the destination DST and if so, b) if it's immediately followed by
2871 DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise,
2872 do nothing. Return true if diagnostic has been issued.
2874 The purpose is to diagnose calls to strncpy and stpncpy that do
2875 not nul-terminate the copy while allowing for the idiom where
2876 such a call is immediately followed by setting the last element
2879 strncpy (a, s, sizeof a);
2880 a[sizeof a - 1] = '\0';
2884 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi
, tree src
, tree cnt
,
2885 pointer_query
*ptr_qry
/* = NULL */)
2887 gimple
*stmt
= gsi_stmt (gsi
);
2888 if (warning_suppressed_p (stmt
, OPT_Wstringop_truncation
))
2891 wide_int cntrange
[2];
2893 if (!get_range_query (cfun
)->range_of_expr (r
, cnt
)
2895 || r
.undefined_p ())
2899 value_range_kind kind
= get_legacy_range (r
, min
, max
);
2900 cntrange
[0] = wi::to_wide (min
);
2901 cntrange
[1] = wi::to_wide (max
);
2902 if (kind
== VR_ANTI_RANGE
)
2904 wide_int maxobjsize
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
));
2906 if (wi::ltu_p (cntrange
[1], maxobjsize
))
2908 cntrange
[0] = cntrange
[1] + 1;
2909 cntrange
[1] = maxobjsize
;
2913 cntrange
[1] = cntrange
[0] - 1;
2914 cntrange
[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt
)));
2918 /* Negative value is the constant string length. If it's less than
2919 the lower bound there is no truncation. Avoid calling get_stridx()
2920 when ssa_ver_to_stridx is empty. That implies the caller isn't
2921 running under the control of this pass and ssa_ver_to_stridx hasn't
2922 been created yet. */
2923 int sidx
= ssa_ver_to_stridx
.length () ? get_stridx (src
, stmt
) : 0;
2924 if (sidx
< 0 && wi::gtu_p (cntrange
[0], ~sidx
))
2927 tree dst
= gimple_call_arg (stmt
, 0);
2929 if (TREE_CODE (dstdecl
) == ADDR_EXPR
)
2930 dstdecl
= TREE_OPERAND (dstdecl
, 0);
2932 tree ref
= NULL_TREE
;
2936 /* If the source is a non-string return early to avoid warning
2937 for possible truncation (if the truncation is certain SIDX
2939 tree srcdecl
= gimple_call_arg (stmt
, 1);
2940 if (TREE_CODE (srcdecl
) == ADDR_EXPR
)
2941 srcdecl
= TREE_OPERAND (srcdecl
, 0);
2942 if (get_attr_nonstring_decl (srcdecl
, &ref
))
2946 /* Likewise, if the destination refers to an array/pointer declared
2947 nonstring return early. */
2948 if (get_attr_nonstring_decl (dstdecl
, &ref
))
2951 /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2952 avoid the truncation warning. */
2953 gsi_next_nondebug (&gsi
);
2954 gimple
*next_stmt
= gsi_stmt (gsi
);
2957 /* When there is no statement in the same basic block check
2958 the immediate successor block. */
2959 if (basic_block bb
= gimple_bb (stmt
))
2961 if (single_succ_p (bb
))
2963 /* For simplicity, ignore blocks with multiple outgoing
2964 edges for now and only consider successor blocks along
2966 edge e
= EDGE_SUCC (bb
, 0);
2967 if (!(e
->flags
& EDGE_ABNORMAL
))
2969 gsi
= gsi_start_bb (e
->dest
);
2970 next_stmt
= gsi_stmt (gsi
);
2971 if (next_stmt
&& is_gimple_debug (next_stmt
))
2973 gsi_next_nondebug (&gsi
);
2974 next_stmt
= gsi_stmt (gsi
);
2981 if (next_stmt
&& is_gimple_assign (next_stmt
))
2983 tree lhs
= gimple_assign_lhs (next_stmt
);
2984 tree_code code
= TREE_CODE (lhs
);
2985 if (code
== ARRAY_REF
|| code
== MEM_REF
)
2986 lhs
= TREE_OPERAND (lhs
, 0);
2988 tree func
= gimple_call_fndecl (stmt
);
2989 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STPNCPY
)
2991 tree ret
= gimple_call_lhs (stmt
);
2992 if (ret
&& operand_equal_p (ret
, lhs
, 0))
2996 /* Determine the base address and offset of the reference,
2997 ignoring the innermost array index. */
2998 if (TREE_CODE (ref
) == ARRAY_REF
)
2999 ref
= TREE_OPERAND (ref
, 0);
3002 tree dstbase
= get_addr_base_and_unit_offset (ref
, &dstoff
);
3005 tree lhsbase
= get_addr_base_and_unit_offset (lhs
, &lhsoff
);
3008 && known_eq (dstoff
, lhsoff
)
3009 && operand_equal_p (dstbase
, lhsbase
, 0))
3013 int prec
= TYPE_PRECISION (TREE_TYPE (cnt
));
3014 wide_int lenrange
[2];
3015 if (strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
)
3017 lenrange
[0] = (sisrc
->nonzero_chars
3018 && TREE_CODE (sisrc
->nonzero_chars
) == INTEGER_CST
3019 ? wi::to_wide (sisrc
->nonzero_chars
)
3021 lenrange
[1] = lenrange
[0];
3024 lenrange
[0] = lenrange
[1] = wi::shwi (~sidx
, prec
);
3027 c_strlen_data lendata
= { };
3028 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
3029 to have it set to the length of the longest string in a PHI. */
3030 lendata
.maxbound
= src
;
3031 get_range_strlen (src
, &lendata
, /* eltsize = */1);
3032 if (TREE_CODE (lendata
.minlen
) == INTEGER_CST
3033 && TREE_CODE (lendata
.maxbound
) == INTEGER_CST
)
3035 /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
3036 which stores the length of the shortest known string. */
3037 if (integer_all_onesp (lendata
.maxlen
))
3038 lenrange
[0] = wi::shwi (0, prec
);
3040 lenrange
[0] = wi::to_wide (lendata
.minlen
, prec
);
3041 lenrange
[1] = wi::to_wide (lendata
.maxbound
, prec
);
3045 lenrange
[0] = wi::shwi (0, prec
);
3046 lenrange
[1] = wi::shwi (-1, prec
);
3050 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3051 tree func
= gimple_call_fndecl (stmt
);
3053 if (lenrange
[0] != 0 || !wi::neg_p (lenrange
[1]))
3055 /* If the longest source string is shorter than the lower bound
3056 of the specified count the copy is definitely nul-terminated. */
3057 if (wi::ltu_p (lenrange
[1], cntrange
[0]))
3060 if (wi::neg_p (lenrange
[1]))
3062 /* The length of one of the strings is unknown but at least
3063 one has non-zero length and that length is stored in
3064 LENRANGE[1]. Swap the bounds to force a "may be truncated"
3066 lenrange
[1] = lenrange
[0];
3067 lenrange
[0] = wi::shwi (0, prec
);
3070 /* Set to true for strncat whose bound is derived from the length
3071 of the destination (the expected usage pattern). */
3072 bool cat_dstlen_bounded
= false;
3073 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STRNCAT
)
3074 cat_dstlen_bounded
= is_strlen_related_p (dst
, cnt
);
3076 if (lenrange
[0] == cntrange
[1] && cntrange
[0] == cntrange
[1])
3077 return warning_n (callloc
, OPT_Wstringop_truncation
,
3078 cntrange
[0].to_uhwi (),
3079 "%qD output truncated before terminating "
3080 "nul copying %E byte from a string of the "
3082 "%qD output truncated before terminating nul "
3083 "copying %E bytes from a string of the same "
3086 else if (!cat_dstlen_bounded
)
3088 if (wi::geu_p (lenrange
[0], cntrange
[1]))
3090 /* The shortest string is longer than the upper bound of
3091 the count so the truncation is certain. */
3092 if (cntrange
[0] == cntrange
[1])
3093 return warning_n (callloc
, OPT_Wstringop_truncation
,
3094 cntrange
[0].to_uhwi (),
3095 "%qD output truncated copying %E byte "
3096 "from a string of length %wu",
3097 "%qD output truncated copying %E bytes "
3098 "from a string of length %wu",
3099 func
, cnt
, lenrange
[0].to_uhwi ());
3101 return warning_at (callloc
, OPT_Wstringop_truncation
,
3102 "%qD output truncated copying between %wu "
3103 "and %wu bytes from a string of length %wu",
3104 func
, cntrange
[0].to_uhwi (),
3105 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3107 else if (wi::geu_p (lenrange
[1], cntrange
[1]))
3109 /* The longest string is longer than the upper bound of
3110 the count so the truncation is possible. */
3111 if (cntrange
[0] == cntrange
[1])
3112 return warning_n (callloc
, OPT_Wstringop_truncation
,
3113 cntrange
[0].to_uhwi (),
3114 "%qD output may be truncated copying %E "
3115 "byte from a string of length %wu",
3116 "%qD output may be truncated copying %E "
3117 "bytes from a string of length %wu",
3118 func
, cnt
, lenrange
[1].to_uhwi ());
3120 return warning_at (callloc
, OPT_Wstringop_truncation
,
3121 "%qD output may be truncated copying between "
3122 "%wu and %wu bytes from a string of length %wu",
3123 func
, cntrange
[0].to_uhwi (),
3124 cntrange
[1].to_uhwi (), lenrange
[1].to_uhwi ());
3128 if (!cat_dstlen_bounded
3129 && cntrange
[0] != cntrange
[1]
3130 && wi::leu_p (cntrange
[0], lenrange
[0])
3131 && wi::leu_p (cntrange
[1], lenrange
[0] + 1))
3133 /* If the source (including the terminating nul) is longer than
3134 the lower bound of the specified count but shorter than the
3135 upper bound the copy may (but need not) be truncated. */
3136 return warning_at (callloc
, OPT_Wstringop_truncation
,
3137 "%qD output may be truncated copying between "
3138 "%wu and %wu bytes from a string of length %wu",
3139 func
, cntrange
[0].to_uhwi (),
3140 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3145 if (tree dstsize
= compute_objsize (dst
, stmt
, 1, &aref
, ptr_qry
))
3147 /* The source length is unknown. Try to determine the destination
3148 size and see if it matches the specified bound. If not, bail.
3149 Otherwise go on to see if it should be diagnosed for possible
3154 if (wi::to_wide (dstsize
) != cntrange
[1])
3157 /* Avoid warning for strncpy(a, b, N) calls where the following
3159 N == sizeof a && N == sizeof b */
3160 if (tree srcsize
= compute_objsize (src
, stmt
, 1, &aref
, ptr_qry
))
3161 if (wi::to_wide (srcsize
) == cntrange
[1])
3164 if (cntrange
[0] == cntrange
[1])
3165 return warning_at (callloc
, OPT_Wstringop_truncation
,
3166 "%qD specified bound %E equals destination size",
3173 /* Check the arguments to the built-in forms of stpncpy, strncpy, and
3174 strncat, for out-of-bounds offsets or overlapping access, and to see
3175 if the size is derived from calling strlen() on the source argument,
3176 and if so, issue the appropriate warning.
3177 APPEND_P is true for strncat. */
3180 strlen_pass::handle_builtin_stxncpy_strncat (bool append_p
)
3182 if (!strlen_to_stridx
)
3185 gimple
*stmt
= gsi_stmt (m_gsi
);
3187 tree dst
= gimple_call_arg (stmt
, 0);
3188 tree src
= gimple_call_arg (stmt
, 1);
3189 tree len
= gimple_call_arg (stmt
, 2);
3190 /* An upper bound of the size of the destination. */
3191 tree dstsize
= NULL_TREE
;
3192 /* The length of the destination and source strings (plus 1 for those
3193 whose FULL_STRING_P is set, i.e., whose length is exact rather than
3195 tree dstlenp1
= NULL_TREE
, srclenp1
= NULL_TREE
;;
3197 int didx
= get_stridx (dst
, stmt
);
3198 if (strinfo
*sidst
= didx
> 0 ? get_strinfo (didx
) : NULL
)
3200 /* Compute the size of the destination string including the nul
3201 if it is known to be nul-terminated. */
3202 if (sidst
->nonzero_chars
)
3204 if (sidst
->full_string_p
)
3206 /* String is known to be nul-terminated. */
3207 tree type
= TREE_TYPE (sidst
->nonzero_chars
);
3208 dstlenp1
= fold_build2 (PLUS_EXPR
, type
, sidst
->nonzero_chars
,
3209 build_int_cst (type
, 1));
3212 dstlenp1
= sidst
->nonzero_chars
;
3214 else if (TREE_CODE (sidst
->ptr
) == SSA_NAME
)
3216 gimple
*def_stmt
= SSA_NAME_DEF_STMT (sidst
->ptr
);
3217 dstsize
= gimple_call_alloc_size (def_stmt
);
3223 int sidx
= get_stridx (src
, stmt
);
3224 strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
;
3227 /* strncat() and strncpy() can modify the source string by writing
3228 over the terminating nul so SISRC->DONT_INVALIDATE must be left
3231 /* Compute the size of the source string including the terminating
3232 nul if its known to be nul-terminated. */
3233 if (sisrc
->nonzero_chars
)
3235 if (sisrc
->full_string_p
)
3237 tree type
= TREE_TYPE (sisrc
->nonzero_chars
);
3238 srclenp1
= fold_build2 (PLUS_EXPR
, type
, sisrc
->nonzero_chars
,
3239 build_int_cst (type
, 1));
3242 srclenp1
= sisrc
->nonzero_chars
;
3248 srclenp1
= NULL_TREE
;
3250 opt_code opt
= check_bounds_or_overlap (stmt
, dst
, src
, dstlenp1
, srclenp1
);
3251 if (opt
!= no_warning
)
3253 suppress_warning (stmt
, opt
);
3257 /* If the length argument was computed from strlen(S) for some string
3258 S retrieve the strinfo index for the string (PSS->FIRST) along with
3259 the location of the strlen() call (PSS->SECOND). */
3260 stridx_strlenloc
*pss
= strlen_to_stridx
->get (len
);
3261 if (!pss
|| pss
->first
<= 0)
3263 if (maybe_diag_stxncpy_trunc (m_gsi
, src
, len
))
3264 suppress_warning (stmt
, OPT_Wstringop_truncation
);
3269 /* Retrieve the strinfo data for the string S that LEN was computed
3270 from as some function F of strlen (S) (i.e., LEN need not be equal
3272 strinfo
*silen
= get_strinfo (pss
->first
);
3274 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3276 tree func
= gimple_call_fndecl (stmt
);
3278 bool warned
= false;
3280 /* When -Wstringop-truncation is set, try to determine truncation
3281 before diagnosing possible overflow. Truncation is implied by
3282 the LEN argument being equal to strlen(SRC), regardless of
3283 whether its value is known. Otherwise, when appending, or
3284 when copying into a destination of known size, issue the more
3285 generic -Wstringop-overflow which triggers for LEN arguments
3286 that in any meaningful way depend on strlen(SRC). */
3289 && is_strlen_related_p (src
, len
)
3290 && warning_at (callloc
, OPT_Wstringop_truncation
,
3291 "%qD output truncated before terminating nul "
3292 "copying as many bytes from a string as its length",
3295 else if ((append_p
|| !dstsize
|| len
== dstlenp1
)
3296 && silen
&& is_strlen_related_p (src
, silen
->ptr
))
3298 /* Issue -Wstringop-overflow when appending or when writing into
3299 a destination of a known size. Otherwise, when copying into
3300 a destination of an unknown size, it's truncation. */
3301 opt_code opt
= (append_p
|| dstsize
3302 ? OPT_Wstringop_overflow_
: OPT_Wstringop_truncation
);
3303 warned
= warning_at (callloc
, opt
,
3304 "%qD specified bound depends on the length "
3305 "of the source argument",
3310 location_t strlenloc
= pss
->second
;
3311 if (strlenloc
!= UNKNOWN_LOCATION
&& strlenloc
!= callloc
)
3312 inform (strlenloc
, "length computed here");
3316 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
3317 If strlen of the second argument is known and length of the third argument
3318 is that plus one, strlen of the first argument is the same after this
3319 call. Uses RVALS to determine range information. */
3322 strlen_pass::handle_builtin_memcpy (built_in_function bcode
)
3324 tree lhs
, oldlen
, newlen
;
3325 gimple
*stmt
= gsi_stmt (m_gsi
);
3328 tree len
= gimple_call_arg (stmt
, 2);
3329 tree src
= gimple_call_arg (stmt
, 1);
3330 tree dst
= gimple_call_arg (stmt
, 0);
3332 int didx
= get_stridx (dst
, stmt
);
3333 strinfo
*olddsi
= NULL
;
3335 olddsi
= get_strinfo (didx
);
3340 && !integer_zerop (len
))
3342 maybe_warn_overflow (stmt
, false, len
, olddsi
, false, true);
3343 adjust_last_stmt (olddsi
, stmt
, false);
3346 int idx
= get_stridx (src
, stmt
);
3355 /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
3357 si
= get_strinfo (idx
);
3358 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
3360 if (TREE_CODE (len
) == INTEGER_CST
3361 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
3363 if (tree_int_cst_le (len
, si
->nonzero_chars
))
3365 /* Copying LEN nonzero characters, where LEN is constant. */
3367 full_string_p
= false;
3371 /* Copying the whole of the analyzed part of SI. */
3372 newlen
= si
->nonzero_chars
;
3373 full_string_p
= si
->full_string_p
;
3378 if (!si
->full_string_p
)
3380 if (TREE_CODE (len
) != SSA_NAME
)
3382 def_stmt
= SSA_NAME_DEF_STMT (len
);
3383 if (!is_gimple_assign (def_stmt
)
3384 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
3385 || gimple_assign_rhs1 (def_stmt
) != si
->nonzero_chars
3386 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
3388 /* Copying variable-length string SI (and no more). */
3389 newlen
= si
->nonzero_chars
;
3390 full_string_p
= true;
3396 /* Handle memcpy (x, "abcd", 5) or
3397 memcpy (x, "abc\0uvw", 7). */
3398 if (!tree_fits_uhwi_p (len
))
3401 unsigned HOST_WIDE_INT clen
= tree_to_uhwi (len
);
3402 unsigned HOST_WIDE_INT nonzero_chars
= ~idx
;
3403 newlen
= build_int_cst (size_type_node
, MIN (nonzero_chars
, clen
));
3404 full_string_p
= clen
> nonzero_chars
;
3409 && olddsi
->nonzero_chars
3410 && TREE_CODE (olddsi
->nonzero_chars
) == INTEGER_CST
3411 && tree_int_cst_le (newlen
, olddsi
->nonzero_chars
))
3413 /* The SRC substring being written strictly overlaps
3414 a subsequence of the existing string OLDDSI. */
3415 newlen
= olddsi
->nonzero_chars
;
3416 full_string_p
= olddsi
->full_string_p
;
3419 if (olddsi
!= NULL
&& TREE_CODE (len
) == SSA_NAME
)
3420 adjust_last_stmt (olddsi
, stmt
, false);
3424 didx
= new_stridx (dst
);
3431 dsi
= unshare_strinfo (olddsi
);
3432 oldlen
= olddsi
->nonzero_chars
;
3433 dsi
->nonzero_chars
= newlen
;
3434 dsi
->full_string_p
= full_string_p
;
3435 /* Break the chain, so adjust_related_strinfo on later pointers in
3436 the chain won't adjust this one anymore. */
3439 dsi
->endptr
= NULL_TREE
;
3443 dsi
= new_strinfo (dst
, didx
, newlen
, full_string_p
);
3444 set_strinfo (didx
, dsi
);
3445 find_equal_ptrs (dst
, didx
);
3447 dsi
->writable
= true;
3448 dsi
->dont_invalidate
= true;
3451 tree adj
= NULL_TREE
;
3452 location_t loc
= gimple_location (stmt
);
3453 if (oldlen
== NULL_TREE
)
3455 else if (integer_zerop (oldlen
))
3457 else if (TREE_CODE (oldlen
) == INTEGER_CST
3458 || TREE_CODE (newlen
) == INTEGER_CST
)
3459 adj
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (newlen
), newlen
,
3460 fold_convert_loc (loc
, TREE_TYPE (newlen
),
3462 if (adj
!= NULL_TREE
)
3463 adjust_related_strinfos (loc
, dsi
, adj
);
3467 /* memcpy src may not overlap dst, so src doesn't need to be
3468 invalidated either. */
3470 si
->dont_invalidate
= true;
3474 lhs
= gimple_call_lhs (stmt
);
3477 case BUILT_IN_MEMCPY
:
3478 case BUILT_IN_MEMCPY_CHK
:
3479 /* Allow adjust_last_stmt to decrease this memcpy's size. */
3480 laststmt
.stmt
= stmt
;
3481 laststmt
.len
= dsi
->nonzero_chars
;
3482 laststmt
.stridx
= dsi
->idx
;
3484 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
3486 case BUILT_IN_MEMPCPY
:
3487 case BUILT_IN_MEMPCPY_CHK
:
3495 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
3496 If strlen of the second argument is known, strlen of the first argument
3497 is increased by the length of the second argument. Furthermore, attempt
3498 to convert it to memcpy/strcpy if the length of the first argument
3502 strlen_pass::handle_builtin_strcat (built_in_function bcode
)
3505 tree srclen
, args
, type
, fn
, objsz
, endptr
;
3507 gimple
*stmt
= gsi_stmt (m_gsi
);
3509 location_t loc
= gimple_location (stmt
);
3511 tree src
= gimple_call_arg (stmt
, 1);
3512 tree dst
= gimple_call_arg (stmt
, 0);
3514 /* Bail if the source is the same as destination. It will be diagnosed
3516 if (operand_equal_p (src
, dst
, 0))
3519 tree lhs
= gimple_call_lhs (stmt
);
3521 didx
= get_stridx (dst
, stmt
);
3527 dsi
= get_strinfo (didx
);
3531 idx
= get_stridx (src
, stmt
);
3533 srclen
= build_int_cst (size_type_node
, ~idx
);
3536 si
= get_strinfo (idx
);
3538 srclen
= get_string_length (si
);
3541 /* Disable warning for the transformed statement? */
3542 opt_code no_warning_opt
= no_warning
;
3544 if (dsi
== NULL
|| get_string_length (dsi
) == NULL_TREE
)
3547 /* The concatenation always involves copying at least one byte
3548 (the terminating nul), even if the source string is empty.
3549 If the source is unknown assume it's one character long and
3550 used that as both sizes. */
3554 tree type
= TREE_TYPE (slen
);
3555 slen
= fold_build2 (PLUS_EXPR
, type
, slen
, build_int_cst (type
, 1));
3558 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3559 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, NULL_TREE
,
3562 suppress_warning (stmt
, no_warning_opt
);
3565 /* strcat (p, q) can be transformed into
3566 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
3567 with length endptr - p if we need to compute the length
3568 later on. Don't do this transformation if we don't need
3570 if (builtin_decl_implicit_p (BUILT_IN_STPCPY
) && lhs
== NULL_TREE
)
3574 didx
= new_stridx (dst
);
3580 dsi
= new_strinfo (dst
, didx
, NULL_TREE
, false);
3581 set_strinfo (didx
, dsi
);
3582 find_equal_ptrs (dst
, didx
);
3586 dsi
= unshare_strinfo (dsi
);
3587 dsi
->nonzero_chars
= NULL_TREE
;
3588 dsi
->full_string_p
= false;
3590 dsi
->endptr
= NULL_TREE
;
3592 dsi
->writable
= true;
3594 dsi
->dont_invalidate
= true;
3599 tree dstlen
= dsi
->nonzero_chars
;
3600 endptr
= dsi
->endptr
;
3602 dsi
= unshare_strinfo (dsi
);
3603 dsi
->endptr
= NULL_TREE
;
3605 dsi
->writable
= true;
3607 if (srclen
!= NULL_TREE
)
3609 dsi
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
3610 TREE_TYPE (dsi
->nonzero_chars
),
3611 dsi
->nonzero_chars
, srclen
);
3612 gcc_assert (dsi
->full_string_p
);
3613 adjust_related_strinfos (loc
, dsi
, srclen
);
3614 dsi
->dont_invalidate
= true;
3618 dsi
->nonzero_chars
= NULL
;
3619 dsi
->full_string_p
= false;
3620 if (lhs
== NULL_TREE
&& builtin_decl_implicit_p (BUILT_IN_STPCPY
))
3621 dsi
->dont_invalidate
= true;
3625 /* strcat src may not overlap dst, so src doesn't need to be
3626 invalidated either. */
3627 si
->dont_invalidate
= true;
3629 /* For now. Could remove the lhs from the call and add
3630 lhs = dst; afterwards. */
3638 case BUILT_IN_STRCAT
:
3639 if (srclen
!= NULL_TREE
)
3640 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
3642 fn
= builtin_decl_implicit (BUILT_IN_STRCPY
);
3644 case BUILT_IN_STRCAT_CHK
:
3645 if (srclen
!= NULL_TREE
)
3646 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
3648 fn
= builtin_decl_explicit (BUILT_IN_STRCPY_CHK
);
3649 objsz
= gimple_call_arg (stmt
, 2);
3655 if (fn
== NULL_TREE
)
3660 tree type
= TREE_TYPE (dstlen
);
3662 /* Compute the size of the source sequence, including the nul. */
3663 tree srcsize
= srclen
? srclen
: size_zero_node
;
3664 tree one
= build_int_cst (type
, 1);
3665 srcsize
= fold_build2 (PLUS_EXPR
, type
, srcsize
, one
);
3666 tree dstsize
= fold_build2 (PLUS_EXPR
, type
, dstlen
, one
);
3667 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3669 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, dstsize
,
3672 suppress_warning (stmt
, no_warning_opt
);
3675 tree len
= NULL_TREE
;
3676 if (srclen
!= NULL_TREE
)
3678 args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
3679 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
3681 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
3682 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
,
3683 build_int_cst (type
, 1));
3684 len
= force_gimple_operand_gsi (&m_gsi
, len
, true, NULL_TREE
, true,
3688 dst
= fold_convert_loc (loc
, TREE_TYPE (dst
), unshare_expr (endptr
));
3690 dst
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
, TREE_TYPE (dst
), dst
,
3691 fold_convert_loc (loc
, sizetype
,
3692 unshare_expr (dstlen
)));
3693 dst
= force_gimple_operand_gsi (&m_gsi
, dst
, true, NULL_TREE
, true,
3697 objsz
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (objsz
), objsz
,
3698 fold_convert_loc (loc
, TREE_TYPE (objsz
),
3699 unshare_expr (dstlen
)));
3700 objsz
= force_gimple_operand_gsi (&m_gsi
, objsz
, true, NULL_TREE
, true,
3703 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3705 fprintf (dump_file
, "Optimizing: ");
3706 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3708 if (srclen
!= NULL_TREE
)
3709 success
= update_gimple_call (&m_gsi
, fn
, 3 + (objsz
!= NULL_TREE
),
3710 dst
, src
, len
, objsz
);
3712 success
= update_gimple_call (&m_gsi
, fn
, 2 + (objsz
!= NULL_TREE
),
3716 stmt
= gsi_stmt (m_gsi
);
3718 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3720 fprintf (dump_file
, "into: ");
3721 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3723 /* If srclen == NULL, note that current string length can be
3724 computed by transforming this strcpy into stpcpy. */
3725 if (srclen
== NULL_TREE
&& dsi
->dont_invalidate
)
3727 adjust_last_stmt (dsi
, stmt
, true);
3728 if (srclen
!= NULL_TREE
)
3730 laststmt
.stmt
= stmt
;
3731 laststmt
.len
= srclen
;
3732 laststmt
.stridx
= dsi
->idx
;
3735 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3736 fprintf (dump_file
, "not possible.\n");
3739 suppress_warning (stmt
, no_warning_opt
);
3742 /* Handle a call to an allocation function like alloca, malloc or calloc,
3743 or an ordinary allocation function declared with attribute alloc_size. */
3746 strlen_pass::handle_alloc_call (built_in_function bcode
)
3748 gimple
*stmt
= gsi_stmt (m_gsi
);
3749 tree lhs
= gimple_call_lhs (stmt
);
3750 if (lhs
== NULL_TREE
)
3753 gcc_assert (get_stridx (lhs
, stmt
) == 0);
3754 int idx
= new_stridx (lhs
);
3755 tree length
= NULL_TREE
;
3756 if (bcode
== BUILT_IN_CALLOC
)
3757 length
= build_int_cst (size_type_node
, 0);
3758 strinfo
*si
= new_strinfo (lhs
, idx
, length
, length
!= NULL_TREE
);
3759 if (bcode
== BUILT_IN_CALLOC
)
3761 /* Only set STMT for calloc and malloc. */
3763 /* Only set ENDPTR for calloc. */
3766 else if (bcode
== BUILT_IN_MALLOC
)
3769 /* Set ALLOC is set for all allocation functions. */
3771 set_strinfo (idx
, si
);
3772 si
->writable
= true;
3773 si
->dont_invalidate
= true;
3776 /* Handle a call to memset.
3777 After a call to calloc, memset(,0,) is unnecessary.
3778 memset(malloc(n),0,n) is calloc(n,1).
3779 return true when the call is transformed, false otherwise.
3780 When nonnull uses RVALS to determine range information. */
3783 strlen_pass::handle_builtin_memset (bool *zero_write
)
3785 gimple
*memset_stmt
= gsi_stmt (m_gsi
);
3786 tree ptr
= gimple_call_arg (memset_stmt
, 0);
3787 tree memset_val
= gimple_call_arg (memset_stmt
, 1);
3788 tree memset_size
= gimple_call_arg (memset_stmt
, 2);
3790 /* Set to the non-constant offset added to PTR. */
3792 int idx1
= get_stridx (ptr
, memset_stmt
, offrng
, ptr_qry
.rvals
);
3794 && TREE_CODE (memset_val
) == INTEGER_CST
3795 && ((TREE_CODE (memset_size
) == INTEGER_CST
3796 && !integer_zerop (memset_size
))
3797 || TREE_CODE (memset_size
) == SSA_NAME
))
3799 unsigned HOST_WIDE_INT mask
= (HOST_WIDE_INT_1U
<< CHAR_TYPE_SIZE
) - 1;
3800 bool full_string_p
= (wi::to_wide (memset_val
) & mask
) == 0;
3802 /* We only handle symbolic lengths when writing non-zero values. */
3803 if (full_string_p
&& TREE_CODE (memset_size
) != INTEGER_CST
)
3806 idx1
= new_stridx (ptr
);
3811 newlen
= build_int_cst (size_type_node
, 0);
3812 else if (TREE_CODE (memset_size
) == INTEGER_CST
)
3813 newlen
= fold_convert (size_type_node
, memset_size
);
3815 newlen
= memset_size
;
3817 strinfo
*dsi
= new_strinfo (ptr
, idx1
, newlen
, full_string_p
);
3818 set_strinfo (idx1
, dsi
);
3819 find_equal_ptrs (ptr
, idx1
);
3820 dsi
->dont_invalidate
= true;
3821 dsi
->writable
= true;
3827 strinfo
*si1
= get_strinfo (idx1
);
3830 gimple
*alloc_stmt
= si1
->alloc
;
3831 if (!alloc_stmt
|| !is_gimple_call (alloc_stmt
))
3833 tree callee1
= gimple_call_fndecl (alloc_stmt
);
3834 if (!valid_builtin_call (alloc_stmt
))
3836 tree alloc_size
= gimple_call_arg (alloc_stmt
, 0);
3838 /* Check for overflow. */
3839 maybe_warn_overflow (memset_stmt
, false, memset_size
, NULL
, false, true);
3841 /* Bail when there is no statement associated with the destination
3842 (the statement may be null even when SI1->ALLOC is not). */
3846 /* Avoid optimizing if store is at a variable offset from the beginning
3847 of the allocated object. */
3848 if (offrng
[0] != 0 || offrng
[0] != offrng
[1])
3851 /* Bail when the call writes a non-zero value. */
3852 if (!integer_zerop (memset_val
))
3855 /* Let the caller know the memset call cleared the destination. */
3858 enum built_in_function code1
= DECL_FUNCTION_CODE (callee1
);
3859 if (code1
== BUILT_IN_CALLOC
)
3860 /* Not touching alloc_stmt */ ;
3861 else if (code1
== BUILT_IN_MALLOC
3862 && operand_equal_p (memset_size
, alloc_size
, 0))
3864 /* Replace the malloc + memset calls with calloc. */
3865 gimple_stmt_iterator gsi1
= gsi_for_stmt (si1
->stmt
);
3866 update_gimple_call (&gsi1
, builtin_decl_implicit (BUILT_IN_CALLOC
), 2,
3867 alloc_size
, build_one_cst (size_type_node
));
3868 si1
->nonzero_chars
= build_int_cst (size_type_node
, 0);
3869 si1
->full_string_p
= true;
3870 si1
->stmt
= gsi_stmt (gsi1
);
3874 tree lhs
= gimple_call_lhs (memset_stmt
);
3875 unlink_stmt_vdef (memset_stmt
);
3878 gimple
*assign
= gimple_build_assign (lhs
, ptr
);
3879 gsi_replace (&m_gsi
, assign
, false);
3883 gsi_remove (&m_gsi
, true);
3884 release_defs (memset_stmt
);
3890 /* Return first such statement if RES is used in statements testing its
3891 equality to zero, and null otherwise. If EXCLUSIVE is true, return
3892 nonnull if and only RES is used in such expressions exclusively and
3896 use_in_zero_equality (tree res
, bool exclusive
)
3898 gimple
*first_use
= NULL
;
3900 use_operand_p use_p
;
3901 imm_use_iterator iter
;
3903 FOR_EACH_IMM_USE_FAST (use_p
, iter
, res
)
3905 gimple
*use_stmt
= USE_STMT (use_p
);
3907 if (is_gimple_debug (use_stmt
))
3910 if (gimple_code (use_stmt
) == GIMPLE_ASSIGN
)
3912 tree_code code
= gimple_assign_rhs_code (use_stmt
);
3913 if (code
== COND_EXPR
)
3915 tree cond_expr
= gimple_assign_rhs1 (use_stmt
);
3916 if ((TREE_CODE (cond_expr
) != EQ_EXPR
3917 && (TREE_CODE (cond_expr
) != NE_EXPR
))
3918 || !integer_zerop (TREE_OPERAND (cond_expr
, 1)))
3925 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
3927 if (!integer_zerop (gimple_assign_rhs2 (use_stmt
)))
3939 else if (gimple_code (use_stmt
) == GIMPLE_COND
)
3941 tree_code code
= gimple_cond_code (use_stmt
);
3942 if ((code
!= EQ_EXPR
&& code
!= NE_EXPR
)
3943 || !integer_zerop (gimple_cond_rhs (use_stmt
)))
3956 first_use
= use_stmt
;
3962 /* Handle a call to memcmp. We try to handle small comparisons by
3963 converting them to load and compare, and replacing the call to memcmp
3964 with a __builtin_memcmp_eq call where possible.
3965 return true when call is transformed, return false otherwise. */
3968 strlen_pass::handle_builtin_memcmp ()
3970 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
3971 tree res
= gimple_call_lhs (stmt
);
3973 if (!res
|| !use_in_zero_equality (res
))
3976 tree arg1
= gimple_call_arg (stmt
, 0);
3977 tree arg2
= gimple_call_arg (stmt
, 1);
3978 tree len
= gimple_call_arg (stmt
, 2);
3979 unsigned HOST_WIDE_INT leni
;
3981 if (tree_fits_uhwi_p (len
)
3982 && (leni
= tree_to_uhwi (len
)) <= GET_MODE_SIZE (word_mode
)
3983 && pow2p_hwi (leni
))
3985 leni
*= CHAR_TYPE_SIZE
;
3986 unsigned align1
= get_pointer_alignment (arg1
);
3987 unsigned align2
= get_pointer_alignment (arg2
);
3988 unsigned align
= MIN (align1
, align2
);
3989 scalar_int_mode mode
;
3990 if (int_mode_for_size (leni
, 1).exists (&mode
)
3991 && (align
>= leni
|| !targetm
.slow_unaligned_access (mode
, align
)))
3993 location_t loc
= gimple_location (stmt
);
3995 type
= build_nonstandard_integer_type (leni
, 1);
3996 gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type
)), leni
));
3997 tree ptrtype
= build_pointer_type_for_mode (char_type_node
,
3999 off
= build_int_cst (ptrtype
, 0);
4000 arg1
= build2_loc (loc
, MEM_REF
, type
, arg1
, off
);
4001 arg2
= build2_loc (loc
, MEM_REF
, type
, arg2
, off
);
4002 tree tem1
= fold_const_aggregate_ref (arg1
);
4005 tree tem2
= fold_const_aggregate_ref (arg2
);
4008 res
= fold_convert_loc (loc
, TREE_TYPE (res
),
4009 fold_build2_loc (loc
, NE_EXPR
,
4012 gimplify_and_update_call_from_tree (&m_gsi
, res
);
4017 gimple_call_set_fndecl (stmt
, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ
));
4021 /* Given strinfo IDX for ARG, sets LENRNG[] to the range of lengths
4022 of the string(s) referenced by ARG if it can be determined.
4023 If the length cannot be determined, sets *SIZE to the size of
4024 the array the string is stored in, if any. If no such array is
4025 known, sets *SIZE to -1. When the strings are nul-terminated sets
4026 *NULTERM to true, otherwise to false. When nonnull uses RVALS to
4027 determine range information. Returns true on success. */
4030 strlen_pass::get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
4031 unsigned HOST_WIDE_INT lenrng
[2],
4032 unsigned HOST_WIDE_INT
*size
, bool *nulterm
)
4035 *size
= HOST_WIDE_INT_M1U
;
4039 /* IDX is the inverted constant string length. */
4041 lenrng
[1] = lenrng
[0];
4046 /* Set so that both LEN and ~LEN are invalid lengths, i.e., maximum
4047 possible length + 1. */
4048 lenrng
[0] = lenrng
[1] = HOST_WIDE_INT_MAX
;
4050 if (strinfo
*si
= idx
? get_strinfo (idx
) : NULL
)
4052 /* FIXME: Handle all this in_range_strlen_dynamic. */
4053 if (!si
->nonzero_chars
)
4055 else if (tree_fits_uhwi_p (si
->nonzero_chars
))
4057 lenrng
[0] = tree_to_uhwi (si
->nonzero_chars
);
4058 *nulterm
= si
->full_string_p
;
4059 /* Set the upper bound only if the string is known to be
4060 nul-terminated, otherwise leave it at maximum + 1. */
4062 lenrng
[1] = lenrng
[0];
4064 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4067 if (get_range_query (cfun
)->range_of_expr (r
, si
->nonzero_chars
)
4068 && !r
.undefined_p ()
4071 lenrng
[0] = r
.lower_bound ().to_uhwi ();
4072 lenrng
[1] = r
.upper_bound ().to_uhwi ();
4073 *nulterm
= si
->full_string_p
;
4078 if (lenrng
[0] != HOST_WIDE_INT_MAX
)
4081 /* Compute the minimum and maximum real or possible lengths. */
4082 c_strlen_data lendata
= { };
4083 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
4084 to have it set to the length of the longest string in a PHI. */
4085 lendata
.maxbound
= arg
;
4086 get_range_strlen_dynamic (arg
, stmt
, &lendata
, ptr_qry
);
4088 unsigned HOST_WIDE_INT maxbound
= HOST_WIDE_INT_M1U
;
4089 if (tree_fits_uhwi_p (lendata
.maxbound
)
4090 && !integer_all_onesp (lendata
.maxbound
))
4091 maxbound
= tree_to_uhwi (lendata
.maxbound
);
4093 if (tree_fits_uhwi_p (lendata
.minlen
) && tree_fits_uhwi_p (lendata
.maxlen
))
4095 unsigned HOST_WIDE_INT minlen
= tree_to_uhwi (lendata
.minlen
);
4096 unsigned HOST_WIDE_INT maxlen
= tree_to_uhwi (lendata
.maxlen
);
4098 /* The longest string in this data model. */
4099 const unsigned HOST_WIDE_INT lenmax
4100 = tree_to_uhwi (max_object_size ()) - 2;
4102 if (maxbound
== HOST_WIDE_INT_M1U
)
4106 *nulterm
= minlen
== maxlen
;
4108 else if (maxlen
< lenmax
)
4110 *size
= maxbound
+ 1;
4119 if (maxbound
!= HOST_WIDE_INT_M1U
4121 && !integer_all_onesp (lendata
.maxlen
))
4123 /* Set *SIZE to LENDATA.MAXBOUND which is a conservative estimate
4124 of the longest string based on the sizes of the arrays referenced
4126 *size
= maxbound
+ 1;
4134 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
4135 the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
4136 for a sufficiently large BOUND). If the result is based on the length
4137 of one string being greater than the longest string that would fit in
4138 the array pointer to by the argument, set *PLEN and *PSIZE to
4139 the corresponding length (or its complement when the string is known
4140 to be at least as long and need not be nul-terminated) and size.
4141 Otherwise return null. */
4144 strlen_pass::strxcmp_eqz_result (gimple
*stmt
, tree arg1
, int idx1
,
4145 tree arg2
, int idx2
,
4146 unsigned HOST_WIDE_INT bound
,
4147 unsigned HOST_WIDE_INT len
[2],
4148 unsigned HOST_WIDE_INT
*psize
)
4150 /* Determine the range the length of each string is in and whether it's
4151 known to be nul-terminated, or the size of the array it's stored in. */
4153 unsigned HOST_WIDE_INT siz1
, siz2
;
4154 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4155 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &siz1
, &nul1
)
4156 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &siz2
, &nul2
))
4159 /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
4160 to HWI_MAX when invalid. Adjust the length of each string to consider
4161 to be no more than BOUND. */
4162 if (len1rng
[0] < HOST_WIDE_INT_MAX
&& len1rng
[0] > bound
)
4164 if (len1rng
[1] < HOST_WIDE_INT_MAX
&& len1rng
[1] > bound
)
4166 if (len2rng
[0] < HOST_WIDE_INT_MAX
&& len2rng
[0] > bound
)
4168 if (len2rng
[1] < HOST_WIDE_INT_MAX
&& len2rng
[1] > bound
)
4171 /* Two empty strings are equal. */
4172 if (len1rng
[1] == 0 && len2rng
[1] == 0)
4173 return integer_one_node
;
4175 /* The strings are definitely unequal when the lower bound of the length
4176 of one of them is greater than the length of the longest string that
4177 would fit into the other array. */
4178 if (len1rng
[0] == HOST_WIDE_INT_MAX
4179 && len2rng
[0] != HOST_WIDE_INT_MAX
4180 && ((len2rng
[0] < bound
&& len2rng
[0] >= siz1
)
4181 || len2rng
[0] > siz1
))
4184 len
[0] = len1rng
[0];
4185 /* Set LEN[0] to the lower bound of ARG1's length when it's
4186 nul-terminated or to the complement of its minimum length
4188 len
[1] = nul2
? len2rng
[0] : ~len2rng
[0];
4189 return integer_zero_node
;
4192 if (len2rng
[0] == HOST_WIDE_INT_MAX
4193 && len1rng
[0] != HOST_WIDE_INT_MAX
4194 && ((len1rng
[0] < bound
&& len1rng
[0] >= siz2
)
4195 || len1rng
[0] > siz2
))
4198 len
[0] = nul1
? len1rng
[0] : ~len1rng
[0];
4199 len
[1] = len2rng
[0];
4200 return integer_zero_node
;
4203 /* The strings are also definitely unequal when their lengths are unequal
4204 and at least one is nul-terminated. */
4205 if (len1rng
[0] != HOST_WIDE_INT_MAX
4206 && len2rng
[0] != HOST_WIDE_INT_MAX
4207 && ((len1rng
[1] < len2rng
[0] && nul1
)
4208 || (len2rng
[1] < len1rng
[0] && nul2
)))
4210 if (bound
<= len1rng
[0] || bound
<= len2rng
[0])
4213 *psize
= HOST_WIDE_INT_M1U
;
4215 len
[0] = len1rng
[0];
4216 len
[1] = len2rng
[0];
4217 return integer_zero_node
;
4220 /* The string lengths may be equal or unequal. Even when equal and
4221 both strings nul-terminated, without the string contents there's
4222 no way to determine whether they are equal. */
4226 /* Diagnose pointless calls to strcmp or strncmp STMT with string
4227 arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
4228 whose result is used in equality expressions that evaluate to
4229 a constant due to one argument being longer than the size of
4233 maybe_warn_pointless_strcmp (gimple
*stmt
, HOST_WIDE_INT bound
,
4234 unsigned HOST_WIDE_INT len
[2],
4235 unsigned HOST_WIDE_INT siz
)
4237 tree lhs
= gimple_call_lhs (stmt
);
4238 gimple
*use
= use_in_zero_equality (lhs
, /* exclusive = */ false);
4242 bool at_least
= false;
4244 /* Excessive LEN[i] indicates a lower bound. */
4245 if (len
[0] > HOST_WIDE_INT_MAX
)
4251 if (len
[1] > HOST_WIDE_INT_MAX
)
4257 unsigned HOST_WIDE_INT minlen
= MIN (len
[0], len
[1]);
4259 /* FIXME: Include a note pointing to the declaration of the smaller
4261 location_t stmt_loc
= gimple_or_expr_nonartificial_location (stmt
, lhs
);
4263 tree callee
= gimple_call_fndecl (stmt
);
4264 bool warned
= false;
4265 if (siz
<= minlen
&& bound
== -1)
4266 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4268 ? G_("%qD of a string of length %wu or more and "
4269 "an array of size %wu evaluates to nonzero")
4270 : G_("%qD of a string of length %wu and an array "
4271 "of size %wu evaluates to nonzero")),
4272 callee
, minlen
, siz
);
4273 else if (!at_least
&& siz
<= HOST_WIDE_INT_MAX
)
4275 if (len
[0] != HOST_WIDE_INT_MAX
&& len
[1] != HOST_WIDE_INT_MAX
)
4276 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4277 "%qD of strings of length %wu and %wu "
4278 "and bound of %wu evaluates to nonzero",
4279 callee
, len
[0], len
[1], bound
);
4281 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4282 "%qD of a string of length %wu, an array "
4283 "of size %wu and bound of %wu evaluates to "
4285 callee
, minlen
, siz
, bound
);
4291 location_t use_loc
= gimple_location (use
);
4292 if (LOCATION_LINE (stmt_loc
) != LOCATION_LINE (use_loc
))
4293 inform (use_loc
, "in this expression");
4297 /* Optimize a call to strcmp or strncmp either by folding it to a constant
4298 when possible or by transforming the latter to the former. Warn about
4299 calls where the length of one argument is greater than the size of
4300 the array to which the other argument points if the latter's length
4301 is not known. Return true when the call has been transformed into
4302 another and false otherwise. */
4305 strlen_pass::handle_builtin_string_cmp ()
4307 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (m_gsi
));
4308 tree lhs
= gimple_call_lhs (stmt
);
4313 tree arg1
= gimple_call_arg (stmt
, 0);
4314 tree arg2
= gimple_call_arg (stmt
, 1);
4315 int idx1
= get_stridx (arg1
, stmt
);
4316 int idx2
= get_stridx (arg2
, stmt
);
4318 /* For strncmp set to the value of the third argument if known. */
4319 HOST_WIDE_INT bound
= -1;
4320 tree len
= NULL_TREE
;
4321 /* Extract the strncmp bound. */
4322 if (gimple_call_num_args (stmt
) == 3)
4324 len
= gimple_call_arg (stmt
, 2);
4325 if (tree_fits_shwi_p (len
))
4326 bound
= tree_to_shwi (len
);
4328 /* If the bound argument is NOT known, do nothing. */
4333 /* Avoid folding if either argument is not a nul-terminated array.
4334 Defer warning until later. */
4335 if (!check_nul_terminated_array (NULL_TREE
, arg1
, len
)
4336 || !check_nul_terminated_array (NULL_TREE
, arg2
, len
))
4340 /* Set to the length of one argument (or its complement if it's
4341 the lower bound of a range) and the size of the array storing
4342 the other if the result is based on the former being equal to
4343 or greater than the latter. */
4344 unsigned HOST_WIDE_INT len
[2] = { HOST_WIDE_INT_MAX
, HOST_WIDE_INT_MAX
};
4345 unsigned HOST_WIDE_INT siz
= HOST_WIDE_INT_M1U
;
4347 /* Try to determine if the two strings are either definitely equal
4348 or definitely unequal and if so, either fold the result to zero
4349 (when equal) or set the range of the result to ~[0, 0] otherwise. */
4350 if (tree eqz
= strxcmp_eqz_result (stmt
, arg1
, idx1
, arg2
, idx2
, bound
,
4353 if (integer_zerop (eqz
))
4355 maybe_warn_pointless_strcmp (stmt
, bound
, len
, siz
);
4357 /* When the lengths of the first two string arguments are
4358 known to be unequal set the range of the result to non-zero.
4359 This allows the call to be eliminated if its result is only
4360 used in tests for equality to zero. */
4362 nz
.set_nonzero (TREE_TYPE (lhs
));
4363 set_range_info (lhs
, nz
);
4366 /* When the two strings are definitely equal (such as when they
4367 are both empty) fold the call to the constant result. */
4368 replace_call_with_value (&m_gsi
, integer_zero_node
);
4373 /* Return if nothing is known about the strings pointed to by ARG1
4375 if (idx1
== 0 && idx2
== 0)
4378 /* Determine either the length or the size of each of the strings,
4379 whichever is available. */
4380 HOST_WIDE_INT cstlen1
= -1, cstlen2
= -1;
4381 HOST_WIDE_INT arysiz1
= -1, arysiz2
= -1;
4384 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4385 unsigned HOST_WIDE_INT arsz1
, arsz2
;
4388 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &arsz1
, nulterm
)
4389 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &arsz2
, nulterm
+ 1))
4392 if (len1rng
[0] == len1rng
[1] && len1rng
[0] < HOST_WIDE_INT_MAX
)
4393 cstlen1
= len1rng
[0];
4394 else if (arsz1
< HOST_WIDE_INT_M1U
)
4397 if (len2rng
[0] == len2rng
[1] && len2rng
[0] < HOST_WIDE_INT_MAX
)
4398 cstlen2
= len2rng
[0];
4399 else if (arsz2
< HOST_WIDE_INT_M1U
)
4403 /* Bail if neither the string length nor the size of the array
4404 it is stored in can be determined. */
4405 if ((cstlen1
< 0 && arysiz1
< 0)
4406 || (cstlen2
< 0 && arysiz2
< 0)
4407 || (cstlen1
< 0 && cstlen2
< 0))
4415 /* The exact number of characters to compare. */
4416 HOST_WIDE_INT cmpsiz
;
4417 if (cstlen1
>= 0 && cstlen2
>= 0)
4418 cmpsiz
= MIN (cstlen1
, cstlen2
);
4419 else if (cstlen1
>= 0)
4424 cmpsiz
= MIN (cmpsiz
, bound
);
4425 /* The size of the array in which the unknown string is stored. */
4426 HOST_WIDE_INT varsiz
= arysiz1
< 0 ? arysiz2
: arysiz1
;
4428 if ((varsiz
< 0 || cmpsiz
< varsiz
) && use_in_zero_equality (lhs
))
4430 /* If the known length is less than the size of the other array
4431 and the strcmp result is only used to test equality to zero,
4432 transform the call to the equivalent _eq call. */
4433 if (tree fn
= builtin_decl_implicit (bound
< 0 ? BUILT_IN_STRCMP_EQ
4434 : BUILT_IN_STRNCMP_EQ
))
4436 tree n
= build_int_cst (size_type_node
, cmpsiz
);
4437 update_gimple_call (&m_gsi
, fn
, 3, arg1
, arg2
, n
);
4445 /* Handle a POINTER_PLUS_EXPR statement.
4446 For p = "abcd" + 2; compute associated length, or if
4447 p = q + off is pointing to a '\0' character of a string, call
4448 zero_length_string on it. */
4451 strlen_pass::handle_pointer_plus ()
4453 gimple
*stmt
= gsi_stmt (m_gsi
);
4454 tree lhs
= gimple_assign_lhs (stmt
), off
;
4455 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
4463 tree off
= gimple_assign_rhs2 (stmt
);
4464 if (tree_fits_uhwi_p (off
)
4465 && tree_to_uhwi (off
) <= (unsigned HOST_WIDE_INT
) ~idx
)
4466 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)]
4467 = ~(~idx
- (int) tree_to_uhwi (off
));
4471 si
= get_strinfo (idx
);
4472 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
4475 off
= gimple_assign_rhs2 (stmt
);
4477 if (si
->full_string_p
&& operand_equal_p (si
->nonzero_chars
, off
, 0))
4478 zsi
= zero_length_string (lhs
, si
);
4479 else if (TREE_CODE (off
) == SSA_NAME
)
4481 gimple
*def_stmt
= SSA_NAME_DEF_STMT (off
);
4482 if (gimple_assign_single_p (def_stmt
)
4483 && si
->full_string_p
4484 && operand_equal_p (si
->nonzero_chars
,
4485 gimple_assign_rhs1 (def_stmt
), 0))
4486 zsi
= zero_length_string (lhs
, si
);
4489 && si
->endptr
!= NULL_TREE
4490 && si
->endptr
!= lhs
4491 && TREE_CODE (si
->endptr
) == SSA_NAME
)
4493 enum tree_code rhs_code
4494 = useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (si
->endptr
))
4495 ? SSA_NAME
: NOP_EXPR
;
4496 gimple_assign_set_rhs_with_ops (&m_gsi
, rhs_code
, si
->endptr
);
4497 gcc_assert (gsi_stmt (m_gsi
) == stmt
);
4502 /* Set LENRANGE to the number of nonzero bytes for a store of TYPE and
4503 clear all flags. Return true on success and false on failure. */
4506 nonzero_bytes_for_type (tree type
, unsigned lenrange
[3],
4507 bool *nulterm
, bool *allnul
, bool *allnonnul
)
4509 /* Use the size of the type of the expression as the size of the store,
4510 and set the upper bound of the length range to that of the size.
4511 Nothing is known about the contents so clear all flags. */
4512 tree typesize
= TYPE_SIZE_UNIT (type
);
4516 if (!tree_fits_uhwi_p (typesize
))
4519 unsigned HOST_WIDE_INT sz
= tree_to_uhwi (typesize
);
4524 lenrange
[1] = lenrange
[2] ? lenrange
[2] - 1 : 0;
4532 /* Recursively determine the minimum and maximum number of leading nonzero
4533 bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
4535 Sets LENRANGE[2] to the total size of the access (which may be less
4536 than LENRANGE[1] when what's being referenced by EXP is a pointer
4537 rather than an array).
4538 Sets *NULTERM if the representation contains a zero byte, sets *ALLNUL
4539 if all the bytes are zero, and *ALLNONNUL is all are nonzero.
4540 OFFSET and NBYTES are the offset into the representation and
4541 the size of the access to it determined from an ADDR_EXPR (i.e.,
4542 a pointer) or MEM_REF or zero for other expressions.
4543 Uses RVALS to determine range information.
4544 Avoids recursing deeper than the limits in SNLIM allow.
4545 Returns true on success and false otherwise. */
4548 strlen_pass::count_nonzero_bytes (tree exp
, gimple
*stmt
,
4549 unsigned HOST_WIDE_INT offset
,
4550 unsigned HOST_WIDE_INT nbytes
,
4551 unsigned lenrange
[3], bool *nulterm
,
4552 bool *allnul
, bool *allnonnul
,
4553 ssa_name_limit_t
&snlim
)
4555 if (TREE_CODE (exp
) == SSA_NAME
)
4557 /* Handle non-zero single-character stores specially. */
4558 tree type
= TREE_TYPE (exp
);
4559 if (TREE_CODE (type
) == INTEGER_TYPE
4560 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
4561 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
)
4562 && tree_expr_nonzero_p (exp
))
4564 /* If the character EXP is known to be non-zero (even if its
4565 exact value is not known) recurse once to set the range
4566 for an arbitrary constant. */
4567 exp
= build_int_cst (type
, 1);
4568 return count_nonzero_bytes (exp
, stmt
,
4569 offset
, 1, lenrange
,
4570 nulterm
, allnul
, allnonnul
, snlim
);
4573 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4574 if (gimple_assign_single_p (stmt
))
4576 exp
= gimple_assign_rhs1 (stmt
);
4578 && TREE_CODE (exp
) != CONSTRUCTOR
4579 && TREE_CODE (exp
) != MEM_REF
)
4581 /* Handle DECLs, CONSTRUCTOR and MEM_REF below. */
4583 else if (gimple_code (stmt
) == GIMPLE_PHI
)
4585 /* Avoid processing an SSA_NAME that has already been visited
4586 or if an SSA_NAME limit has been reached. Indicate success
4587 if the former and failure if the latter. */
4588 if (int res
= snlim
.next_phi (exp
))
4591 /* Determine the minimum and maximum from the PHI arguments. */
4592 unsigned int n
= gimple_phi_num_args (stmt
);
4593 for (unsigned i
= 0; i
!= n
; i
++)
4595 tree def
= gimple_phi_arg_def (stmt
, i
);
4596 if (!count_nonzero_bytes (def
, stmt
,
4597 offset
, nbytes
, lenrange
, nulterm
,
4598 allnul
, allnonnul
, snlim
))
4606 if (TREE_CODE (exp
) == CONSTRUCTOR
)
4609 /* If NBYTES has already been determined by an outer MEM_REF
4610 fail rather than overwriting it (this shouldn't happen). */
4613 tree type
= TREE_TYPE (exp
);
4614 tree size
= TYPE_SIZE_UNIT (type
);
4615 if (!size
|| !tree_fits_uhwi_p (size
))
4618 unsigned HOST_WIDE_INT byte_size
= tree_to_uhwi (size
);
4619 if (byte_size
< offset
)
4622 nbytes
= byte_size
- offset
;
4625 if (TREE_CODE (exp
) == MEM_REF
)
4630 tree arg
= TREE_OPERAND (exp
, 0);
4631 tree off
= TREE_OPERAND (exp
, 1);
4633 if (TREE_CODE (off
) != INTEGER_CST
|| !tree_fits_uhwi_p (off
))
4636 unsigned HOST_WIDE_INT wioff
= tree_to_uhwi (off
);
4637 if (INT_MAX
< wioff
)
4641 if (INT_MAX
< offset
)
4644 /* The size of the MEM_REF access determines the number of bytes. */
4645 tree type
= TREE_TYPE (exp
);
4646 tree typesize
= TYPE_SIZE_UNIT (type
);
4647 if (!typesize
|| !tree_fits_uhwi_p (typesize
))
4649 nbytes
= tree_to_uhwi (typesize
);
4653 /* Handle MEM_REF = SSA_NAME types of assignments. */
4654 return count_nonzero_bytes_addr (arg
, stmt
,
4655 offset
, nbytes
, lenrange
, nulterm
,
4656 allnul
, allnonnul
, snlim
);
4659 if (VAR_P (exp
) || TREE_CODE (exp
) == CONST_DECL
)
4661 /* If EXP can be folded into a constant use the result. Otherwise
4662 proceed to use EXP to determine a range of the result. */
4663 if (tree fold_exp
= ctor_for_folding (exp
))
4664 if (fold_exp
!= error_mark_node
)
4668 const char *prep
= NULL
;
4669 if (TREE_CODE (exp
) == STRING_CST
)
4671 unsigned nchars
= TREE_STRING_LENGTH (exp
);
4672 if (nchars
< offset
)
4676 /* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
4677 (i.e., it's the size of a pointer), or from MEM_REF (as the size
4678 of the access), set it here to the size of the string, including
4679 all internal and trailing nuls if the string has any. */
4680 nbytes
= nchars
- offset
;
4681 else if (nchars
- offset
< nbytes
)
4684 prep
= TREE_STRING_POINTER (exp
) + offset
;
4687 unsigned char buf
[256];
4690 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8)
4692 /* If the pointer to representation hasn't been set above
4693 for STRING_CST point it at the buffer. */
4694 prep
= reinterpret_cast <char *>(buf
);
4695 /* Try to extract the representation of the constant object
4696 or expression starting from the offset. */
4697 unsigned repsize
= native_encode_expr (exp
, buf
, sizeof buf
, offset
);
4698 if (repsize
< nbytes
)
4700 /* This should only happen when REPSIZE is zero because EXP
4701 doesn't denote an object with a known initializer, except
4702 perhaps when the reference reads past its end. */
4708 else if (nbytes
< repsize
)
4713 return nonzero_bytes_for_type (TREE_TYPE (exp
), lenrange
,
4714 nulterm
, allnul
, allnonnul
);
4716 /* Compute the number of leading nonzero bytes in the representation
4717 and update the minimum and maximum. */
4718 unsigned HOST_WIDE_INT n
= prep
? strnlen (prep
, nbytes
) : nbytes
;
4720 if (n
< lenrange
[0])
4722 if (lenrange
[1] < n
)
4725 /* Set the size of the representation. */
4726 if (lenrange
[2] < nbytes
)
4727 lenrange
[2] = nbytes
;
4729 /* Clear NULTERM if none of the bytes is zero. */
4735 /* When the initial number of non-zero bytes N is non-zero, reset
4736 *ALLNUL; if N is less than that the size of the representation
4737 also clear *ALLNONNUL. */
4742 else if (*allnul
|| *allnonnul
)
4748 /* When either ALLNUL is set and N is zero, also determine
4749 whether all subsequent bytes after the first one (which
4750 is nul) are zero or nonzero and clear ALLNUL if not. */
4751 for (const char *p
= prep
; p
!= prep
+ nbytes
; ++p
)
4763 /* Like count_nonzero_bytes, but instead of counting bytes in EXP, count
4764 bytes that are pointed to by EXP, which should be a pointer. */
4767 strlen_pass::count_nonzero_bytes_addr (tree exp
, gimple
*stmt
,
4768 unsigned HOST_WIDE_INT offset
,
4769 unsigned HOST_WIDE_INT nbytes
,
4770 unsigned lenrange
[3], bool *nulterm
,
4771 bool *allnul
, bool *allnonnul
,
4772 ssa_name_limit_t
&snlim
)
4774 int idx
= get_stridx (exp
, stmt
);
4777 strinfo
*si
= get_strinfo (idx
);
4781 /* Handle both constant lengths as well non-constant lengths
4783 unsigned HOST_WIDE_INT minlen
, maxlen
;
4784 if (tree_fits_shwi_p (si
->nonzero_chars
))
4785 minlen
= maxlen
= tree_to_shwi (si
->nonzero_chars
);
4786 else if (si
->nonzero_chars
4787 && TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4790 if (!ptr_qry
.rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
)
4791 || vr
.undefined_p ()
4795 minlen
= vr
.lower_bound ().to_uhwi ();
4796 maxlen
= vr
.upper_bound ().to_uhwi ();
4801 if (maxlen
< offset
)
4804 minlen
= minlen
< offset
? 0 : minlen
- offset
;
4806 if (maxlen
+ 1 < nbytes
)
4809 if (nbytes
<= minlen
)
4812 if (nbytes
< minlen
)
4815 if (nbytes
< maxlen
)
4819 if (minlen
< lenrange
[0])
4820 lenrange
[0] = minlen
;
4821 if (lenrange
[1] < maxlen
)
4822 lenrange
[1] = maxlen
;
4824 if (lenrange
[2] < nbytes
)
4825 lenrange
[2] = nbytes
;
4827 /* Since only the length of the string are known and not its contents,
4828 clear ALLNUL and ALLNONNUL purely on the basis of the length. */
4830 if (minlen
< nbytes
)
4836 if (TREE_CODE (exp
) == ADDR_EXPR
)
4837 return count_nonzero_bytes (TREE_OPERAND (exp
, 0), stmt
,
4839 lenrange
, nulterm
, allnul
, allnonnul
, snlim
);
4841 if (TREE_CODE (exp
) == SSA_NAME
)
4843 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4844 if (gimple_code (stmt
) == GIMPLE_PHI
)
4846 /* Avoid processing an SSA_NAME that has already been visited
4847 or if an SSA_NAME limit has been reached. Indicate success
4848 if the former and failure if the latter. */
4849 if (int res
= snlim
.next_phi (exp
))
4852 /* Determine the minimum and maximum from the PHI arguments. */
4853 unsigned int n
= gimple_phi_num_args (stmt
);
4854 for (unsigned i
= 0; i
!= n
; i
++)
4856 tree def
= gimple_phi_arg_def (stmt
, i
);
4857 if (!count_nonzero_bytes_addr (def
, stmt
,
4858 offset
, nbytes
, lenrange
,
4859 nulterm
, allnul
, allnonnul
,
4868 /* Otherwise we don't know anything. */
4870 if (lenrange
[1] < nbytes
)
4871 lenrange
[1] = nbytes
;
4872 if (lenrange
[2] < nbytes
)
4873 lenrange
[2] = nbytes
;
4880 /* Same as above except with an implicit SSA_NAME limit. When EXPR_OR_TYPE
4881 is a type rather than an expression use its size to compute the range.
4882 RVALS is used to determine ranges of dynamically computed string lengths
4883 (the results of strlen). */
4886 strlen_pass::count_nonzero_bytes (tree expr_or_type
, gimple
*stmt
,
4887 unsigned lenrange
[3], bool *nulterm
,
4888 bool *allnul
, bool *allnonnul
)
4890 if (TYPE_P (expr_or_type
))
4891 return nonzero_bytes_for_type (expr_or_type
, lenrange
,
4892 nulterm
, allnul
, allnonnul
);
4894 /* Set to optimistic values so the caller doesn't have to worry about
4895 initializing these and to what. On success, the function will clear
4896 these if it determines their values are different but being recursive
4897 it never sets either to true. On failure, their values are
4903 ssa_name_limit_t snlim
;
4904 tree expr
= expr_or_type
;
4905 return count_nonzero_bytes (expr
, stmt
,
4906 0, 0, lenrange
, nulterm
, allnul
, allnonnul
,
4910 /* Handle a single or multibyte store other than by a built-in function,
4911 either via a single character assignment or by multi-byte assignment
4912 either via MEM_REF or via a type other than char (such as in
4913 '*(int*)a = 12345'). Return true to let the caller advance *GSI to
4914 the next statement in the basic block and false otherwise. */
4917 strlen_pass::handle_store (bool *zero_write
)
4919 gimple
*stmt
= gsi_stmt (m_gsi
);
4920 /* The LHS and RHS of the store. The RHS is null if STMT is a function
4921 call. STORETYPE is the type of the store (determined from either
4922 the RHS of the assignment statement or the LHS of a function call. */
4923 tree lhs
, rhs
, storetype
;
4924 if (is_gimple_assign (stmt
))
4926 lhs
= gimple_assign_lhs (stmt
);
4927 rhs
= gimple_assign_rhs1 (stmt
);
4928 storetype
= TREE_TYPE (rhs
);
4930 else if (is_gimple_call (stmt
))
4932 lhs
= gimple_call_lhs (stmt
);
4934 storetype
= TREE_TYPE (lhs
);
4939 tree ssaname
= NULL_TREE
;
4943 range_query
*const rvals
= ptr_qry
.rvals
;
4945 /* The offset of the first byte in LHS modified by the store. */
4946 unsigned HOST_WIDE_INT offset
= 0;
4948 if (TREE_CODE (lhs
) == MEM_REF
4949 && TREE_CODE (TREE_OPERAND (lhs
, 0)) == SSA_NAME
)
4951 tree mem_offset
= TREE_OPERAND (lhs
, 1);
4952 if (tree_fits_uhwi_p (mem_offset
))
4954 /* Get the strinfo for the base, and use it if it starts with at
4955 least OFFSET nonzero characters. This is trivially true if
4957 offset
= tree_to_uhwi (mem_offset
);
4958 idx
= get_stridx (TREE_OPERAND (lhs
, 0), stmt
);
4960 si
= get_strinfo (idx
);
4962 ssaname
= TREE_OPERAND (lhs
, 0);
4964 || compare_nonzero_chars (si
, stmt
, offset
, rvals
) < 0)
4966 *zero_write
= rhs
? initializer_zerop (rhs
) : false;
4969 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4970 if (count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
, lenrange
,
4971 &dummy
, &dummy
, &dummy
))
4972 maybe_warn_overflow (stmt
, true, lenrange
[2]);
4980 idx
= get_addr_stridx (lhs
, stmt
, NULL_TREE
, &offset
, rvals
);
4982 si
= get_strinfo (idx
);
4985 /* Minimum and maximum leading non-zero bytes and the size of the store. */
4986 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4988 /* Set to the minimum length of the string being assigned if known. */
4989 unsigned HOST_WIDE_INT rhs_minlen
;
4991 /* STORING_NONZERO_P is true iff not all stored characters are zero.
4992 STORING_ALL_NONZERO_P is true if all stored characters are zero.
4993 STORING_ALL_ZEROS_P is true iff all stored characters are zero.
4994 Both are false when it's impossible to determine which is true. */
4995 bool storing_nonzero_p
;
4996 bool storing_all_nonzero_p
;
4997 bool storing_all_zeros_p
;
4998 /* FULL_STRING_P is set when the stored sequence of characters form
4999 a nul-terminated string. */
5002 const bool ranges_valid
5003 = count_nonzero_bytes (rhs
? rhs
: storetype
, stmt
,
5004 lenrange
, &full_string_p
,
5005 &storing_all_zeros_p
, &storing_all_nonzero_p
);
5009 rhs_minlen
= lenrange
[0];
5010 storing_nonzero_p
= lenrange
[1] > 0;
5011 *zero_write
= storing_all_zeros_p
;
5013 maybe_warn_overflow (stmt
, true, lenrange
[2]);
5017 rhs_minlen
= HOST_WIDE_INT_M1U
;
5018 full_string_p
= false;
5019 storing_nonzero_p
= false;
5020 storing_all_zeros_p
= false;
5021 storing_all_nonzero_p
= false;
5026 /* The corresponding element is set to 1 if the first and last
5027 element, respectively, of the sequence of characters being
5028 written over the string described by SI ends before
5029 the terminating nul (if it has one), to zero if the nul is
5030 being overwritten but not beyond, or negative otherwise. */
5031 int store_before_nul
[2];
5034 /* The offset of the last stored byte. */
5035 unsigned HOST_WIDE_INT endoff
= offset
+ lenrange
[2] - 1;
5037 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
5038 if (endoff
== offset
)
5039 store_before_nul
[1] = store_before_nul
[0];
5042 = compare_nonzero_chars (si
, stmt
, endoff
, rvals
);
5047 = compare_nonzero_chars (si
, stmt
, offset
, rvals
);
5048 store_before_nul
[1] = store_before_nul
[0];
5049 gcc_assert (offset
== 0 || store_before_nul
[0] >= 0);
5052 if (storing_all_zeros_p
5053 && store_before_nul
[0] == 0
5054 && store_before_nul
[1] == 0
5055 && si
->full_string_p
)
5057 /* When overwriting a '\0' with a '\0', the store can be removed
5058 if we know it has been stored in the current function. */
5059 if (!stmt_could_throw_p (cfun
, stmt
) && si
->writable
)
5061 unlink_stmt_vdef (stmt
);
5062 release_defs (stmt
);
5063 gsi_remove (&m_gsi
, true);
5068 si
->writable
= true;
5074 if (store_before_nul
[1] > 0
5075 && storing_nonzero_p
5076 && lenrange
[0] == lenrange
[1]
5077 && lenrange
[0] == lenrange
[2]
5078 && TREE_CODE (storetype
) == INTEGER_TYPE
)
5080 /* Handle a store of one or more non-nul characters that ends
5081 before the terminating nul of the destination and so does
5082 not affect its length
5083 If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
5084 and if we aren't storing '\0', we know that the length of
5085 the string and any other zero terminated string in memory
5086 remains the same. In that case we move to the next gimple
5087 statement and return to signal the caller that it shouldn't
5088 invalidate anything.
5090 This is beneficial for cases like:
5095 strcpy (p, "foobar");
5096 size_t len = strlen (p); // can be folded to 6
5097 size_t len2 = strlen (q); // has to be computed
5099 size_t len3 = strlen (p); // can be folded to 6
5100 size_t len4 = strlen (q); // can be folded to len2
5101 bar (len, len2, len3, len4);
5107 if (storing_nonzero_p
5108 || storing_all_zeros_p
5109 || (full_string_p
&& lenrange
[1] == 0)
5110 || (offset
!= 0 && store_before_nul
[1] > 0))
5112 /* When STORING_NONZERO_P, we know that the string will start
5113 with at least OFFSET + 1 nonzero characters. If storing
5114 a single character, set si->NONZERO_CHARS to the result.
5115 If storing multiple characters, try to determine the number
5116 of leading non-zero characters and set si->NONZERO_CHARS to
5119 When STORING_ALL_ZEROS_P, or the first byte written is zero,
5120 i.e. FULL_STRING_P && LENRANGE[1] == 0, we know that the
5121 string is now OFFSET characters long.
5123 Otherwise, we're storing an unknown value at offset OFFSET,
5124 so need to clip the nonzero_chars to OFFSET.
5125 Use the minimum length of the string (or individual character)
5126 being stored if it's known. Otherwise, STORING_NONZERO_P
5127 guarantees it's at least 1. */
5129 = storing_nonzero_p
&& ranges_valid
? lenrange
[0] : 1;
5130 location_t loc
= gimple_location (stmt
);
5131 tree oldlen
= si
->nonzero_chars
;
5132 if (store_before_nul
[1] == 0 && si
->full_string_p
)
5133 /* We're overwriting the nul terminator with a nonzero or
5134 unknown character. If the previous stmt was a memcpy,
5135 its length may be decreased. */
5136 adjust_last_stmt (si
, stmt
, false);
5137 si
= unshare_strinfo (si
);
5138 if (storing_nonzero_p
)
5140 gcc_assert (len
>= 0);
5141 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
+ len
);
5144 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
);
5146 /* Set FULL_STRING_P only if the length of the strings being
5147 written is the same, and clear it if the strings have
5148 different lengths. In the latter case the length stored
5149 in si->NONZERO_CHARS becomes the lower bound.
5150 FIXME: Handle the upper bound of the length if possible. */
5151 si
->full_string_p
= full_string_p
&& lenrange
[0] == lenrange
[1];
5153 if (storing_all_zeros_p
5155 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5156 si
->endptr
= ssaname
;
5161 si
->writable
= true;
5162 si
->dont_invalidate
= true;
5165 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
5166 si
->nonzero_chars
, oldlen
);
5167 adjust_related_strinfos (loc
, si
, adj
);
5173 else if (idx
== 0 && (storing_all_zeros_p
|| storing_nonzero_p
))
5176 idx
= new_stridx (ssaname
);
5178 idx
= new_addr_stridx (lhs
);
5181 tree ptr
= (ssaname
? ssaname
: build_fold_addr_expr (lhs
));
5184 if (storing_all_zeros_p
)
5186 else if (storing_nonzero_p
&& ranges_valid
)
5188 /* FIXME: Handle the upper bound of the length when
5189 LENRANGE[0] != LENRANGE[1]. */
5191 if (lenrange
[0] != lenrange
[1])
5192 /* Set the minimum length but ignore the maximum
5194 full_string_p
= false;
5199 tree len
= (slen
<= 0
5201 : build_int_cst (size_type_node
, slen
));
5202 si
= new_strinfo (ptr
, idx
, len
, slen
>= 0 && full_string_p
);
5203 set_strinfo (idx
, si
);
5204 if (storing_all_zeros_p
5206 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5207 si
->endptr
= ssaname
;
5208 si
->dont_invalidate
= true;
5209 si
->writable
= true;
5213 && rhs_minlen
< HOST_WIDE_INT_M1U
5214 && ssaname
== NULL_TREE
5215 && TREE_CODE (TREE_TYPE (lhs
)) == ARRAY_TYPE
)
5217 HOST_WIDE_INT a
= int_size_in_bytes (TREE_TYPE (lhs
));
5218 if (a
> 0 && (unsigned HOST_WIDE_INT
) a
> rhs_minlen
)
5220 int idx
= new_addr_stridx (lhs
);
5223 si
= new_strinfo (build_fold_addr_expr (lhs
), idx
,
5224 build_int_cst (size_type_node
, rhs_minlen
),
5226 set_strinfo (idx
, si
);
5227 si
->dont_invalidate
= true;
5232 if (si
!= NULL
&& offset
== 0 && storing_all_zeros_p
&& lenrange
[2] == 1)
5234 /* For single-byte stores only, allow adjust_last_stmt to remove
5235 the statement if the stored '\0' is immediately overwritten. */
5236 laststmt
.stmt
= stmt
;
5237 laststmt
.len
= build_int_cst (size_type_node
, 1);
5238 laststmt
.stridx
= si
->idx
;
5243 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0. */
5246 fold_strstr_to_strncmp (tree rhs1
, tree rhs2
, gimple
*stmt
)
5248 if (TREE_CODE (rhs1
) != SSA_NAME
5249 || TREE_CODE (rhs2
) != SSA_NAME
)
5252 gimple
*call_stmt
= NULL
;
5253 for (int pass
= 0; pass
< 2; pass
++)
5255 gimple
*g
= SSA_NAME_DEF_STMT (rhs1
);
5256 if (gimple_call_builtin_p (g
, BUILT_IN_STRSTR
)
5257 && has_single_use (rhs1
)
5258 && gimple_call_arg (g
, 0) == rhs2
)
5263 std::swap (rhs1
, rhs2
);
5268 tree arg0
= gimple_call_arg (call_stmt
, 0);
5272 tree arg1
= gimple_call_arg (call_stmt
, 1);
5273 tree arg1_len
= NULL_TREE
;
5274 int idx
= get_stridx (arg1
, call_stmt
);
5279 arg1_len
= build_int_cst (size_type_node
, ~idx
);
5282 strinfo
*si
= get_strinfo (idx
);
5284 arg1_len
= get_string_length (si
);
5288 if (arg1_len
!= NULL_TREE
)
5290 gimple_stmt_iterator gsi
= gsi_for_stmt (call_stmt
);
5291 tree strncmp_decl
= builtin_decl_explicit (BUILT_IN_STRNCMP
);
5293 if (!is_gimple_val (arg1_len
))
5295 tree arg1_len_tmp
= make_ssa_name (TREE_TYPE (arg1_len
));
5296 gassign
*arg1_stmt
= gimple_build_assign (arg1_len_tmp
,
5298 gsi_insert_before (&gsi
, arg1_stmt
, GSI_SAME_STMT
);
5299 arg1_len
= arg1_len_tmp
;
5302 gcall
*strncmp_call
= gimple_build_call (strncmp_decl
, 3,
5303 arg0
, arg1
, arg1_len
);
5304 tree strncmp_lhs
= make_ssa_name (integer_type_node
);
5305 gimple_set_vuse (strncmp_call
, gimple_vuse (call_stmt
));
5306 gimple_call_set_lhs (strncmp_call
, strncmp_lhs
);
5307 gsi_remove (&gsi
, true);
5308 gsi_insert_before (&gsi
, strncmp_call
, GSI_SAME_STMT
);
5309 tree zero
= build_zero_cst (TREE_TYPE (strncmp_lhs
));
5311 if (is_gimple_assign (stmt
))
5313 if (gimple_assign_rhs_code (stmt
) == COND_EXPR
)
5315 tree cond
= gimple_assign_rhs1 (stmt
);
5316 TREE_OPERAND (cond
, 0) = strncmp_lhs
;
5317 TREE_OPERAND (cond
, 1) = zero
;
5321 gimple_assign_set_rhs1 (stmt
, strncmp_lhs
);
5322 gimple_assign_set_rhs2 (stmt
, zero
);
5327 gcond
*cond
= as_a
<gcond
*> (stmt
);
5328 gimple_cond_set_lhs (cond
, strncmp_lhs
);
5329 gimple_cond_set_rhs (cond
, zero
);
5337 /* Return true if TYPE corresponds to a narrow character type. */
5340 is_char_type (tree type
)
5342 return (TREE_CODE (type
) == INTEGER_TYPE
5343 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
5344 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
));
5347 /* Check the built-in call at GSI for validity and optimize it.
5348 Uses RVALS to determine range information.
5349 Return true to let the caller advance *GSI to the next statement
5350 in the basic block and false otherwise. */
5353 strlen_pass::check_and_optimize_call (bool *zero_write
)
5355 gimple
*stmt
= gsi_stmt (m_gsi
);
5357 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
5359 tree fntype
= gimple_call_fntype (stmt
);
5363 if (lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype
)))
5365 handle_alloc_call (BUILT_IN_NONE
);
5369 if (tree lhs
= gimple_call_lhs (stmt
))
5370 handle_assign (lhs
, zero_write
);
5372 /* Proceed to handle user-defined formatting functions. */
5375 /* When not optimizing we must be checking printf calls which
5376 we do even for user-defined functions when they are declared
5377 with attribute format. */
5378 if (!flag_optimize_strlen
5380 || !valid_builtin_call (stmt
))
5381 return !handle_printf_call (&m_gsi
, ptr_qry
);
5383 tree callee
= gimple_call_fndecl (stmt
);
5384 switch (DECL_FUNCTION_CODE (callee
))
5386 case BUILT_IN_STRLEN
:
5387 case BUILT_IN_STRNLEN
:
5388 handle_builtin_strlen ();
5390 case BUILT_IN_STRCHR
:
5391 handle_builtin_strchr ();
5393 case BUILT_IN_STRCPY
:
5394 case BUILT_IN_STRCPY_CHK
:
5395 case BUILT_IN_STPCPY
:
5396 case BUILT_IN_STPCPY_CHK
:
5397 handle_builtin_strcpy (DECL_FUNCTION_CODE (callee
));
5400 case BUILT_IN_STRNCAT
:
5401 case BUILT_IN_STRNCAT_CHK
:
5402 handle_builtin_strncat (DECL_FUNCTION_CODE (callee
));
5405 case BUILT_IN_STPNCPY
:
5406 case BUILT_IN_STPNCPY_CHK
:
5407 case BUILT_IN_STRNCPY
:
5408 case BUILT_IN_STRNCPY_CHK
:
5409 handle_builtin_stxncpy_strncat (false);
5412 case BUILT_IN_MEMCPY
:
5413 case BUILT_IN_MEMCPY_CHK
:
5414 case BUILT_IN_MEMPCPY
:
5415 case BUILT_IN_MEMPCPY_CHK
:
5416 handle_builtin_memcpy (DECL_FUNCTION_CODE (callee
));
5418 case BUILT_IN_STRCAT
:
5419 case BUILT_IN_STRCAT_CHK
:
5420 handle_builtin_strcat (DECL_FUNCTION_CODE (callee
));
5422 case BUILT_IN_ALLOCA
:
5423 case BUILT_IN_ALLOCA_WITH_ALIGN
:
5424 case BUILT_IN_MALLOC
:
5425 case BUILT_IN_CALLOC
:
5426 handle_alloc_call (DECL_FUNCTION_CODE (callee
));
5428 case BUILT_IN_MEMSET
:
5429 if (handle_builtin_memset (zero_write
))
5432 case BUILT_IN_MEMCMP
:
5433 if (handle_builtin_memcmp ())
5436 case BUILT_IN_STRCMP
:
5437 case BUILT_IN_STRNCMP
:
5438 if (handle_builtin_string_cmp ())
5442 if (handle_printf_call (&m_gsi
, ptr_qry
))
5450 /* Handle an assignment statement at *GSI to a LHS of integral type.
5451 If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */
5454 strlen_pass::handle_integral_assign (bool *cleanup_eh
)
5456 gimple
*stmt
= gsi_stmt (m_gsi
);
5457 tree lhs
= gimple_assign_lhs (stmt
);
5458 tree lhs_type
= TREE_TYPE (lhs
);
5460 enum tree_code code
= gimple_assign_rhs_code (stmt
);
5461 if (code
== COND_EXPR
)
5463 tree cond
= gimple_assign_rhs1 (stmt
);
5464 enum tree_code cond_code
= TREE_CODE (cond
);
5466 if (cond_code
== EQ_EXPR
|| cond_code
== NE_EXPR
)
5467 fold_strstr_to_strncmp (TREE_OPERAND (cond
, 0),
5468 TREE_OPERAND (cond
, 1), stmt
);
5470 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5471 fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt
),
5472 gimple_assign_rhs2 (stmt
), stmt
);
5473 else if (gimple_assign_load_p (stmt
)
5474 && TREE_CODE (lhs_type
) == INTEGER_TYPE
5475 && TYPE_MODE (lhs_type
) == TYPE_MODE (char_type_node
)
5476 && (TYPE_PRECISION (lhs_type
)
5477 == TYPE_PRECISION (char_type_node
))
5478 && !gimple_has_volatile_ops (stmt
))
5480 tree off
= integer_zero_node
;
5481 unsigned HOST_WIDE_INT coff
= 0;
5483 tree rhs1
= gimple_assign_rhs1 (stmt
);
5484 if (code
== MEM_REF
)
5486 idx
= get_stridx (TREE_OPERAND (rhs1
, 0), stmt
);
5489 strinfo
*si
= get_strinfo (idx
);
5491 && si
->nonzero_chars
5492 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
5493 && (wi::to_widest (si
->nonzero_chars
)
5494 >= wi::to_widest (off
)))
5495 off
= TREE_OPERAND (rhs1
, 1);
5497 /* This case is not useful. See if get_addr_stridx
5498 returns something usable. */
5503 idx
= get_addr_stridx (rhs1
, stmt
, NULL_TREE
, &coff
);
5506 strinfo
*si
= get_strinfo (idx
);
5508 && si
->nonzero_chars
5509 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
5511 widest_int w1
= wi::to_widest (si
->nonzero_chars
);
5512 widest_int w2
= wi::to_widest (off
) + coff
;
5514 && si
->full_string_p
)
5516 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5518 fprintf (dump_file
, "Optimizing: ");
5519 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5522 /* Reading the final '\0' character. */
5523 tree zero
= build_int_cst (lhs_type
, 0);
5524 gimple_set_vuse (stmt
, NULL_TREE
);
5525 gimple_assign_set_rhs_from_tree (&m_gsi
, zero
);
5527 |= maybe_clean_or_replace_eh_stmt (stmt
,
5529 stmt
= gsi_stmt (m_gsi
);
5532 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5534 fprintf (dump_file
, "into: ");
5535 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5540 /* Reading a character before the final '\0'
5541 character. Just set the value range to ~[0, 0]
5542 if we don't have anything better. */
5544 if (!get_range_query (cfun
)->range_of_expr (r
, lhs
)
5547 r
.set_nonzero (lhs_type
);
5548 set_range_info (lhs
, r
);
5554 else if (code
== MEM_REF
&& TREE_CODE (lhs
) == SSA_NAME
)
5556 if (int idx
= new_stridx (lhs
))
5558 /* Record multi-byte assignments from MEM_REFs. */
5559 bool storing_all_nonzero_p
;
5560 bool storing_all_zeros_p
;
5562 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
5563 tree rhs
= gimple_assign_rhs1 (stmt
);
5564 const bool ranges_valid
5565 = count_nonzero_bytes (rhs
, stmt
,
5566 lenrange
, &full_string_p
,
5567 &storing_all_zeros_p
,
5568 &storing_all_nonzero_p
);
5571 tree length
= build_int_cst (sizetype
, lenrange
[0]);
5572 strinfo
*si
= new_strinfo (lhs
, idx
, length
, full_string_p
);
5573 set_strinfo (idx
, si
);
5574 si
->writable
= true;
5575 si
->dont_invalidate
= true;
5580 if (strlen_to_stridx
)
5582 tree rhs1
= gimple_assign_rhs1 (stmt
);
5583 if (stridx_strlenloc
*ps
= strlen_to_stridx
->get (rhs1
))
5584 strlen_to_stridx
->put (lhs
, stridx_strlenloc (*ps
));
5588 /* Handle assignment statement at *GSI to LHS. Set *ZERO_WRITE if
5589 the assignment stores all zero bytes. */
5592 strlen_pass::handle_assign (tree lhs
, bool *zero_write
)
5594 tree type
= TREE_TYPE (lhs
);
5595 if (TREE_CODE (type
) == ARRAY_TYPE
)
5596 type
= TREE_TYPE (type
);
5598 bool is_char_store
= is_char_type (type
);
5599 if (!is_char_store
&& TREE_CODE (lhs
) == MEM_REF
)
5601 /* To consider stores into char objects via integer types other
5602 than char but not those to non-character objects, determine
5603 the type of the destination rather than just the type of
5605 for (int i
= 0; i
!= 2; ++i
)
5607 tree ref
= TREE_OPERAND (lhs
, i
);
5608 type
= TREE_TYPE (ref
);
5609 if (TREE_CODE (type
) == POINTER_TYPE
)
5610 type
= TREE_TYPE (type
);
5611 if (TREE_CODE (type
) == ARRAY_TYPE
)
5612 type
= TREE_TYPE (type
);
5613 if (is_char_type (type
))
5615 is_char_store
= true;
5621 /* Handle a single or multibyte assignment. */
5622 if (is_char_store
&& !handle_store (zero_write
))
5629 /* Attempt to check for validity of the performed access a single statement
5630 at *GSI using string length knowledge, and to optimize it.
5631 If the given basic block needs clean-up of EH, CLEANUP_EH is set to
5632 true. Return true to let the caller advance *GSI to the next statement
5633 in the basic block and false otherwise. */
5636 strlen_pass::check_and_optimize_stmt (bool *cleanup_eh
)
5638 gimple
*stmt
= gsi_stmt (m_gsi
);
5640 /* For statements that modify a string, set to true if the write
5642 bool zero_write
= false;
5644 if (is_gimple_call (stmt
))
5646 if (!check_and_optimize_call (&zero_write
))
5649 else if (!flag_optimize_strlen
|| !strlen_optimize
)
5651 else if (is_gimple_assign (stmt
) && !gimple_clobber_p (stmt
))
5653 /* Handle non-clobbering assignment. */
5654 tree lhs
= gimple_assign_lhs (stmt
);
5655 tree lhs_type
= TREE_TYPE (lhs
);
5657 if (TREE_CODE (lhs
) == SSA_NAME
&& POINTER_TYPE_P (lhs_type
))
5659 if (gimple_assign_single_p (stmt
)
5660 || (gimple_assign_cast_p (stmt
)
5661 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt
)))))
5663 int idx
= get_stridx (gimple_assign_rhs1 (stmt
), stmt
);
5664 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = idx
;
5666 else if (gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
5667 handle_pointer_plus ();
5669 else if (TREE_CODE (lhs
) == SSA_NAME
&& INTEGRAL_TYPE_P (lhs_type
))
5670 /* Handle assignment to a character. */
5671 handle_integral_assign (cleanup_eh
);
5672 else if (TREE_CODE (lhs
) != SSA_NAME
&& !TREE_SIDE_EFFECTS (lhs
))
5673 if (!handle_assign (lhs
, &zero_write
))
5676 else if (gcond
*cond
= dyn_cast
<gcond
*> (stmt
))
5678 enum tree_code code
= gimple_cond_code (cond
);
5679 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5680 fold_strstr_to_strncmp (gimple_cond_lhs (stmt
),
5681 gimple_cond_rhs (stmt
), stmt
);
5684 if (gimple_vdef (stmt
))
5685 maybe_invalidate (stmt
, zero_write
);
5689 /* Recursively call maybe_invalidate on stmts that might be executed
5690 in between dombb and current bb and that contain a vdef. Stop when
5691 *count stmts are inspected, or if the whole strinfo vector has
5692 been invalidated. */
5695 do_invalidate (basic_block dombb
, gimple
*phi
, bitmap visited
, int *count
)
5697 unsigned int i
, n
= gimple_phi_num_args (phi
);
5699 for (i
= 0; i
< n
; i
++)
5701 tree vuse
= gimple_phi_arg_def (phi
, i
);
5702 gimple
*stmt
= SSA_NAME_DEF_STMT (vuse
);
5703 basic_block bb
= gimple_bb (stmt
);
5706 || !bitmap_set_bit (visited
, bb
->index
)
5707 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5711 if (gimple_code (stmt
) == GIMPLE_PHI
)
5713 do_invalidate (dombb
, stmt
, visited
, count
);
5720 if (!maybe_invalidate (stmt
))
5725 vuse
= gimple_vuse (stmt
);
5726 stmt
= SSA_NAME_DEF_STMT (vuse
);
5727 if (gimple_bb (stmt
) != bb
)
5729 bb
= gimple_bb (stmt
);
5732 || !bitmap_set_bit (visited
, bb
->index
)
5733 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5740 /* Release pointer_query cache. */
5742 strlen_pass::~strlen_pass ()
5744 ptr_qry
.flush_cache ();
5747 /* Callback for walk_dominator_tree. Attempt to optimize various
5748 string ops by remembering string lengths pointed by pointer SSA_NAMEs. */
5751 strlen_pass::before_dom_children (basic_block bb
)
5753 basic_block dombb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
5756 stridx_to_strinfo
= NULL
;
5759 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) dombb
->aux
);
5760 if (stridx_to_strinfo
)
5762 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5765 gphi
*phi
= gsi
.phi ();
5766 if (virtual_operand_p (gimple_phi_result (phi
)))
5768 bitmap visited
= BITMAP_ALLOC (NULL
);
5769 int count_vdef
= 100;
5770 do_invalidate (dombb
, phi
, visited
, &count_vdef
);
5771 BITMAP_FREE (visited
);
5772 if (count_vdef
== 0)
5774 /* If there were too many vdefs in between immediate
5775 dominator and current bb, invalidate everything.
5776 If stridx_to_strinfo has been unshared, we need
5777 to free it, otherwise just set it to NULL. */
5778 if (!strinfo_shared ())
5784 vec_safe_iterate (stridx_to_strinfo
, i
, &si
);
5788 (*stridx_to_strinfo
)[i
] = NULL
;
5792 stridx_to_strinfo
= NULL
;
5800 /* If all PHI arguments have the same string index, the PHI result
5802 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5805 gphi
*phi
= gsi
.phi ();
5806 tree result
= gimple_phi_result (phi
);
5807 if (!virtual_operand_p (result
) && POINTER_TYPE_P (TREE_TYPE (result
)))
5809 int idx
= get_stridx (gimple_phi_arg_def (phi
, 0), phi
);
5812 unsigned int i
, n
= gimple_phi_num_args (phi
);
5813 for (i
= 1; i
< n
; i
++)
5814 if (idx
!= get_stridx (gimple_phi_arg_def (phi
, i
), phi
))
5817 ssa_ver_to_stridx
[SSA_NAME_VERSION (result
)] = idx
;
5822 bool cleanup_eh
= false;
5824 /* Attempt to optimize individual statements. */
5825 for (m_gsi
= gsi_start_bb (bb
); !gsi_end_p (m_gsi
); )
5827 /* Reset search depth performance counter. */
5830 if (check_and_optimize_stmt (&cleanup_eh
))
5834 if (cleanup_eh
&& gimple_purge_dead_eh_edges (bb
))
5835 m_cleanup_cfg
= true;
5837 bb
->aux
= stridx_to_strinfo
;
5838 if (vec_safe_length (stridx_to_strinfo
) && !strinfo_shared ())
5839 (*stridx_to_strinfo
)[0] = (strinfo
*) bb
;
5843 /* Callback for walk_dominator_tree. Free strinfo vector if it is
5844 owned by the current bb, clear bb->aux. */
5847 strlen_pass::after_dom_children (basic_block bb
)
5851 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) bb
->aux
);
5852 if (vec_safe_length (stridx_to_strinfo
)
5853 && (*stridx_to_strinfo
)[0] == (strinfo
*) bb
)
5858 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
5860 vec_free (stridx_to_strinfo
);
5869 printf_strlen_execute (function
*fun
, bool warn_only
)
5871 strlen_optimize
= !warn_only
;
5873 calculate_dominance_info (CDI_DOMINATORS
);
5874 loop_optimizer_init (LOOPS_NORMAL
);
5877 gcc_assert (!strlen_to_stridx
);
5878 if (warn_stringop_overflow
|| warn_stringop_truncation
)
5879 strlen_to_stridx
= new hash_map
<tree
, stridx_strlenloc
> ();
5881 /* This has to happen after initializing the loop optimizer
5882 and initializing SCEV as they create new SSA_NAMEs. */
5883 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
5886 /* String length optimization is implemented as a walk of the dominator
5887 tree and a forward walk of statements within each block. */
5888 strlen_pass
walker (CDI_DOMINATORS
);
5889 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));
5891 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5892 walker
.ptr_qry
.dump (dump_file
, true);
5894 ssa_ver_to_stridx
.release ();
5895 strinfo_pool
.release ();
5896 if (decl_to_stridxlist_htab
)
5898 obstack_free (&stridx_obstack
, NULL
);
5899 delete decl_to_stridxlist_htab
;
5900 decl_to_stridxlist_htab
= NULL
;
5902 laststmt
.stmt
= NULL
;
5903 laststmt
.len
= NULL_TREE
;
5904 laststmt
.stridx
= 0;
5906 if (strlen_to_stridx
)
5908 strlen_to_stridx
->empty ();
5909 delete strlen_to_stridx
;
5910 strlen_to_stridx
= NULL
;
5914 loop_optimizer_finalize ();
5916 return walker
.m_cleanup_cfg
? TODO_cleanup_cfg
: 0;
5919 /* This file defines two passes: one for warnings that runs only when
5920 optimization is disabled, and another that implements optimizations
5921 and also issues warnings. */
5923 const pass_data pass_data_warn_printf
=
5925 GIMPLE_PASS
, /* type */
5926 "warn-printf", /* name */
5927 OPTGROUP_NONE
, /* optinfo_flags */
5928 TV_NONE
, /* tv_id */
5929 /* Normally an optimization pass would require PROP_ssa but because
5930 this pass runs early, with no optimization, to do sprintf format
5931 checking, it only requires PROP_cfg. */
5932 PROP_cfg
, /* properties_required */
5933 0, /* properties_provided */
5934 0, /* properties_destroyed */
5935 0, /* todo_flags_start */
5936 0, /* todo_flags_finish */
5939 class pass_warn_printf
: public gimple_opt_pass
5942 pass_warn_printf (gcc::context
*ctxt
)
5943 : gimple_opt_pass (pass_data_warn_printf
, ctxt
)
5946 bool gate (function
*) final override
;
5947 unsigned int execute (function
*fun
) final override
5949 return printf_strlen_execute (fun
, true);
5954 /* Return true to run the warning pass only when not optimizing and
5955 iff either -Wformat-overflow or -Wformat-truncation is specified. */
5958 pass_warn_printf::gate (function
*)
5960 return !optimize
&& (warn_format_overflow
> 0 || warn_format_trunc
> 0);
5963 const pass_data pass_data_strlen
=
5965 GIMPLE_PASS
, /* type */
5966 "strlen", /* name */
5967 OPTGROUP_NONE
, /* optinfo_flags */
5968 TV_TREE_STRLEN
, /* tv_id */
5969 PROP_cfg
| PROP_ssa
, /* properties_required */
5970 0, /* properties_provided */
5971 0, /* properties_destroyed */
5972 0, /* todo_flags_start */
5973 0, /* todo_flags_finish */
5976 class pass_strlen
: public gimple_opt_pass
5979 pass_strlen (gcc::context
*ctxt
)
5980 : gimple_opt_pass (pass_data_strlen
, ctxt
)
5983 opt_pass
* clone () final override
{ return new pass_strlen (m_ctxt
); }
5985 bool gate (function
*) final override
;
5986 unsigned int execute (function
*fun
) final override
5988 return printf_strlen_execute (fun
, false);
5992 /* Return true to run the pass only when the sprintf and/or strlen
5993 optimizations are enabled and -Wformat-overflow or -Wformat-truncation
5997 pass_strlen::gate (function
*)
5999 return ((warn_format_overflow
> 0
6000 || warn_format_trunc
> 0
6001 || warn_restrict
> 0
6002 || flag_optimize_strlen
> 0
6003 || flag_printf_return_value
)
6010 make_pass_warn_printf (gcc::context
*ctxt
)
6012 return new pass_warn_printf (ctxt
);
6016 make_pass_strlen (gcc::context
*ctxt
)
6018 return new pass_strlen (ctxt
);