1 /* String length optimization
2 Copyright (C) 2011-2021 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "alloc-pool.h"
29 #include "tree-pass.h"
32 #include "gimple-pretty-print.h"
33 #include "gimple-ssa-warn-access.h"
34 #include "gimple-ssa-warn-restrict.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "gimple-fold.h"
40 #include "gimple-iterator.h"
41 #include "gimplify-me.h"
46 #include "tree-ssa-alias.h"
47 #include "tree-ssa-propagate.h"
48 #include "tree-ssa-strlen.h"
49 #include "tree-hash-traits.h"
51 #include "pointer-query.h"
53 #include "diagnostic-core.h"
54 #include "diagnostic.h"
59 #include "tree-ssa-loop.h"
60 #include "tree-scalar-evolution.h"
61 #include "vr-values.h"
62 #include "gimple-ssa-evrp-analyze.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 void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator
*);
197 static bool handle_assign (gimple_stmt_iterator
*, tree
, bool *,
200 /* Sets MINMAX to either the constant value or the range VAL is in
201 and returns either the constant value or VAL on success or null
202 when the range couldn't be determined. Uses RVALS or CFUN for
203 range info, whichever is nonnull. */
206 get_range (tree val
, gimple
*stmt
, wide_int minmax
[2],
207 range_query
*rvals
/* = NULL */)
212 /* When called from front ends for global initializers CFUN
216 rvals
= get_range_query (cfun
);
220 if (!rvals
->range_of_expr (vr
, val
, stmt
))
223 value_range_kind rng
= vr
.kind ();
226 /* Only handle straight ranges. */
227 minmax
[0] = wi::to_wide (vr
.min ());
228 minmax
[1] = wi::to_wide (vr
.max ());
237 * +1 if SI is known to start with more than OFF nonzero characters.
239 * 0 if SI is known to start with exactly OFF nonzero characters.
241 * -1 if SI either does not start with OFF nonzero characters
242 or the relationship between the number of leading nonzero
243 characters in SI and OFF is unknown. */
246 compare_nonzero_chars (strinfo
*si
, unsigned HOST_WIDE_INT off
)
248 if (si
->nonzero_chars
249 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
250 return compare_tree_int (si
->nonzero_chars
, off
);
255 /* Same as above but suitable also for strings with non-constant lengths.
256 Uses RVALS to determine length range. */
259 compare_nonzero_chars (strinfo
*si
, unsigned HOST_WIDE_INT off
,
262 if (!si
->nonzero_chars
)
265 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
266 return compare_tree_int (si
->nonzero_chars
, off
);
268 if (!rvals
|| TREE_CODE (si
->nonzero_chars
) != SSA_NAME
)
272 if (!rvals
->range_of_expr (vr
, si
->nonzero_chars
, si
->stmt
))
274 value_range_kind rng
= vr
.kind ();
278 /* If the offset is less than the minimum length or if the bounds
279 of the length range are equal return the result of the comparison
280 same as in the constant case. Otherwise return a conservative
282 int cmpmin
= compare_tree_int (vr
.min (), off
);
283 if (cmpmin
> 0 || tree_int_cst_equal (vr
.min (), vr
.max ()))
289 /* Return true if SI is known to be a zero-length string. */
292 zero_length_string_p (strinfo
*si
)
294 return si
->full_string_p
&& integer_zerop (si
->nonzero_chars
);
297 /* Return strinfo vector entry IDX. */
299 static inline strinfo
*
300 get_strinfo (int idx
)
302 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
304 return (*stridx_to_strinfo
)[idx
];
307 /* Get the next strinfo in the chain after SI, or null if none. */
309 static inline strinfo
*
310 get_next_strinfo (strinfo
*si
)
314 strinfo
*nextsi
= get_strinfo (si
->next
);
315 if (nextsi
== NULL
|| nextsi
->first
!= si
->first
|| nextsi
->prev
!= si
->idx
)
320 /* Helper function for get_stridx. Return the strinfo index of the address
321 of EXP, which is available in PTR if nonnull. If OFFSET_OUT, it is
322 OK to return the index for some X <= &EXP and store &EXP - X in
323 *OFFSET_OUT. When RVALS is nonnull uses it to determine range
327 get_addr_stridx (tree exp
, tree ptr
, unsigned HOST_WIDE_INT
*offset_out
,
328 range_query
*rvals
= NULL
)
331 struct stridxlist
*list
, *last
= NULL
;
334 if (!decl_to_stridxlist_htab
)
338 base
= get_addr_base_and_unit_offset (exp
, &poff
);
339 if (base
== NULL
|| !DECL_P (base
) || !poff
.is_constant (&off
))
342 list
= decl_to_stridxlist_htab
->get (base
);
348 if (list
->offset
== off
)
354 if (list
->offset
> off
)
361 if ((offset_out
|| ptr
) && last
&& last
->idx
> 0)
363 unsigned HOST_WIDE_INT rel_off
364 = (unsigned HOST_WIDE_INT
) off
- last
->offset
;
365 strinfo
*si
= get_strinfo (last
->idx
);
366 if (si
&& compare_nonzero_chars (si
, rel_off
, rvals
) >= 0)
370 *offset_out
= rel_off
;
374 return get_stridx_plus_constant (si
, rel_off
, ptr
);
380 /* Returns string index for EXP. When EXP is an SSA_NAME that refers
381 to a known strinfo with an offset and OFFRNG is non-null, sets
382 both elements of the OFFRNG array to the range of the offset and
383 returns the index of the known strinfo. In this case the result
384 must not be used in for functions that modify the string.
385 When nonnull, uses RVALS to determine range information. */
388 get_stridx (tree exp
, wide_int offrng
[2] = NULL
, range_query
*rvals
= NULL
)
391 offrng
[0] = offrng
[1] = wi::zero (TYPE_PRECISION (ptrdiff_type_node
));
393 if (TREE_CODE (exp
) == SSA_NAME
)
395 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)])
396 return ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)];
400 HOST_WIDE_INT offset
= 0;
401 /* Follow a chain of at most 5 assignments. */
402 for (int i
= 0; i
< 5; i
++)
404 gimple
*def_stmt
= SSA_NAME_DEF_STMT (e
);
405 if (!is_gimple_assign (def_stmt
))
408 tree_code rhs_code
= gimple_assign_rhs_code (def_stmt
);
411 if (rhs_code
== ADDR_EXPR
)
413 /* Handle indices/offsets into VLAs which are implemented
414 as pointers to arrays. */
415 ptr
= gimple_assign_rhs1 (def_stmt
);
416 ptr
= TREE_OPERAND (ptr
, 0);
418 /* Handle also VLAs of types larger than char. */
419 if (tree eltsize
= TYPE_SIZE_UNIT (TREE_TYPE (ptr
)))
421 if (TREE_CODE (ptr
) == ARRAY_REF
)
423 off
= TREE_OPERAND (ptr
, 1);
424 ptr
= TREE_OPERAND (ptr
, 0);
425 if (!integer_onep (eltsize
))
427 /* Scale the array index by the size of the element
428 type in the rare case that it's greater than
429 the typical 1 for char, making sure both operands
430 have the same type. */
431 eltsize
= fold_convert (ssizetype
, eltsize
);
432 off
= fold_convert (ssizetype
, off
);
433 off
= fold_build2 (MULT_EXPR
, ssizetype
, off
, eltsize
);
437 off
= integer_zero_node
;
442 if (TREE_CODE (ptr
) != MEM_REF
)
445 /* Add the MEM_REF byte offset. */
446 tree mem_off
= TREE_OPERAND (ptr
, 1);
447 off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (off
), off
, mem_off
);
448 ptr
= TREE_OPERAND (ptr
, 0);
450 else if (rhs_code
== POINTER_PLUS_EXPR
)
452 ptr
= gimple_assign_rhs1 (def_stmt
);
453 off
= gimple_assign_rhs2 (def_stmt
);
458 if (TREE_CODE (ptr
) != SSA_NAME
)
461 if (!tree_fits_shwi_p (off
))
463 if (int idx
= ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)])
466 /* Only when requested by setting OFFRNG to non-null,
467 return the index corresponding to the SSA_NAME.
468 Do this irrespective of the whether the offset
470 if (get_range (off
, def_stmt
, offrng
, rvals
))
472 /* When the offset range is known, increment it
473 it by the constant offset computed in prior
474 iterations and store it in the OFFRNG array. */
480 /* When the offset range cannot be determined
481 store [0, SIZE_MAX] and let the caller decide
482 if the offset matters. */
483 offrng
[1] = wi::to_wide (TYPE_MAX_VALUE (sizetype
));
484 offrng
[0] = wi::zero (offrng
[1].get_precision ());
491 HOST_WIDE_INT this_off
= tree_to_shwi (off
);
494 offrng
[0] += wi::shwi (this_off
, offrng
->get_precision ());
495 offrng
[1] += offrng
[0];
501 offset
= (unsigned HOST_WIDE_INT
) offset
+ this_off
;
505 if (int idx
= ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)])
507 strinfo
*si
= get_strinfo (idx
);
510 if (compare_nonzero_chars (si
, offset
) >= 0)
511 return get_stridx_plus_constant (si
, offset
, exp
);
523 if (TREE_CODE (exp
) == ADDR_EXPR
)
525 int idx
= get_addr_stridx (TREE_OPERAND (exp
, 0), exp
, NULL
);
530 const char *p
= c_getstr (exp
);
532 return ~(int) strlen (p
);
537 /* Return true if strinfo vector is shared with the immediate dominator. */
540 strinfo_shared (void)
542 return vec_safe_length (stridx_to_strinfo
)
543 && (*stridx_to_strinfo
)[0] != NULL
;
546 /* Unshare strinfo vector that is shared with the immediate dominator. */
549 unshare_strinfo_vec (void)
554 gcc_assert (strinfo_shared ());
555 stridx_to_strinfo
= vec_safe_copy (stridx_to_strinfo
);
556 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
559 (*stridx_to_strinfo
)[0] = NULL
;
562 /* Attempt to create a string index for exp, ADDR_EXPR's operand.
563 Return a pointer to the location where the string index can
564 be stored (if 0) or is stored, or NULL if this can't be tracked. */
567 addr_stridxptr (tree exp
)
572 tree base
= get_addr_base_and_unit_offset (exp
, &poff
);
573 if (base
== NULL_TREE
|| !DECL_P (base
) || !poff
.is_constant (&off
))
576 if (!decl_to_stridxlist_htab
)
578 decl_to_stridxlist_htab
579 = new hash_map
<tree_decl_hash
, stridxlist
> (64);
580 gcc_obstack_init (&stridx_obstack
);
584 stridxlist
*list
= &decl_to_stridxlist_htab
->get_or_insert (base
, &existed
);
588 stridxlist
*before
= NULL
;
589 for (i
= 0; i
< 32; i
++)
591 if (list
->offset
== off
)
593 if (list
->offset
> off
&& before
== NULL
)
595 if (list
->next
== NULL
)
604 before
= XOBNEW (&stridx_obstack
, struct stridxlist
);
611 list
->next
= XOBNEW (&stridx_obstack
, struct stridxlist
);
621 /* Create a new string index, or return 0 if reached limit. */
624 new_stridx (tree exp
)
627 if (max_stridx
>= param_max_tracked_strlens
)
629 if (TREE_CODE (exp
) == SSA_NAME
)
631 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp
))
634 ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)] = idx
;
637 if (TREE_CODE (exp
) == ADDR_EXPR
)
639 int *pidx
= addr_stridxptr (TREE_OPERAND (exp
, 0));
642 gcc_assert (*pidx
== 0);
643 *pidx
= max_stridx
++;
650 /* Like new_stridx, but for ADDR_EXPR's operand instead. */
653 new_addr_stridx (tree exp
)
656 if (max_stridx
>= param_max_tracked_strlens
)
658 pidx
= addr_stridxptr (exp
);
661 gcc_assert (*pidx
== 0);
662 *pidx
= max_stridx
++;
668 /* Create a new strinfo. */
671 new_strinfo (tree ptr
, int idx
, tree nonzero_chars
, bool full_string_p
)
673 strinfo
*si
= strinfo_pool
.allocate ();
674 si
->nonzero_chars
= nonzero_chars
;
675 STRIP_USELESS_TYPE_CONVERSION (ptr
);
679 si
->endptr
= NULL_TREE
;
685 si
->writable
= false;
686 si
->dont_invalidate
= false;
687 si
->full_string_p
= full_string_p
;
691 /* Decrease strinfo refcount and free it if not referenced anymore. */
694 free_strinfo (strinfo
*si
)
696 if (si
&& --si
->refcount
== 0)
697 strinfo_pool
.remove (si
);
700 /* Set strinfo in the vector entry IDX to SI. */
703 set_strinfo (int idx
, strinfo
*si
)
705 if (vec_safe_length (stridx_to_strinfo
) && (*stridx_to_strinfo
)[0])
706 unshare_strinfo_vec ();
707 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
708 vec_safe_grow_cleared (stridx_to_strinfo
, idx
+ 1, true);
709 (*stridx_to_strinfo
)[idx
] = si
;
712 /* Return the first strinfo in the related strinfo chain
713 if all strinfos in between belong to the chain, otherwise NULL. */
716 verify_related_strinfos (strinfo
*origsi
)
718 strinfo
*si
= origsi
, *psi
;
720 if (origsi
->first
== 0)
722 for (; si
->prev
; si
= psi
)
724 if (si
->first
!= origsi
->first
)
726 psi
= get_strinfo (si
->prev
);
729 if (psi
->next
!= si
->idx
)
732 if (si
->idx
!= si
->first
)
737 /* Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
738 Use LOC for folding. */
741 set_endptr_and_length (location_t loc
, strinfo
*si
, tree endptr
)
745 tree start_as_size
= fold_convert_loc (loc
, size_type_node
, si
->ptr
);
746 tree end_as_size
= fold_convert_loc (loc
, size_type_node
, endptr
);
747 si
->nonzero_chars
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
748 end_as_size
, start_as_size
);
749 si
->full_string_p
= true;
752 /* Return the string length, or NULL if it can't be computed.
753 The length may but need not be constant. Instead, it might be
754 the result of a strlen() call. */
757 get_string_length (strinfo
*si
)
759 /* If the length has already been computed return it if it's exact
760 (i.e., the string is nul-terminated at NONZERO_CHARS), or return
762 if (si
->nonzero_chars
)
763 return si
->full_string_p
? si
->nonzero_chars
: NULL
;
765 /* If the string is the result of one of the built-in calls below
766 attempt to compute the length from the call statement. */
769 gimple
*stmt
= si
->stmt
, *lenstmt
;
770 tree callee
, lhs
, fn
, tem
;
772 gimple_stmt_iterator gsi
;
774 gcc_assert (is_gimple_call (stmt
));
775 callee
= gimple_call_fndecl (stmt
);
776 gcc_assert (callee
&& fndecl_built_in_p (callee
, BUILT_IN_NORMAL
));
777 lhs
= gimple_call_lhs (stmt
);
778 /* unshare_strinfo is intentionally not called here. The (delayed)
779 transformation of strcpy or strcat into stpcpy is done at the place
780 of the former strcpy/strcat call and so can affect all the strinfos
781 with the same stmt. If they were unshared before and transformation
782 has been already done, the handling of BUILT_IN_STPCPY{,_CHK} should
783 just compute the right length. */
784 switch (DECL_FUNCTION_CODE (callee
))
786 case BUILT_IN_STRCAT
:
787 case BUILT_IN_STRCAT_CHK
:
788 gsi
= gsi_for_stmt (stmt
);
789 fn
= builtin_decl_implicit (BUILT_IN_STRLEN
);
790 gcc_assert (lhs
== NULL_TREE
);
791 tem
= unshare_expr (gimple_call_arg (stmt
, 0));
792 lenstmt
= gimple_build_call (fn
, 1, tem
);
793 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), lenstmt
);
794 gimple_call_set_lhs (lenstmt
, lhs
);
795 gimple_set_vuse (lenstmt
, gimple_vuse (stmt
));
796 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
797 tem
= gimple_call_arg (stmt
, 0);
798 if (!ptrofftype_p (TREE_TYPE (lhs
)))
800 lhs
= convert_to_ptrofftype (lhs
);
801 lhs
= force_gimple_operand_gsi (&gsi
, lhs
, true, NULL_TREE
,
802 true, GSI_SAME_STMT
);
804 lenstmt
= gimple_build_assign
805 (make_ssa_name (TREE_TYPE (gimple_call_arg (stmt
, 0))),
806 POINTER_PLUS_EXPR
,tem
, lhs
);
807 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
808 gimple_call_set_arg (stmt
, 0, gimple_assign_lhs (lenstmt
));
811 case BUILT_IN_STRCPY
:
812 case BUILT_IN_STRCPY_CHK
:
813 gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY
));
814 if (gimple_call_num_args (stmt
) == 2)
815 fn
= builtin_decl_implicit (BUILT_IN_STPCPY
);
817 fn
= builtin_decl_explicit (BUILT_IN_STPCPY_CHK
);
818 gcc_assert (lhs
== NULL_TREE
);
819 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
821 fprintf (dump_file
, "Optimizing: ");
822 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
824 gimple_call_set_fndecl (stmt
, fn
);
825 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), stmt
);
826 gimple_call_set_lhs (stmt
, lhs
);
828 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
830 fprintf (dump_file
, "into: ");
831 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
834 case BUILT_IN_STPCPY
:
835 case BUILT_IN_STPCPY_CHK
:
836 gcc_assert (lhs
!= NULL_TREE
);
837 loc
= gimple_location (stmt
);
838 set_endptr_and_length (loc
, si
, lhs
);
839 for (strinfo
*chainsi
= verify_related_strinfos (si
);
841 chainsi
= get_next_strinfo (chainsi
))
842 if (chainsi
->nonzero_chars
== NULL
)
843 set_endptr_and_length (loc
, chainsi
, lhs
);
845 case BUILT_IN_ALLOCA
:
846 case BUILT_IN_ALLOCA_WITH_ALIGN
:
847 case BUILT_IN_MALLOC
:
849 /* BUILT_IN_CALLOC always has si->nonzero_chars set. */
856 return si
->nonzero_chars
;
859 /* Dump strlen data to FP for statement STMT. When non-null, RVALS
860 points to the valuation engine used to calculate ranges, and is
861 used to dump strlen range for non-constant results. */
864 dump_strlen_info (FILE *fp
, gimple
*stmt
, range_query
*rvals
)
868 fprintf (fp
, "\nDumping strlen pass data after ");
869 print_gimple_expr (fp
, stmt
, TDF_LINENO
);
873 fprintf (fp
, "\nDumping strlen pass data\n");
875 fprintf (fp
, "max_stridx = %i\n", max_stridx
);
876 fprintf (fp
, "ssa_ver_to_stridx has %u elements\n",
877 ssa_ver_to_stridx
.length ());
878 fprintf (fp
, "stridx_to_strinfo");
879 if (stridx_to_strinfo
)
881 fprintf (fp
, " has %u elements\n", stridx_to_strinfo
->length ());
882 for (unsigned i
= 0; i
!= stridx_to_strinfo
->length (); ++i
)
884 if (strinfo
*si
= (*stridx_to_strinfo
)[i
])
888 fprintf (fp
, " idx = %i", si
->idx
);
891 fprintf (fp
, ", ptr = ");
892 print_generic_expr (fp
, si
->ptr
);
895 if (si
->nonzero_chars
)
897 fprintf (fp
, ", nonzero_chars = ");
898 print_generic_expr (fp
, si
->nonzero_chars
);
899 if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
901 value_range_kind rng
= VR_UNDEFINED
;
906 rvals
->range_of_expr (vr
, si
->nonzero_chars
,
909 if (range_int_cst_p (&vr
))
911 min
= wi::to_wide (vr
.min ());
912 max
= wi::to_wide (vr
.max ());
920 get_range_query (cfun
)
921 ->range_of_expr (vr
, si
->nonzero_chars
);
923 if (!vr
.undefined_p ())
925 min
= wi::to_wide (vr
.min ());
926 max
= wi::to_wide (vr
.max ());
930 if (rng
== VR_RANGE
|| rng
== VR_ANTI_RANGE
)
932 fprintf (fp
, " %s[%llu, %llu]",
933 rng
== VR_RANGE
? "" : "~",
934 (long long) min
.to_uhwi (),
935 (long long) max
.to_uhwi ());
940 fprintf (fp
, ", refcount = %i", si
->refcount
);
943 fprintf (fp
, ", stmt = ");
944 print_gimple_expr (fp
, si
->stmt
, 0);
948 fprintf (fp
, ", alloc = ");
949 print_gimple_expr (fp
, si
->alloc
, 0);
952 fprintf (fp
, ", writable");
953 if (si
->dont_invalidate
)
954 fprintf (fp
, ", dont_invalidate");
955 if (si
->full_string_p
)
956 fprintf (fp
, ", full_string_p");
957 if (strinfo
*next
= get_next_strinfo (si
))
961 fprintf (fp
, "%i%s", next
->idx
, next
->first
? ", " : "");
962 while ((next
= get_next_strinfo (next
)));
970 fprintf (fp
, " = null\n");
972 fprintf (fp
, "decl_to_stridxlist_htab");
973 if (decl_to_stridxlist_htab
)
976 typedef decl_to_stridxlist_htab_t::iterator iter_t
;
977 for (iter_t it
= decl_to_stridxlist_htab
->begin ();
978 it
!= decl_to_stridxlist_htab
->end (); ++it
)
980 tree decl
= (*it
).first
;
981 stridxlist
*list
= &(*it
).second
;
982 fprintf (fp
, " decl = ");
983 print_generic_expr (fp
, decl
);
986 fprintf (fp
, ", offsets = {");
987 for (; list
; list
= list
->next
)
988 fprintf (fp
, "%lli%s", (long long) list
->offset
,
989 list
->next
? ", " : "");
996 fprintf (fp
, " = null\n");
1000 fprintf (fp
, "laststmt = ");
1001 print_gimple_expr (fp
, laststmt
.stmt
, 0);
1002 fprintf (fp
, ", len = ");
1003 print_generic_expr (fp
, laststmt
.len
);
1004 fprintf (fp
, ", stridx = %i\n", laststmt
.stridx
);
1008 /* Attempt to determine the length of the string SRC. On success, store
1009 the length in *PDATA and return true. Otherwise, return false.
1010 VISITED is a bitmap of visited PHI nodes. RVALS points to the valuation
1011 engine used to calculate ranges. PSSA_DEF_MAX to an SSA_NAME
1012 assignment limit used to prevent runaway recursion. */
1015 get_range_strlen_dynamic (tree src
, gimple
*stmt
,
1016 c_strlen_data
*pdata
, bitmap
*visited
,
1017 range_query
*rvals
, unsigned *pssa_def_max
)
1019 int idx
= get_stridx (src
);
1022 if (TREE_CODE (src
) == SSA_NAME
)
1024 gimple
*def_stmt
= SSA_NAME_DEF_STMT (src
);
1025 if (gimple_code (def_stmt
) == GIMPLE_PHI
)
1028 *visited
= BITMAP_ALLOC (NULL
);
1030 if (!bitmap_set_bit (*visited
, SSA_NAME_VERSION (src
)))
1033 if (*pssa_def_max
== 0)
1038 /* Iterate over the PHI arguments and determine the minimum
1039 and maximum length/size of each and incorporate them into
1040 the overall result. */
1041 gphi
*phi
= as_a
<gphi
*> (def_stmt
);
1042 for (unsigned i
= 0; i
!= gimple_phi_num_args (phi
); ++i
)
1044 tree arg
= gimple_phi_arg_def (phi
, i
);
1045 if (arg
== gimple_phi_result (def_stmt
))
1048 c_strlen_data argdata
= { };
1049 if (get_range_strlen_dynamic (arg
, phi
, &argdata
, visited
,
1050 rvals
, pssa_def_max
))
1052 /* Set the DECL of an unterminated array this argument
1053 refers to if one hasn't been found yet. */
1054 if (!pdata
->decl
&& argdata
.decl
)
1055 pdata
->decl
= argdata
.decl
;
1058 || (integer_zerop (argdata
.minlen
)
1059 && (!argdata
.maxbound
1060 || integer_all_onesp (argdata
.maxbound
))
1061 && integer_all_onesp (argdata
.maxlen
)))
1063 /* Set the upper bound of the length to unbounded. */
1064 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1068 /* Adjust the minimum and maximum length determined
1069 so far and the upper bound on the array size. */
1071 || tree_int_cst_lt (argdata
.minlen
, pdata
->minlen
))
1072 pdata
->minlen
= argdata
.minlen
;
1075 && tree_int_cst_lt (pdata
->maxlen
, argdata
.maxlen
)))
1076 pdata
->maxlen
= argdata
.maxlen
;
1077 if (!pdata
->maxbound
1078 || TREE_CODE (pdata
->maxbound
) != INTEGER_CST
1079 || (argdata
.maxbound
1080 && tree_int_cst_lt (pdata
->maxbound
,
1082 && !integer_all_onesp (argdata
.maxbound
)))
1083 pdata
->maxbound
= argdata
.maxbound
;
1086 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1093 /* Return success regardless of the result and handle *PDATA
1095 get_range_strlen (src
, pdata
, 1);
1101 /* SRC is a string of constant length. */
1102 pdata
->minlen
= build_int_cst (size_type_node
, ~idx
);
1103 pdata
->maxlen
= pdata
->minlen
;
1104 pdata
->maxbound
= pdata
->maxlen
;
1108 if (strinfo
*si
= get_strinfo (idx
))
1110 pdata
->minlen
= get_string_length (si
);
1111 if (!pdata
->minlen
&& si
->nonzero_chars
)
1113 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
1114 pdata
->minlen
= si
->nonzero_chars
;
1115 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
1118 rvals
->range_of_expr (vr
, si
->nonzero_chars
, si
->stmt
);
1119 if (range_int_cst_p (&vr
))
1121 pdata
->minlen
= vr
.min ();
1122 pdata
->maxlen
= vr
.max ();
1125 pdata
->minlen
= build_zero_cst (size_type_node
);
1128 pdata
->minlen
= build_zero_cst (size_type_node
);
1130 tree base
= si
->ptr
;
1131 if (TREE_CODE (base
) == ADDR_EXPR
)
1132 base
= TREE_OPERAND (base
, 0);
1136 base
= get_addr_base_and_unit_offset (base
, &poff
);
1139 && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
1140 && TYPE_SIZE_UNIT (TREE_TYPE (base
))
1141 && poff
.is_constant (&off
))
1143 tree basetype
= TREE_TYPE (base
);
1144 tree size
= TYPE_SIZE_UNIT (basetype
);
1145 if (TREE_CODE (size
) == INTEGER_CST
)
1147 ++off
; /* Increment for the terminating nul. */
1148 tree toffset
= build_int_cst (size_type_node
, off
);
1149 pdata
->maxlen
= fold_build2 (MINUS_EXPR
, size_type_node
, size
,
1151 pdata
->maxbound
= pdata
->maxlen
;
1154 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1157 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1159 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == SSA_NAME
)
1162 rvals
->range_of_expr (vr
, si
->nonzero_chars
, stmt
);
1163 if (range_int_cst_p (&vr
))
1165 pdata
->minlen
= vr
.min ();
1166 pdata
->maxlen
= vr
.max ();
1167 pdata
->maxbound
= pdata
->maxlen
;
1171 pdata
->minlen
= build_zero_cst (size_type_node
);
1172 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1175 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == INTEGER_CST
)
1177 pdata
->maxlen
= pdata
->minlen
;
1178 pdata
->maxbound
= pdata
->minlen
;
1182 /* For PDATA->MINLEN that's a non-constant expression such
1183 as PLUS_EXPR whose value range is unknown, set the bounds
1184 to zero and SIZE_MAX. */
1185 pdata
->minlen
= build_zero_cst (size_type_node
);
1186 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1195 /* Analogous to get_range_strlen but for dynamically created strings,
1196 i.e., those created by calls to strcpy as opposed to just string
1198 Try to obtain the range of the lengths of the string(s) referenced
1199 by SRC, or the size of the largest array SRC refers to if the range
1200 of lengths cannot be determined, and store all in *PDATA. RVALS
1201 points to the valuation engine used to calculate ranges. */
1204 get_range_strlen_dynamic (tree src
, gimple
*stmt
, c_strlen_data
*pdata
,
1207 bitmap visited
= NULL
;
1208 tree maxbound
= pdata
->maxbound
;
1210 unsigned limit
= param_ssa_name_def_chain_limit
;
1211 if (!get_range_strlen_dynamic (src
, stmt
, pdata
, &visited
, rvals
, &limit
))
1213 /* On failure extend the length range to an impossible maximum
1214 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1215 members can stay unchanged regardless. */
1216 pdata
->minlen
= ssize_int (0);
1217 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1219 else if (!pdata
->minlen
)
1220 pdata
->minlen
= ssize_int (0);
1222 /* If it's unchanged from it initial non-null value, set the conservative
1223 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1224 if (maxbound
&& pdata
->maxbound
== maxbound
)
1225 pdata
->maxbound
= build_all_ones_cst (size_type_node
);
1228 BITMAP_FREE (visited
);
1231 /* Invalidate string length information for strings whose length might
1232 change due to stores in STMT, except those marked DONT_INVALIDATE.
1233 For string-modifying statements, ZERO_WRITE is set when the statement
1235 Returns true if any STRIDX_TO_STRINFO entries were considered
1236 for invalidation. */
1239 maybe_invalidate (gimple
*stmt
, bool zero_write
= false)
1241 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1243 fprintf (dump_file
, "%s called for ", __func__
);
1244 print_gimple_stmt (dump_file
, stmt
, TDF_LINENO
);
1248 bool nonempty
= false;
1250 for (unsigned i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
1252 if (si
== NULL
|| !POINTER_TYPE_P (TREE_TYPE (si
->ptr
)))
1257 /* Unconditionally reset DONT_INVALIDATE. */
1258 bool dont_invalidate
= si
->dont_invalidate
;
1259 si
->dont_invalidate
= false;
1261 if (dont_invalidate
)
1265 tree size
= si
->nonzero_chars
;
1266 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, size
);
1267 /* Include the terminating nul in the size of the string
1268 to consider when determining possible clobber. But do not
1269 add it to 'size' since we don't know whether it would
1270 actually fit the allocated area. */
1271 if (known_size_p (r
.size
))
1273 if (known_le (r
.size
, HOST_WIDE_INT_MAX
- BITS_PER_UNIT
))
1274 r
.max_size
+= BITS_PER_UNIT
;
1278 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1280 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1282 fputs (" statement may clobber object ", dump_file
);
1283 print_generic_expr (dump_file
, si
->ptr
);
1284 if (size
&& tree_fits_uhwi_p (size
))
1285 fprintf (dump_file
, " " HOST_WIDE_INT_PRINT_UNSIGNED
1286 " bytes in size", tree_to_uhwi (size
));
1287 fputc ('\n', dump_file
);
1290 set_strinfo (i
, NULL
);
1298 && is_gimple_call (si
->stmt
)
1299 && (DECL_FUNCTION_CODE (gimple_call_fndecl (si
->stmt
))
1300 == BUILT_IN_CALLOC
))
1302 /* If the clobber test above considered the length of
1303 the string (including the nul), then for (potentially)
1304 non-zero writes that might modify storage allocated by
1305 calloc consider the whole object and if it might be
1306 clobbered by the statement reset the statement. */
1307 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, NULL_TREE
);
1308 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1313 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1314 fprintf (dump_file
, "%s returns %i\n", __func__
, nonempty
);
1319 /* Unshare strinfo record SI, if it has refcount > 1 or
1320 if stridx_to_strinfo vector is shared with some other
1324 unshare_strinfo (strinfo
*si
)
1328 if (si
->refcount
== 1 && !strinfo_shared ())
1331 nsi
= new_strinfo (si
->ptr
, si
->idx
, si
->nonzero_chars
, si
->full_string_p
);
1332 nsi
->stmt
= si
->stmt
;
1333 nsi
->alloc
= si
->alloc
;
1334 nsi
->endptr
= si
->endptr
;
1335 nsi
->first
= si
->first
;
1336 nsi
->prev
= si
->prev
;
1337 nsi
->next
= si
->next
;
1338 nsi
->writable
= si
->writable
;
1339 set_strinfo (si
->idx
, nsi
);
1344 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1345 strinfo if there is any. Return it's idx, or 0 if no strinfo has
1349 get_stridx_plus_constant (strinfo
*basesi
, unsigned HOST_WIDE_INT off
,
1352 if (TREE_CODE (ptr
) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1355 if (compare_nonzero_chars (basesi
, off
) < 0
1356 || !tree_fits_uhwi_p (basesi
->nonzero_chars
))
1359 unsigned HOST_WIDE_INT nonzero_chars
1360 = tree_to_uhwi (basesi
->nonzero_chars
) - off
;
1361 strinfo
*si
= basesi
, *chainsi
;
1362 if (si
->first
|| si
->prev
|| si
->next
)
1363 si
= verify_related_strinfos (basesi
);
1365 || si
->nonzero_chars
== NULL_TREE
1366 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1369 if (TREE_CODE (ptr
) == SSA_NAME
1370 && ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1371 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1373 gcc_checking_assert (compare_tree_int (si
->nonzero_chars
, off
) != -1);
1374 for (chainsi
= si
; chainsi
->next
; chainsi
= si
)
1376 si
= get_next_strinfo (chainsi
);
1378 || si
->nonzero_chars
== NULL_TREE
1379 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1381 int r
= compare_tree_int (si
->nonzero_chars
, nonzero_chars
);
1386 if (TREE_CODE (ptr
) == SSA_NAME
)
1387 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = si
->idx
;
1390 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1391 if (pidx
!= NULL
&& *pidx
== 0)
1400 int idx
= new_stridx (ptr
);
1403 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, nonzero_chars
),
1404 basesi
->full_string_p
);
1405 set_strinfo (idx
, si
);
1406 if (strinfo
*nextsi
= get_strinfo (chainsi
->next
))
1408 nextsi
= unshare_strinfo (nextsi
);
1409 si
->next
= nextsi
->idx
;
1412 chainsi
= unshare_strinfo (chainsi
);
1413 if (chainsi
->first
== 0)
1414 chainsi
->first
= chainsi
->idx
;
1415 chainsi
->next
= idx
;
1416 if (chainsi
->endptr
== NULL_TREE
&& zero_length_string_p (si
))
1417 chainsi
->endptr
= ptr
;
1418 si
->endptr
= chainsi
->endptr
;
1419 si
->prev
= chainsi
->idx
;
1420 si
->first
= chainsi
->first
;
1421 si
->writable
= chainsi
->writable
;
1425 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1426 to a zero-length string and if possible chain it to a related strinfo
1427 chain whose part is or might be CHAINSI. */
1430 zero_length_string (tree ptr
, strinfo
*chainsi
)
1434 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1435 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1436 gcc_checking_assert (TREE_CODE (ptr
) == SSA_NAME
1437 && ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] == 0);
1439 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1441 if (chainsi
!= NULL
)
1443 si
= verify_related_strinfos (chainsi
);
1448 /* We shouldn't mix delayed and non-delayed lengths. */
1449 gcc_assert (si
->full_string_p
);
1450 if (si
->endptr
== NULL_TREE
)
1452 si
= unshare_strinfo (si
);
1456 si
= get_next_strinfo (si
);
1459 if (zero_length_string_p (chainsi
))
1463 chainsi
= unshare_strinfo (chainsi
);
1466 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = chainsi
->idx
;
1472 /* We shouldn't mix delayed and non-delayed lengths. */
1473 gcc_assert (chainsi
->full_string_p
);
1474 if (chainsi
->first
|| chainsi
->prev
|| chainsi
->next
)
1476 chainsi
= unshare_strinfo (chainsi
);
1483 idx
= new_stridx (ptr
);
1486 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, 0), true);
1487 set_strinfo (idx
, si
);
1489 if (chainsi
!= NULL
)
1491 chainsi
= unshare_strinfo (chainsi
);
1492 if (chainsi
->first
== 0)
1493 chainsi
->first
= chainsi
->idx
;
1494 chainsi
->next
= idx
;
1495 if (chainsi
->endptr
== NULL_TREE
)
1496 chainsi
->endptr
= ptr
;
1497 si
->prev
= chainsi
->idx
;
1498 si
->first
= chainsi
->first
;
1499 si
->writable
= chainsi
->writable
;
1504 /* For strinfo ORIGSI whose length has been just updated, adjust other
1505 related strinfos so that they match the new ORIGSI. This involves:
1507 - adding ADJ to the nonzero_chars fields
1508 - copying full_string_p from the new ORIGSI. */
1511 adjust_related_strinfos (location_t loc
, strinfo
*origsi
, tree adj
)
1513 strinfo
*si
= verify_related_strinfos (origsi
);
1526 si
= unshare_strinfo (si
);
1527 /* We shouldn't see delayed lengths here; the caller must
1528 have calculated the old length in order to calculate
1530 gcc_assert (si
->nonzero_chars
);
1531 tem
= fold_convert_loc (loc
, TREE_TYPE (si
->nonzero_chars
), adj
);
1532 si
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
1533 TREE_TYPE (si
->nonzero_chars
),
1534 si
->nonzero_chars
, tem
);
1535 si
->full_string_p
= origsi
->full_string_p
;
1537 si
->endptr
= NULL_TREE
;
1538 si
->dont_invalidate
= true;
1540 nsi
= get_next_strinfo (si
);
1547 /* Find if there are other SSA_NAME pointers equal to PTR
1548 for which we don't track their string lengths yet. If so, use
1552 find_equal_ptrs (tree ptr
, int idx
)
1554 if (TREE_CODE (ptr
) != SSA_NAME
)
1558 gimple
*stmt
= SSA_NAME_DEF_STMT (ptr
);
1559 if (!is_gimple_assign (stmt
))
1561 ptr
= gimple_assign_rhs1 (stmt
);
1562 switch (gimple_assign_rhs_code (stmt
))
1567 if (!POINTER_TYPE_P (TREE_TYPE (ptr
)))
1569 if (TREE_CODE (ptr
) == SSA_NAME
)
1571 if (TREE_CODE (ptr
) != ADDR_EXPR
)
1576 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1577 if (pidx
!= NULL
&& *pidx
== 0)
1585 /* We might find an endptr created in this pass. Grow the
1586 vector in that case. */
1587 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1588 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
1590 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] != 0)
1592 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = idx
;
1596 /* Return true if STMT is a call to a builtin function with the right
1597 arguments and attributes that should be considered for optimization
1601 valid_builtin_call (gimple
*stmt
)
1603 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
1606 tree callee
= gimple_call_fndecl (stmt
);
1607 tree decl
= builtin_decl_explicit (DECL_FUNCTION_CODE (callee
));
1610 && !gimple_builtin_call_types_compatible_p (stmt
, decl
))
1613 switch (DECL_FUNCTION_CODE (callee
))
1615 case BUILT_IN_MEMCMP
:
1616 case BUILT_IN_MEMCMP_EQ
:
1617 case BUILT_IN_STRCMP
:
1618 case BUILT_IN_STRNCMP
:
1619 case BUILT_IN_STRCHR
:
1620 case BUILT_IN_STRLEN
:
1621 case BUILT_IN_STRNLEN
:
1622 /* The above functions should be pure. Punt if they aren't. */
1623 if (gimple_vdef (stmt
) || gimple_vuse (stmt
) == NULL_TREE
)
1627 case BUILT_IN_ALLOCA
:
1628 case BUILT_IN_ALLOCA_WITH_ALIGN
:
1629 case BUILT_IN_CALLOC
:
1630 case BUILT_IN_MALLOC
:
1631 case BUILT_IN_MEMCPY
:
1632 case BUILT_IN_MEMCPY_CHK
:
1633 case BUILT_IN_MEMPCPY
:
1634 case BUILT_IN_MEMPCPY_CHK
:
1635 case BUILT_IN_MEMSET
:
1636 case BUILT_IN_STPCPY
:
1637 case BUILT_IN_STPCPY_CHK
:
1638 case BUILT_IN_STPNCPY
:
1639 case BUILT_IN_STPNCPY_CHK
:
1640 case BUILT_IN_STRCAT
:
1641 case BUILT_IN_STRCAT_CHK
:
1642 case BUILT_IN_STRCPY
:
1643 case BUILT_IN_STRCPY_CHK
:
1644 case BUILT_IN_STRNCAT
:
1645 case BUILT_IN_STRNCAT_CHK
:
1646 case BUILT_IN_STRNCPY
:
1647 case BUILT_IN_STRNCPY_CHK
:
1648 /* The above functions should be neither const nor pure. Punt if they
1650 if (gimple_vdef (stmt
) == NULL_TREE
|| gimple_vuse (stmt
) == NULL_TREE
)
1661 /* If the last .MEM setter statement before STMT is
1662 memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1663 and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1664 just memcpy (x, y, strlen (y)). SI must be the zero length
1668 adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
,
1669 pointer_query
&ptr_qry
)
1671 tree vuse
, callee
, len
;
1672 struct laststmt_struct last
= laststmt
;
1673 strinfo
*lastsi
, *firstsi
;
1674 unsigned len_arg_no
= 2;
1676 laststmt
.stmt
= NULL
;
1677 laststmt
.len
= NULL_TREE
;
1678 laststmt
.stridx
= 0;
1680 if (last
.stmt
== NULL
)
1683 vuse
= gimple_vuse (stmt
);
1684 if (vuse
== NULL_TREE
1685 || SSA_NAME_DEF_STMT (vuse
) != last
.stmt
1686 || !has_single_use (vuse
))
1689 gcc_assert (last
.stridx
> 0);
1690 lastsi
= get_strinfo (last
.stridx
);
1696 if (lastsi
->first
== 0 || lastsi
->first
!= si
->first
)
1699 firstsi
= verify_related_strinfos (si
);
1700 if (firstsi
== NULL
)
1702 while (firstsi
!= lastsi
)
1704 firstsi
= get_next_strinfo (firstsi
);
1705 if (firstsi
== NULL
)
1710 if (!is_strcat
&& !zero_length_string_p (si
))
1713 if (is_gimple_assign (last
.stmt
))
1715 gimple_stmt_iterator gsi
;
1717 if (!integer_zerop (gimple_assign_rhs1 (last
.stmt
)))
1719 if (stmt_could_throw_p (cfun
, last
.stmt
))
1721 gsi
= gsi_for_stmt (last
.stmt
);
1722 unlink_stmt_vdef (last
.stmt
);
1723 release_defs (last
.stmt
);
1724 gsi_remove (&gsi
, true);
1728 if (!valid_builtin_call (last
.stmt
))
1731 callee
= gimple_call_fndecl (last
.stmt
);
1732 switch (DECL_FUNCTION_CODE (callee
))
1734 case BUILT_IN_MEMCPY
:
1735 case BUILT_IN_MEMCPY_CHK
:
1741 len
= gimple_call_arg (last
.stmt
, len_arg_no
);
1742 if (tree_fits_uhwi_p (len
))
1744 if (!tree_fits_uhwi_p (last
.len
)
1745 || integer_zerop (len
)
1746 || tree_to_uhwi (len
) != tree_to_uhwi (last
.len
) + 1)
1748 /* Don't adjust the length if it is divisible by 4, it is more efficient
1749 to store the extra '\0' in that case. */
1750 if ((tree_to_uhwi (len
) & 3) == 0)
1753 /* Don't fold away an out of bounds access, as this defeats proper
1755 tree dst
= gimple_call_arg (last
.stmt
, 0);
1758 tree size
= compute_objsize (dst
, 1, &aref
, &ptr_qry
);
1759 if (size
&& tree_int_cst_lt (size
, len
))
1762 else if (TREE_CODE (len
) == SSA_NAME
)
1764 gimple
*def_stmt
= SSA_NAME_DEF_STMT (len
);
1765 if (!is_gimple_assign (def_stmt
)
1766 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
1767 || gimple_assign_rhs1 (def_stmt
) != last
.len
1768 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
1774 gimple_call_set_arg (last
.stmt
, len_arg_no
, last
.len
);
1775 update_stmt (last
.stmt
);
1778 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1779 call, or when BOUND is non-null, of a strnlen() call, set LHS
1780 range info to [0, min (MAX, BOUND)] when the range includes more
1781 than one value and return LHS. Otherwise, when the range
1782 [MIN, MAX] is such that MIN == MAX, return the tree representation
1783 of (MIN). The latter allows callers to fold suitable strnlen() calls
1787 set_strlen_range (tree lhs
, wide_int min
, wide_int max
,
1788 tree bound
/* = NULL_TREE */)
1790 if (TREE_CODE (lhs
) != SSA_NAME
1791 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1796 /* For strnlen, adjust MIN and MAX as necessary. If the bound
1797 is less than the size of the array set MAX to it. It it's
1798 greater than MAX and MAX is non-zero bump MAX down to account
1799 for the necessary terminating nul. Otherwise leave it alone. */
1800 if (TREE_CODE (bound
) == INTEGER_CST
)
1802 wide_int wibnd
= wi::to_wide (bound
);
1803 int cmp
= wi::cmpu (wibnd
, max
);
1806 else if (cmp
&& wi::ne_p (max
, min
))
1809 else if (TREE_CODE (bound
) == SSA_NAME
)
1812 get_range_query (cfun
)->range_of_expr (r
, bound
);
1813 if (!r
.undefined_p ())
1815 /* For a bound in a known range, adjust the range determined
1816 above as necessary. For a bound in some anti-range or
1817 in an unknown range, use the range determined by callers. */
1818 if (wi::ltu_p (r
.lower_bound (), min
))
1819 min
= r
.lower_bound ();
1820 if (wi::ltu_p (r
.upper_bound (), max
))
1821 max
= r
.upper_bound ();
1827 return wide_int_to_tree (size_type_node
, min
);
1829 set_range_info (lhs
, VR_RANGE
, min
, max
);
1833 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1834 SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1835 a character array A[N] with unknown length bounded by N, and for
1836 strnlen(), by min (N, BOUND). */
1839 maybe_set_strlen_range (tree lhs
, tree src
, tree bound
)
1841 if (TREE_CODE (lhs
) != SSA_NAME
1842 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1845 if (TREE_CODE (src
) == SSA_NAME
)
1847 gimple
*def
= SSA_NAME_DEF_STMT (src
);
1848 if (is_gimple_assign (def
)
1849 && gimple_assign_rhs_code (def
) == ADDR_EXPR
)
1850 src
= gimple_assign_rhs1 (def
);
1853 /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1854 NUL so that the difference between a pointer to just past it and
1855 one to its beginning is positive. */
1856 wide_int max
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
1858 if (TREE_CODE (src
) == ADDR_EXPR
)
1860 /* The last array member of a struct can be bigger than its size
1861 suggests if it's treated as a poor-man's flexible array member. */
1862 src
= TREE_OPERAND (src
, 0);
1863 if (TREE_CODE (src
) != MEM_REF
1864 && !array_at_struct_end_p (src
))
1866 tree type
= TREE_TYPE (src
);
1867 tree size
= TYPE_SIZE_UNIT (type
);
1869 && TREE_CODE (size
) == INTEGER_CST
1870 && !integer_zerop (size
))
1872 /* Even though such uses of strlen would be undefined,
1873 avoid relying on arrays of arrays in case some genius
1874 decides to call strlen on an unterminated array element
1875 that's followed by a terminated one. Likewise, avoid
1876 assuming that a struct array member is necessarily
1877 nul-terminated (the nul may be in the member that
1878 follows). In those cases, assume that the length
1879 of the string stored in such an array is bounded
1880 by the size of the enclosing object if one can be
1882 tree base
= get_base_address (src
);
1885 if (tree size
= DECL_SIZE_UNIT (base
))
1887 && TREE_CODE (size
) == INTEGER_CST
1888 && TREE_CODE (TREE_TYPE (base
)) != POINTER_TYPE
)
1889 max
= wi::to_wide (size
);
1893 /* For strlen() the upper bound above is equal to
1894 the longest string that can be stored in the array
1895 (i.e., it accounts for the terminating nul. For
1896 strnlen() bump up the maximum by one since the array
1897 need not be nul-terminated. */
1898 if (!bound
&& max
!= 0)
1903 wide_int min
= wi::zero (max
.get_precision ());
1904 return set_strlen_range (lhs
, min
, max
, bound
);
1907 /* Diagnose buffer overflow by a STMT writing LEN + PLUS_ONE bytes,
1908 either into a region allocated for the object SI when non-null,
1909 or into an object designated by the LHS of STMT otherwise.
1910 For a call STMT, when CALL_LHS is set use its left hand side
1911 as the destination, otherwise use argument zero.
1912 When nonnull uses RVALS to determine range information.
1913 RAWMEM may be set by memcpy and other raw memory functions
1914 to allow accesses across subobject boundaries. */
1917 maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, tree len
,
1918 pointer_query
&ptr_qry
,
1919 strinfo
*si
= NULL
, bool plus_one
= false,
1920 bool rawmem
= false)
1922 if (!len
|| warning_suppressed_p (stmt
, OPT_Wstringop_overflow_
))
1925 /* The DECL of the function performing the write if it is done
1927 tree writefn
= NULL_TREE
;
1928 /* The destination expression involved in the store or call STMT. */
1929 tree dest
= NULL_TREE
;
1931 if (is_gimple_assign (stmt
))
1932 dest
= gimple_assign_lhs (stmt
);
1933 else if (is_gimple_call (stmt
))
1936 dest
= gimple_call_lhs (stmt
);
1939 gcc_assert (gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
));
1940 dest
= gimple_call_arg (stmt
, 0);
1945 writefn
= gimple_call_fndecl (stmt
);
1950 if (warning_suppressed_p (dest
, OPT_Wstringop_overflow_
))
1953 const int ostype
= rawmem
? 0 : 1;
1955 /* Use maximum precision to avoid overflow in the addition below.
1956 Make sure all operands have the same precision to keep wide_int
1960 /* The size of the destination region (which is smaller than
1961 the destination object for stores at a non-zero offset). */
1962 tree destsize
= compute_objsize (dest
, ostype
, &aref
, &ptr_qry
);
1967 aref
.sizrng
[1] = wi::to_offset (max_object_size ());
1970 /* Return early if the DESTSIZE size expression is the same as LEN
1971 and the offset into the destination is zero. This might happen
1972 in the case of a pair of malloc and memset calls to allocate
1973 an object and clear it as if by calloc. */
1974 if (destsize
== len
&& !plus_one
1975 && aref
.offrng
[0] == 0 && aref
.offrng
[0] == aref
.offrng
[1])
1979 if (!get_range (len
, stmt
, rng
, ptr_qry
.rvals
))
1982 widest_int lenrng
[2] =
1983 { widest_int::from (rng
[0], SIGNED
), widest_int::from (rng
[1], SIGNED
) };
1991 /* The size of the remaining space in the destination computed
1992 as the size of the latter minus the offset into it. */
1993 widest_int spcrng
[2];
1995 offset_int remrng
[2];
1996 remrng
[1] = aref
.size_remaining (remrng
);
1997 spcrng
[0] = remrng
[0] == -1 ? 0 : widest_int::from (remrng
[0], UNSIGNED
);
1998 spcrng
[1] = widest_int::from (remrng
[1], UNSIGNED
);
2001 if (wi::leu_p (lenrng
[0], spcrng
[0])
2002 && wi::leu_p (lenrng
[1], spcrng
[1]))
2005 location_t loc
= gimple_or_expr_nonartificial_location (stmt
, dest
);
2006 bool warned
= false;
2007 if (wi::leu_p (lenrng
[0], spcrng
[1]))
2010 && (!si
|| rawmem
|| !is_strlen_related_p (si
->ptr
, len
)))
2014 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2015 "%qD writing one too many bytes into a region "
2016 "of a size that depends on %<strlen%>",
2018 : warning_at (loc
, OPT_Wstringop_overflow_
,
2019 "writing one too many bytes into a region "
2020 "of a size that depends on %<strlen%>"));
2022 else if (lenrng
[0] == lenrng
[1])
2024 if (spcrng
[0] == spcrng
[1])
2026 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2027 lenrng
[0].to_uhwi (),
2028 "%qD writing %wu byte into a region "
2030 "%qD writing %wu bytes into a region "
2032 writefn
, lenrng
[0].to_uhwi (),
2033 spcrng
[0].to_uhwi ())
2034 : warning_n (loc
, OPT_Wstringop_overflow_
,
2035 lenrng
[0].to_uhwi (),
2036 "writing %wu byte into a region "
2038 "writing %wu bytes into a region "
2040 lenrng
[0].to_uhwi (),
2041 spcrng
[0].to_uhwi ()));
2044 ? warning_n (loc
, OPT_Wstringop_overflow_
,
2045 lenrng
[0].to_uhwi (),
2046 "%qD writing %wu byte into a region "
2047 "of size between %wu and %wu",
2048 "%qD writing %wu bytes into a region "
2049 "of size between %wu and %wu",
2050 writefn
, lenrng
[0].to_uhwi (),
2051 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2052 : warning_n (loc
, OPT_Wstringop_overflow_
,
2053 lenrng
[0].to_uhwi (),
2054 "writing %wu byte into a region "
2055 "of size between %wu and %wu",
2056 "writing %wu bytes into a region "
2057 "of size between %wu and %wu",
2058 lenrng
[0].to_uhwi (),
2059 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2061 else if (spcrng
[0] == spcrng
[1])
2063 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2064 "%qD writing between %wu and %wu bytes "
2065 "into a region of size %wu",
2066 writefn
, lenrng
[0].to_uhwi (),
2067 lenrng
[1].to_uhwi (),
2068 spcrng
[0].to_uhwi ())
2069 : warning_at (loc
, OPT_Wstringop_overflow_
,
2070 "writing between %wu and %wu bytes "
2071 "into a region of size %wu",
2072 lenrng
[0].to_uhwi (),
2073 lenrng
[1].to_uhwi (),
2074 spcrng
[0].to_uhwi ()));
2077 ? warning_at (loc
, OPT_Wstringop_overflow_
,
2078 "%qD writing between %wu and %wu bytes "
2079 "into a region of size between %wu and %wu",
2080 writefn
, lenrng
[0].to_uhwi (),
2081 lenrng
[1].to_uhwi (),
2082 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ())
2083 : warning_at (loc
, OPT_Wstringop_overflow_
,
2084 "writing between %wu and %wu bytes "
2085 "into a region of size between %wu and %wu",
2086 lenrng
[0].to_uhwi (),
2087 lenrng
[1].to_uhwi (),
2088 spcrng
[0].to_uhwi (), spcrng
[1].to_uhwi ()));
2093 suppress_warning (stmt
, OPT_Wstringop_overflow_
);
2095 aref
.inform_access (access_write_only
);
2098 /* Convenience wrapper for the above. */
2101 maybe_warn_overflow (gimple
*stmt
, bool call_lhs
, unsigned HOST_WIDE_INT len
,
2102 pointer_query
&ptr_qry
, strinfo
*si
= NULL
,
2103 bool plus_one
= false, bool rawmem
= false)
2105 tree tlen
= build_int_cst (size_type_node
, len
);
2106 maybe_warn_overflow (stmt
, call_lhs
, tlen
, ptr_qry
, si
, plus_one
, rawmem
);
2109 /* Handle a strlen call. If strlen of the argument is known, replace
2110 the strlen call with the known value, otherwise remember that strlen
2111 of the argument is stored in the lhs SSA_NAME. */
2114 handle_builtin_strlen (gimple_stmt_iterator
*gsi
)
2116 gimple
*stmt
= gsi_stmt (*gsi
);
2117 tree lhs
= gimple_call_lhs (stmt
);
2119 if (lhs
== NULL_TREE
)
2122 location_t loc
= gimple_location (stmt
);
2123 tree callee
= gimple_call_fndecl (stmt
);
2124 tree src
= gimple_call_arg (stmt
, 0);
2125 tree bound
= (DECL_FUNCTION_CODE (callee
) == BUILT_IN_STRNLEN
2126 ? gimple_call_arg (stmt
, 1) : NULL_TREE
);
2127 int idx
= get_stridx (src
);
2128 if (idx
|| (bound
&& integer_zerop (bound
)))
2134 rhs
= build_int_cst (TREE_TYPE (lhs
), ~idx
);
2140 si
= get_strinfo (idx
);
2143 rhs
= get_string_length (si
);
2144 /* For strnlen, if bound is constant, even if si is not known
2145 to be zero terminated, if we know at least bound bytes are
2146 not zero, the return value will be bound. */
2147 if (rhs
== NULL_TREE
2148 && bound
!= NULL_TREE
2149 && TREE_CODE (bound
) == INTEGER_CST
2150 && si
->nonzero_chars
!= NULL_TREE
2151 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
2152 && tree_int_cst_le (bound
, si
->nonzero_chars
))
2156 if (rhs
!= NULL_TREE
)
2158 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2160 fprintf (dump_file
, "Optimizing: ");
2161 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2163 rhs
= unshare_expr (rhs
);
2164 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
2165 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2168 rhs
= fold_build2_loc (loc
, MIN_EXPR
, TREE_TYPE (rhs
), rhs
, bound
);
2170 gimplify_and_update_call_from_tree (gsi
, rhs
);
2171 stmt
= gsi_stmt (*gsi
);
2173 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2175 fprintf (dump_file
, "into: ");
2176 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2180 /* Don't update anything for strnlen. */
2181 && bound
== NULL_TREE
2182 && TREE_CODE (si
->nonzero_chars
) != SSA_NAME
2183 && TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
2184 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2186 si
= unshare_strinfo (si
);
2187 si
->nonzero_chars
= lhs
;
2188 gcc_assert (si
->full_string_p
);
2191 if (strlen_to_stridx
2192 && (bound
== NULL_TREE
2193 /* For strnlen record this only if the call is proven
2194 to return the same value as strlen would. */
2195 || (TREE_CODE (bound
) == INTEGER_CST
2196 && TREE_CODE (rhs
) == INTEGER_CST
2197 && tree_int_cst_lt (rhs
, bound
))))
2198 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2203 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2207 idx
= new_stridx (src
);
2210 strinfo
*si
= get_strinfo (idx
);
2213 if (!si
->full_string_p
&& !si
->stmt
)
2215 /* Until now we only had a lower bound on the string length.
2216 Install LHS as the actual length. */
2217 si
= unshare_strinfo (si
);
2218 tree old
= si
->nonzero_chars
;
2219 si
->nonzero_chars
= lhs
;
2220 si
->full_string_p
= true;
2221 if (old
&& TREE_CODE (old
) == INTEGER_CST
)
2223 old
= fold_convert_loc (loc
, TREE_TYPE (lhs
), old
);
2224 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2225 TREE_TYPE (lhs
), lhs
, old
);
2226 adjust_related_strinfos (loc
, si
, adj
);
2227 /* Use the constant minimum length as the lower bound
2228 of the non-constant length. */
2229 wide_int min
= wi::to_wide (old
);
2231 = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
2232 set_strlen_range (lhs
, min
, max
);
2248 /* Only store the new length information for calls to strlen(),
2249 not for those to strnlen(). */
2250 strinfo
*si
= new_strinfo (src
, idx
, lhs
, true);
2251 set_strinfo (idx
, si
);
2252 find_equal_ptrs (src
, idx
);
2255 /* For SRC that is an array of N elements, set LHS's range
2256 to [0, min (N, BOUND)]. A constant return value means
2257 the range would have consisted of a single value. In
2258 that case, fold the result into the returned constant. */
2259 if (tree ret
= maybe_set_strlen_range (lhs
, src
, bound
))
2260 if (TREE_CODE (ret
) == INTEGER_CST
)
2262 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2264 fprintf (dump_file
, "Optimizing: ");
2265 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2267 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (ret
)))
2268 ret
= fold_convert_loc (loc
, TREE_TYPE (lhs
), ret
);
2269 gimplify_and_update_call_from_tree (gsi
, ret
);
2270 stmt
= gsi_stmt (*gsi
);
2272 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2274 fprintf (dump_file
, "into: ");
2275 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2279 if (strlen_to_stridx
&& !bound
)
2280 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
2284 /* Handle a strchr call. If strlen of the first argument is known, replace
2285 the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
2286 that lhs of the call is endptr and strlen of the argument is endptr - x. */
2289 handle_builtin_strchr (gimple_stmt_iterator
*gsi
)
2291 gimple
*stmt
= gsi_stmt (*gsi
);
2292 tree lhs
= gimple_call_lhs (stmt
);
2294 if (lhs
== NULL_TREE
)
2297 if (!integer_zerop (gimple_call_arg (stmt
, 1)))
2300 tree src
= gimple_call_arg (stmt
, 0);
2302 /* Avoid folding if the first argument is not a nul-terminated array.
2303 Defer warning until later. */
2304 if (!check_nul_terminated_array (NULL_TREE
, src
))
2307 int idx
= get_stridx (src
);
2314 rhs
= build_int_cst (size_type_node
, ~idx
);
2318 si
= get_strinfo (idx
);
2320 rhs
= get_string_length (si
);
2322 if (rhs
!= NULL_TREE
)
2324 location_t loc
= gimple_location (stmt
);
2326 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2328 fprintf (dump_file
, "Optimizing: ");
2329 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2331 if (si
!= NULL
&& si
->endptr
!= NULL_TREE
)
2333 rhs
= unshare_expr (si
->endptr
);
2334 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2336 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2340 rhs
= fold_convert_loc (loc
, sizetype
, unshare_expr (rhs
));
2341 rhs
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
,
2342 TREE_TYPE (src
), src
, rhs
);
2343 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
2345 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
2347 gimplify_and_update_call_from_tree (gsi
, rhs
);
2348 stmt
= gsi_stmt (*gsi
);
2350 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2352 fprintf (dump_file
, "into: ");
2353 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2356 && si
->endptr
== NULL_TREE
2357 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2359 si
= unshare_strinfo (si
);
2362 zero_length_string (lhs
, si
);
2366 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
2368 if (TREE_CODE (src
) != SSA_NAME
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src
))
2371 idx
= new_stridx (src
);
2372 else if (get_strinfo (idx
) != NULL
)
2374 zero_length_string (lhs
, NULL
);
2379 location_t loc
= gimple_location (stmt
);
2380 tree lhsu
= fold_convert_loc (loc
, size_type_node
, lhs
);
2381 tree srcu
= fold_convert_loc (loc
, size_type_node
, src
);
2382 tree length
= fold_build2_loc (loc
, MINUS_EXPR
,
2383 size_type_node
, lhsu
, srcu
);
2384 strinfo
*si
= new_strinfo (src
, idx
, length
, true);
2386 set_strinfo (idx
, si
);
2387 find_equal_ptrs (src
, idx
);
2388 zero_length_string (lhs
, si
);
2392 zero_length_string (lhs
, NULL
);
2395 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
2396 If strlen of the second argument is known, strlen of the first argument
2397 is the same after this call. Furthermore, attempt to convert it to
2398 memcpy. Uses RVALS to determine range information. */
2401 handle_builtin_strcpy (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
,
2402 pointer_query
&ptr_qry
)
2405 tree src
, dst
, srclen
, len
, lhs
, type
, fn
, oldlen
;
2407 gimple
*stmt
= gsi_stmt (*gsi
);
2408 strinfo
*si
, *dsi
, *olddsi
, *zsi
;
2411 src
= gimple_call_arg (stmt
, 1);
2412 dst
= gimple_call_arg (stmt
, 0);
2413 lhs
= gimple_call_lhs (stmt
);
2414 idx
= get_stridx (src
);
2417 si
= get_strinfo (idx
);
2419 didx
= get_stridx (dst
);
2423 olddsi
= get_strinfo (didx
);
2428 adjust_last_stmt (olddsi
, stmt
, false, ptr_qry
);
2432 srclen
= get_string_length (si
);
2434 srclen
= build_int_cst (size_type_node
, ~idx
);
2436 maybe_warn_overflow (stmt
, false, srclen
, ptr_qry
, olddsi
, true);
2439 adjust_last_stmt (olddsi
, stmt
, false, ptr_qry
);
2441 loc
= gimple_location (stmt
);
2442 if (srclen
== NULL_TREE
)
2445 case BUILT_IN_STRCPY
:
2446 case BUILT_IN_STRCPY_CHK
:
2447 if (lhs
!= NULL_TREE
|| !builtin_decl_implicit_p (BUILT_IN_STPCPY
))
2450 case BUILT_IN_STPCPY
:
2451 case BUILT_IN_STPCPY_CHK
:
2452 if (lhs
== NULL_TREE
)
2456 tree lhsuint
= fold_convert_loc (loc
, size_type_node
, lhs
);
2457 srclen
= fold_convert_loc (loc
, size_type_node
, dst
);
2458 srclen
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
2468 didx
= new_stridx (dst
);
2474 oldlen
= olddsi
->nonzero_chars
;
2475 dsi
= unshare_strinfo (olddsi
);
2476 dsi
->nonzero_chars
= srclen
;
2477 dsi
->full_string_p
= (srclen
!= NULL_TREE
);
2478 /* Break the chain, so adjust_related_strinfo on later pointers in
2479 the chain won't adjust this one anymore. */
2482 dsi
->endptr
= NULL_TREE
;
2486 dsi
= new_strinfo (dst
, didx
, srclen
, srclen
!= NULL_TREE
);
2487 set_strinfo (didx
, dsi
);
2488 find_equal_ptrs (dst
, didx
);
2490 dsi
->writable
= true;
2491 dsi
->dont_invalidate
= true;
2493 if (dsi
->nonzero_chars
== NULL_TREE
)
2497 /* If string length of src is unknown, use delayed length
2498 computation. If string length of dst will be needed, it
2499 can be computed by transforming this strcpy call into
2500 stpcpy and subtracting dst from the return value. */
2502 /* Look for earlier strings whose length could be determined if
2503 this strcpy is turned into an stpcpy. */
2505 if (dsi
->prev
!= 0 && (chainsi
= verify_related_strinfos (dsi
)) != NULL
)
2507 for (; chainsi
&& chainsi
!= dsi
; chainsi
= get_strinfo (chainsi
->next
))
2509 /* When setting a stmt for delayed length computation
2510 prevent all strinfos through dsi from being
2512 chainsi
= unshare_strinfo (chainsi
);
2513 chainsi
->stmt
= stmt
;
2514 chainsi
->nonzero_chars
= NULL_TREE
;
2515 chainsi
->full_string_p
= false;
2516 chainsi
->endptr
= NULL_TREE
;
2517 chainsi
->dont_invalidate
= true;
2522 /* Try to detect overlap before returning. This catches cases
2523 like strcpy (d, d + n) where n is non-constant whose range
2524 is such that (n <= strlen (d) holds).
2526 OLDDSI->NONZERO_chars may have been reset by this point with
2527 oldlen holding it original value. */
2528 if (olddsi
&& oldlen
)
2530 /* Add 1 for the terminating NUL. */
2531 tree type
= TREE_TYPE (oldlen
);
2532 oldlen
= fold_build2 (PLUS_EXPR
, type
, oldlen
,
2533 build_int_cst (type
, 1));
2534 check_bounds_or_overlap (stmt
, olddsi
->ptr
, src
, oldlen
, NULL_TREE
);
2542 tree adj
= NULL_TREE
;
2543 if (oldlen
== NULL_TREE
)
2545 else if (integer_zerop (oldlen
))
2547 else if (TREE_CODE (oldlen
) == INTEGER_CST
2548 || TREE_CODE (srclen
) == INTEGER_CST
)
2549 adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2550 TREE_TYPE (srclen
), srclen
,
2551 fold_convert_loc (loc
, TREE_TYPE (srclen
),
2553 if (adj
!= NULL_TREE
)
2554 adjust_related_strinfos (loc
, dsi
, adj
);
2558 /* strcpy src may not overlap dst, so src doesn't need to be
2559 invalidated either. */
2561 si
->dont_invalidate
= true;
2567 case BUILT_IN_STRCPY
:
2568 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
2570 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2572 case BUILT_IN_STRCPY_CHK
:
2573 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
2575 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2577 case BUILT_IN_STPCPY
:
2578 /* This would need adjustment of the lhs (subtract one),
2579 or detection that the trailing '\0' doesn't need to be
2580 written, if it will be immediately overwritten.
2581 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); */
2585 zsi
= zero_length_string (lhs
, dsi
);
2588 case BUILT_IN_STPCPY_CHK
:
2589 /* This would need adjustment of the lhs (subtract one),
2590 or detection that the trailing '\0' doesn't need to be
2591 written, if it will be immediately overwritten.
2592 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK); */
2596 zsi
= zero_length_string (lhs
, dsi
);
2603 zsi
->dont_invalidate
= true;
2607 tree args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
2608 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
2611 type
= size_type_node
;
2613 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
2614 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
, build_int_cst (type
, 1));
2616 /* Disable warning for the transformed statement? */
2617 opt_code no_warning_opt
= no_warning
;
2619 if (const strinfo
*chksi
= si
? olddsi
? olddsi
: dsi
: NULL
)
2621 no_warning_opt
= check_bounds_or_overlap (stmt
, chksi
->ptr
, si
->ptr
,
2624 suppress_warning (stmt
, no_warning_opt
);
2627 if (fn
== NULL_TREE
)
2630 len
= force_gimple_operand_gsi (gsi
, len
, true, NULL_TREE
, true,
2632 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2634 fprintf (dump_file
, "Optimizing: ");
2635 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2637 if (gimple_call_num_args (stmt
) == 2)
2638 success
= update_gimple_call (gsi
, fn
, 3, dst
, src
, len
);
2640 success
= update_gimple_call (gsi
, fn
, 4, dst
, src
, len
,
2641 gimple_call_arg (stmt
, 2));
2644 stmt
= gsi_stmt (*gsi
);
2646 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2648 fprintf (dump_file
, "into: ");
2649 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2651 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2652 laststmt
.stmt
= stmt
;
2653 laststmt
.len
= srclen
;
2654 laststmt
.stridx
= dsi
->idx
;
2656 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2657 fprintf (dump_file
, "not possible.\n");
2660 suppress_warning (stmt
, no_warning_opt
);
2663 /* Check the size argument to the built-in forms of stpncpy and strncpy
2664 for out-of-bounds offsets or overlapping access, and to see if the
2665 size argument is derived from a call to strlen() on the source argument,
2666 and if so, issue an appropriate warning. */
2669 handle_builtin_strncat (built_in_function
, gimple_stmt_iterator
*gsi
)
2671 /* Same as stxncpy(). */
2672 handle_builtin_stxncpy_strncat (true, gsi
);
2675 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2676 way. LEN can either be an integer expression, or a pointer (to char).
2677 When it is the latter (such as in recursive calls to self) it is
2678 assumed to be the argument in some call to strlen() whose relationship
2679 to SRC is being ascertained. */
2682 is_strlen_related_p (tree src
, tree len
)
2684 if (TREE_CODE (TREE_TYPE (len
)) == POINTER_TYPE
2685 && operand_equal_p (src
, len
, 0))
2688 if (TREE_CODE (len
) != SSA_NAME
)
2691 if (TREE_CODE (src
) == SSA_NAME
)
2693 gimple
*srcdef
= SSA_NAME_DEF_STMT (src
);
2694 if (is_gimple_assign (srcdef
))
2696 /* Handle bitwise AND used in conversions from wider size_t
2697 to narrower unsigned types. */
2698 tree_code code
= gimple_assign_rhs_code (srcdef
);
2699 if (code
== BIT_AND_EXPR
2700 || code
== NOP_EXPR
)
2701 return is_strlen_related_p (gimple_assign_rhs1 (srcdef
), len
);
2706 if (gimple_call_builtin_p (srcdef
, BUILT_IN_NORMAL
))
2708 /* If SRC is the result of a call to an allocation function
2709 or strlen, use the function's argument instead. */
2710 tree func
= gimple_call_fndecl (srcdef
);
2711 built_in_function code
= DECL_FUNCTION_CODE (func
);
2712 if (code
== BUILT_IN_ALLOCA
2713 || code
== BUILT_IN_ALLOCA_WITH_ALIGN
2714 || code
== BUILT_IN_MALLOC
2715 || code
== BUILT_IN_STRLEN
)
2716 return is_strlen_related_p (gimple_call_arg (srcdef
, 0), len
);
2718 /* FIXME: Handle other functions with attribute alloc_size. */
2723 gimple
*lendef
= SSA_NAME_DEF_STMT (len
);
2727 if (is_gimple_call (lendef
))
2729 tree func
= gimple_call_fndecl (lendef
);
2730 if (!valid_builtin_call (lendef
)
2731 || DECL_FUNCTION_CODE (func
) != BUILT_IN_STRLEN
)
2734 tree arg
= gimple_call_arg (lendef
, 0);
2735 return is_strlen_related_p (src
, arg
);
2738 if (!is_gimple_assign (lendef
))
2741 tree_code code
= gimple_assign_rhs_code (lendef
);
2742 tree rhs1
= gimple_assign_rhs1 (lendef
);
2743 tree rhstype
= TREE_TYPE (rhs1
);
2745 if ((TREE_CODE (rhstype
) == POINTER_TYPE
&& code
== POINTER_PLUS_EXPR
)
2746 || (INTEGRAL_TYPE_P (rhstype
)
2747 && (code
== BIT_AND_EXPR
2748 || code
== NOP_EXPR
)))
2750 /* Pointer plus (an integer), and truncation are considered among
2751 the (potentially) related expressions to strlen. */
2752 return is_strlen_related_p (src
, rhs1
);
2755 if (tree rhs2
= gimple_assign_rhs2 (lendef
))
2757 /* Integer subtraction is considered strlen-related when both
2758 arguments are integers and second one is strlen-related. */
2759 rhstype
= TREE_TYPE (rhs2
);
2760 if (INTEGRAL_TYPE_P (rhstype
) && code
== MINUS_EXPR
)
2761 return is_strlen_related_p (src
, rhs2
);
2767 /* Called by handle_builtin_stxncpy_strncat and by
2768 gimple_fold_builtin_strncpy in gimple-fold.c.
2769 Check to see if the specified bound is a) equal to the size of
2770 the destination DST and if so, b) if it's immediately followed by
2771 DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise,
2772 do nothing. Return true if diagnostic has been issued.
2774 The purpose is to diagnose calls to strncpy and stpncpy that do
2775 not nul-terminate the copy while allowing for the idiom where
2776 such a call is immediately followed by setting the last element
2779 strncpy (a, s, sizeof a);
2780 a[sizeof a - 1] = '\0';
2784 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi
, tree src
, tree cnt
,
2785 pointer_query
*ptr_qry
/* = NULL */)
2787 gimple
*stmt
= gsi_stmt (gsi
);
2788 if (warning_suppressed_p (stmt
, OPT_Wstringop_truncation
))
2791 wide_int cntrange
[2];
2793 if (!get_range_query (cfun
)->range_of_expr (r
, cnt
)
2795 || r
.undefined_p ())
2798 cntrange
[0] = wi::to_wide (r
.min ());
2799 cntrange
[1] = wi::to_wide (r
.max ());
2800 if (r
.kind () == VR_ANTI_RANGE
)
2802 wide_int maxobjsize
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
));
2804 if (wi::ltu_p (cntrange
[1], maxobjsize
))
2806 cntrange
[0] = cntrange
[1] + 1;
2807 cntrange
[1] = maxobjsize
;
2811 cntrange
[1] = cntrange
[0] - 1;
2812 cntrange
[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt
)));
2816 /* Negative value is the constant string length. If it's less than
2817 the lower bound there is no truncation. Avoid calling get_stridx()
2818 when ssa_ver_to_stridx is empty. That implies the caller isn't
2819 running under the control of this pass and ssa_ver_to_stridx hasn't
2820 been created yet. */
2821 int sidx
= ssa_ver_to_stridx
.length () ? get_stridx (src
) : 0;
2822 if (sidx
< 0 && wi::gtu_p (cntrange
[0], ~sidx
))
2825 tree dst
= gimple_call_arg (stmt
, 0);
2827 if (TREE_CODE (dstdecl
) == ADDR_EXPR
)
2828 dstdecl
= TREE_OPERAND (dstdecl
, 0);
2830 tree ref
= NULL_TREE
;
2834 /* If the source is a non-string return early to avoid warning
2835 for possible truncation (if the truncation is certain SIDX
2837 tree srcdecl
= gimple_call_arg (stmt
, 1);
2838 if (TREE_CODE (srcdecl
) == ADDR_EXPR
)
2839 srcdecl
= TREE_OPERAND (srcdecl
, 0);
2840 if (get_attr_nonstring_decl (srcdecl
, &ref
))
2844 /* Likewise, if the destination refers to an array/pointer declared
2845 nonstring return early. */
2846 if (get_attr_nonstring_decl (dstdecl
, &ref
))
2849 /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2850 avoid the truncation warning. */
2851 gsi_next_nondebug (&gsi
);
2852 gimple
*next_stmt
= gsi_stmt (gsi
);
2855 /* When there is no statement in the same basic block check
2856 the immediate successor block. */
2857 if (basic_block bb
= gimple_bb (stmt
))
2859 if (single_succ_p (bb
))
2861 /* For simplicity, ignore blocks with multiple outgoing
2862 edges for now and only consider successor blocks along
2864 edge e
= EDGE_SUCC (bb
, 0);
2865 if (!(e
->flags
& EDGE_ABNORMAL
))
2867 gsi
= gsi_start_bb (e
->dest
);
2868 next_stmt
= gsi_stmt (gsi
);
2869 if (next_stmt
&& is_gimple_debug (next_stmt
))
2871 gsi_next_nondebug (&gsi
);
2872 next_stmt
= gsi_stmt (gsi
);
2879 if (next_stmt
&& is_gimple_assign (next_stmt
))
2881 tree lhs
= gimple_assign_lhs (next_stmt
);
2882 tree_code code
= TREE_CODE (lhs
);
2883 if (code
== ARRAY_REF
|| code
== MEM_REF
)
2884 lhs
= TREE_OPERAND (lhs
, 0);
2886 tree func
= gimple_call_fndecl (stmt
);
2887 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STPNCPY
)
2889 tree ret
= gimple_call_lhs (stmt
);
2890 if (ret
&& operand_equal_p (ret
, lhs
, 0))
2894 /* Determine the base address and offset of the reference,
2895 ignoring the innermost array index. */
2896 if (TREE_CODE (ref
) == ARRAY_REF
)
2897 ref
= TREE_OPERAND (ref
, 0);
2900 tree dstbase
= get_addr_base_and_unit_offset (ref
, &dstoff
);
2903 tree lhsbase
= get_addr_base_and_unit_offset (lhs
, &lhsoff
);
2906 && known_eq (dstoff
, lhsoff
)
2907 && operand_equal_p (dstbase
, lhsbase
, 0))
2911 int prec
= TYPE_PRECISION (TREE_TYPE (cnt
));
2912 wide_int lenrange
[2];
2913 if (strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
)
2915 lenrange
[0] = (sisrc
->nonzero_chars
2916 && TREE_CODE (sisrc
->nonzero_chars
) == INTEGER_CST
2917 ? wi::to_wide (sisrc
->nonzero_chars
)
2919 lenrange
[1] = lenrange
[0];
2922 lenrange
[0] = lenrange
[1] = wi::shwi (~sidx
, prec
);
2925 c_strlen_data lendata
= { };
2926 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
2927 to have it set to the length of the longest string in a PHI. */
2928 lendata
.maxbound
= src
;
2929 get_range_strlen (src
, &lendata
, /* eltsize = */1);
2930 if (TREE_CODE (lendata
.minlen
) == INTEGER_CST
2931 && TREE_CODE (lendata
.maxbound
) == INTEGER_CST
)
2933 /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
2934 which stores the length of the shortest known string. */
2935 if (integer_all_onesp (lendata
.maxlen
))
2936 lenrange
[0] = wi::shwi (0, prec
);
2938 lenrange
[0] = wi::to_wide (lendata
.minlen
, prec
);
2939 lenrange
[1] = wi::to_wide (lendata
.maxbound
, prec
);
2943 lenrange
[0] = wi::shwi (0, prec
);
2944 lenrange
[1] = wi::shwi (-1, prec
);
2948 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
2949 tree func
= gimple_call_fndecl (stmt
);
2951 if (lenrange
[0] != 0 || !wi::neg_p (lenrange
[1]))
2953 /* If the longest source string is shorter than the lower bound
2954 of the specified count the copy is definitely nul-terminated. */
2955 if (wi::ltu_p (lenrange
[1], cntrange
[0]))
2958 if (wi::neg_p (lenrange
[1]))
2960 /* The length of one of the strings is unknown but at least
2961 one has non-zero length and that length is stored in
2962 LENRANGE[1]. Swap the bounds to force a "may be truncated"
2964 lenrange
[1] = lenrange
[0];
2965 lenrange
[0] = wi::shwi (0, prec
);
2968 /* Set to true for strncat whose bound is derived from the length
2969 of the destination (the expected usage pattern). */
2970 bool cat_dstlen_bounded
= false;
2971 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STRNCAT
)
2972 cat_dstlen_bounded
= is_strlen_related_p (dst
, cnt
);
2974 if (lenrange
[0] == cntrange
[1] && cntrange
[0] == cntrange
[1])
2975 return warning_n (callloc
, OPT_Wstringop_truncation
,
2976 cntrange
[0].to_uhwi (),
2977 "%qD output truncated before terminating "
2978 "nul copying %E byte from a string of the "
2980 "%qD output truncated before terminating nul "
2981 "copying %E bytes from a string of the same "
2984 else if (!cat_dstlen_bounded
)
2986 if (wi::geu_p (lenrange
[0], cntrange
[1]))
2988 /* The shortest string is longer than the upper bound of
2989 the count so the truncation is certain. */
2990 if (cntrange
[0] == cntrange
[1])
2991 return warning_n (callloc
, OPT_Wstringop_truncation
,
2992 cntrange
[0].to_uhwi (),
2993 "%qD output truncated copying %E byte "
2994 "from a string of length %wu",
2995 "%qD output truncated copying %E bytes "
2996 "from a string of length %wu",
2997 func
, cnt
, lenrange
[0].to_uhwi ());
2999 return warning_at (callloc
, OPT_Wstringop_truncation
,
3000 "%qD output truncated copying between %wu "
3001 "and %wu bytes from a string of length %wu",
3002 func
, cntrange
[0].to_uhwi (),
3003 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3005 else if (wi::geu_p (lenrange
[1], cntrange
[1]))
3007 /* The longest string is longer than the upper bound of
3008 the count so the truncation is possible. */
3009 if (cntrange
[0] == cntrange
[1])
3010 return warning_n (callloc
, OPT_Wstringop_truncation
,
3011 cntrange
[0].to_uhwi (),
3012 "%qD output may be truncated copying %E "
3013 "byte from a string of length %wu",
3014 "%qD output may be truncated copying %E "
3015 "bytes from a string of length %wu",
3016 func
, cnt
, lenrange
[1].to_uhwi ());
3018 return warning_at (callloc
, OPT_Wstringop_truncation
,
3019 "%qD output may be truncated copying between "
3020 "%wu and %wu bytes from a string of length %wu",
3021 func
, cntrange
[0].to_uhwi (),
3022 cntrange
[1].to_uhwi (), lenrange
[1].to_uhwi ());
3026 if (!cat_dstlen_bounded
3027 && cntrange
[0] != cntrange
[1]
3028 && wi::leu_p (cntrange
[0], lenrange
[0])
3029 && wi::leu_p (cntrange
[1], lenrange
[0] + 1))
3031 /* If the source (including the terminating nul) is longer than
3032 the lower bound of the specified count but shorter than the
3033 upper bound the copy may (but need not) be truncated. */
3034 return warning_at (callloc
, OPT_Wstringop_truncation
,
3035 "%qD output may be truncated copying between "
3036 "%wu and %wu bytes from a string of length %wu",
3037 func
, cntrange
[0].to_uhwi (),
3038 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
3043 if (tree dstsize
= compute_objsize (dst
, 1, &aref
, ptr_qry
))
3045 /* The source length is unknown. Try to determine the destination
3046 size and see if it matches the specified bound. If not, bail.
3047 Otherwise go on to see if it should be diagnosed for possible
3052 if (wi::to_wide (dstsize
) != cntrange
[1])
3055 /* Avoid warning for strncpy(a, b, N) calls where the following
3057 N == sizeof a && N == sizeof b */
3058 if (tree srcsize
= compute_objsize (src
, 1, &aref
, ptr_qry
))
3059 if (wi::to_wide (srcsize
) == cntrange
[1])
3062 if (cntrange
[0] == cntrange
[1])
3063 return warning_at (callloc
, OPT_Wstringop_truncation
,
3064 "%qD specified bound %E equals destination size",
3071 /* Check the arguments to the built-in forms of stpncpy, strncpy, and
3072 strncat, for out-of-bounds offsets or overlapping access, and to see
3073 if the size is derived from calling strlen() on the source argument,
3074 and if so, issue the appropriate warning.
3075 APPEND_P is true for strncat. */
3078 handle_builtin_stxncpy_strncat (bool append_p
, gimple_stmt_iterator
*gsi
)
3080 if (!strlen_to_stridx
)
3083 gimple
*stmt
= gsi_stmt (*gsi
);
3085 tree dst
= gimple_call_arg (stmt
, 0);
3086 tree src
= gimple_call_arg (stmt
, 1);
3087 tree len
= gimple_call_arg (stmt
, 2);
3088 /* An upper bound of the size of the destination. */
3089 tree dstsize
= NULL_TREE
;
3090 /* The length of the destination and source strings (plus 1 for those
3091 whose FULL_STRING_P is set, i.e., whose length is exact rather than
3093 tree dstlenp1
= NULL_TREE
, srclenp1
= NULL_TREE
;;
3095 int didx
= get_stridx (dst
);
3096 if (strinfo
*sidst
= didx
> 0 ? get_strinfo (didx
) : NULL
)
3098 /* Compute the size of the destination string including the nul
3099 if it is known to be nul-terminated. */
3100 if (sidst
->nonzero_chars
)
3102 if (sidst
->full_string_p
)
3104 /* String is known to be nul-terminated. */
3105 tree type
= TREE_TYPE (sidst
->nonzero_chars
);
3106 dstlenp1
= fold_build2 (PLUS_EXPR
, type
, sidst
->nonzero_chars
,
3107 build_int_cst (type
, 1));
3110 dstlenp1
= sidst
->nonzero_chars
;
3112 else if (TREE_CODE (sidst
->ptr
) == SSA_NAME
)
3114 gimple
*def_stmt
= SSA_NAME_DEF_STMT (sidst
->ptr
);
3115 dstsize
= gimple_call_alloc_size (def_stmt
);
3121 int sidx
= get_stridx (src
);
3122 strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
;
3125 /* strncat() and strncpy() can modify the source string by writing
3126 over the terminating nul so SISRC->DONT_INVALIDATE must be left
3129 /* Compute the size of the source string including the terminating
3130 nul if its known to be nul-terminated. */
3131 if (sisrc
->nonzero_chars
)
3133 if (sisrc
->full_string_p
)
3135 tree type
= TREE_TYPE (sisrc
->nonzero_chars
);
3136 srclenp1
= fold_build2 (PLUS_EXPR
, type
, sisrc
->nonzero_chars
,
3137 build_int_cst (type
, 1));
3140 srclenp1
= sisrc
->nonzero_chars
;
3146 srclenp1
= NULL_TREE
;
3148 opt_code opt
= check_bounds_or_overlap (stmt
, dst
, src
, dstlenp1
, srclenp1
);
3149 if (opt
!= no_warning
)
3151 suppress_warning (stmt
, opt
);
3155 /* If the length argument was computed from strlen(S) for some string
3156 S retrieve the strinfo index for the string (PSS->FIRST) along with
3157 the location of the strlen() call (PSS->SECOND). */
3158 stridx_strlenloc
*pss
= strlen_to_stridx
->get (len
);
3159 if (!pss
|| pss
->first
<= 0)
3161 if (maybe_diag_stxncpy_trunc (*gsi
, src
, len
))
3162 suppress_warning (stmt
, OPT_Wstringop_truncation
);
3167 /* Retrieve the strinfo data for the string S that LEN was computed
3168 from as some function F of strlen (S) (i.e., LEN need not be equal
3170 strinfo
*silen
= get_strinfo (pss
->first
);
3172 location_t callloc
= gimple_or_expr_nonartificial_location (stmt
, dst
);
3174 tree func
= gimple_call_fndecl (stmt
);
3176 bool warned
= false;
3178 /* When -Wstringop-truncation is set, try to determine truncation
3179 before diagnosing possible overflow. Truncation is implied by
3180 the LEN argument being equal to strlen(SRC), regardless of
3181 whether its value is known. Otherwise, when appending, or
3182 when copying into a destination of known size, issue the more
3183 generic -Wstringop-overflow which triggers for LEN arguments
3184 that in any meaningful way depend on strlen(SRC). */
3187 && is_strlen_related_p (src
, len
)
3188 && warning_at (callloc
, OPT_Wstringop_truncation
,
3189 "%qD output truncated before terminating nul "
3190 "copying as many bytes from a string as its length",
3193 else if ((append_p
|| !dstsize
|| len
== dstlenp1
)
3194 && silen
&& is_strlen_related_p (src
, silen
->ptr
))
3196 /* Issue -Wstringop-overflow when appending or when writing into
3197 a destination of a known size. Otherwise, when copying into
3198 a destination of an unknown size, it's truncation. */
3199 opt_code opt
= (append_p
|| dstsize
3200 ? OPT_Wstringop_overflow_
: OPT_Wstringop_truncation
);
3201 warned
= warning_at (callloc
, opt
,
3202 "%qD specified bound depends on the length "
3203 "of the source argument",
3208 location_t strlenloc
= pss
->second
;
3209 if (strlenloc
!= UNKNOWN_LOCATION
&& strlenloc
!= callloc
)
3210 inform (strlenloc
, "length computed here");
3214 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
3215 If strlen of the second argument is known and length of the third argument
3216 is that plus one, strlen of the first argument is the same after this
3217 call. Uses RVALS to determine range information. */
3220 handle_builtin_memcpy (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
,
3221 pointer_query
&ptr_qry
)
3223 tree lhs
, oldlen
, newlen
;
3224 gimple
*stmt
= gsi_stmt (*gsi
);
3227 tree len
= gimple_call_arg (stmt
, 2);
3228 tree src
= gimple_call_arg (stmt
, 1);
3229 tree dst
= gimple_call_arg (stmt
, 0);
3231 int didx
= get_stridx (dst
);
3232 strinfo
*olddsi
= NULL
;
3234 olddsi
= get_strinfo (didx
);
3239 && !integer_zerop (len
))
3241 maybe_warn_overflow (stmt
, false, len
, ptr_qry
, olddsi
, false, true);
3242 adjust_last_stmt (olddsi
, stmt
, false, ptr_qry
);
3245 int idx
= get_stridx (src
);
3254 /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
3256 si
= get_strinfo (idx
);
3257 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
3259 if (TREE_CODE (len
) == INTEGER_CST
3260 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
3262 if (tree_int_cst_le (len
, si
->nonzero_chars
))
3264 /* Copying LEN nonzero characters, where LEN is constant. */
3266 full_string_p
= false;
3270 /* Copying the whole of the analyzed part of SI. */
3271 newlen
= si
->nonzero_chars
;
3272 full_string_p
= si
->full_string_p
;
3277 if (!si
->full_string_p
)
3279 if (TREE_CODE (len
) != SSA_NAME
)
3281 def_stmt
= SSA_NAME_DEF_STMT (len
);
3282 if (!is_gimple_assign (def_stmt
)
3283 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
3284 || gimple_assign_rhs1 (def_stmt
) != si
->nonzero_chars
3285 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
3287 /* Copying variable-length string SI (and no more). */
3288 newlen
= si
->nonzero_chars
;
3289 full_string_p
= true;
3295 /* Handle memcpy (x, "abcd", 5) or
3296 memcpy (x, "abc\0uvw", 7). */
3297 if (!tree_fits_uhwi_p (len
))
3300 unsigned HOST_WIDE_INT clen
= tree_to_uhwi (len
);
3301 unsigned HOST_WIDE_INT nonzero_chars
= ~idx
;
3302 newlen
= build_int_cst (size_type_node
, MIN (nonzero_chars
, clen
));
3303 full_string_p
= clen
> nonzero_chars
;
3308 && olddsi
->nonzero_chars
3309 && TREE_CODE (olddsi
->nonzero_chars
) == INTEGER_CST
3310 && tree_int_cst_le (newlen
, olddsi
->nonzero_chars
))
3312 /* The SRC substring being written strictly overlaps
3313 a subsequence of the existing string OLDDSI. */
3314 newlen
= olddsi
->nonzero_chars
;
3315 full_string_p
= olddsi
->full_string_p
;
3318 if (olddsi
!= NULL
&& TREE_CODE (len
) == SSA_NAME
)
3319 adjust_last_stmt (olddsi
, stmt
, false, ptr_qry
);
3323 didx
= new_stridx (dst
);
3330 dsi
= unshare_strinfo (olddsi
);
3331 oldlen
= olddsi
->nonzero_chars
;
3332 dsi
->nonzero_chars
= newlen
;
3333 dsi
->full_string_p
= full_string_p
;
3334 /* Break the chain, so adjust_related_strinfo on later pointers in
3335 the chain won't adjust this one anymore. */
3338 dsi
->endptr
= NULL_TREE
;
3342 dsi
= new_strinfo (dst
, didx
, newlen
, full_string_p
);
3343 set_strinfo (didx
, dsi
);
3344 find_equal_ptrs (dst
, didx
);
3346 dsi
->writable
= true;
3347 dsi
->dont_invalidate
= true;
3350 tree adj
= NULL_TREE
;
3351 location_t loc
= gimple_location (stmt
);
3352 if (oldlen
== NULL_TREE
)
3354 else if (integer_zerop (oldlen
))
3356 else if (TREE_CODE (oldlen
) == INTEGER_CST
3357 || TREE_CODE (newlen
) == INTEGER_CST
)
3358 adj
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (newlen
), newlen
,
3359 fold_convert_loc (loc
, TREE_TYPE (newlen
),
3361 if (adj
!= NULL_TREE
)
3362 adjust_related_strinfos (loc
, dsi
, adj
);
3366 /* memcpy src may not overlap dst, so src doesn't need to be
3367 invalidated either. */
3369 si
->dont_invalidate
= true;
3373 lhs
= gimple_call_lhs (stmt
);
3376 case BUILT_IN_MEMCPY
:
3377 case BUILT_IN_MEMCPY_CHK
:
3378 /* Allow adjust_last_stmt to decrease this memcpy's size. */
3379 laststmt
.stmt
= stmt
;
3380 laststmt
.len
= dsi
->nonzero_chars
;
3381 laststmt
.stridx
= dsi
->idx
;
3383 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
3385 case BUILT_IN_MEMPCPY
:
3386 case BUILT_IN_MEMPCPY_CHK
:
3394 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
3395 If strlen of the second argument is known, strlen of the first argument
3396 is increased by the length of the second argument. Furthermore, attempt
3397 to convert it to memcpy/strcpy if the length of the first argument
3401 handle_builtin_strcat (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
,
3402 pointer_query
&ptr_qry
)
3405 tree srclen
, args
, type
, fn
, objsz
, endptr
;
3407 gimple
*stmt
= gsi_stmt (*gsi
);
3409 location_t loc
= gimple_location (stmt
);
3411 tree src
= gimple_call_arg (stmt
, 1);
3412 tree dst
= gimple_call_arg (stmt
, 0);
3414 /* Bail if the source is the same as destination. It will be diagnosed
3416 if (operand_equal_p (src
, dst
, 0))
3419 tree lhs
= gimple_call_lhs (stmt
);
3421 didx
= get_stridx (dst
);
3427 dsi
= get_strinfo (didx
);
3431 idx
= get_stridx (src
);
3433 srclen
= build_int_cst (size_type_node
, ~idx
);
3436 si
= get_strinfo (idx
);
3438 srclen
= get_string_length (si
);
3441 /* Disable warning for the transformed statement? */
3442 opt_code no_warning_opt
= no_warning
;
3444 if (dsi
== NULL
|| get_string_length (dsi
) == NULL_TREE
)
3447 /* The concatenation always involves copying at least one byte
3448 (the terminating nul), even if the source string is empty.
3449 If the source is unknown assume it's one character long and
3450 used that as both sizes. */
3454 tree type
= TREE_TYPE (slen
);
3455 slen
= fold_build2 (PLUS_EXPR
, type
, slen
, build_int_cst (type
, 1));
3458 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3459 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, NULL_TREE
,
3462 suppress_warning (stmt
, no_warning_opt
);
3465 /* strcat (p, q) can be transformed into
3466 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
3467 with length endptr - p if we need to compute the length
3468 later on. Don't do this transformation if we don't need
3470 if (builtin_decl_implicit_p (BUILT_IN_STPCPY
) && lhs
== NULL_TREE
)
3474 didx
= new_stridx (dst
);
3480 dsi
= new_strinfo (dst
, didx
, NULL_TREE
, false);
3481 set_strinfo (didx
, dsi
);
3482 find_equal_ptrs (dst
, didx
);
3486 dsi
= unshare_strinfo (dsi
);
3487 dsi
->nonzero_chars
= NULL_TREE
;
3488 dsi
->full_string_p
= false;
3490 dsi
->endptr
= NULL_TREE
;
3492 dsi
->writable
= true;
3494 dsi
->dont_invalidate
= true;
3499 tree dstlen
= dsi
->nonzero_chars
;
3500 endptr
= dsi
->endptr
;
3502 dsi
= unshare_strinfo (dsi
);
3503 dsi
->endptr
= NULL_TREE
;
3505 dsi
->writable
= true;
3507 if (srclen
!= NULL_TREE
)
3509 dsi
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
3510 TREE_TYPE (dsi
->nonzero_chars
),
3511 dsi
->nonzero_chars
, srclen
);
3512 gcc_assert (dsi
->full_string_p
);
3513 adjust_related_strinfos (loc
, dsi
, srclen
);
3514 dsi
->dont_invalidate
= true;
3518 dsi
->nonzero_chars
= NULL
;
3519 dsi
->full_string_p
= false;
3520 if (lhs
== NULL_TREE
&& builtin_decl_implicit_p (BUILT_IN_STPCPY
))
3521 dsi
->dont_invalidate
= true;
3525 /* strcat src may not overlap dst, so src doesn't need to be
3526 invalidated either. */
3527 si
->dont_invalidate
= true;
3529 /* For now. Could remove the lhs from the call and add
3530 lhs = dst; afterwards. */
3538 case BUILT_IN_STRCAT
:
3539 if (srclen
!= NULL_TREE
)
3540 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
3542 fn
= builtin_decl_implicit (BUILT_IN_STRCPY
);
3544 case BUILT_IN_STRCAT_CHK
:
3545 if (srclen
!= NULL_TREE
)
3546 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
3548 fn
= builtin_decl_explicit (BUILT_IN_STRCPY_CHK
);
3549 objsz
= gimple_call_arg (stmt
, 2);
3555 if (fn
== NULL_TREE
)
3560 tree type
= TREE_TYPE (dstlen
);
3562 /* Compute the size of the source sequence, including the nul. */
3563 tree srcsize
= srclen
? srclen
: size_zero_node
;
3564 tree one
= build_int_cst (type
, 1);
3565 srcsize
= fold_build2 (PLUS_EXPR
, type
, srcsize
, one
);
3566 tree dstsize
= fold_build2 (PLUS_EXPR
, type
, dstlen
, one
);
3567 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3569 no_warning_opt
= check_bounds_or_overlap (stmt
, dst
, sptr
, dstsize
,
3572 suppress_warning (stmt
, no_warning_opt
);
3575 tree len
= NULL_TREE
;
3576 if (srclen
!= NULL_TREE
)
3578 args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
3579 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
3581 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
3582 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
,
3583 build_int_cst (type
, 1));
3584 len
= force_gimple_operand_gsi (gsi
, len
, true, NULL_TREE
, true,
3588 dst
= fold_convert_loc (loc
, TREE_TYPE (dst
), unshare_expr (endptr
));
3590 dst
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
, TREE_TYPE (dst
), dst
,
3591 fold_convert_loc (loc
, sizetype
,
3592 unshare_expr (dstlen
)));
3593 dst
= force_gimple_operand_gsi (gsi
, dst
, true, NULL_TREE
, true,
3597 objsz
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (objsz
), objsz
,
3598 fold_convert_loc (loc
, TREE_TYPE (objsz
),
3599 unshare_expr (dstlen
)));
3600 objsz
= force_gimple_operand_gsi (gsi
, objsz
, true, NULL_TREE
, true,
3603 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3605 fprintf (dump_file
, "Optimizing: ");
3606 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3608 if (srclen
!= NULL_TREE
)
3609 success
= update_gimple_call (gsi
, fn
, 3 + (objsz
!= NULL_TREE
),
3610 dst
, src
, len
, objsz
);
3612 success
= update_gimple_call (gsi
, fn
, 2 + (objsz
!= NULL_TREE
),
3616 stmt
= gsi_stmt (*gsi
);
3618 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3620 fprintf (dump_file
, "into: ");
3621 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3623 /* If srclen == NULL, note that current string length can be
3624 computed by transforming this strcpy into stpcpy. */
3625 if (srclen
== NULL_TREE
&& dsi
->dont_invalidate
)
3627 adjust_last_stmt (dsi
, stmt
, true, ptr_qry
);
3628 if (srclen
!= NULL_TREE
)
3630 laststmt
.stmt
= stmt
;
3631 laststmt
.len
= srclen
;
3632 laststmt
.stridx
= dsi
->idx
;
3635 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3636 fprintf (dump_file
, "not possible.\n");
3639 suppress_warning (stmt
, no_warning_opt
);
3642 /* Handle a call to an allocation function like alloca, malloc or calloc,
3643 or an ordinary allocation function declared with attribute alloc_size. */
3646 handle_alloc_call (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
)
3648 gimple
*stmt
= gsi_stmt (*gsi
);
3649 tree lhs
= gimple_call_lhs (stmt
);
3650 if (lhs
== NULL_TREE
)
3653 gcc_assert (get_stridx (lhs
) == 0);
3654 int idx
= new_stridx (lhs
);
3655 tree length
= NULL_TREE
;
3656 if (bcode
== BUILT_IN_CALLOC
)
3657 length
= build_int_cst (size_type_node
, 0);
3658 strinfo
*si
= new_strinfo (lhs
, idx
, length
, length
!= NULL_TREE
);
3659 if (bcode
== BUILT_IN_CALLOC
)
3661 /* Only set STMT for calloc and malloc. */
3663 /* Only set ENDPTR for calloc. */
3666 else if (bcode
== BUILT_IN_MALLOC
)
3669 /* Set ALLOC is set for all allocation functions. */
3671 set_strinfo (idx
, si
);
3672 si
->writable
= true;
3673 si
->dont_invalidate
= true;
3676 /* Handle a call to memset.
3677 After a call to calloc, memset(,0,) is unnecessary.
3678 memset(malloc(n),0,n) is calloc(n,1).
3679 return true when the call is transformed, false otherwise.
3680 When nonnull uses RVALS to determine range information. */
3683 handle_builtin_memset (gimple_stmt_iterator
*gsi
, bool *zero_write
,
3684 pointer_query
&ptr_qry
)
3686 gimple
*memset_stmt
= gsi_stmt (*gsi
);
3687 tree ptr
= gimple_call_arg (memset_stmt
, 0);
3688 /* Set to the non-constant offset added to PTR. */
3690 int idx1
= get_stridx (ptr
, offrng
, ptr_qry
.rvals
);
3693 strinfo
*si1
= get_strinfo (idx1
);
3696 gimple
*alloc_stmt
= si1
->alloc
;
3697 if (!alloc_stmt
|| !is_gimple_call (alloc_stmt
))
3699 tree callee1
= gimple_call_fndecl (alloc_stmt
);
3700 if (!valid_builtin_call (alloc_stmt
))
3702 tree alloc_size
= gimple_call_arg (alloc_stmt
, 0);
3703 tree memset_size
= gimple_call_arg (memset_stmt
, 2);
3705 /* Check for overflow. */
3706 maybe_warn_overflow (memset_stmt
, false, memset_size
, ptr_qry
, NULL
,
3709 /* Bail when there is no statement associated with the destination
3710 (the statement may be null even when SI1->ALLOC is not). */
3714 /* Avoid optimizing if store is at a variable offset from the beginning
3715 of the allocated object. */
3716 if (offrng
[0] != 0 || offrng
[0] != offrng
[1])
3719 /* Bail when the call writes a non-zero value. */
3720 if (!integer_zerop (gimple_call_arg (memset_stmt
, 1)))
3723 /* Let the caller know the memset call cleared the destination. */
3726 enum built_in_function code1
= DECL_FUNCTION_CODE (callee1
);
3727 if (code1
== BUILT_IN_CALLOC
)
3728 /* Not touching alloc_stmt */ ;
3729 else if (code1
== BUILT_IN_MALLOC
3730 && operand_equal_p (memset_size
, alloc_size
, 0))
3732 /* Replace the malloc + memset calls with calloc. */
3733 gimple_stmt_iterator gsi1
= gsi_for_stmt (si1
->stmt
);
3734 update_gimple_call (&gsi1
, builtin_decl_implicit (BUILT_IN_CALLOC
), 2,
3735 alloc_size
, build_one_cst (size_type_node
));
3736 si1
->nonzero_chars
= build_int_cst (size_type_node
, 0);
3737 si1
->full_string_p
= true;
3738 si1
->stmt
= gsi_stmt (gsi1
);
3742 tree lhs
= gimple_call_lhs (memset_stmt
);
3743 unlink_stmt_vdef (memset_stmt
);
3746 gimple
*assign
= gimple_build_assign (lhs
, ptr
);
3747 gsi_replace (gsi
, assign
, false);
3751 gsi_remove (gsi
, true);
3752 release_defs (memset_stmt
);
3758 /* Return first such statement if RES is used in statements testing its
3759 equality to zero, and null otherwise. If EXCLUSIVE is true, return
3760 nonnull if and only RES is used in such expressions exclusively and
3764 use_in_zero_equality (tree res
, bool exclusive
= true)
3766 gimple
*first_use
= NULL
;
3768 use_operand_p use_p
;
3769 imm_use_iterator iter
;
3771 FOR_EACH_IMM_USE_FAST (use_p
, iter
, res
)
3773 gimple
*use_stmt
= USE_STMT (use_p
);
3775 if (is_gimple_debug (use_stmt
))
3778 if (gimple_code (use_stmt
) == GIMPLE_ASSIGN
)
3780 tree_code code
= gimple_assign_rhs_code (use_stmt
);
3781 if (code
== COND_EXPR
)
3783 tree cond_expr
= gimple_assign_rhs1 (use_stmt
);
3784 if ((TREE_CODE (cond_expr
) != EQ_EXPR
3785 && (TREE_CODE (cond_expr
) != NE_EXPR
))
3786 || !integer_zerop (TREE_OPERAND (cond_expr
, 1)))
3793 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
3795 if (!integer_zerop (gimple_assign_rhs2 (use_stmt
)))
3807 else if (gimple_code (use_stmt
) == GIMPLE_COND
)
3809 tree_code code
= gimple_cond_code (use_stmt
);
3810 if ((code
!= EQ_EXPR
&& code
!= NE_EXPR
)
3811 || !integer_zerop (gimple_cond_rhs (use_stmt
)))
3824 first_use
= use_stmt
;
3830 /* Handle a call to memcmp. We try to handle small comparisons by
3831 converting them to load and compare, and replacing the call to memcmp
3832 with a __builtin_memcmp_eq call where possible.
3833 return true when call is transformed, return false otherwise. */
3836 handle_builtin_memcmp (gimple_stmt_iterator
*gsi
)
3838 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (*gsi
));
3839 tree res
= gimple_call_lhs (stmt
);
3841 if (!res
|| !use_in_zero_equality (res
))
3844 tree arg1
= gimple_call_arg (stmt
, 0);
3845 tree arg2
= gimple_call_arg (stmt
, 1);
3846 tree len
= gimple_call_arg (stmt
, 2);
3847 unsigned HOST_WIDE_INT leni
;
3849 if (tree_fits_uhwi_p (len
)
3850 && (leni
= tree_to_uhwi (len
)) <= GET_MODE_SIZE (word_mode
)
3851 && pow2p_hwi (leni
))
3853 leni
*= CHAR_TYPE_SIZE
;
3854 unsigned align1
= get_pointer_alignment (arg1
);
3855 unsigned align2
= get_pointer_alignment (arg2
);
3856 unsigned align
= MIN (align1
, align2
);
3857 scalar_int_mode mode
;
3858 if (int_mode_for_size (leni
, 1).exists (&mode
)
3859 && (align
>= leni
|| !targetm
.slow_unaligned_access (mode
, align
)))
3861 location_t loc
= gimple_location (stmt
);
3863 type
= build_nonstandard_integer_type (leni
, 1);
3864 gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type
)), leni
));
3865 tree ptrtype
= build_pointer_type_for_mode (char_type_node
,
3867 off
= build_int_cst (ptrtype
, 0);
3868 arg1
= build2_loc (loc
, MEM_REF
, type
, arg1
, off
);
3869 arg2
= build2_loc (loc
, MEM_REF
, type
, arg2
, off
);
3870 tree tem1
= fold_const_aggregate_ref (arg1
);
3873 tree tem2
= fold_const_aggregate_ref (arg2
);
3876 res
= fold_convert_loc (loc
, TREE_TYPE (res
),
3877 fold_build2_loc (loc
, NE_EXPR
,
3880 gimplify_and_update_call_from_tree (gsi
, res
);
3885 gimple_call_set_fndecl (stmt
, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ
));
3889 /* Given strinfo IDX for ARG, sets LENRNG[] to the range of lengths
3890 of the string(s) referenced by ARG if it can be determined.
3891 If the length cannot be determined, sets *SIZE to the size of
3892 the array the string is stored in, if any. If no such array is
3893 known, sets *SIZE to -1. When the strings are nul-terminated sets
3894 *NULTERM to true, otherwise to false. When nonnull uses RVALS to
3895 determine range information. Returns true on success. */
3898 get_len_or_size (gimple
*stmt
, tree arg
, int idx
,
3899 unsigned HOST_WIDE_INT lenrng
[2],
3900 unsigned HOST_WIDE_INT
*size
, bool *nulterm
,
3904 *size
= HOST_WIDE_INT_M1U
;
3908 /* IDX is the inverted constant string length. */
3910 lenrng
[1] = lenrng
[0];
3915 /* Set so that both LEN and ~LEN are invalid lengths, i.e., maximum
3916 possible length + 1. */
3917 lenrng
[0] = lenrng
[1] = HOST_WIDE_INT_MAX
;
3919 if (strinfo
*si
= idx
? get_strinfo (idx
) : NULL
)
3921 /* FIXME: Handle all this in_range_strlen_dynamic. */
3922 if (!si
->nonzero_chars
)
3924 else if (tree_fits_uhwi_p (si
->nonzero_chars
))
3926 lenrng
[0] = tree_to_uhwi (si
->nonzero_chars
);
3927 *nulterm
= si
->full_string_p
;
3928 /* Set the upper bound only if the string is known to be
3929 nul-terminated, otherwise leave it at maximum + 1. */
3931 lenrng
[1] = lenrng
[0];
3933 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
3936 get_range_query (cfun
)->range_of_expr (r
, si
->nonzero_chars
);
3937 if (r
.kind () == VR_RANGE
)
3939 lenrng
[0] = r
.lower_bound ().to_uhwi ();
3940 lenrng
[1] = r
.upper_bound ().to_uhwi ();
3941 *nulterm
= si
->full_string_p
;
3946 if (lenrng
[0] != HOST_WIDE_INT_MAX
)
3949 /* Compute the minimum and maximum real or possible lengths. */
3950 c_strlen_data lendata
= { };
3951 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
3952 to have it set to the length of the longest string in a PHI. */
3953 lendata
.maxbound
= arg
;
3954 get_range_strlen_dynamic (arg
, stmt
, &lendata
, rvals
);
3956 unsigned HOST_WIDE_INT maxbound
= HOST_WIDE_INT_M1U
;
3957 if (tree_fits_uhwi_p (lendata
.maxbound
)
3958 && !integer_all_onesp (lendata
.maxbound
))
3959 maxbound
= tree_to_uhwi (lendata
.maxbound
);
3961 if (tree_fits_uhwi_p (lendata
.minlen
) && tree_fits_uhwi_p (lendata
.maxlen
))
3963 unsigned HOST_WIDE_INT minlen
= tree_to_uhwi (lendata
.minlen
);
3964 unsigned HOST_WIDE_INT maxlen
= tree_to_uhwi (lendata
.maxlen
);
3966 /* The longest string in this data model. */
3967 const unsigned HOST_WIDE_INT lenmax
3968 = tree_to_uhwi (max_object_size ()) - 2;
3970 if (maxbound
== HOST_WIDE_INT_M1U
)
3974 *nulterm
= minlen
== maxlen
;
3976 else if (maxlen
< lenmax
)
3978 *size
= maxbound
+ 1;
3987 if (maxbound
!= HOST_WIDE_INT_M1U
3989 && !integer_all_onesp (lendata
.maxlen
))
3991 /* Set *SIZE to LENDATA.MAXBOUND which is a conservative estimate
3992 of the longest string based on the sizes of the arrays referenced
3994 *size
= maxbound
+ 1;
4002 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
4003 the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
4004 for a sufficiently large BOUND). If the result is based on the length
4005 of one string being greater than the longest string that would fit in
4006 the array pointer to by the argument, set *PLEN and *PSIZE to
4007 the corresponding length (or its complement when the string is known
4008 to be at least as long and need not be nul-terminated) and size.
4009 Otherwise return null. */
4012 strxcmp_eqz_result (gimple
*stmt
, tree arg1
, int idx1
, tree arg2
, int idx2
,
4013 unsigned HOST_WIDE_INT bound
, unsigned HOST_WIDE_INT len
[2],
4014 unsigned HOST_WIDE_INT
*psize
, range_query
*rvals
)
4016 /* Determine the range the length of each string is in and whether it's
4017 known to be nul-terminated, or the size of the array it's stored in. */
4019 unsigned HOST_WIDE_INT siz1
, siz2
;
4020 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4021 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &siz1
, &nul1
, rvals
)
4022 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &siz2
, &nul2
, rvals
))
4025 /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
4026 to HWI_MAX when invalid. Adjust the length of each string to consider
4027 to be no more than BOUND. */
4028 if (len1rng
[0] < HOST_WIDE_INT_MAX
&& len1rng
[0] > bound
)
4030 if (len1rng
[1] < HOST_WIDE_INT_MAX
&& len1rng
[1] > bound
)
4032 if (len2rng
[0] < HOST_WIDE_INT_MAX
&& len2rng
[0] > bound
)
4034 if (len2rng
[1] < HOST_WIDE_INT_MAX
&& len2rng
[1] > bound
)
4037 /* Two empty strings are equal. */
4038 if (len1rng
[1] == 0 && len2rng
[1] == 0)
4039 return integer_one_node
;
4041 /* The strings are definitely unequal when the lower bound of the length
4042 of one of them is greater than the length of the longest string that
4043 would fit into the other array. */
4044 if (len1rng
[0] == HOST_WIDE_INT_MAX
4045 && len2rng
[0] != HOST_WIDE_INT_MAX
4046 && ((len2rng
[0] < bound
&& len2rng
[0] >= siz1
)
4047 || len2rng
[0] > siz1
))
4050 len
[0] = len1rng
[0];
4051 /* Set LEN[0] to the lower bound of ARG1's length when it's
4052 nul-terminated or to the complement of its minimum length
4054 len
[1] = nul2
? len2rng
[0] : ~len2rng
[0];
4055 return integer_zero_node
;
4058 if (len2rng
[0] == HOST_WIDE_INT_MAX
4059 && len1rng
[0] != HOST_WIDE_INT_MAX
4060 && ((len1rng
[0] < bound
&& len1rng
[0] >= siz2
)
4061 || len1rng
[0] > siz2
))
4064 len
[0] = nul1
? len1rng
[0] : ~len1rng
[0];
4065 len
[1] = len2rng
[0];
4066 return integer_zero_node
;
4069 /* The strings are also definitely unequal when their lengths are unequal
4070 and at least one is nul-terminated. */
4071 if (len1rng
[0] != HOST_WIDE_INT_MAX
4072 && len2rng
[0] != HOST_WIDE_INT_MAX
4073 && ((len1rng
[1] < len2rng
[0] && nul1
)
4074 || (len2rng
[1] < len1rng
[0] && nul2
)))
4076 if (bound
<= len1rng
[0] || bound
<= len2rng
[0])
4079 *psize
= HOST_WIDE_INT_M1U
;
4081 len
[0] = len1rng
[0];
4082 len
[1] = len2rng
[0];
4083 return integer_zero_node
;
4086 /* The string lengths may be equal or unequal. Even when equal and
4087 both strings nul-terminated, without the string contents there's
4088 no way to determine whether they are equal. */
4092 /* Diagnose pointless calls to strcmp or strncmp STMT with string
4093 arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
4094 whose result is used in equality expressions that evaluate to
4095 a constant due to one argument being longer than the size of
4099 maybe_warn_pointless_strcmp (gimple
*stmt
, HOST_WIDE_INT bound
,
4100 unsigned HOST_WIDE_INT len
[2],
4101 unsigned HOST_WIDE_INT siz
)
4103 tree lhs
= gimple_call_lhs (stmt
);
4104 gimple
*use
= use_in_zero_equality (lhs
, /* exclusive = */ false);
4108 bool at_least
= false;
4110 /* Excessive LEN[i] indicates a lower bound. */
4111 if (len
[0] > HOST_WIDE_INT_MAX
)
4117 if (len
[1] > HOST_WIDE_INT_MAX
)
4123 unsigned HOST_WIDE_INT minlen
= MIN (len
[0], len
[1]);
4125 /* FIXME: Include a note pointing to the declaration of the smaller
4127 location_t stmt_loc
= gimple_or_expr_nonartificial_location (stmt
, lhs
);
4129 tree callee
= gimple_call_fndecl (stmt
);
4130 bool warned
= false;
4131 if (siz
<= minlen
&& bound
== -1)
4132 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4134 ? G_("%qD of a string of length %wu or more and "
4135 "an array of size %wu evaluates to nonzero")
4136 : G_("%qD of a string of length %wu and an array "
4137 "of size %wu evaluates to nonzero")),
4138 callee
, minlen
, siz
);
4139 else if (!at_least
&& siz
<= HOST_WIDE_INT_MAX
)
4141 if (len
[0] != HOST_WIDE_INT_MAX
&& len
[1] != HOST_WIDE_INT_MAX
)
4142 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4143 "%qD of strings of length %wu and %wu "
4144 "and bound of %wu evaluates to nonzero",
4145 callee
, len
[0], len
[1], bound
);
4147 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
4148 "%qD of a string of length %wu, an array "
4149 "of size %wu and bound of %wu evaluates to "
4151 callee
, minlen
, siz
, bound
);
4157 location_t use_loc
= gimple_location (use
);
4158 if (LOCATION_LINE (stmt_loc
) != LOCATION_LINE (use_loc
))
4159 inform (use_loc
, "in this expression");
4163 /* Optimize a call to strcmp or strncmp either by folding it to a constant
4164 when possible or by transforming the latter to the former. Warn about
4165 calls where the length of one argument is greater than the size of
4166 the array to which the other argument points if the latter's length
4167 is not known. Return true when the call has been transformed into
4168 another and false otherwise. */
4171 handle_builtin_string_cmp (gimple_stmt_iterator
*gsi
, range_query
*rvals
)
4173 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (*gsi
));
4174 tree lhs
= gimple_call_lhs (stmt
);
4179 tree arg1
= gimple_call_arg (stmt
, 0);
4180 tree arg2
= gimple_call_arg (stmt
, 1);
4181 int idx1
= get_stridx (arg1
);
4182 int idx2
= get_stridx (arg2
);
4184 /* For strncmp set to the value of the third argument if known. */
4185 HOST_WIDE_INT bound
= -1;
4186 tree len
= NULL_TREE
;
4187 /* Extract the strncmp bound. */
4188 if (gimple_call_num_args (stmt
) == 3)
4190 len
= gimple_call_arg (stmt
, 2);
4191 if (tree_fits_shwi_p (len
))
4192 bound
= tree_to_shwi (len
);
4194 /* If the bound argument is NOT known, do nothing. */
4199 /* Avoid folding if either argument is not a nul-terminated array.
4200 Defer warning until later. */
4201 if (!check_nul_terminated_array (NULL_TREE
, arg1
, len
)
4202 || !check_nul_terminated_array (NULL_TREE
, arg2
, len
))
4206 /* Set to the length of one argument (or its complement if it's
4207 the lower bound of a range) and the size of the array storing
4208 the other if the result is based on the former being equal to
4209 or greater than the latter. */
4210 unsigned HOST_WIDE_INT len
[2] = { HOST_WIDE_INT_MAX
, HOST_WIDE_INT_MAX
};
4211 unsigned HOST_WIDE_INT siz
= HOST_WIDE_INT_M1U
;
4213 /* Try to determine if the two strings are either definitely equal
4214 or definitely unequal and if so, either fold the result to zero
4215 (when equal) or set the range of the result to ~[0, 0] otherwise. */
4216 if (tree eqz
= strxcmp_eqz_result (stmt
, arg1
, idx1
, arg2
, idx2
, bound
,
4219 if (integer_zerop (eqz
))
4221 maybe_warn_pointless_strcmp (stmt
, bound
, len
, siz
);
4223 /* When the lengths of the first two string arguments are
4224 known to be unequal set the range of the result to non-zero.
4225 This allows the call to be eliminated if its result is only
4226 used in tests for equality to zero. */
4227 wide_int zero
= wi::zero (TYPE_PRECISION (TREE_TYPE (lhs
)));
4228 set_range_info (lhs
, VR_ANTI_RANGE
, zero
, zero
);
4231 /* When the two strings are definitely equal (such as when they
4232 are both empty) fold the call to the constant result. */
4233 replace_call_with_value (gsi
, integer_zero_node
);
4238 /* Return if nothing is known about the strings pointed to by ARG1
4240 if (idx1
== 0 && idx2
== 0)
4243 /* Determine either the length or the size of each of the strings,
4244 whichever is available. */
4245 HOST_WIDE_INT cstlen1
= -1, cstlen2
= -1;
4246 HOST_WIDE_INT arysiz1
= -1, arysiz2
= -1;
4249 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
4250 unsigned HOST_WIDE_INT arsz1
, arsz2
;
4253 if (!get_len_or_size (stmt
, arg1
, idx1
, len1rng
, &arsz1
, nulterm
, rvals
)
4254 || !get_len_or_size (stmt
, arg2
, idx2
, len2rng
, &arsz2
, nulterm
+ 1,
4258 if (len1rng
[0] == len1rng
[1] && len1rng
[0] < HOST_WIDE_INT_MAX
)
4259 cstlen1
= len1rng
[0];
4260 else if (arsz1
< HOST_WIDE_INT_M1U
)
4263 if (len2rng
[0] == len2rng
[1] && len2rng
[0] < HOST_WIDE_INT_MAX
)
4264 cstlen2
= len2rng
[0];
4265 else if (arsz2
< HOST_WIDE_INT_M1U
)
4269 /* Bail if neither the string length nor the size of the array
4270 it is stored in can be determined. */
4271 if ((cstlen1
< 0 && arysiz1
< 0)
4272 || (cstlen2
< 0 && arysiz2
< 0)
4273 || (cstlen1
< 0 && cstlen2
< 0))
4281 /* The exact number of characters to compare. */
4282 HOST_WIDE_INT cmpsiz
;
4283 if (cstlen1
>= 0 && cstlen2
>= 0)
4284 cmpsiz
= MIN (cstlen1
, cstlen2
);
4285 else if (cstlen1
>= 0)
4290 cmpsiz
= MIN (cmpsiz
, bound
);
4291 /* The size of the array in which the unknown string is stored. */
4292 HOST_WIDE_INT varsiz
= arysiz1
< 0 ? arysiz2
: arysiz1
;
4294 if ((varsiz
< 0 || cmpsiz
< varsiz
) && use_in_zero_equality (lhs
))
4296 /* If the known length is less than the size of the other array
4297 and the strcmp result is only used to test equality to zero,
4298 transform the call to the equivalent _eq call. */
4299 if (tree fn
= builtin_decl_implicit (bound
< 0 ? BUILT_IN_STRCMP_EQ
4300 : BUILT_IN_STRNCMP_EQ
))
4302 tree n
= build_int_cst (size_type_node
, cmpsiz
);
4303 update_gimple_call (gsi
, fn
, 3, arg1
, arg2
, n
);
4311 /* Handle a POINTER_PLUS_EXPR statement.
4312 For p = "abcd" + 2; compute associated length, or if
4313 p = q + off is pointing to a '\0' character of a string, call
4314 zero_length_string on it. */
4317 handle_pointer_plus (gimple_stmt_iterator
*gsi
)
4319 gimple
*stmt
= gsi_stmt (*gsi
);
4320 tree lhs
= gimple_assign_lhs (stmt
), off
;
4321 int idx
= get_stridx (gimple_assign_rhs1 (stmt
));
4329 tree off
= gimple_assign_rhs2 (stmt
);
4330 if (tree_fits_uhwi_p (off
)
4331 && tree_to_uhwi (off
) <= (unsigned HOST_WIDE_INT
) ~idx
)
4332 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)]
4333 = ~(~idx
- (int) tree_to_uhwi (off
));
4337 si
= get_strinfo (idx
);
4338 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
4341 off
= gimple_assign_rhs2 (stmt
);
4343 if (si
->full_string_p
&& operand_equal_p (si
->nonzero_chars
, off
, 0))
4344 zsi
= zero_length_string (lhs
, si
);
4345 else if (TREE_CODE (off
) == SSA_NAME
)
4347 gimple
*def_stmt
= SSA_NAME_DEF_STMT (off
);
4348 if (gimple_assign_single_p (def_stmt
)
4349 && si
->full_string_p
4350 && operand_equal_p (si
->nonzero_chars
,
4351 gimple_assign_rhs1 (def_stmt
), 0))
4352 zsi
= zero_length_string (lhs
, si
);
4355 && si
->endptr
!= NULL_TREE
4356 && si
->endptr
!= lhs
4357 && TREE_CODE (si
->endptr
) == SSA_NAME
)
4359 enum tree_code rhs_code
4360 = useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (si
->endptr
))
4361 ? SSA_NAME
: NOP_EXPR
;
4362 gimple_assign_set_rhs_with_ops (gsi
, rhs_code
, si
->endptr
);
4363 gcc_assert (gsi_stmt (*gsi
) == stmt
);
4368 /* Set LENRANGE to the number of nonzero bytes for a store of TYPE and
4369 clear all flags. Return true on success and false on failure. */
4372 nonzero_bytes_for_type (tree type
, unsigned lenrange
[3],
4373 bool *nulterm
, bool *allnul
, bool *allnonnul
)
4375 /* Use the size of the type of the expression as the size of the store,
4376 and set the upper bound of the length range to that of the size.
4377 Nothing is known about the contents so clear all flags. */
4378 tree typesize
= TYPE_SIZE_UNIT (type
);
4382 if (!tree_fits_uhwi_p (typesize
))
4385 unsigned HOST_WIDE_INT sz
= tree_to_uhwi (typesize
);
4390 lenrange
[1] = lenrange
[2] ? lenrange
[2] - 1 : 0;
4399 count_nonzero_bytes_addr (tree
, unsigned HOST_WIDE_INT
, unsigned HOST_WIDE_INT
,
4400 unsigned [3], bool *, bool *, bool *,
4401 range_query
*, ssa_name_limit_t
&);
4403 /* Recursively determine the minimum and maximum number of leading nonzero
4404 bytes in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
4406 Sets LENRANGE[2] to the total size of the access (which may be less
4407 than LENRANGE[1] when what's being referenced by EXP is a pointer
4408 rather than an array).
4409 Sets *NULTERM if the representation contains a zero byte, sets *ALLNUL
4410 if all the bytes are zero, and *ALLNONNUL is all are nonzero.
4411 OFFSET and NBYTES are the offset into the representation and
4412 the size of the access to it determined from an ADDR_EXPR (i.e.,
4413 a pointer) or MEM_REF or zero for other expressions.
4414 Uses RVALS to determine range information.
4415 Avoids recursing deeper than the limits in SNLIM allow.
4416 Returns true on success and false otherwise. */
4419 count_nonzero_bytes (tree exp
, unsigned HOST_WIDE_INT offset
,
4420 unsigned HOST_WIDE_INT nbytes
,
4421 unsigned lenrange
[3], bool *nulterm
,
4422 bool *allnul
, bool *allnonnul
, range_query
*rvals
,
4423 ssa_name_limit_t
&snlim
)
4425 if (TREE_CODE (exp
) == SSA_NAME
)
4427 /* Handle non-zero single-character stores specially. */
4428 tree type
= TREE_TYPE (exp
);
4429 if (TREE_CODE (type
) == INTEGER_TYPE
4430 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
4431 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
)
4432 && tree_expr_nonzero_p (exp
))
4434 /* If the character EXP is known to be non-zero (even if its
4435 exact value is not known) recurse once to set the range
4436 for an arbitrary constant. */
4437 exp
= build_int_cst (type
, 1);
4438 return count_nonzero_bytes (exp
, offset
, 1, lenrange
,
4439 nulterm
, allnul
, allnonnul
, rvals
, snlim
);
4442 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4443 if (gimple_assign_single_p (stmt
))
4445 exp
= gimple_assign_rhs1 (stmt
);
4447 && TREE_CODE (exp
) != CONSTRUCTOR
4448 && TREE_CODE (exp
) != MEM_REF
)
4450 /* Handle DECLs, CONSTRUCTOR and MEM_REF below. */
4452 else if (gimple_code (stmt
) == GIMPLE_PHI
)
4454 /* Avoid processing an SSA_NAME that has already been visited
4455 or if an SSA_NAME limit has been reached. Indicate success
4456 if the former and failure if the latter. */
4457 if (int res
= snlim
.next_phi (exp
))
4460 /* Determine the minimum and maximum from the PHI arguments. */
4461 unsigned int n
= gimple_phi_num_args (stmt
);
4462 for (unsigned i
= 0; i
!= n
; i
++)
4464 tree def
= gimple_phi_arg_def (stmt
, i
);
4465 if (!count_nonzero_bytes (def
, offset
, nbytes
, lenrange
, nulterm
,
4466 allnul
, allnonnul
, rvals
, snlim
))
4474 if (TREE_CODE (exp
) == CONSTRUCTOR
)
4477 /* If NBYTES has already been determined by an outer MEM_REF
4478 fail rather than overwriting it (this shouldn't happen). */
4481 tree type
= TREE_TYPE (exp
);
4482 tree size
= TYPE_SIZE_UNIT (type
);
4483 if (!size
|| !tree_fits_uhwi_p (size
))
4486 unsigned HOST_WIDE_INT byte_size
= tree_to_uhwi (size
);
4487 if (byte_size
< offset
)
4490 nbytes
= byte_size
- offset
;
4493 if (TREE_CODE (exp
) == MEM_REF
)
4498 tree arg
= TREE_OPERAND (exp
, 0);
4499 tree off
= TREE_OPERAND (exp
, 1);
4501 if (TREE_CODE (off
) != INTEGER_CST
|| !tree_fits_uhwi_p (off
))
4504 unsigned HOST_WIDE_INT wioff
= tree_to_uhwi (off
);
4505 if (INT_MAX
< wioff
)
4509 if (INT_MAX
< offset
)
4512 /* The size of the MEM_REF access determines the number of bytes. */
4513 tree type
= TREE_TYPE (exp
);
4514 tree typesize
= TYPE_SIZE_UNIT (type
);
4515 if (!typesize
|| !tree_fits_uhwi_p (typesize
))
4517 nbytes
= tree_to_uhwi (typesize
);
4521 /* Handle MEM_REF = SSA_NAME types of assignments. */
4522 return count_nonzero_bytes_addr (arg
, offset
, nbytes
, lenrange
, nulterm
,
4523 allnul
, allnonnul
, rvals
, snlim
);
4526 if (VAR_P (exp
) || TREE_CODE (exp
) == CONST_DECL
)
4528 /* If EXP can be folded into a constant use the result. Otherwise
4529 proceed to use EXP to determine a range of the result. */
4530 if (tree fold_exp
= ctor_for_folding (exp
))
4531 if (fold_exp
!= error_mark_node
)
4535 const char *prep
= NULL
;
4536 if (TREE_CODE (exp
) == STRING_CST
)
4538 unsigned nchars
= TREE_STRING_LENGTH (exp
);
4539 if (nchars
< offset
)
4543 /* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
4544 (i.e., it's the size of a pointer), or from MEM_REF (as the size
4545 of the access), set it here to the size of the string, including
4546 all internal and trailing nuls if the string has any. */
4547 nbytes
= nchars
- offset
;
4548 else if (nchars
- offset
< nbytes
)
4551 prep
= TREE_STRING_POINTER (exp
) + offset
;
4554 unsigned char buf
[256];
4557 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8)
4559 /* If the pointer to representation hasn't been set above
4560 for STRING_CST point it at the buffer. */
4561 prep
= reinterpret_cast <char *>(buf
);
4562 /* Try to extract the representation of the constant object
4563 or expression starting from the offset. */
4564 unsigned repsize
= native_encode_expr (exp
, buf
, sizeof buf
, offset
);
4565 if (repsize
< nbytes
)
4567 /* This should only happen when REPSIZE is zero because EXP
4568 doesn't denote an object with a known initializer, except
4569 perhaps when the reference reads past its end. */
4575 else if (nbytes
< repsize
)
4580 return nonzero_bytes_for_type (TREE_TYPE (exp
), lenrange
,
4581 nulterm
, allnul
, allnonnul
);
4583 /* Compute the number of leading nonzero bytes in the representation
4584 and update the minimum and maximum. */
4585 unsigned n
= prep
? strnlen (prep
, nbytes
) : nbytes
;
4587 if (n
< lenrange
[0])
4589 if (lenrange
[1] < n
)
4592 /* Set the size of the representation. */
4593 if (lenrange
[2] < nbytes
)
4594 lenrange
[2] = nbytes
;
4596 /* Clear NULTERM if none of the bytes is zero. */
4602 /* When the initial number of non-zero bytes N is non-zero, reset
4603 *ALLNUL; if N is less than that the size of the representation
4604 also clear *ALLNONNUL. */
4609 else if (*allnul
|| *allnonnul
)
4615 /* When either ALLNUL is set and N is zero, also determine
4616 whether all subsequent bytes after the first one (which
4617 is nul) are zero or nonzero and clear ALLNUL if not. */
4618 for (const char *p
= prep
; p
!= prep
+ nbytes
; ++p
)
4630 /* Like count_nonzero_bytes, but instead of counting bytes in EXP, count
4631 bytes that are pointed to by EXP, which should be a pointer. */
4634 count_nonzero_bytes_addr (tree exp
, unsigned HOST_WIDE_INT offset
,
4635 unsigned HOST_WIDE_INT nbytes
,
4636 unsigned lenrange
[3], bool *nulterm
,
4637 bool *allnul
, bool *allnonnul
,
4638 range_query
*rvals
, ssa_name_limit_t
&snlim
)
4640 int idx
= get_stridx (exp
);
4643 strinfo
*si
= get_strinfo (idx
);
4647 /* Handle both constant lengths as well non-constant lengths
4649 unsigned HOST_WIDE_INT minlen
, maxlen
;
4650 if (tree_fits_shwi_p (si
->nonzero_chars
))
4651 minlen
= maxlen
= tree_to_shwi (si
->nonzero_chars
);
4652 else if (si
->nonzero_chars
4653 && TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
4656 rvals
->range_of_expr (vr
, si
->nonzero_chars
, si
->stmt
);
4657 if (vr
.kind () != VR_RANGE
)
4660 minlen
= tree_to_uhwi (vr
.min ());
4661 maxlen
= tree_to_uhwi (vr
.max ());
4666 if (maxlen
< offset
)
4669 minlen
= minlen
< offset
? 0 : minlen
- offset
;
4671 if (maxlen
+ 1 < nbytes
)
4674 if (nbytes
<= minlen
)
4677 if (nbytes
< minlen
)
4680 if (nbytes
< maxlen
)
4684 if (minlen
< lenrange
[0])
4685 lenrange
[0] = minlen
;
4686 if (lenrange
[1] < maxlen
)
4687 lenrange
[1] = maxlen
;
4689 if (lenrange
[2] < nbytes
)
4690 lenrange
[2] = nbytes
;
4692 /* Since only the length of the string are known and not its contents,
4693 clear ALLNUL and ALLNONNUL purely on the basis of the length. */
4695 if (minlen
< nbytes
)
4701 if (TREE_CODE (exp
) == ADDR_EXPR
)
4702 return count_nonzero_bytes (TREE_OPERAND (exp
, 0), offset
, nbytes
,
4703 lenrange
, nulterm
, allnul
, allnonnul
, rvals
,
4706 if (TREE_CODE (exp
) == SSA_NAME
)
4708 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
4709 if (gimple_code (stmt
) == GIMPLE_PHI
)
4711 /* Avoid processing an SSA_NAME that has already been visited
4712 or if an SSA_NAME limit has been reached. Indicate success
4713 if the former and failure if the latter. */
4714 if (int res
= snlim
.next_phi (exp
))
4717 /* Determine the minimum and maximum from the PHI arguments. */
4718 unsigned int n
= gimple_phi_num_args (stmt
);
4719 for (unsigned i
= 0; i
!= n
; i
++)
4721 tree def
= gimple_phi_arg_def (stmt
, i
);
4722 if (!count_nonzero_bytes_addr (def
, offset
, nbytes
, lenrange
,
4723 nulterm
, allnul
, allnonnul
, rvals
,
4732 /* Otherwise we don't know anything. */
4734 if (lenrange
[1] < nbytes
)
4735 lenrange
[1] = nbytes
;
4736 if (lenrange
[2] < nbytes
)
4737 lenrange
[2] = nbytes
;
4744 /* Same as above except with an implicit SSA_NAME limit. When EXPR_OR_TYPE
4745 is a type rather than an expression use its size to compute the range.
4746 RVALS is used to determine ranges of dynamically computed string lengths
4747 (the results of strlen). */
4750 count_nonzero_bytes (tree expr_or_type
, unsigned lenrange
[3], bool *nulterm
,
4751 bool *allnul
, bool *allnonnul
, range_query
*rvals
)
4753 if (TYPE_P (expr_or_type
))
4754 return nonzero_bytes_for_type (expr_or_type
, lenrange
,
4755 nulterm
, allnul
, allnonnul
);
4757 /* Set to optimistic values so the caller doesn't have to worry about
4758 initializing these and to what. On success, the function will clear
4759 these if it determines their values are different but being recursive
4760 it never sets either to true. On failure, their values are
4766 ssa_name_limit_t snlim
;
4767 tree expr
= expr_or_type
;
4768 return count_nonzero_bytes (expr
, 0, 0, lenrange
, nulterm
, allnul
, allnonnul
,
4772 /* Handle a single or multibyte store other than by a built-in function,
4773 either via a single character assignment or by multi-byte assignment
4774 either via MEM_REF or via a type other than char (such as in
4775 '*(int*)a = 12345'). Return true to let the caller advance *GSI to
4776 the next statement in the basic block and false otherwise. */
4779 handle_store (gimple_stmt_iterator
*gsi
, bool *zero_write
,
4780 pointer_query
&ptr_qry
)
4782 gimple
*stmt
= gsi_stmt (*gsi
);
4783 /* The LHS and RHS of the store. The RHS is null if STMT is a function
4784 call. STORETYPE is the type of the store (determined from either
4785 the RHS of the assignment statement or the LHS of a function call. */
4786 tree lhs
, rhs
, storetype
;
4787 if (is_gimple_assign (stmt
))
4789 lhs
= gimple_assign_lhs (stmt
);
4790 rhs
= gimple_assign_rhs1 (stmt
);
4791 storetype
= TREE_TYPE (rhs
);
4793 else if (is_gimple_call (stmt
))
4795 lhs
= gimple_call_lhs (stmt
);
4797 storetype
= TREE_TYPE (lhs
);
4802 tree ssaname
= NULL_TREE
;
4806 range_query
*const rvals
= ptr_qry
.rvals
;
4808 /* The offset of the first byte in LHS modified by the store. */
4809 unsigned HOST_WIDE_INT offset
= 0;
4811 if (TREE_CODE (lhs
) == MEM_REF
4812 && TREE_CODE (TREE_OPERAND (lhs
, 0)) == SSA_NAME
)
4814 tree mem_offset
= TREE_OPERAND (lhs
, 1);
4815 if (tree_fits_uhwi_p (mem_offset
))
4817 /* Get the strinfo for the base, and use it if it starts with at
4818 least OFFSET nonzero characters. This is trivially true if
4820 offset
= tree_to_uhwi (mem_offset
);
4821 idx
= get_stridx (TREE_OPERAND (lhs
, 0));
4823 si
= get_strinfo (idx
);
4825 ssaname
= TREE_OPERAND (lhs
, 0);
4826 else if (si
== NULL
|| compare_nonzero_chars (si
, offset
, rvals
) < 0)
4828 *zero_write
= rhs
? initializer_zerop (rhs
) : false;
4831 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4832 if (count_nonzero_bytes (rhs
? rhs
: storetype
, lenrange
,
4833 &dummy
, &dummy
, &dummy
, rvals
))
4834 maybe_warn_overflow (stmt
, true, lenrange
[2], ptr_qry
);
4842 idx
= get_addr_stridx (lhs
, NULL_TREE
, &offset
, rvals
);
4844 si
= get_strinfo (idx
);
4847 /* Minimum and maximum leading non-zero bytes and the size of the store. */
4848 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4850 /* Set to the minimum length of the string being assigned if known. */
4851 unsigned HOST_WIDE_INT rhs_minlen
;
4853 /* STORING_NONZERO_P is true iff not all stored characters are zero.
4854 STORING_ALL_NONZERO_P is true if all stored characters are zero.
4855 STORING_ALL_ZEROS_P is true iff all stored characters are zero.
4856 Both are false when it's impossible to determine which is true. */
4857 bool storing_nonzero_p
;
4858 bool storing_all_nonzero_p
;
4859 bool storing_all_zeros_p
;
4860 /* FULL_STRING_P is set when the stored sequence of characters form
4861 a nul-terminated string. */
4864 const bool ranges_valid
4865 = count_nonzero_bytes (rhs
? rhs
: storetype
, lenrange
, &full_string_p
,
4866 &storing_all_zeros_p
, &storing_all_nonzero_p
,
4871 rhs_minlen
= lenrange
[0];
4872 storing_nonzero_p
= lenrange
[1] > 0;
4873 *zero_write
= storing_all_zeros_p
;
4875 maybe_warn_overflow (stmt
, true, lenrange
[2], ptr_qry
);
4879 rhs_minlen
= HOST_WIDE_INT_M1U
;
4880 full_string_p
= false;
4881 storing_nonzero_p
= false;
4882 storing_all_zeros_p
= false;
4883 storing_all_nonzero_p
= false;
4888 /* The corresponding element is set to 1 if the first and last
4889 element, respectively, of the sequence of characters being
4890 written over the string described by SI ends before
4891 the terminating nul (if it has one), to zero if the nul is
4892 being overwritten but not beyond, or negative otherwise. */
4893 int store_before_nul
[2];
4896 /* The offset of the last stored byte. */
4897 unsigned HOST_WIDE_INT endoff
= offset
+ lenrange
[2] - 1;
4898 store_before_nul
[0] = compare_nonzero_chars (si
, offset
, rvals
);
4899 if (endoff
== offset
)
4900 store_before_nul
[1] = store_before_nul
[0];
4902 store_before_nul
[1] = compare_nonzero_chars (si
, endoff
, rvals
);
4906 store_before_nul
[0] = compare_nonzero_chars (si
, offset
, rvals
);
4907 store_before_nul
[1] = store_before_nul
[0];
4908 gcc_assert (offset
== 0 || store_before_nul
[0] >= 0);
4911 if (storing_all_zeros_p
4912 && store_before_nul
[0] == 0
4913 && store_before_nul
[1] == 0
4914 && si
->full_string_p
)
4916 /* When overwriting a '\0' with a '\0', the store can be removed
4917 if we know it has been stored in the current function. */
4918 if (!stmt_could_throw_p (cfun
, stmt
) && si
->writable
)
4920 unlink_stmt_vdef (stmt
);
4921 release_defs (stmt
);
4922 gsi_remove (gsi
, true);
4927 si
->writable
= true;
4933 if (store_before_nul
[1] > 0
4934 && storing_nonzero_p
4935 && lenrange
[0] == lenrange
[1]
4936 && lenrange
[0] == lenrange
[2]
4937 && TREE_CODE (storetype
) == INTEGER_TYPE
)
4939 /* Handle a store of one or more non-nul characters that ends
4940 before the terminating nul of the destination and so does
4941 not affect its length
4942 If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
4943 and if we aren't storing '\0', we know that the length of
4944 the string and any other zero terminated string in memory
4945 remains the same. In that case we move to the next gimple
4946 statement and return to signal the caller that it shouldn't
4947 invalidate anything.
4949 This is beneficial for cases like:
4954 strcpy (p, "foobar");
4955 size_t len = strlen (p); // can be folded to 6
4956 size_t len2 = strlen (q); // has to be computed
4958 size_t len3 = strlen (p); // can be folded to 6
4959 size_t len4 = strlen (q); // can be folded to len2
4960 bar (len, len2, len3, len4);
4966 if (storing_all_zeros_p
4967 || storing_nonzero_p
4968 || (offset
!= 0 && store_before_nul
[1] > 0))
4970 /* When STORING_NONZERO_P, we know that the string will start
4971 with at least OFFSET + 1 nonzero characters. If storing
4972 a single character, set si->NONZERO_CHARS to the result.
4973 If storing multiple characters, try to determine the number
4974 of leading non-zero characters and set si->NONZERO_CHARS to
4977 When STORING_ALL_ZEROS_P, we know that the string is now
4978 OFFSET characters long.
4980 Otherwise, we're storing an unknown value at offset OFFSET,
4981 so need to clip the nonzero_chars to OFFSET.
4982 Use the minimum length of the string (or individual character)
4983 being stored if it's known. Otherwise, STORING_NONZERO_P
4984 guarantees it's at least 1. */
4986 = storing_nonzero_p
&& ranges_valid
? lenrange
[0] : 1;
4987 location_t loc
= gimple_location (stmt
);
4988 tree oldlen
= si
->nonzero_chars
;
4989 if (store_before_nul
[1] == 0 && si
->full_string_p
)
4990 /* We're overwriting the nul terminator with a nonzero or
4991 unknown character. If the previous stmt was a memcpy,
4992 its length may be decreased. */
4993 adjust_last_stmt (si
, stmt
, false, ptr_qry
);
4994 si
= unshare_strinfo (si
);
4995 if (storing_nonzero_p
)
4997 gcc_assert (len
>= 0);
4998 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
+ len
);
5001 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
);
5003 /* Set FULL_STRING_P only if the length of the strings being
5004 written is the same, and clear it if the strings have
5005 different lengths. In the latter case the length stored
5006 in si->NONZERO_CHARS becomes the lower bound.
5007 FIXME: Handle the upper bound of the length if possible. */
5008 si
->full_string_p
= full_string_p
&& lenrange
[0] == lenrange
[1];
5010 if (storing_all_zeros_p
5012 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5013 si
->endptr
= ssaname
;
5018 si
->writable
= true;
5019 si
->dont_invalidate
= true;
5022 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
5023 si
->nonzero_chars
, oldlen
);
5024 adjust_related_strinfos (loc
, si
, adj
);
5030 else if (idx
== 0 && (storing_all_zeros_p
|| storing_nonzero_p
))
5033 idx
= new_stridx (ssaname
);
5035 idx
= new_addr_stridx (lhs
);
5038 tree ptr
= (ssaname
? ssaname
: build_fold_addr_expr (lhs
));
5041 if (storing_all_zeros_p
)
5043 else if (storing_nonzero_p
&& ranges_valid
)
5045 /* FIXME: Handle the upper bound of the length when
5046 LENRANGE[0] != LENRANGE[1]. */
5048 if (lenrange
[0] != lenrange
[1])
5049 /* Set the minimum length but ignore the maximum
5051 full_string_p
= false;
5056 tree len
= (slen
<= 0
5058 : build_int_cst (size_type_node
, slen
));
5059 si
= new_strinfo (ptr
, idx
, len
, slen
>= 0 && full_string_p
);
5060 set_strinfo (idx
, si
);
5061 if (storing_all_zeros_p
5063 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
5064 si
->endptr
= ssaname
;
5065 si
->dont_invalidate
= true;
5066 si
->writable
= true;
5070 && rhs_minlen
< HOST_WIDE_INT_M1U
5071 && ssaname
== NULL_TREE
5072 && TREE_CODE (TREE_TYPE (lhs
)) == ARRAY_TYPE
)
5074 HOST_WIDE_INT a
= int_size_in_bytes (TREE_TYPE (lhs
));
5075 if (a
> 0 && (unsigned HOST_WIDE_INT
) a
> rhs_minlen
)
5077 int idx
= new_addr_stridx (lhs
);
5080 si
= new_strinfo (build_fold_addr_expr (lhs
), idx
,
5081 build_int_cst (size_type_node
, rhs_minlen
),
5083 set_strinfo (idx
, si
);
5084 si
->dont_invalidate
= true;
5089 if (si
!= NULL
&& offset
== 0 && storing_all_zeros_p
&& lenrange
[2] == 1)
5091 /* For single-byte stores only, allow adjust_last_stmt to remove
5092 the statement if the stored '\0' is immediately overwritten. */
5093 laststmt
.stmt
= stmt
;
5094 laststmt
.len
= build_int_cst (size_type_node
, 1);
5095 laststmt
.stridx
= si
->idx
;
5100 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0. */
5103 fold_strstr_to_strncmp (tree rhs1
, tree rhs2
, gimple
*stmt
)
5105 if (TREE_CODE (rhs1
) != SSA_NAME
5106 || TREE_CODE (rhs2
) != SSA_NAME
)
5109 gimple
*call_stmt
= NULL
;
5110 for (int pass
= 0; pass
< 2; pass
++)
5112 gimple
*g
= SSA_NAME_DEF_STMT (rhs1
);
5113 if (gimple_call_builtin_p (g
, BUILT_IN_STRSTR
)
5114 && has_single_use (rhs1
)
5115 && gimple_call_arg (g
, 0) == rhs2
)
5120 std::swap (rhs1
, rhs2
);
5125 tree arg0
= gimple_call_arg (call_stmt
, 0);
5129 tree arg1
= gimple_call_arg (call_stmt
, 1);
5130 tree arg1_len
= NULL_TREE
;
5131 int idx
= get_stridx (arg1
);
5136 arg1_len
= build_int_cst (size_type_node
, ~idx
);
5139 strinfo
*si
= get_strinfo (idx
);
5141 arg1_len
= get_string_length (si
);
5145 if (arg1_len
!= NULL_TREE
)
5147 gimple_stmt_iterator gsi
= gsi_for_stmt (call_stmt
);
5148 tree strncmp_decl
= builtin_decl_explicit (BUILT_IN_STRNCMP
);
5150 if (!is_gimple_val (arg1_len
))
5152 tree arg1_len_tmp
= make_ssa_name (TREE_TYPE (arg1_len
));
5153 gassign
*arg1_stmt
= gimple_build_assign (arg1_len_tmp
,
5155 gsi_insert_before (&gsi
, arg1_stmt
, GSI_SAME_STMT
);
5156 arg1_len
= arg1_len_tmp
;
5159 gcall
*strncmp_call
= gimple_build_call (strncmp_decl
, 3,
5160 arg0
, arg1
, arg1_len
);
5161 tree strncmp_lhs
= make_ssa_name (integer_type_node
);
5162 gimple_set_vuse (strncmp_call
, gimple_vuse (call_stmt
));
5163 gimple_call_set_lhs (strncmp_call
, strncmp_lhs
);
5164 gsi_remove (&gsi
, true);
5165 gsi_insert_before (&gsi
, strncmp_call
, GSI_SAME_STMT
);
5166 tree zero
= build_zero_cst (TREE_TYPE (strncmp_lhs
));
5168 if (is_gimple_assign (stmt
))
5170 if (gimple_assign_rhs_code (stmt
) == COND_EXPR
)
5172 tree cond
= gimple_assign_rhs1 (stmt
);
5173 TREE_OPERAND (cond
, 0) = strncmp_lhs
;
5174 TREE_OPERAND (cond
, 1) = zero
;
5178 gimple_assign_set_rhs1 (stmt
, strncmp_lhs
);
5179 gimple_assign_set_rhs2 (stmt
, zero
);
5184 gcond
*cond
= as_a
<gcond
*> (stmt
);
5185 gimple_cond_set_lhs (cond
, strncmp_lhs
);
5186 gimple_cond_set_rhs (cond
, zero
);
5194 /* Return true if TYPE corresponds to a narrow character type. */
5197 is_char_type (tree type
)
5199 return (TREE_CODE (type
) == INTEGER_TYPE
5200 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
5201 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
));
5204 /* Check the built-in call at GSI for validity and optimize it.
5205 Uses RVALS to determine range information.
5206 Return true to let the caller advance *GSI to the next statement
5207 in the basic block and false otherwise. */
5210 strlen_check_and_optimize_call (gimple_stmt_iterator
*gsi
, bool *zero_write
,
5211 pointer_query
&ptr_qry
)
5213 gimple
*stmt
= gsi_stmt (*gsi
);
5215 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
5217 tree fntype
= gimple_call_fntype (stmt
);
5221 if (lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype
)))
5223 handle_alloc_call (BUILT_IN_NONE
, gsi
);
5227 if (tree lhs
= gimple_call_lhs (stmt
))
5228 handle_assign (gsi
, lhs
, zero_write
, ptr_qry
);
5230 /* Proceed to handle user-defined formatting functions. */
5233 /* When not optimizing we must be checking printf calls which
5234 we do even for user-defined functions when they are declared
5235 with attribute format. */
5236 if (!flag_optimize_strlen
5238 || !valid_builtin_call (stmt
))
5239 return !handle_printf_call (gsi
, ptr_qry
);
5241 tree callee
= gimple_call_fndecl (stmt
);
5242 switch (DECL_FUNCTION_CODE (callee
))
5244 case BUILT_IN_STRLEN
:
5245 case BUILT_IN_STRNLEN
:
5246 handle_builtin_strlen (gsi
);
5248 case BUILT_IN_STRCHR
:
5249 handle_builtin_strchr (gsi
);
5251 case BUILT_IN_STRCPY
:
5252 case BUILT_IN_STRCPY_CHK
:
5253 case BUILT_IN_STPCPY
:
5254 case BUILT_IN_STPCPY_CHK
:
5255 handle_builtin_strcpy (DECL_FUNCTION_CODE (callee
), gsi
, ptr_qry
);
5258 case BUILT_IN_STRNCAT
:
5259 case BUILT_IN_STRNCAT_CHK
:
5260 handle_builtin_strncat (DECL_FUNCTION_CODE (callee
), gsi
);
5263 case BUILT_IN_STPNCPY
:
5264 case BUILT_IN_STPNCPY_CHK
:
5265 case BUILT_IN_STRNCPY
:
5266 case BUILT_IN_STRNCPY_CHK
:
5267 handle_builtin_stxncpy_strncat (false, gsi
);
5270 case BUILT_IN_MEMCPY
:
5271 case BUILT_IN_MEMCPY_CHK
:
5272 case BUILT_IN_MEMPCPY
:
5273 case BUILT_IN_MEMPCPY_CHK
:
5274 handle_builtin_memcpy (DECL_FUNCTION_CODE (callee
), gsi
, ptr_qry
);
5276 case BUILT_IN_STRCAT
:
5277 case BUILT_IN_STRCAT_CHK
:
5278 handle_builtin_strcat (DECL_FUNCTION_CODE (callee
), gsi
, ptr_qry
);
5280 case BUILT_IN_ALLOCA
:
5281 case BUILT_IN_ALLOCA_WITH_ALIGN
:
5282 case BUILT_IN_MALLOC
:
5283 case BUILT_IN_CALLOC
:
5284 handle_alloc_call (DECL_FUNCTION_CODE (callee
), gsi
);
5286 case BUILT_IN_MEMSET
:
5287 if (handle_builtin_memset (gsi
, zero_write
, ptr_qry
))
5290 case BUILT_IN_MEMCMP
:
5291 if (handle_builtin_memcmp (gsi
))
5294 case BUILT_IN_STRCMP
:
5295 case BUILT_IN_STRNCMP
:
5296 if (handle_builtin_string_cmp (gsi
, ptr_qry
.rvals
))
5300 if (handle_printf_call (gsi
, ptr_qry
))
5308 /* Handle an assignment statement at *GSI to a LHS of integral type.
5309 If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */
5312 handle_integral_assign (gimple_stmt_iterator
*gsi
, bool *cleanup_eh
,
5315 gimple
*stmt
= gsi_stmt (*gsi
);
5316 tree lhs
= gimple_assign_lhs (stmt
);
5317 tree lhs_type
= TREE_TYPE (lhs
);
5319 enum tree_code code
= gimple_assign_rhs_code (stmt
);
5320 if (code
== COND_EXPR
)
5322 tree cond
= gimple_assign_rhs1 (stmt
);
5323 enum tree_code cond_code
= TREE_CODE (cond
);
5325 if (cond_code
== EQ_EXPR
|| cond_code
== NE_EXPR
)
5326 fold_strstr_to_strncmp (TREE_OPERAND (cond
, 0),
5327 TREE_OPERAND (cond
, 1), stmt
);
5329 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5330 fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt
),
5331 gimple_assign_rhs2 (stmt
), stmt
);
5332 else if (gimple_assign_load_p (stmt
)
5333 && TREE_CODE (lhs_type
) == INTEGER_TYPE
5334 && TYPE_MODE (lhs_type
) == TYPE_MODE (char_type_node
)
5335 && (TYPE_PRECISION (lhs_type
)
5336 == TYPE_PRECISION (char_type_node
))
5337 && !gimple_has_volatile_ops (stmt
))
5339 tree off
= integer_zero_node
;
5340 unsigned HOST_WIDE_INT coff
= 0;
5342 tree rhs1
= gimple_assign_rhs1 (stmt
);
5343 if (code
== MEM_REF
)
5345 idx
= get_stridx (TREE_OPERAND (rhs1
, 0));
5348 strinfo
*si
= get_strinfo (idx
);
5350 && si
->nonzero_chars
5351 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
5352 && (wi::to_widest (si
->nonzero_chars
)
5353 >= wi::to_widest (off
)))
5354 off
= TREE_OPERAND (rhs1
, 1);
5356 /* This case is not useful. See if get_addr_stridx
5357 returns something usable. */
5362 idx
= get_addr_stridx (rhs1
, NULL_TREE
, &coff
);
5365 strinfo
*si
= get_strinfo (idx
);
5367 && si
->nonzero_chars
5368 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
5370 widest_int w1
= wi::to_widest (si
->nonzero_chars
);
5371 widest_int w2
= wi::to_widest (off
) + coff
;
5373 && si
->full_string_p
)
5375 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5377 fprintf (dump_file
, "Optimizing: ");
5378 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5381 /* Reading the final '\0' character. */
5382 tree zero
= build_int_cst (lhs_type
, 0);
5383 gimple_set_vuse (stmt
, NULL_TREE
);
5384 gimple_assign_set_rhs_from_tree (gsi
, zero
);
5386 |= maybe_clean_or_replace_eh_stmt (stmt
,
5388 stmt
= gsi_stmt (*gsi
);
5391 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
5393 fprintf (dump_file
, "into: ");
5394 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
5399 /* Reading a character before the final '\0'
5400 character. Just set the value range to ~[0, 0]
5401 if we don't have anything better. */
5403 if (!get_range_query (cfun
)->range_of_expr (r
, lhs
)
5406 r
.set_nonzero (lhs_type
);
5407 set_range_info (lhs
, r
);
5413 else if (code
== MEM_REF
&& TREE_CODE (lhs
) == SSA_NAME
)
5415 if (int idx
= new_stridx (lhs
))
5417 /* Record multi-byte assignments from MEM_REFs. */
5418 bool storing_all_nonzero_p
;
5419 bool storing_all_zeros_p
;
5421 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
5422 tree rhs
= gimple_assign_rhs1 (stmt
);
5423 const bool ranges_valid
5424 = count_nonzero_bytes (rhs
, lenrange
, &full_string_p
,
5425 &storing_all_zeros_p
, &storing_all_nonzero_p
,
5429 tree length
= build_int_cst (sizetype
, lenrange
[0]);
5430 strinfo
*si
= new_strinfo (lhs
, idx
, length
, full_string_p
);
5431 set_strinfo (idx
, si
);
5432 si
->writable
= true;
5433 si
->dont_invalidate
= true;
5438 if (strlen_to_stridx
)
5440 tree rhs1
= gimple_assign_rhs1 (stmt
);
5441 if (stridx_strlenloc
*ps
= strlen_to_stridx
->get (rhs1
))
5442 strlen_to_stridx
->put (lhs
, stridx_strlenloc (*ps
));
5446 /* Handle assignment statement at *GSI to LHS. Set *ZERO_WRITE if
5447 the assignent stores all zero bytes.. */
5450 handle_assign (gimple_stmt_iterator
*gsi
, tree lhs
, bool *zero_write
,
5451 pointer_query
&ptr_qry
)
5453 tree type
= TREE_TYPE (lhs
);
5454 if (TREE_CODE (type
) == ARRAY_TYPE
)
5455 type
= TREE_TYPE (type
);
5457 bool is_char_store
= is_char_type (type
);
5458 if (!is_char_store
&& TREE_CODE (lhs
) == MEM_REF
)
5460 /* To consider stores into char objects via integer types other
5461 than char but not those to non-character objects, determine
5462 the type of the destination rather than just the type of
5464 for (int i
= 0; i
!= 2; ++i
)
5466 tree ref
= TREE_OPERAND (lhs
, i
);
5467 type
= TREE_TYPE (ref
);
5468 if (TREE_CODE (type
) == POINTER_TYPE
)
5469 type
= TREE_TYPE (type
);
5470 if (TREE_CODE (type
) == ARRAY_TYPE
)
5471 type
= TREE_TYPE (type
);
5472 if (is_char_type (type
))
5474 is_char_store
= true;
5480 /* Handle a single or multibyte assignment. */
5481 if (is_char_store
&& !handle_store (gsi
, zero_write
, ptr_qry
))
5488 /* Attempt to check for validity of the performed access a single statement
5489 at *GSI using string length knowledge, and to optimize it.
5490 If the given basic block needs clean-up of EH, CLEANUP_EH is set to
5491 true. Return true to let the caller advance *GSI to the next statement
5492 in the basic block and false otherwise. */
5495 check_and_optimize_stmt (gimple_stmt_iterator
*gsi
, bool *cleanup_eh
,
5496 pointer_query
&ptr_qry
)
5498 gimple
*stmt
= gsi_stmt (*gsi
);
5500 /* For statements that modify a string, set to true if the write
5502 bool zero_write
= false;
5504 if (is_gimple_call (stmt
))
5506 if (!strlen_check_and_optimize_call (gsi
, &zero_write
, ptr_qry
))
5509 else if (!flag_optimize_strlen
|| !strlen_optimize
)
5511 else if (is_gimple_assign (stmt
) && !gimple_clobber_p (stmt
))
5513 /* Handle non-clobbering assignment. */
5514 tree lhs
= gimple_assign_lhs (stmt
);
5515 tree lhs_type
= TREE_TYPE (lhs
);
5517 if (TREE_CODE (lhs
) == SSA_NAME
&& POINTER_TYPE_P (lhs_type
))
5519 if (gimple_assign_single_p (stmt
)
5520 || (gimple_assign_cast_p (stmt
)
5521 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt
)))))
5523 int idx
= get_stridx (gimple_assign_rhs1 (stmt
));
5524 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = idx
;
5526 else if (gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
5527 handle_pointer_plus (gsi
);
5529 else if (TREE_CODE (lhs
) == SSA_NAME
&& INTEGRAL_TYPE_P (lhs_type
))
5530 /* Handle assignment to a character. */
5531 handle_integral_assign (gsi
, cleanup_eh
, ptr_qry
.rvals
);
5532 else if (TREE_CODE (lhs
) != SSA_NAME
&& !TREE_SIDE_EFFECTS (lhs
))
5533 if (!handle_assign (gsi
, lhs
, &zero_write
, ptr_qry
))
5536 else if (gcond
*cond
= dyn_cast
<gcond
*> (stmt
))
5538 enum tree_code code
= gimple_cond_code (cond
);
5539 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
5540 fold_strstr_to_strncmp (gimple_cond_lhs (stmt
),
5541 gimple_cond_rhs (stmt
), stmt
);
5544 if (gimple_vdef (stmt
))
5545 maybe_invalidate (stmt
, zero_write
);
5549 /* Recursively call maybe_invalidate on stmts that might be executed
5550 in between dombb and current bb and that contain a vdef. Stop when
5551 *count stmts are inspected, or if the whole strinfo vector has
5552 been invalidated. */
5555 do_invalidate (basic_block dombb
, gimple
*phi
, bitmap visited
, int *count
)
5557 unsigned int i
, n
= gimple_phi_num_args (phi
);
5559 for (i
= 0; i
< n
; i
++)
5561 tree vuse
= gimple_phi_arg_def (phi
, i
);
5562 gimple
*stmt
= SSA_NAME_DEF_STMT (vuse
);
5563 basic_block bb
= gimple_bb (stmt
);
5566 || !bitmap_set_bit (visited
, bb
->index
)
5567 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5571 if (gimple_code (stmt
) == GIMPLE_PHI
)
5573 do_invalidate (dombb
, stmt
, visited
, count
);
5580 if (!maybe_invalidate (stmt
))
5585 vuse
= gimple_vuse (stmt
);
5586 stmt
= SSA_NAME_DEF_STMT (vuse
);
5587 if (gimple_bb (stmt
) != bb
)
5589 bb
= gimple_bb (stmt
);
5592 || !bitmap_set_bit (visited
, bb
->index
)
5593 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
5600 class strlen_dom_walker
: public dom_walker
5603 strlen_dom_walker (cdi_direction direction
)
5604 : dom_walker (direction
),
5606 ptr_qry (&evrp
, &var_cache
),
5608 m_cleanup_cfg (false)
5611 ~strlen_dom_walker ();
5613 virtual edge
before_dom_children (basic_block
);
5614 virtual void after_dom_children (basic_block
);
5616 /* EVRP analyzer used for printf argument range processing, and
5617 to track strlen results across integer variable assignments. */
5618 evrp_range_analyzer evrp
;
5620 /* A pointer_query object and its cache to store information about
5621 pointers and their targets in. */
5622 pointer_query ptr_qry
;
5623 pointer_query::cache_type var_cache
;
5625 /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
5626 execute function. */
5630 /* Release pointer_query cache. */
5632 strlen_dom_walker::~strlen_dom_walker ()
5634 ptr_qry
.flush_cache ();
5637 /* Callback for walk_dominator_tree. Attempt to optimize various
5638 string ops by remembering string lengths pointed by pointer SSA_NAMEs. */
5641 strlen_dom_walker::before_dom_children (basic_block bb
)
5645 basic_block dombb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
5648 stridx_to_strinfo
= NULL
;
5651 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) dombb
->aux
);
5652 if (stridx_to_strinfo
)
5654 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5657 gphi
*phi
= gsi
.phi ();
5658 if (virtual_operand_p (gimple_phi_result (phi
)))
5660 bitmap visited
= BITMAP_ALLOC (NULL
);
5661 int count_vdef
= 100;
5662 do_invalidate (dombb
, phi
, visited
, &count_vdef
);
5663 BITMAP_FREE (visited
);
5664 if (count_vdef
== 0)
5666 /* If there were too many vdefs in between immediate
5667 dominator and current bb, invalidate everything.
5668 If stridx_to_strinfo has been unshared, we need
5669 to free it, otherwise just set it to NULL. */
5670 if (!strinfo_shared ())
5676 vec_safe_iterate (stridx_to_strinfo
, i
, &si
);
5680 (*stridx_to_strinfo
)[i
] = NULL
;
5684 stridx_to_strinfo
= NULL
;
5692 /* If all PHI arguments have the same string index, the PHI result
5694 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
5697 gphi
*phi
= gsi
.phi ();
5698 tree result
= gimple_phi_result (phi
);
5699 if (!virtual_operand_p (result
) && POINTER_TYPE_P (TREE_TYPE (result
)))
5701 int idx
= get_stridx (gimple_phi_arg_def (phi
, 0));
5704 unsigned int i
, n
= gimple_phi_num_args (phi
);
5705 for (i
= 1; i
< n
; i
++)
5706 if (idx
!= get_stridx (gimple_phi_arg_def (phi
, i
)))
5709 ssa_ver_to_stridx
[SSA_NAME_VERSION (result
)] = idx
;
5714 bool cleanup_eh
= false;
5716 /* Attempt to optimize individual statements. */
5717 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); )
5719 gimple
*stmt
= gsi_stmt (gsi
);
5721 /* First record ranges generated by this statement so they
5722 can be used by printf argument processing. */
5723 evrp
.record_ranges_from_stmt (stmt
, false);
5725 /* Reset search depth preformance counter. */
5728 if (check_and_optimize_stmt (&gsi
, &cleanup_eh
, ptr_qry
))
5732 if (cleanup_eh
&& gimple_purge_dead_eh_edges (bb
))
5733 m_cleanup_cfg
= true;
5735 bb
->aux
= stridx_to_strinfo
;
5736 if (vec_safe_length (stridx_to_strinfo
) && !strinfo_shared ())
5737 (*stridx_to_strinfo
)[0] = (strinfo
*) bb
;
5741 /* Callback for walk_dominator_tree. Free strinfo vector if it is
5742 owned by the current bb, clear bb->aux. */
5745 strlen_dom_walker::after_dom_children (basic_block bb
)
5751 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) bb
->aux
);
5752 if (vec_safe_length (stridx_to_strinfo
)
5753 && (*stridx_to_strinfo
)[0] == (strinfo
*) bb
)
5758 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
5760 vec_free (stridx_to_strinfo
);
5769 printf_strlen_execute (function
*fun
, bool warn_only
)
5771 strlen_optimize
= !warn_only
;
5773 calculate_dominance_info (CDI_DOMINATORS
);
5775 bool use_scev
= optimize
> 0 && flag_printf_return_value
;
5778 loop_optimizer_init (LOOPS_NORMAL
);
5782 gcc_assert (!strlen_to_stridx
);
5783 if (warn_stringop_overflow
|| warn_stringop_truncation
)
5784 strlen_to_stridx
= new hash_map
<tree
, stridx_strlenloc
> ();
5786 /* This has to happen after initializing the loop optimizer
5787 and initializing SCEV as they create new SSA_NAMEs. */
5788 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
, true);
5791 /* String length optimization is implemented as a walk of the dominator
5792 tree and a forward walk of statements within each block. */
5793 strlen_dom_walker
walker (CDI_DOMINATORS
);
5794 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));
5796 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5797 walker
.ptr_qry
.dump (dump_file
);
5799 ssa_ver_to_stridx
.release ();
5800 strinfo_pool
.release ();
5801 if (decl_to_stridxlist_htab
)
5803 obstack_free (&stridx_obstack
, NULL
);
5804 delete decl_to_stridxlist_htab
;
5805 decl_to_stridxlist_htab
= NULL
;
5807 laststmt
.stmt
= NULL
;
5808 laststmt
.len
= NULL_TREE
;
5809 laststmt
.stridx
= 0;
5811 if (strlen_to_stridx
)
5813 strlen_to_stridx
->empty ();
5814 delete strlen_to_stridx
;
5815 strlen_to_stridx
= NULL
;
5821 loop_optimizer_finalize ();
5824 return walker
.m_cleanup_cfg
? TODO_cleanup_cfg
: 0;
5827 /* This file defines two passes: one for warnings that runs only when
5828 optimization is disabled, and another that implements optimizations
5829 and also issues warnings. */
5831 const pass_data pass_data_warn_printf
=
5833 GIMPLE_PASS
, /* type */
5834 "warn-printf", /* name */
5835 OPTGROUP_NONE
, /* optinfo_flags */
5836 TV_NONE
, /* tv_id */
5837 /* Normally an optimization pass would require PROP_ssa but because
5838 this pass runs early, with no optimization, to do sprintf format
5839 checking, it only requires PROP_cfg. */
5840 PROP_cfg
, /* properties_required */
5841 0, /* properties_provided */
5842 0, /* properties_destroyed */
5843 0, /* todo_flags_start */
5844 0, /* todo_flags_finish */
5847 class pass_warn_printf
: public gimple_opt_pass
5850 pass_warn_printf (gcc::context
*ctxt
)
5851 : gimple_opt_pass (pass_data_warn_printf
, ctxt
)
5854 virtual bool gate (function
*);
5855 virtual unsigned int execute (function
*fun
)
5857 return printf_strlen_execute (fun
, true);
5862 /* Return true to run the warning pass only when not optimizing and
5863 iff either -Wformat-overflow or -Wformat-truncation is specified. */
5866 pass_warn_printf::gate (function
*)
5868 return !optimize
&& (warn_format_overflow
> 0 || warn_format_trunc
> 0);
5871 const pass_data pass_data_strlen
=
5873 GIMPLE_PASS
, /* type */
5874 "strlen", /* name */
5875 OPTGROUP_NONE
, /* optinfo_flags */
5876 TV_TREE_STRLEN
, /* tv_id */
5877 PROP_cfg
| PROP_ssa
, /* properties_required */
5878 0, /* properties_provided */
5879 0, /* properties_destroyed */
5880 0, /* todo_flags_start */
5881 0, /* todo_flags_finish */
5884 class pass_strlen
: public gimple_opt_pass
5887 pass_strlen (gcc::context
*ctxt
)
5888 : gimple_opt_pass (pass_data_strlen
, ctxt
)
5891 opt_pass
* clone () { return new pass_strlen (m_ctxt
); }
5893 virtual bool gate (function
*);
5894 virtual unsigned int execute (function
*fun
)
5896 return printf_strlen_execute (fun
, false);
5900 /* Return true to run the pass only when the sprintf and/or strlen
5901 optimizations are enabled and -Wformat-overflow or -Wformat-truncation
5905 pass_strlen::gate (function
*)
5907 return ((warn_format_overflow
> 0
5908 || warn_format_trunc
> 0
5909 || warn_restrict
> 0
5910 || flag_optimize_strlen
> 0
5911 || flag_printf_return_value
)
5918 make_pass_warn_printf (gcc::context
*ctxt
)
5920 return new pass_warn_printf (ctxt
);
5924 make_pass_strlen (gcc::context
*ctxt
)
5926 return new pass_strlen (ctxt
);