1 /* String length optimization
2 Copyright (C) 2011-2019 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-restrict.h"
34 #include "fold-const.h"
35 #include "stor-layout.h"
36 #include "gimple-fold.h"
39 #include "gimple-iterator.h"
40 #include "gimplify-me.h"
45 #include "tree-ssa-alias.h"
46 #include "tree-ssa-propagate.h"
47 #include "tree-ssa-strlen.h"
49 #include "tree-hash-traits.h"
50 #include "tree-object-size.h"
53 #include "diagnostic-core.h"
54 #include "diagnostic.h"
59 #include "tree-ssa-loop.h"
60 #include "tree-scalar-evolution.h"
62 #include "vr-values.h"
63 #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 /* This 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. */
96 /* Pointer to '\0' if known, if NULL, it can be computed as
99 /* Reference count. Any changes to strinfo entry possibly shared
100 with dominating basic blocks need unshare_strinfo first, except
101 for dont_invalidate which affects only the immediately next
104 /* Copy of index. get_strinfo (si->idx) should return si; */
106 /* These 3 fields are for chaining related string pointers together.
108 bl = strlen (b); dl = strlen (d); strcpy (a, b); c = a + bl;
109 strcpy (c, d); e = c + dl;
110 strinfo(a) -> strinfo(c) -> strinfo(e)
111 All have ->first field equal to strinfo(a)->idx and are doubly
112 chained through prev/next fields. The later strinfos are required
113 to point into the same string with zero or more bytes after
114 the previous pointer and all bytes in between the two pointers
115 must be non-zero. Functions like strcpy or memcpy are supposed
116 to adjust all previous strinfo lengths, but not following strinfo
117 lengths (those are uncertain, usually invalidated during
118 maybe_invalidate, except when the alias oracle knows better).
119 Functions like strcat on the other side adjust the whole
120 related strinfo chain.
121 They are updated lazily, so to use the chain the same first fields
122 and si->prev->next == si->idx needs to be verified. */
126 /* A flag whether the string is known to be written in the current
129 /* A flag for the next maybe_invalidate that this strinfo shouldn't
130 be invalidated. Always cleared by maybe_invalidate. */
131 bool dont_invalidate
;
132 /* True if the string is known to be nul-terminated after NONZERO_CHARS
133 characters. False is useful when detecting strings that are built
134 up via successive memcpys. */
138 /* Pool for allocating strinfo_struct entries. */
139 static object_allocator
<strinfo
> strinfo_pool ("strinfo pool");
141 /* Vector mapping positive string indexes to strinfo, for the
142 current basic block. The first pointer in the vector is special,
143 it is either NULL, meaning the vector isn't shared, or it is
144 a basic block pointer to the owner basic_block if shared.
145 If some other bb wants to modify the vector, the vector needs
146 to be unshared first, and only the owner bb is supposed to free it. */
147 static vec
<strinfo
*, va_heap
, vl_embed
> *stridx_to_strinfo
;
149 /* One OFFSET->IDX mapping. */
152 struct stridxlist
*next
;
153 HOST_WIDE_INT offset
;
157 /* Hash table entry, mapping a DECL to a chain of OFFSET->IDX mappings. */
158 struct decl_stridxlist_map
160 struct tree_map_base base
;
161 struct stridxlist list
;
164 /* Hash table for mapping decls to a chained list of offset -> idx
166 typedef hash_map
<tree_decl_hash
, stridxlist
> decl_to_stridxlist_htab_t
;
167 static decl_to_stridxlist_htab_t
*decl_to_stridxlist_htab
;
169 /* Hash table mapping strlen (or strnlen with constant bound and return
170 smaller than bound) calls to stridx instances describing
171 the calls' arguments. Non-null only when warn_stringop_truncation
173 typedef std::pair
<int, location_t
> stridx_strlenloc
;
174 static hash_map
<tree
, stridx_strlenloc
> *strlen_to_stridx
;
176 /* Obstack for struct stridxlist and struct decl_stridxlist_map. */
177 static struct obstack stridx_obstack
;
179 /* Last memcpy statement if it could be adjusted if the trailing
180 '\0' written is immediately overwritten, or
181 *x = '\0' store that could be removed if it is immediately overwritten. */
182 struct laststmt_struct
189 static int get_stridx_plus_constant (strinfo
*, unsigned HOST_WIDE_INT
, tree
);
190 static void handle_builtin_stxncpy (built_in_function
, gimple_stmt_iterator
*);
194 - 1 if SI is known to start with more than OFF nonzero characters.
196 - 0 if SI is known to start with OFF nonzero characters,
197 but is not known to start with more.
199 - -1 if SI might not start with OFF nonzero characters. */
202 compare_nonzero_chars (strinfo
*si
, unsigned HOST_WIDE_INT off
)
204 if (si
->nonzero_chars
205 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
206 return compare_tree_int (si
->nonzero_chars
, off
);
211 /* Return true if SI is known to be a zero-length string. */
214 zero_length_string_p (strinfo
*si
)
216 return si
->full_string_p
&& integer_zerop (si
->nonzero_chars
);
219 /* Return strinfo vector entry IDX. */
221 static inline strinfo
*
222 get_strinfo (int idx
)
224 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
226 return (*stridx_to_strinfo
)[idx
];
229 /* Get the next strinfo in the chain after SI, or null if none. */
231 static inline strinfo
*
232 get_next_strinfo (strinfo
*si
)
236 strinfo
*nextsi
= get_strinfo (si
->next
);
237 if (nextsi
== NULL
|| nextsi
->first
!= si
->first
|| nextsi
->prev
!= si
->idx
)
242 /* Helper function for get_stridx. Return the strinfo index of the address
243 of EXP, which is available in PTR if nonnull. If OFFSET_OUT, it is
244 OK to return the index for some X <= &EXP and store &EXP - X in
248 get_addr_stridx (tree exp
, tree ptr
, unsigned HOST_WIDE_INT
*offset_out
)
251 struct stridxlist
*list
, *last
= NULL
;
254 if (!decl_to_stridxlist_htab
)
258 base
= get_addr_base_and_unit_offset (exp
, &poff
);
259 if (base
== NULL
|| !DECL_P (base
) || !poff
.is_constant (&off
))
262 list
= decl_to_stridxlist_htab
->get (base
);
268 if (list
->offset
== off
)
274 if (list
->offset
> off
)
281 if ((offset_out
|| ptr
) && last
&& last
->idx
> 0)
283 unsigned HOST_WIDE_INT rel_off
284 = (unsigned HOST_WIDE_INT
) off
- last
->offset
;
285 strinfo
*si
= get_strinfo (last
->idx
);
286 if (si
&& compare_nonzero_chars (si
, rel_off
) >= 0)
290 *offset_out
= rel_off
;
294 return get_stridx_plus_constant (si
, rel_off
, ptr
);
300 /* Return string index for EXP. */
303 get_stridx (tree exp
)
305 if (TREE_CODE (exp
) == SSA_NAME
)
307 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)])
308 return ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)];
311 HOST_WIDE_INT offset
= 0;
312 /* Follow a chain of at most 5 assignments. */
313 for (int i
= 0; i
< 5; i
++)
315 gimple
*def_stmt
= SSA_NAME_DEF_STMT (e
);
316 if (!is_gimple_assign (def_stmt
))
319 tree_code rhs_code
= gimple_assign_rhs_code (def_stmt
);
322 if (rhs_code
== ADDR_EXPR
)
324 /* Handle indices/offsets into VLAs which are implemented
325 as pointers to arrays. */
326 ptr
= gimple_assign_rhs1 (def_stmt
);
327 ptr
= TREE_OPERAND (ptr
, 0);
329 /* Handle also VLAs of types larger than char. */
330 if (tree eltsize
= TYPE_SIZE_UNIT (TREE_TYPE (ptr
)))
332 if (TREE_CODE (ptr
) == ARRAY_REF
)
334 off
= TREE_OPERAND (ptr
, 1);
335 ptr
= TREE_OPERAND (ptr
, 0);
336 if (!integer_onep (eltsize
))
338 /* Scale the array index by the size of the element
339 type in the rare case that it's greater than
340 the typical 1 for char, making sure both operands
341 have the same type. */
342 eltsize
= fold_convert (ssizetype
, eltsize
);
343 off
= fold_convert (ssizetype
, off
);
344 off
= fold_build2 (MULT_EXPR
, ssizetype
, off
, eltsize
);
348 off
= integer_zero_node
;
353 if (TREE_CODE (ptr
) != MEM_REF
)
356 /* Add the MEM_REF byte offset. */
357 tree mem_off
= TREE_OPERAND (ptr
, 1);
358 off
= fold_build2 (PLUS_EXPR
, TREE_TYPE (off
), off
, mem_off
);
359 ptr
= TREE_OPERAND (ptr
, 0);
361 else if (rhs_code
== POINTER_PLUS_EXPR
)
363 ptr
= gimple_assign_rhs1 (def_stmt
);
364 off
= gimple_assign_rhs2 (def_stmt
);
369 if (TREE_CODE (ptr
) != SSA_NAME
370 || !tree_fits_shwi_p (off
))
372 HOST_WIDE_INT this_off
= tree_to_shwi (off
);
375 offset
= (unsigned HOST_WIDE_INT
) offset
+ this_off
;
378 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)])
381 = get_strinfo (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)]);
382 if (si
&& compare_nonzero_chars (si
, offset
) >= 0)
383 return get_stridx_plus_constant (si
, offset
, exp
);
390 if (TREE_CODE (exp
) == ADDR_EXPR
)
392 int idx
= get_addr_stridx (TREE_OPERAND (exp
, 0), exp
, NULL
);
397 const char *p
= c_getstr (exp
);
399 return ~(int) strlen (p
);
404 /* Return true if strinfo vector is shared with the immediate dominator. */
407 strinfo_shared (void)
409 return vec_safe_length (stridx_to_strinfo
)
410 && (*stridx_to_strinfo
)[0] != NULL
;
413 /* Unshare strinfo vector that is shared with the immediate dominator. */
416 unshare_strinfo_vec (void)
421 gcc_assert (strinfo_shared ());
422 stridx_to_strinfo
= vec_safe_copy (stridx_to_strinfo
);
423 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
426 (*stridx_to_strinfo
)[0] = NULL
;
429 /* Attempt to create a string index for exp, ADDR_EXPR's operand.
430 Return a pointer to the location where the string index can
431 be stored (if 0) or is stored, or NULL if this can't be tracked. */
434 addr_stridxptr (tree exp
)
439 tree base
= get_addr_base_and_unit_offset (exp
, &poff
);
440 if (base
== NULL_TREE
|| !DECL_P (base
) || !poff
.is_constant (&off
))
443 if (!decl_to_stridxlist_htab
)
445 decl_to_stridxlist_htab
446 = new hash_map
<tree_decl_hash
, stridxlist
> (64);
447 gcc_obstack_init (&stridx_obstack
);
451 stridxlist
*list
= &decl_to_stridxlist_htab
->get_or_insert (base
, &existed
);
455 stridxlist
*before
= NULL
;
456 for (i
= 0; i
< 32; i
++)
458 if (list
->offset
== off
)
460 if (list
->offset
> off
&& before
== NULL
)
462 if (list
->next
== NULL
)
471 before
= XOBNEW (&stridx_obstack
, struct stridxlist
);
478 list
->next
= XOBNEW (&stridx_obstack
, struct stridxlist
);
488 /* Create a new string index, or return 0 if reached limit. */
491 new_stridx (tree exp
)
494 if (max_stridx
>= PARAM_VALUE (PARAM_MAX_TRACKED_STRLENS
))
496 if (TREE_CODE (exp
) == SSA_NAME
)
498 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp
))
501 ssa_ver_to_stridx
[SSA_NAME_VERSION (exp
)] = idx
;
504 if (TREE_CODE (exp
) == ADDR_EXPR
)
506 int *pidx
= addr_stridxptr (TREE_OPERAND (exp
, 0));
509 gcc_assert (*pidx
== 0);
510 *pidx
= max_stridx
++;
517 /* Like new_stridx, but for ADDR_EXPR's operand instead. */
520 new_addr_stridx (tree exp
)
523 if (max_stridx
>= PARAM_VALUE (PARAM_MAX_TRACKED_STRLENS
))
525 pidx
= addr_stridxptr (exp
);
528 gcc_assert (*pidx
== 0);
529 *pidx
= max_stridx
++;
535 /* Create a new strinfo. */
538 new_strinfo (tree ptr
, int idx
, tree nonzero_chars
, bool full_string_p
)
540 strinfo
*si
= strinfo_pool
.allocate ();
541 si
->nonzero_chars
= nonzero_chars
;
544 si
->endptr
= NULL_TREE
;
550 si
->writable
= false;
551 si
->dont_invalidate
= false;
552 si
->full_string_p
= full_string_p
;
556 /* Decrease strinfo refcount and free it if not referenced anymore. */
559 free_strinfo (strinfo
*si
)
561 if (si
&& --si
->refcount
== 0)
562 strinfo_pool
.remove (si
);
565 /* Set strinfo in the vector entry IDX to SI. */
568 set_strinfo (int idx
, strinfo
*si
)
570 if (vec_safe_length (stridx_to_strinfo
) && (*stridx_to_strinfo
)[0])
571 unshare_strinfo_vec ();
572 if (vec_safe_length (stridx_to_strinfo
) <= (unsigned int) idx
)
573 vec_safe_grow_cleared (stridx_to_strinfo
, idx
+ 1);
574 (*stridx_to_strinfo
)[idx
] = si
;
577 /* Return the first strinfo in the related strinfo chain
578 if all strinfos in between belong to the chain, otherwise NULL. */
581 verify_related_strinfos (strinfo
*origsi
)
583 strinfo
*si
= origsi
, *psi
;
585 if (origsi
->first
== 0)
587 for (; si
->prev
; si
= psi
)
589 if (si
->first
!= origsi
->first
)
591 psi
= get_strinfo (si
->prev
);
594 if (psi
->next
!= si
->idx
)
597 if (si
->idx
!= si
->first
)
602 /* Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
603 Use LOC for folding. */
606 set_endptr_and_length (location_t loc
, strinfo
*si
, tree endptr
)
610 tree start_as_size
= fold_convert_loc (loc
, size_type_node
, si
->ptr
);
611 tree end_as_size
= fold_convert_loc (loc
, size_type_node
, endptr
);
612 si
->nonzero_chars
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
613 end_as_size
, start_as_size
);
614 si
->full_string_p
= true;
617 /* Return the string length, or NULL if it can't be computed.
618 The length may but need not be constant. Instead, it might be
619 the result of a strlen() call. */
622 get_string_length (strinfo
*si
)
624 /* If the length has already been computed return it if it's exact
625 (i.e., the string is nul-terminated at NONZERO_CHARS), or return
627 if (si
->nonzero_chars
)
628 return si
->full_string_p
? si
->nonzero_chars
: NULL
;
630 /* If the string is the result of one of the built-in calls below
631 attempt to compute the length from the call statement. */
634 gimple
*stmt
= si
->stmt
, *lenstmt
;
635 tree callee
, lhs
, fn
, tem
;
637 gimple_stmt_iterator gsi
;
639 gcc_assert (is_gimple_call (stmt
));
640 callee
= gimple_call_fndecl (stmt
);
641 gcc_assert (callee
&& fndecl_built_in_p (callee
, BUILT_IN_NORMAL
));
642 lhs
= gimple_call_lhs (stmt
);
643 /* unshare_strinfo is intentionally not called here. The (delayed)
644 transformation of strcpy or strcat into stpcpy is done at the place
645 of the former strcpy/strcat call and so can affect all the strinfos
646 with the same stmt. If they were unshared before and transformation
647 has been already done, the handling of BUILT_IN_STPCPY{,_CHK} should
648 just compute the right length. */
649 switch (DECL_FUNCTION_CODE (callee
))
651 case BUILT_IN_STRCAT
:
652 case BUILT_IN_STRCAT_CHK
:
653 gsi
= gsi_for_stmt (stmt
);
654 fn
= builtin_decl_implicit (BUILT_IN_STRLEN
);
655 gcc_assert (lhs
== NULL_TREE
);
656 tem
= unshare_expr (gimple_call_arg (stmt
, 0));
657 lenstmt
= gimple_build_call (fn
, 1, tem
);
658 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), lenstmt
);
659 gimple_call_set_lhs (lenstmt
, lhs
);
660 gimple_set_vuse (lenstmt
, gimple_vuse (stmt
));
661 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
662 tem
= gimple_call_arg (stmt
, 0);
663 if (!ptrofftype_p (TREE_TYPE (lhs
)))
665 lhs
= convert_to_ptrofftype (lhs
);
666 lhs
= force_gimple_operand_gsi (&gsi
, lhs
, true, NULL_TREE
,
667 true, GSI_SAME_STMT
);
669 lenstmt
= gimple_build_assign
670 (make_ssa_name (TREE_TYPE (gimple_call_arg (stmt
, 0))),
671 POINTER_PLUS_EXPR
,tem
, lhs
);
672 gsi_insert_before (&gsi
, lenstmt
, GSI_SAME_STMT
);
673 gimple_call_set_arg (stmt
, 0, gimple_assign_lhs (lenstmt
));
676 case BUILT_IN_STRCPY
:
677 case BUILT_IN_STRCPY_CHK
:
678 gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY
));
679 if (gimple_call_num_args (stmt
) == 2)
680 fn
= builtin_decl_implicit (BUILT_IN_STPCPY
);
682 fn
= builtin_decl_explicit (BUILT_IN_STPCPY_CHK
);
683 gcc_assert (lhs
== NULL_TREE
);
684 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
686 fprintf (dump_file
, "Optimizing: ");
687 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
689 gimple_call_set_fndecl (stmt
, fn
);
690 lhs
= make_ssa_name (TREE_TYPE (TREE_TYPE (fn
)), stmt
);
691 gimple_call_set_lhs (stmt
, lhs
);
693 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
695 fprintf (dump_file
, "into: ");
696 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
699 case BUILT_IN_STPCPY
:
700 case BUILT_IN_STPCPY_CHK
:
701 gcc_assert (lhs
!= NULL_TREE
);
702 loc
= gimple_location (stmt
);
703 set_endptr_and_length (loc
, si
, lhs
);
704 for (strinfo
*chainsi
= verify_related_strinfos (si
);
706 chainsi
= get_next_strinfo (chainsi
))
707 if (chainsi
->nonzero_chars
== NULL
)
708 set_endptr_and_length (loc
, chainsi
, lhs
);
710 case BUILT_IN_MALLOC
:
712 /* BUILT_IN_CALLOC always has si->nonzero_chars set. */
719 return si
->nonzero_chars
;
722 /* Dump strlen data to FP for statement STMT. When non-null, RVALS
723 points to EVRP info and is used to dump strlen range for non-constant
727 dump_strlen_info (FILE *fp
, gimple
*stmt
, const vr_values
*rvals
)
731 fprintf (fp
, "\nDumping strlen pass data after ");
732 print_gimple_expr (fp
, stmt
, TDF_LINENO
);
736 fprintf (fp
, "\nDumping strlen pass data\n");
738 fprintf (fp
, "max_stridx = %i\n", max_stridx
);
739 fprintf (fp
, "ssa_ver_to_stridx has %u elements\n",
740 ssa_ver_to_stridx
.length ());
741 fprintf (fp
, "stridx_to_strinfo");
742 if (stridx_to_strinfo
)
744 fprintf (fp
, " has %u elements\n", stridx_to_strinfo
->length ());
745 for (unsigned i
= 0; i
!= stridx_to_strinfo
->length (); ++i
)
747 if (strinfo
*si
= (*stridx_to_strinfo
)[i
])
751 fprintf (fp
, " idx = %i", si
->idx
);
754 fprintf (fp
, ", ptr = ");
755 print_generic_expr (fp
, si
->ptr
);
757 fprintf (fp
, ", nonzero_chars = ");
758 print_generic_expr (fp
, si
->nonzero_chars
);
759 if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
761 value_range_kind rng
= VR_UNDEFINED
;
765 const value_range
*vr
766 = CONST_CAST (class vr_values
*, rvals
)
767 ->get_value_range (si
->nonzero_chars
);
769 if (range_int_cst_p (vr
))
771 min
= wi::to_wide (vr
->min ());
772 max
= wi::to_wide (vr
->max ());
778 rng
= get_range_info (si
->nonzero_chars
, &min
, &max
);
780 if (rng
== VR_RANGE
|| rng
== VR_ANTI_RANGE
)
782 fprintf (fp
, " %s[%llu, %llu]",
783 rng
== VR_RANGE
? "" : "~",
784 (long long) min
.to_uhwi (),
785 (long long) max
.to_uhwi ());
788 fprintf (fp
, " , refcount = %i", si
->refcount
);
791 fprintf (fp
, ", stmt = ");
792 print_gimple_expr (fp
, si
->stmt
, 0);
795 fprintf (fp
, ", writable");
796 if (si
->full_string_p
)
797 fprintf (fp
, ", full_string_p");
798 if (strinfo
*next
= get_next_strinfo (si
))
802 fprintf (fp
, "%i%s", next
->idx
, next
->first
? ", " : "");
803 while ((next
= get_next_strinfo (next
)));
811 fprintf (fp
, " = null\n");
813 fprintf (fp
, "decl_to_stridxlist_htab");
814 if (decl_to_stridxlist_htab
)
817 typedef decl_to_stridxlist_htab_t::iterator iter_t
;
818 for (iter_t it
= decl_to_stridxlist_htab
->begin ();
819 it
!= decl_to_stridxlist_htab
->end (); ++it
)
821 tree decl
= (*it
).first
;
822 stridxlist
*list
= &(*it
).second
;
823 fprintf (fp
, " decl = ");
824 print_generic_expr (fp
, decl
);
827 fprintf (fp
, ", offsets = {");
828 for (; list
; list
= list
->next
)
829 fprintf (fp
, "%lli%s", (long long) list
->offset
,
830 list
->next
? ", " : "");
837 fprintf (fp
, " = null\n");
841 fprintf (fp
, "laststmt = ");
842 print_gimple_expr (fp
, laststmt
.stmt
, 0);
843 fprintf (fp
, ", len = ");
844 print_generic_expr (fp
, laststmt
.len
);
845 fprintf (fp
, ", stridx = %i\n", laststmt
.stridx
);
849 /* Attempt to determine the length of the string SRC. On success, store
850 the length in *PDATA and return true. Otherwise, return false.
851 VISITED is a bitmap of visited PHI nodes. RVALS points to EVRP info
852 and PSSA_DEF_MAX to an SSA_NAME assignment limit used to prevent runaway
856 get_range_strlen_dynamic (tree src
, c_strlen_data
*pdata
, bitmap
*visited
,
857 const vr_values
*rvals
, unsigned *pssa_def_max
)
859 int idx
= get_stridx (src
);
862 if (TREE_CODE (src
) == SSA_NAME
)
864 gimple
*def_stmt
= SSA_NAME_DEF_STMT (src
);
865 if (gimple_code (def_stmt
) == GIMPLE_PHI
)
868 *visited
= BITMAP_ALLOC (NULL
);
870 if (!bitmap_set_bit (*visited
, SSA_NAME_VERSION (src
)))
873 if (*pssa_def_max
== 0)
878 /* Iterate over the PHI arguments and determine the minimum
879 and maximum length/size of each and incorporate them into
880 the overall result. */
881 gphi
*phi
= as_a
<gphi
*> (def_stmt
);
882 for (unsigned i
= 0; i
!= gimple_phi_num_args (phi
); ++i
)
884 tree arg
= gimple_phi_arg_def (phi
, i
);
885 if (arg
== gimple_phi_result (def_stmt
))
888 c_strlen_data argdata
= { };
889 if (get_range_strlen_dynamic (arg
, &argdata
, visited
, rvals
,
892 /* Set the DECL of an unterminated array this argument
893 refers to if one hasn't been found yet. */
894 if (!pdata
->decl
&& argdata
.decl
)
895 pdata
->decl
= argdata
.decl
;
898 || (integer_zerop (argdata
.minlen
)
899 && (!argdata
.maxbound
900 || integer_all_onesp (argdata
.maxbound
))
901 && integer_all_onesp (argdata
.maxlen
)))
903 /* Set the upper bound of the length to unbounded. */
904 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
908 /* Adjust the minimum and maximum length determined
909 so far and the upper bound on the array size. */
911 || tree_int_cst_lt (argdata
.minlen
, pdata
->minlen
))
912 pdata
->minlen
= argdata
.minlen
;
915 && tree_int_cst_lt (pdata
->maxlen
, argdata
.maxlen
)))
916 pdata
->maxlen
= argdata
.maxlen
;
918 || TREE_CODE (pdata
->maxbound
) != INTEGER_CST
920 && tree_int_cst_lt (pdata
->maxbound
,
922 && !integer_all_onesp (argdata
.maxbound
)))
923 pdata
->maxbound
= argdata
.maxbound
;
926 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
933 /* Return success regardless of the result and handle *PDATA
935 get_range_strlen (src
, pdata
, 1);
941 /* SRC is a string of constant length. */
942 pdata
->minlen
= build_int_cst (size_type_node
, ~idx
);
943 pdata
->maxlen
= pdata
->minlen
;
944 pdata
->maxbound
= pdata
->maxlen
;
948 if (strinfo
*si
= get_strinfo (idx
))
950 pdata
->minlen
= get_string_length (si
);
951 if (!pdata
->minlen
&& si
->nonzero_chars
)
953 if (TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
954 pdata
->minlen
= si
->nonzero_chars
;
955 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
957 const value_range
*vr
958 = CONST_CAST (class vr_values
*, rvals
)
959 ->get_value_range (si
->nonzero_chars
);
960 if (vr
->kind () == VR_RANGE
961 && range_int_cst_p (vr
))
963 pdata
->minlen
= vr
->min ();
964 pdata
->maxlen
= vr
->max ();
967 pdata
->minlen
= build_zero_cst (size_type_node
);
970 pdata
->minlen
= build_zero_cst (size_type_node
);
973 if (TREE_CODE (base
) == ADDR_EXPR
)
974 base
= TREE_OPERAND (base
, 0);
978 base
= get_addr_base_and_unit_offset (base
, &poff
);
981 && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
982 && TYPE_SIZE_UNIT (TREE_TYPE (base
))
983 && poff
.is_constant (&off
))
985 tree basetype
= TREE_TYPE (base
);
986 tree size
= TYPE_SIZE_UNIT (basetype
);
987 ++off
; /* Increment for the terminating nul. */
988 pdata
->maxlen
= fold_build2 (MINUS_EXPR
, size_type_node
, size
,
989 build_int_cst (size_type_node
, off
));
990 pdata
->maxbound
= pdata
->maxlen
;
993 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
995 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == SSA_NAME
)
997 const value_range
*vr
998 = CONST_CAST (class vr_values
*, rvals
)
999 ->get_value_range (si
->nonzero_chars
);
1000 if (vr
->kind () == VR_RANGE
1001 && range_int_cst_p (vr
))
1003 pdata
->minlen
= vr
->min ();
1004 pdata
->maxlen
= vr
->max ();
1005 pdata
->maxbound
= pdata
->maxlen
;
1009 pdata
->minlen
= build_zero_cst (size_type_node
);
1010 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1013 else if (pdata
->minlen
&& TREE_CODE (pdata
->minlen
) == INTEGER_CST
)
1015 pdata
->maxlen
= pdata
->minlen
;
1016 pdata
->maxbound
= pdata
->minlen
;
1020 /* For PDATA->MINLEN that's a non-constant expression such
1021 as PLUS_EXPR whose value range is unknown, set the bounds
1022 to zero and SIZE_MAX. */
1023 pdata
->minlen
= build_zero_cst (size_type_node
);
1024 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1033 /* Analogous to get_range_strlen but for dynamically created strings,
1034 i.e., those created by calls to strcpy as opposed to just string
1036 Try to obtain the range of the lengths of the string(s) referenced
1037 by SRC, or the size of the largest array SRC refers to if the range
1038 of lengths cannot be determined, and store all in *PDATA. RVALS
1039 points to EVRP info. */
1042 get_range_strlen_dynamic (tree src
, c_strlen_data
*pdata
,
1043 const vr_values
*rvals
)
1045 bitmap visited
= NULL
;
1046 tree maxbound
= pdata
->maxbound
;
1048 unsigned limit
= PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT
);
1049 if (!get_range_strlen_dynamic (src
, pdata
, &visited
, rvals
, &limit
))
1051 /* On failure extend the length range to an impossible maximum
1052 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1053 members can stay unchanged regardless. */
1054 pdata
->minlen
= ssize_int (0);
1055 pdata
->maxlen
= build_all_ones_cst (size_type_node
);
1057 else if (!pdata
->minlen
)
1058 pdata
->minlen
= ssize_int (0);
1060 /* If it's unchanged from it initial non-null value, set the conservative
1061 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1062 if (maxbound
&& pdata
->maxbound
== maxbound
)
1063 pdata
->maxbound
= build_all_ones_cst (size_type_node
);
1066 BITMAP_FREE (visited
);
1069 /* Invalidate string length information for strings whose length
1070 might change due to stores in stmt. */
1073 maybe_invalidate (gimple
*stmt
)
1077 bool nonempty
= false;
1079 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
1082 if (!si
->dont_invalidate
)
1085 /* Do not use si->nonzero_chars. */
1086 ao_ref_init_from_ptr_and_size (&r
, si
->ptr
, NULL_TREE
);
1087 if (stmt_may_clobber_ref_p_1 (stmt
, &r
))
1089 set_strinfo (i
, NULL
);
1094 si
->dont_invalidate
= false;
1100 /* Unshare strinfo record SI, if it has refcount > 1 or
1101 if stridx_to_strinfo vector is shared with some other
1105 unshare_strinfo (strinfo
*si
)
1109 if (si
->refcount
== 1 && !strinfo_shared ())
1112 nsi
= new_strinfo (si
->ptr
, si
->idx
, si
->nonzero_chars
, si
->full_string_p
);
1113 nsi
->stmt
= si
->stmt
;
1114 nsi
->endptr
= si
->endptr
;
1115 nsi
->first
= si
->first
;
1116 nsi
->prev
= si
->prev
;
1117 nsi
->next
= si
->next
;
1118 nsi
->writable
= si
->writable
;
1119 set_strinfo (si
->idx
, nsi
);
1124 /* Attempt to create a new strinfo for BASESI + OFF, or find existing
1125 strinfo if there is any. Return it's idx, or 0 if no strinfo has
1129 get_stridx_plus_constant (strinfo
*basesi
, unsigned HOST_WIDE_INT off
,
1132 if (TREE_CODE (ptr
) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1135 if (compare_nonzero_chars (basesi
, off
) < 0
1136 || !tree_fits_uhwi_p (basesi
->nonzero_chars
))
1139 unsigned HOST_WIDE_INT nonzero_chars
1140 = tree_to_uhwi (basesi
->nonzero_chars
) - off
;
1141 strinfo
*si
= basesi
, *chainsi
;
1142 if (si
->first
|| si
->prev
|| si
->next
)
1143 si
= verify_related_strinfos (basesi
);
1145 || si
->nonzero_chars
== NULL_TREE
1146 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1149 if (TREE_CODE (ptr
) == SSA_NAME
1150 && ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1151 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
);
1153 gcc_checking_assert (compare_tree_int (si
->nonzero_chars
, off
) != -1);
1154 for (chainsi
= si
; chainsi
->next
; chainsi
= si
)
1156 si
= get_next_strinfo (chainsi
);
1158 || si
->nonzero_chars
== NULL_TREE
1159 || TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
)
1161 int r
= compare_tree_int (si
->nonzero_chars
, nonzero_chars
);
1166 if (TREE_CODE (ptr
) == SSA_NAME
)
1167 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = si
->idx
;
1170 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1171 if (pidx
!= NULL
&& *pidx
== 0)
1180 int idx
= new_stridx (ptr
);
1183 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, nonzero_chars
),
1184 basesi
->full_string_p
);
1185 set_strinfo (idx
, si
);
1186 if (strinfo
*nextsi
= get_strinfo (chainsi
->next
))
1188 nextsi
= unshare_strinfo (nextsi
);
1189 si
->next
= nextsi
->idx
;
1192 chainsi
= unshare_strinfo (chainsi
);
1193 if (chainsi
->first
== 0)
1194 chainsi
->first
= chainsi
->idx
;
1195 chainsi
->next
= idx
;
1196 if (chainsi
->endptr
== NULL_TREE
&& zero_length_string_p (si
))
1197 chainsi
->endptr
= ptr
;
1198 si
->endptr
= chainsi
->endptr
;
1199 si
->prev
= chainsi
->idx
;
1200 si
->first
= chainsi
->first
;
1201 si
->writable
= chainsi
->writable
;
1205 /* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
1206 to a zero-length string and if possible chain it to a related strinfo
1207 chain whose part is or might be CHAINSI. */
1210 zero_length_string (tree ptr
, strinfo
*chainsi
)
1214 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1215 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
);
1216 gcc_checking_assert (TREE_CODE (ptr
) == SSA_NAME
1217 && ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] == 0);
1219 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr
))
1221 if (chainsi
!= NULL
)
1223 si
= verify_related_strinfos (chainsi
);
1228 /* We shouldn't mix delayed and non-delayed lengths. */
1229 gcc_assert (si
->full_string_p
);
1230 if (si
->endptr
== NULL_TREE
)
1232 si
= unshare_strinfo (si
);
1236 si
= get_next_strinfo (si
);
1239 if (zero_length_string_p (chainsi
))
1243 chainsi
= unshare_strinfo (chainsi
);
1246 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = chainsi
->idx
;
1252 /* We shouldn't mix delayed and non-delayed lengths. */
1253 gcc_assert (chainsi
->full_string_p
);
1254 if (chainsi
->first
|| chainsi
->prev
|| chainsi
->next
)
1256 chainsi
= unshare_strinfo (chainsi
);
1263 idx
= new_stridx (ptr
);
1266 si
= new_strinfo (ptr
, idx
, build_int_cst (size_type_node
, 0), true);
1267 set_strinfo (idx
, si
);
1269 if (chainsi
!= NULL
)
1271 chainsi
= unshare_strinfo (chainsi
);
1272 if (chainsi
->first
== 0)
1273 chainsi
->first
= chainsi
->idx
;
1274 chainsi
->next
= idx
;
1275 if (chainsi
->endptr
== NULL_TREE
)
1276 chainsi
->endptr
= ptr
;
1277 si
->prev
= chainsi
->idx
;
1278 si
->first
= chainsi
->first
;
1279 si
->writable
= chainsi
->writable
;
1284 /* For strinfo ORIGSI whose length has been just updated, adjust other
1285 related strinfos so that they match the new ORIGSI. This involves:
1287 - adding ADJ to the nonzero_chars fields
1288 - copying full_string_p from the new ORIGSI. */
1291 adjust_related_strinfos (location_t loc
, strinfo
*origsi
, tree adj
)
1293 strinfo
*si
= verify_related_strinfos (origsi
);
1306 si
= unshare_strinfo (si
);
1307 /* We shouldn't see delayed lengths here; the caller must
1308 have calculated the old length in order to calculate
1310 gcc_assert (si
->nonzero_chars
);
1311 tem
= fold_convert_loc (loc
, TREE_TYPE (si
->nonzero_chars
), adj
);
1312 si
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
1313 TREE_TYPE (si
->nonzero_chars
),
1314 si
->nonzero_chars
, tem
);
1315 si
->full_string_p
= origsi
->full_string_p
;
1317 si
->endptr
= NULL_TREE
;
1318 si
->dont_invalidate
= true;
1320 nsi
= get_next_strinfo (si
);
1327 /* Find if there are other SSA_NAME pointers equal to PTR
1328 for which we don't track their string lengths yet. If so, use
1332 find_equal_ptrs (tree ptr
, int idx
)
1334 if (TREE_CODE (ptr
) != SSA_NAME
)
1338 gimple
*stmt
= SSA_NAME_DEF_STMT (ptr
);
1339 if (!is_gimple_assign (stmt
))
1341 ptr
= gimple_assign_rhs1 (stmt
);
1342 switch (gimple_assign_rhs_code (stmt
))
1347 if (!POINTER_TYPE_P (TREE_TYPE (ptr
)))
1349 if (TREE_CODE (ptr
) == SSA_NAME
)
1351 if (TREE_CODE (ptr
) != ADDR_EXPR
)
1356 int *pidx
= addr_stridxptr (TREE_OPERAND (ptr
, 0));
1357 if (pidx
!= NULL
&& *pidx
== 0)
1365 /* We might find an endptr created in this pass. Grow the
1366 vector in that case. */
1367 if (ssa_ver_to_stridx
.length () <= SSA_NAME_VERSION (ptr
))
1368 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
);
1370 if (ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] != 0)
1372 ssa_ver_to_stridx
[SSA_NAME_VERSION (ptr
)] = idx
;
1376 /* Return true if STMT is a call to a builtin function with the right
1377 arguments and attributes that should be considered for optimization
1381 valid_builtin_call (gimple
*stmt
)
1383 if (!gimple_call_builtin_p (stmt
, BUILT_IN_NORMAL
))
1386 tree callee
= gimple_call_fndecl (stmt
);
1387 tree decl
= builtin_decl_explicit (DECL_FUNCTION_CODE (callee
));
1390 && !gimple_builtin_call_types_compatible_p (stmt
, decl
))
1393 switch (DECL_FUNCTION_CODE (callee
))
1395 case BUILT_IN_MEMCMP
:
1396 case BUILT_IN_MEMCMP_EQ
:
1397 case BUILT_IN_STRCMP
:
1398 case BUILT_IN_STRNCMP
:
1399 case BUILT_IN_STRCHR
:
1400 case BUILT_IN_STRLEN
:
1401 case BUILT_IN_STRNLEN
:
1402 /* The above functions should be pure. Punt if they aren't. */
1403 if (gimple_vdef (stmt
) || gimple_vuse (stmt
) == NULL_TREE
)
1407 case BUILT_IN_CALLOC
:
1408 case BUILT_IN_MALLOC
:
1409 case BUILT_IN_MEMCPY
:
1410 case BUILT_IN_MEMCPY_CHK
:
1411 case BUILT_IN_MEMPCPY
:
1412 case BUILT_IN_MEMPCPY_CHK
:
1413 case BUILT_IN_MEMSET
:
1414 case BUILT_IN_STPCPY
:
1415 case BUILT_IN_STPCPY_CHK
:
1416 case BUILT_IN_STPNCPY
:
1417 case BUILT_IN_STPNCPY_CHK
:
1418 case BUILT_IN_STRCAT
:
1419 case BUILT_IN_STRCAT_CHK
:
1420 case BUILT_IN_STRCPY
:
1421 case BUILT_IN_STRCPY_CHK
:
1422 case BUILT_IN_STRNCAT
:
1423 case BUILT_IN_STRNCAT_CHK
:
1424 case BUILT_IN_STRNCPY
:
1425 case BUILT_IN_STRNCPY_CHK
:
1426 /* The above functions should be neither const nor pure. Punt if they
1428 if (gimple_vdef (stmt
) == NULL_TREE
|| gimple_vuse (stmt
) == NULL_TREE
)
1439 /* If the last .MEM setter statement before STMT is
1440 memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
1441 and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
1442 just memcpy (x, y, strlen (y)). SI must be the zero length
1446 adjust_last_stmt (strinfo
*si
, gimple
*stmt
, bool is_strcat
)
1448 tree vuse
, callee
, len
;
1449 struct laststmt_struct last
= laststmt
;
1450 strinfo
*lastsi
, *firstsi
;
1451 unsigned len_arg_no
= 2;
1453 laststmt
.stmt
= NULL
;
1454 laststmt
.len
= NULL_TREE
;
1455 laststmt
.stridx
= 0;
1457 if (last
.stmt
== NULL
)
1460 vuse
= gimple_vuse (stmt
);
1461 if (vuse
== NULL_TREE
1462 || SSA_NAME_DEF_STMT (vuse
) != last
.stmt
1463 || !has_single_use (vuse
))
1466 gcc_assert (last
.stridx
> 0);
1467 lastsi
= get_strinfo (last
.stridx
);
1473 if (lastsi
->first
== 0 || lastsi
->first
!= si
->first
)
1476 firstsi
= verify_related_strinfos (si
);
1477 if (firstsi
== NULL
)
1479 while (firstsi
!= lastsi
)
1481 firstsi
= get_next_strinfo (firstsi
);
1482 if (firstsi
== NULL
)
1487 if (!is_strcat
&& !zero_length_string_p (si
))
1490 if (is_gimple_assign (last
.stmt
))
1492 gimple_stmt_iterator gsi
;
1494 if (!integer_zerop (gimple_assign_rhs1 (last
.stmt
)))
1496 if (stmt_could_throw_p (cfun
, last
.stmt
))
1498 gsi
= gsi_for_stmt (last
.stmt
);
1499 unlink_stmt_vdef (last
.stmt
);
1500 release_defs (last
.stmt
);
1501 gsi_remove (&gsi
, true);
1505 if (!valid_builtin_call (last
.stmt
))
1508 callee
= gimple_call_fndecl (last
.stmt
);
1509 switch (DECL_FUNCTION_CODE (callee
))
1511 case BUILT_IN_MEMCPY
:
1512 case BUILT_IN_MEMCPY_CHK
:
1518 len
= gimple_call_arg (last
.stmt
, len_arg_no
);
1519 if (tree_fits_uhwi_p (len
))
1521 if (!tree_fits_uhwi_p (last
.len
)
1522 || integer_zerop (len
)
1523 || tree_to_uhwi (len
) != tree_to_uhwi (last
.len
) + 1)
1525 /* Don't adjust the length if it is divisible by 4, it is more efficient
1526 to store the extra '\0' in that case. */
1527 if ((tree_to_uhwi (len
) & 3) == 0)
1530 /* Don't fold away an out of bounds access, as this defeats proper
1532 tree dst
= gimple_call_arg (last
.stmt
, 0);
1533 tree size
= compute_objsize (dst
, 0);
1534 if (size
&& tree_int_cst_lt (size
, len
))
1537 else if (TREE_CODE (len
) == SSA_NAME
)
1539 gimple
*def_stmt
= SSA_NAME_DEF_STMT (len
);
1540 if (!is_gimple_assign (def_stmt
)
1541 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
1542 || gimple_assign_rhs1 (def_stmt
) != last
.len
1543 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
1549 gimple_call_set_arg (last
.stmt
, len_arg_no
, last
.len
);
1550 update_stmt (last
.stmt
);
1553 /* For an LHS that is an SSA_NAME that is the result of a strlen()
1554 call, or when BOUND is non-null, of a strnlen() call, set LHS
1555 range info to [0, min (MAX, BOUND)] when the range includes more
1556 than one value and return LHS. Otherwise, when the range
1557 [MIN, MAX] is such that MIN == MAX, return the tree representation
1558 of (MIN). The latter allows callers to fold suitable strnlen() calls
1562 set_strlen_range (tree lhs
, wide_int min
, wide_int max
,
1563 tree bound
/* = NULL_TREE */)
1565 if (TREE_CODE (lhs
) != SSA_NAME
1566 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1571 /* For strnlen, adjust MIN and MAX as necessary. If the bound
1572 is less than the size of the array set MAX to it. It it's
1573 greater than MAX and MAX is non-zero bump MAX down to account
1574 for the necessary terminating nul. Otherwise leave it alone. */
1575 if (TREE_CODE (bound
) == INTEGER_CST
)
1577 wide_int wibnd
= wi::to_wide (bound
);
1578 int cmp
= wi::cmpu (wibnd
, max
);
1581 else if (cmp
&& wi::ne_p (max
, min
))
1584 else if (TREE_CODE (bound
) == SSA_NAME
)
1586 wide_int minbound
, maxbound
;
1587 value_range_kind rng
= get_range_info (bound
, &minbound
, &maxbound
);
1588 if (rng
== VR_RANGE
)
1590 /* For a bound in a known range, adjust the range determined
1591 above as necessary. For a bound in some anti-range or
1592 in an unknown range, use the range determined by callers. */
1593 if (wi::ltu_p (minbound
, min
))
1595 if (wi::ltu_p (maxbound
, max
))
1602 return wide_int_to_tree (size_type_node
, min
);
1604 set_range_info (lhs
, VR_RANGE
, min
, max
);
1608 /* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
1609 SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
1610 a character array A[N] with unknown length bounded by N, and for
1611 strnlen(), by min (N, BOUND). */
1614 maybe_set_strlen_range (tree lhs
, tree src
, tree bound
)
1616 if (TREE_CODE (lhs
) != SSA_NAME
1617 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs
)))
1620 if (TREE_CODE (src
) == SSA_NAME
)
1622 gimple
*def
= SSA_NAME_DEF_STMT (src
);
1623 if (is_gimple_assign (def
)
1624 && gimple_assign_rhs_code (def
) == ADDR_EXPR
)
1625 src
= gimple_assign_rhs1 (def
);
1628 /* The longest string is PTRDIFF_MAX - 1 bytes including the final
1629 NUL so that the difference between a pointer to just past it and
1630 one to its beginning is positive. */
1631 wide_int max
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
1633 if (TREE_CODE (src
) == ADDR_EXPR
)
1635 /* The last array member of a struct can be bigger than its size
1636 suggests if it's treated as a poor-man's flexible array member. */
1637 src
= TREE_OPERAND (src
, 0);
1638 if (TREE_CODE (src
) != MEM_REF
1639 && !array_at_struct_end_p (src
))
1641 tree type
= TREE_TYPE (src
);
1642 tree size
= TYPE_SIZE_UNIT (type
);
1644 && TREE_CODE (size
) == INTEGER_CST
1645 && !integer_zerop (size
))
1647 /* Even though such uses of strlen would be undefined,
1648 avoid relying on arrays of arrays in case some genius
1649 decides to call strlen on an unterminated array element
1650 that's followed by a terminated one. Likewise, avoid
1651 assuming that a struct array member is necessarily
1652 nul-terminated (the nul may be in the member that
1653 follows). In those cases, assume that the length
1654 of the string stored in such an array is bounded
1655 by the size of the enclosing object if one can be
1657 tree base
= get_base_address (src
);
1660 if (tree size
= DECL_SIZE_UNIT (base
))
1662 && TREE_CODE (size
) == INTEGER_CST
1663 && TREE_CODE (TREE_TYPE (base
)) != POINTER_TYPE
)
1664 max
= wi::to_wide (size
);
1668 /* For strlen() the upper bound above is equal to
1669 the longest string that can be stored in the array
1670 (i.e., it accounts for the terminating nul. For
1671 strnlen() bump up the maximum by one since the array
1672 need not be nul-terminated. */
1673 if (!bound
&& max
!= 0)
1678 wide_int min
= wi::zero (max
.get_precision ());
1679 return set_strlen_range (lhs
, min
, max
, bound
);
1682 /* Handle a strlen call. If strlen of the argument is known, replace
1683 the strlen call with the known value, otherwise remember that strlen
1684 of the argument is stored in the lhs SSA_NAME. */
1687 handle_builtin_strlen (gimple_stmt_iterator
*gsi
)
1689 gimple
*stmt
= gsi_stmt (*gsi
);
1690 tree lhs
= gimple_call_lhs (stmt
);
1692 if (lhs
== NULL_TREE
)
1695 location_t loc
= gimple_location (stmt
);
1696 tree callee
= gimple_call_fndecl (stmt
);
1697 tree src
= gimple_call_arg (stmt
, 0);
1698 tree bound
= (DECL_FUNCTION_CODE (callee
) == BUILT_IN_STRNLEN
1699 ? gimple_call_arg (stmt
, 1) : NULL_TREE
);
1700 int idx
= get_stridx (src
);
1701 if (idx
|| (bound
&& integer_zerop (bound
)))
1707 rhs
= build_int_cst (TREE_TYPE (lhs
), ~idx
);
1713 si
= get_strinfo (idx
);
1716 rhs
= get_string_length (si
);
1717 /* For strnlen, if bound is constant, even if si is not known
1718 to be zero terminated, if we know at least bound bytes are
1719 not zero, the return value will be bound. */
1720 if (rhs
== NULL_TREE
1721 && bound
!= NULL_TREE
1722 && TREE_CODE (bound
) == INTEGER_CST
1723 && si
->nonzero_chars
!= NULL_TREE
1724 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
1725 && tree_int_cst_le (bound
, si
->nonzero_chars
))
1729 if (rhs
!= NULL_TREE
)
1731 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
1733 fprintf (dump_file
, "Optimizing: ");
1734 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1736 rhs
= unshare_expr (rhs
);
1737 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (rhs
)))
1738 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
1741 rhs
= fold_build2_loc (loc
, MIN_EXPR
, TREE_TYPE (rhs
), rhs
, bound
);
1743 if (!update_call_from_tree (gsi
, rhs
))
1744 gimplify_and_update_call_from_tree (gsi
, rhs
);
1745 stmt
= gsi_stmt (*gsi
);
1747 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
1749 fprintf (dump_file
, "into: ");
1750 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1754 /* Don't update anything for strnlen. */
1755 && bound
== NULL_TREE
1756 && TREE_CODE (si
->nonzero_chars
) != SSA_NAME
1757 && TREE_CODE (si
->nonzero_chars
) != INTEGER_CST
1758 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
1760 si
= unshare_strinfo (si
);
1761 si
->nonzero_chars
= lhs
;
1762 gcc_assert (si
->full_string_p
);
1765 if (strlen_to_stridx
1766 && (bound
== NULL_TREE
1767 /* For strnlen record this only if the call is proven
1768 to return the same value as strlen would. */
1769 || (TREE_CODE (bound
) == INTEGER_CST
1770 && TREE_CODE (rhs
) == INTEGER_CST
1771 && tree_int_cst_lt (rhs
, bound
))))
1772 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
1777 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
1781 idx
= new_stridx (src
);
1784 strinfo
*si
= get_strinfo (idx
);
1787 if (!si
->full_string_p
&& !si
->stmt
)
1789 /* Until now we only had a lower bound on the string length.
1790 Install LHS as the actual length. */
1791 si
= unshare_strinfo (si
);
1792 tree old
= si
->nonzero_chars
;
1793 si
->nonzero_chars
= lhs
;
1794 si
->full_string_p
= true;
1795 if (TREE_CODE (old
) == INTEGER_CST
)
1797 old
= fold_convert_loc (loc
, TREE_TYPE (lhs
), old
);
1798 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
,
1799 TREE_TYPE (lhs
), lhs
, old
);
1800 adjust_related_strinfos (loc
, si
, adj
);
1801 /* Use the constant minimim length as the lower bound
1802 of the non-constant length. */
1803 wide_int min
= wi::to_wide (old
);
1805 = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
)) - 2;
1806 set_strlen_range (lhs
, min
, max
);
1822 /* Only store the new length information for calls to strlen(),
1823 not for those to strnlen(). */
1824 strinfo
*si
= new_strinfo (src
, idx
, lhs
, true);
1825 set_strinfo (idx
, si
);
1826 find_equal_ptrs (src
, idx
);
1829 /* For SRC that is an array of N elements, set LHS's range
1830 to [0, min (N, BOUND)]. A constant return value means
1831 the range would have consisted of a single value. In
1832 that case, fold the result into the returned constant. */
1833 if (tree ret
= maybe_set_strlen_range (lhs
, src
, bound
))
1834 if (TREE_CODE (ret
) == INTEGER_CST
)
1836 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
1838 fprintf (dump_file
, "Optimizing: ");
1839 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1841 if (!useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (ret
)))
1842 ret
= fold_convert_loc (loc
, TREE_TYPE (lhs
), ret
);
1843 if (!update_call_from_tree (gsi
, ret
))
1844 gimplify_and_update_call_from_tree (gsi
, ret
);
1845 stmt
= gsi_stmt (*gsi
);
1847 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
1849 fprintf (dump_file
, "into: ");
1850 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1854 if (strlen_to_stridx
&& !bound
)
1855 strlen_to_stridx
->put (lhs
, stridx_strlenloc (idx
, loc
));
1859 /* Handle a strchr call. If strlen of the first argument is known, replace
1860 the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
1861 that lhs of the call is endptr and strlen of the argument is endptr - x. */
1864 handle_builtin_strchr (gimple_stmt_iterator
*gsi
)
1868 gimple
*stmt
= gsi_stmt (*gsi
);
1869 tree lhs
= gimple_call_lhs (stmt
);
1871 if (lhs
== NULL_TREE
)
1874 if (!integer_zerop (gimple_call_arg (stmt
, 1)))
1877 src
= gimple_call_arg (stmt
, 0);
1878 idx
= get_stridx (src
);
1885 rhs
= build_int_cst (size_type_node
, ~idx
);
1889 si
= get_strinfo (idx
);
1891 rhs
= get_string_length (si
);
1893 if (rhs
!= NULL_TREE
)
1895 location_t loc
= gimple_location (stmt
);
1897 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
1899 fprintf (dump_file
, "Optimizing: ");
1900 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1902 if (si
!= NULL
&& si
->endptr
!= NULL_TREE
)
1904 rhs
= unshare_expr (si
->endptr
);
1905 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
1907 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
1911 rhs
= fold_convert_loc (loc
, sizetype
, unshare_expr (rhs
));
1912 rhs
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
,
1913 TREE_TYPE (src
), src
, rhs
);
1914 if (!useless_type_conversion_p (TREE_TYPE (lhs
),
1916 rhs
= fold_convert_loc (loc
, TREE_TYPE (lhs
), rhs
);
1918 if (!update_call_from_tree (gsi
, rhs
))
1919 gimplify_and_update_call_from_tree (gsi
, rhs
);
1920 stmt
= gsi_stmt (*gsi
);
1922 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
1924 fprintf (dump_file
, "into: ");
1925 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
1928 && si
->endptr
== NULL_TREE
1929 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
1931 si
= unshare_strinfo (si
);
1934 zero_length_string (lhs
, si
);
1938 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
1940 if (TREE_CODE (src
) != SSA_NAME
|| !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src
))
1943 idx
= new_stridx (src
);
1944 else if (get_strinfo (idx
) != NULL
)
1946 zero_length_string (lhs
, NULL
);
1951 location_t loc
= gimple_location (stmt
);
1952 tree lhsu
= fold_convert_loc (loc
, size_type_node
, lhs
);
1953 tree srcu
= fold_convert_loc (loc
, size_type_node
, src
);
1954 tree length
= fold_build2_loc (loc
, MINUS_EXPR
,
1955 size_type_node
, lhsu
, srcu
);
1956 strinfo
*si
= new_strinfo (src
, idx
, length
, true);
1958 set_strinfo (idx
, si
);
1959 find_equal_ptrs (src
, idx
);
1960 zero_length_string (lhs
, si
);
1964 zero_length_string (lhs
, NULL
);
1967 /* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
1968 If strlen of the second argument is known, strlen of the first argument
1969 is the same after this call. Furthermore, attempt to convert it to
1973 handle_builtin_strcpy (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
)
1976 tree src
, dst
, srclen
, len
, lhs
, type
, fn
, oldlen
;
1978 gimple
*stmt
= gsi_stmt (*gsi
);
1979 strinfo
*si
, *dsi
, *olddsi
, *zsi
;
1982 src
= gimple_call_arg (stmt
, 1);
1983 dst
= gimple_call_arg (stmt
, 0);
1984 lhs
= gimple_call_lhs (stmt
);
1985 idx
= get_stridx (src
);
1988 si
= get_strinfo (idx
);
1990 didx
= get_stridx (dst
);
1994 olddsi
= get_strinfo (didx
);
1999 adjust_last_stmt (olddsi
, stmt
, false);
2003 srclen
= get_string_length (si
);
2005 srclen
= build_int_cst (size_type_node
, ~idx
);
2007 loc
= gimple_location (stmt
);
2008 if (srclen
== NULL_TREE
)
2011 case BUILT_IN_STRCPY
:
2012 case BUILT_IN_STRCPY_CHK
:
2013 if (lhs
!= NULL_TREE
|| !builtin_decl_implicit_p (BUILT_IN_STPCPY
))
2016 case BUILT_IN_STPCPY
:
2017 case BUILT_IN_STPCPY_CHK
:
2018 if (lhs
== NULL_TREE
)
2022 tree lhsuint
= fold_convert_loc (loc
, size_type_node
, lhs
);
2023 srclen
= fold_convert_loc (loc
, size_type_node
, dst
);
2024 srclen
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
2034 didx
= new_stridx (dst
);
2040 oldlen
= olddsi
->nonzero_chars
;
2041 dsi
= unshare_strinfo (olddsi
);
2042 dsi
->nonzero_chars
= srclen
;
2043 dsi
->full_string_p
= (srclen
!= NULL_TREE
);
2044 /* Break the chain, so adjust_related_strinfo on later pointers in
2045 the chain won't adjust this one anymore. */
2048 dsi
->endptr
= NULL_TREE
;
2052 dsi
= new_strinfo (dst
, didx
, srclen
, srclen
!= NULL_TREE
);
2053 set_strinfo (didx
, dsi
);
2054 find_equal_ptrs (dst
, didx
);
2056 dsi
->writable
= true;
2057 dsi
->dont_invalidate
= true;
2059 if (dsi
->nonzero_chars
== NULL_TREE
)
2063 /* If string length of src is unknown, use delayed length
2064 computation. If string lenth of dst will be needed, it
2065 can be computed by transforming this strcpy call into
2066 stpcpy and subtracting dst from the return value. */
2068 /* Look for earlier strings whose length could be determined if
2069 this strcpy is turned into an stpcpy. */
2071 if (dsi
->prev
!= 0 && (chainsi
= verify_related_strinfos (dsi
)) != NULL
)
2073 for (; chainsi
&& chainsi
!= dsi
; chainsi
= get_strinfo (chainsi
->next
))
2075 /* When setting a stmt for delayed length computation
2076 prevent all strinfos through dsi from being
2078 chainsi
= unshare_strinfo (chainsi
);
2079 chainsi
->stmt
= stmt
;
2080 chainsi
->nonzero_chars
= NULL_TREE
;
2081 chainsi
->full_string_p
= false;
2082 chainsi
->endptr
= NULL_TREE
;
2083 chainsi
->dont_invalidate
= true;
2088 /* Try to detect overlap before returning. This catches cases
2089 like strcpy (d, d + n) where n is non-constant whose range
2090 is such that (n <= strlen (d) holds).
2092 OLDDSI->NONZERO_chars may have been reset by this point with
2093 oldlen holding it original value. */
2094 if (olddsi
&& oldlen
)
2096 /* Add 1 for the terminating NUL. */
2097 tree type
= TREE_TYPE (oldlen
);
2098 oldlen
= fold_build2 (PLUS_EXPR
, type
, oldlen
,
2099 build_int_cst (type
, 1));
2100 check_bounds_or_overlap (stmt
, olddsi
->ptr
, src
, oldlen
, NULL_TREE
);
2108 tree adj
= NULL_TREE
;
2109 if (oldlen
== NULL_TREE
)
2111 else if (integer_zerop (oldlen
))
2113 else if (TREE_CODE (oldlen
) == INTEGER_CST
2114 || TREE_CODE (srclen
) == INTEGER_CST
)
2115 adj
= fold_build2_loc (loc
, MINUS_EXPR
,
2116 TREE_TYPE (srclen
), srclen
,
2117 fold_convert_loc (loc
, TREE_TYPE (srclen
),
2119 if (adj
!= NULL_TREE
)
2120 adjust_related_strinfos (loc
, dsi
, adj
);
2124 /* strcpy src may not overlap dst, so src doesn't need to be
2125 invalidated either. */
2127 si
->dont_invalidate
= true;
2133 case BUILT_IN_STRCPY
:
2134 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
2136 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2138 case BUILT_IN_STRCPY_CHK
:
2139 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
2141 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2143 case BUILT_IN_STPCPY
:
2144 /* This would need adjustment of the lhs (subtract one),
2145 or detection that the trailing '\0' doesn't need to be
2146 written, if it will be immediately overwritten.
2147 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY); */
2151 zsi
= zero_length_string (lhs
, dsi
);
2154 case BUILT_IN_STPCPY_CHK
:
2155 /* This would need adjustment of the lhs (subtract one),
2156 or detection that the trailing '\0' doesn't need to be
2157 written, if it will be immediately overwritten.
2158 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK); */
2162 zsi
= zero_length_string (lhs
, dsi
);
2169 zsi
->dont_invalidate
= true;
2173 tree args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
2174 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
2177 type
= size_type_node
;
2179 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
2180 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
, build_int_cst (type
, 1));
2182 /* Set the no-warning bit on the transformed statement? */
2183 bool set_no_warning
= false;
2185 if (const strinfo
*chksi
= olddsi
? olddsi
: dsi
)
2187 && check_bounds_or_overlap (stmt
, chksi
->ptr
, si
->ptr
, NULL_TREE
, len
))
2189 gimple_set_no_warning (stmt
, true);
2190 set_no_warning
= true;
2193 if (fn
== NULL_TREE
)
2196 len
= force_gimple_operand_gsi (gsi
, len
, true, NULL_TREE
, true,
2198 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2200 fprintf (dump_file
, "Optimizing: ");
2201 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2203 if (gimple_call_num_args (stmt
) == 2)
2204 success
= update_gimple_call (gsi
, fn
, 3, dst
, src
, len
);
2206 success
= update_gimple_call (gsi
, fn
, 4, dst
, src
, len
,
2207 gimple_call_arg (stmt
, 2));
2210 stmt
= gsi_stmt (*gsi
);
2212 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2214 fprintf (dump_file
, "into: ");
2215 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2217 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2218 laststmt
.stmt
= stmt
;
2219 laststmt
.len
= srclen
;
2220 laststmt
.stridx
= dsi
->idx
;
2222 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
2223 fprintf (dump_file
, "not possible.\n");
2226 gimple_set_no_warning (stmt
, true);
2229 /* Check the size argument to the built-in forms of stpncpy and strncpy
2230 for out-of-bounds offsets or overlapping access, and to see if the
2231 size argument is derived from a call to strlen() on the source argument,
2232 and if so, issue an appropriate warning. */
2235 handle_builtin_strncat (built_in_function bcode
, gimple_stmt_iterator
*gsi
)
2237 /* Same as stxncpy(). */
2238 handle_builtin_stxncpy (bcode
, gsi
);
2241 /* Return true if LEN depends on a call to strlen(SRC) in an interesting
2242 way. LEN can either be an integer expression, or a pointer (to char).
2243 When it is the latter (such as in recursive calls to self) is is
2244 assumed to be the argument in some call to strlen() whose relationship
2245 to SRC is being ascertained. */
2248 is_strlen_related_p (tree src
, tree len
)
2250 if (TREE_CODE (TREE_TYPE (len
)) == POINTER_TYPE
2251 && operand_equal_p (src
, len
, 0))
2254 if (TREE_CODE (len
) != SSA_NAME
)
2257 gimple
*def_stmt
= SSA_NAME_DEF_STMT (len
);
2261 if (is_gimple_call (def_stmt
))
2263 tree func
= gimple_call_fndecl (def_stmt
);
2264 if (!valid_builtin_call (def_stmt
)
2265 || DECL_FUNCTION_CODE (func
) != BUILT_IN_STRLEN
)
2268 tree arg
= gimple_call_arg (def_stmt
, 0);
2269 return is_strlen_related_p (src
, arg
);
2272 if (!is_gimple_assign (def_stmt
))
2275 tree_code code
= gimple_assign_rhs_code (def_stmt
);
2276 tree rhs1
= gimple_assign_rhs1 (def_stmt
);
2277 tree rhstype
= TREE_TYPE (rhs1
);
2279 if ((TREE_CODE (rhstype
) == POINTER_TYPE
&& code
== POINTER_PLUS_EXPR
)
2280 || (INTEGRAL_TYPE_P (rhstype
)
2281 && (code
== BIT_AND_EXPR
2282 || code
== NOP_EXPR
)))
2284 /* Pointer plus (an integer), and truncation are considered among
2285 the (potentially) related expressions to strlen. */
2286 return is_strlen_related_p (src
, rhs1
);
2289 if (tree rhs2
= gimple_assign_rhs2 (def_stmt
))
2291 /* Integer subtraction is considered strlen-related when both
2292 arguments are integers and second one is strlen-related. */
2293 rhstype
= TREE_TYPE (rhs2
);
2294 if (INTEGRAL_TYPE_P (rhstype
) && code
== MINUS_EXPR
)
2295 return is_strlen_related_p (src
, rhs2
);
2301 /* Called by handle_builtin_stxncpy and by gimple_fold_builtin_strncpy
2303 Check to see if the specified bound is a) equal to the size of
2304 the destination DST and if so, b) if it's immediately followed by
2305 DST[CNT - 1] = '\0'. If a) holds and b) does not, warn. Otherwise,
2306 do nothing. Return true if diagnostic has been issued.
2308 The purpose is to diagnose calls to strncpy and stpncpy that do
2309 not nul-terminate the copy while allowing for the idiom where
2310 such a call is immediately followed by setting the last element
2313 strncpy (a, s, sizeof a);
2314 a[sizeof a - 1] = '\0';
2318 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi
, tree src
, tree cnt
)
2320 gimple
*stmt
= gsi_stmt (gsi
);
2321 if (gimple_no_warning_p (stmt
))
2324 wide_int cntrange
[2];
2326 if (TREE_CODE (cnt
) == INTEGER_CST
)
2327 cntrange
[0] = cntrange
[1] = wi::to_wide (cnt
);
2328 else if (TREE_CODE (cnt
) == SSA_NAME
)
2330 enum value_range_kind rng
= get_range_info (cnt
, cntrange
, cntrange
+ 1);
2331 if (rng
== VR_RANGE
)
2333 else if (rng
== VR_ANTI_RANGE
)
2335 wide_int maxobjsize
= wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node
));
2337 if (wi::ltu_p (cntrange
[1], maxobjsize
))
2339 cntrange
[0] = cntrange
[1] + 1;
2340 cntrange
[1] = maxobjsize
;
2344 cntrange
[1] = cntrange
[0] - 1;
2345 cntrange
[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt
)));
2354 /* Negative value is the constant string length. If it's less than
2355 the lower bound there is no truncation. Avoid calling get_stridx()
2356 when ssa_ver_to_stridx is empty. That implies the caller isn't
2357 running under the control of this pass and ssa_ver_to_stridx hasn't
2358 been created yet. */
2359 int sidx
= ssa_ver_to_stridx
.length () ? get_stridx (src
) : 0;
2360 if (sidx
< 0 && wi::gtu_p (cntrange
[0], ~sidx
))
2363 tree dst
= gimple_call_arg (stmt
, 0);
2365 if (TREE_CODE (dstdecl
) == ADDR_EXPR
)
2366 dstdecl
= TREE_OPERAND (dstdecl
, 0);
2368 tree ref
= NULL_TREE
;
2372 /* If the source is a non-string return early to avoid warning
2373 for possible truncation (if the truncation is certain SIDX
2375 tree srcdecl
= gimple_call_arg (stmt
, 1);
2376 if (TREE_CODE (srcdecl
) == ADDR_EXPR
)
2377 srcdecl
= TREE_OPERAND (srcdecl
, 0);
2378 if (get_attr_nonstring_decl (srcdecl
, &ref
))
2382 /* Likewise, if the destination refers to a an array/pointer declared
2383 nonstring return early. */
2384 if (get_attr_nonstring_decl (dstdecl
, &ref
))
2387 /* Look for dst[i] = '\0'; after the stxncpy() call and if found
2388 avoid the truncation warning. */
2389 gsi_next_nondebug (&gsi
);
2390 gimple
*next_stmt
= gsi_stmt (gsi
);
2393 /* When there is no statement in the same basic block check
2394 the immediate successor block. */
2395 if (basic_block bb
= gimple_bb (stmt
))
2397 if (single_succ_p (bb
))
2399 /* For simplicity, ignore blocks with multiple outgoing
2400 edges for now and only consider successor blocks along
2402 edge e
= EDGE_SUCC (bb
, 0);
2403 if (!(e
->flags
& EDGE_ABNORMAL
))
2405 gsi
= gsi_start_bb (e
->dest
);
2406 next_stmt
= gsi_stmt (gsi
);
2407 if (next_stmt
&& is_gimple_debug (next_stmt
))
2409 gsi_next_nondebug (&gsi
);
2410 next_stmt
= gsi_stmt (gsi
);
2417 if (next_stmt
&& is_gimple_assign (next_stmt
))
2419 tree lhs
= gimple_assign_lhs (next_stmt
);
2420 tree_code code
= TREE_CODE (lhs
);
2421 if (code
== ARRAY_REF
|| code
== MEM_REF
)
2422 lhs
= TREE_OPERAND (lhs
, 0);
2424 tree func
= gimple_call_fndecl (stmt
);
2425 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STPNCPY
)
2427 tree ret
= gimple_call_lhs (stmt
);
2428 if (ret
&& operand_equal_p (ret
, lhs
, 0))
2432 /* Determine the base address and offset of the reference,
2433 ignoring the innermost array index. */
2434 if (TREE_CODE (ref
) == ARRAY_REF
)
2435 ref
= TREE_OPERAND (ref
, 0);
2438 tree dstbase
= get_addr_base_and_unit_offset (ref
, &dstoff
);
2441 tree lhsbase
= get_addr_base_and_unit_offset (lhs
, &lhsoff
);
2444 && known_eq (dstoff
, lhsoff
)
2445 && operand_equal_p (dstbase
, lhsbase
, 0))
2449 int prec
= TYPE_PRECISION (TREE_TYPE (cnt
));
2450 wide_int lenrange
[2];
2451 if (strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
)
2453 lenrange
[0] = (sisrc
->nonzero_chars
2454 && TREE_CODE (sisrc
->nonzero_chars
) == INTEGER_CST
2455 ? wi::to_wide (sisrc
->nonzero_chars
)
2457 lenrange
[1] = lenrange
[0];
2460 lenrange
[0] = lenrange
[1] = wi::shwi (~sidx
, prec
);
2463 c_strlen_data lendata
= { };
2464 /* Set MAXBOUND to an arbitrary non-null non-integer node as a request
2465 to have it set to the length of the longest string in a PHI. */
2466 lendata
.maxbound
= src
;
2467 get_range_strlen (src
, &lendata
, /* eltsize = */1);
2468 if (TREE_CODE (lendata
.minlen
) == INTEGER_CST
2469 && TREE_CODE (lendata
.maxbound
) == INTEGER_CST
)
2471 /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
2472 which stores the length of the shortest known string. */
2473 if (integer_all_onesp (lendata
.maxlen
))
2474 lenrange
[0] = wi::shwi (0, prec
);
2476 lenrange
[0] = wi::to_wide (lendata
.minlen
, prec
);
2477 lenrange
[1] = wi::to_wide (lendata
.maxbound
, prec
);
2481 lenrange
[0] = wi::shwi (0, prec
);
2482 lenrange
[1] = wi::shwi (-1, prec
);
2486 location_t callloc
= gimple_nonartificial_location (stmt
);
2487 callloc
= expansion_point_location_if_in_system_header (callloc
);
2489 tree func
= gimple_call_fndecl (stmt
);
2491 if (lenrange
[0] != 0 || !wi::neg_p (lenrange
[1]))
2493 /* If the longest source string is shorter than the lower bound
2494 of the specified count the copy is definitely nul-terminated. */
2495 if (wi::ltu_p (lenrange
[1], cntrange
[0]))
2498 if (wi::neg_p (lenrange
[1]))
2500 /* The length of one of the strings is unknown but at least
2501 one has non-zero length and that length is stored in
2502 LENRANGE[1]. Swap the bounds to force a "may be truncated"
2504 lenrange
[1] = lenrange
[0];
2505 lenrange
[0] = wi::shwi (0, prec
);
2508 /* Set to true for strncat whose bound is derived from the length
2509 of the destination (the expected usage pattern). */
2510 bool cat_dstlen_bounded
= false;
2511 if (DECL_FUNCTION_CODE (func
) == BUILT_IN_STRNCAT
)
2512 cat_dstlen_bounded
= is_strlen_related_p (dst
, cnt
);
2514 if (lenrange
[0] == cntrange
[1] && cntrange
[0] == cntrange
[1])
2515 return warning_n (callloc
, OPT_Wstringop_truncation
,
2516 cntrange
[0].to_uhwi (),
2517 "%G%qD output truncated before terminating "
2518 "nul copying %E byte from a string of the "
2520 "%G%qD output truncated before terminating nul "
2521 "copying %E bytes from a string of the same "
2524 else if (!cat_dstlen_bounded
)
2526 if (wi::geu_p (lenrange
[0], cntrange
[1]))
2528 /* The shortest string is longer than the upper bound of
2529 the count so the truncation is certain. */
2530 if (cntrange
[0] == cntrange
[1])
2531 return warning_n (callloc
, OPT_Wstringop_truncation
,
2532 cntrange
[0].to_uhwi (),
2533 "%G%qD output truncated copying %E byte "
2534 "from a string of length %wu",
2535 "%G%qD output truncated copying %E bytes "
2536 "from a string of length %wu",
2537 stmt
, func
, cnt
, lenrange
[0].to_uhwi ());
2539 return warning_at (callloc
, OPT_Wstringop_truncation
,
2540 "%G%qD output truncated copying between %wu "
2541 "and %wu bytes from a string of length %wu",
2542 stmt
, func
, cntrange
[0].to_uhwi (),
2543 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
2545 else if (wi::geu_p (lenrange
[1], cntrange
[1]))
2547 /* The longest string is longer than the upper bound of
2548 the count so the truncation is possible. */
2549 if (cntrange
[0] == cntrange
[1])
2550 return warning_n (callloc
, OPT_Wstringop_truncation
,
2551 cntrange
[0].to_uhwi (),
2552 "%G%qD output may be truncated copying %E "
2553 "byte from a string of length %wu",
2554 "%G%qD output may be truncated copying %E "
2555 "bytes from a string of length %wu",
2556 stmt
, func
, cnt
, lenrange
[1].to_uhwi ());
2558 return warning_at (callloc
, OPT_Wstringop_truncation
,
2559 "%G%qD output may be truncated copying between "
2560 "%wu and %wu bytes from a string of length %wu",
2561 stmt
, func
, cntrange
[0].to_uhwi (),
2562 cntrange
[1].to_uhwi (), lenrange
[1].to_uhwi ());
2566 if (!cat_dstlen_bounded
2567 && cntrange
[0] != cntrange
[1]
2568 && wi::leu_p (cntrange
[0], lenrange
[0])
2569 && wi::leu_p (cntrange
[1], lenrange
[0] + 1))
2571 /* If the source (including the terminating nul) is longer than
2572 the lower bound of the specified count but shorter than the
2573 upper bound the copy may (but need not) be truncated. */
2574 return warning_at (callloc
, OPT_Wstringop_truncation
,
2575 "%G%qD output may be truncated copying between "
2576 "%wu and %wu bytes from a string of length %wu",
2577 stmt
, func
, cntrange
[0].to_uhwi (),
2578 cntrange
[1].to_uhwi (), lenrange
[0].to_uhwi ());
2582 if (tree dstsize
= compute_objsize (dst
, 1))
2584 /* The source length is uknown. Try to determine the destination
2585 size and see if it matches the specified bound. If not, bail.
2586 Otherwise go on to see if it should be diagnosed for possible
2591 if (wi::to_wide (dstsize
) != cntrange
[1])
2594 /* Avoid warning for strncpy(a, b, N) calls where the following
2596 N == sizeof a && N == sizeof b */
2597 if (tree srcsize
= compute_objsize (src
, 1))
2598 if (wi::to_wide (srcsize
) == cntrange
[1])
2601 if (cntrange
[0] == cntrange
[1])
2602 return warning_at (callloc
, OPT_Wstringop_truncation
,
2603 "%G%qD specified bound %E equals destination size",
2610 /* Check the arguments to the built-in forms of stpncpy and strncpy for
2611 out-of-bounds offsets or overlapping access, and to see if the size
2612 is derived from calling strlen() on the source argument, and if so,
2613 issue the appropriate warning. */
2616 handle_builtin_stxncpy (built_in_function
, gimple_stmt_iterator
*gsi
)
2618 if (!strlen_to_stridx
)
2621 gimple
*stmt
= gsi_stmt (*gsi
);
2623 tree dst
= gimple_call_arg (stmt
, 0);
2624 tree src
= gimple_call_arg (stmt
, 1);
2625 tree len
= gimple_call_arg (stmt
, 2);
2626 tree dstsize
= NULL_TREE
, srcsize
= NULL_TREE
;
2628 int didx
= get_stridx (dst
);
2629 if (strinfo
*sidst
= didx
> 0 ? get_strinfo (didx
) : NULL
)
2631 /* Compute the size of the destination string including the nul
2632 if it is known to be nul-terminated. */
2633 if (sidst
->nonzero_chars
)
2635 if (sidst
->full_string_p
)
2637 /* String is known to be nul-terminated. */
2638 tree type
= TREE_TYPE (sidst
->nonzero_chars
);
2639 dstsize
= fold_build2 (PLUS_EXPR
, type
, sidst
->nonzero_chars
,
2640 build_int_cst (type
, 1));
2643 dstsize
= sidst
->nonzero_chars
;
2649 int sidx
= get_stridx (src
);
2650 strinfo
*sisrc
= sidx
> 0 ? get_strinfo (sidx
) : NULL
;
2653 /* strncat() and strncpy() can modify the source string by writing
2654 over the terminating nul so SISRC->DONT_INVALIDATE must be left
2657 /* Compute the size of the source string including the terminating
2658 nul if its known to be nul-terminated. */
2659 if (sisrc
->nonzero_chars
)
2661 if (sisrc
->full_string_p
)
2663 tree type
= TREE_TYPE (sisrc
->nonzero_chars
);
2664 srcsize
= fold_build2 (PLUS_EXPR
, type
, sisrc
->nonzero_chars
,
2665 build_int_cst (type
, 1));
2668 srcsize
= sisrc
->nonzero_chars
;
2674 srcsize
= NULL_TREE
;
2676 if (check_bounds_or_overlap (stmt
, dst
, src
, dstsize
, srcsize
))
2678 gimple_set_no_warning (stmt
, true);
2682 /* If the length argument was computed from strlen(S) for some string
2683 S retrieve the strinfo index for the string (PSS->FIRST) alonng with
2684 the location of the strlen() call (PSS->SECOND). */
2685 stridx_strlenloc
*pss
= strlen_to_stridx
->get (len
);
2686 if (!pss
|| pss
->first
<= 0)
2688 if (maybe_diag_stxncpy_trunc (*gsi
, src
, len
))
2689 gimple_set_no_warning (stmt
, true);
2694 /* Retrieve the strinfo data for the string S that LEN was computed
2695 from as some function F of strlen (S) (i.e., LEN need not be equal
2697 strinfo
*silen
= get_strinfo (pss
->first
);
2699 location_t callloc
= gimple_nonartificial_location (stmt
);
2700 callloc
= expansion_point_location_if_in_system_header (callloc
);
2702 tree func
= gimple_call_fndecl (stmt
);
2704 bool warned
= false;
2706 /* When -Wstringop-truncation is set, try to determine truncation
2707 before diagnosing possible overflow. Truncation is implied by
2708 the LEN argument being equal to strlen(SRC), regardless of
2709 whether its value is known. Otherwise, issue the more generic
2710 -Wstringop-overflow which triggers for LEN arguments that in
2711 any meaningful way depend on strlen(SRC). */
2713 && is_strlen_related_p (src
, len
)
2714 && warning_at (callloc
, OPT_Wstringop_truncation
,
2715 "%G%qD output truncated before terminating nul "
2716 "copying as many bytes from a string as its length",
2719 else if (silen
&& is_strlen_related_p (src
, silen
->ptr
))
2720 warned
= warning_at (callloc
, OPT_Wstringop_overflow_
,
2721 "%G%qD specified bound depends on the length "
2722 "of the source argument",
2726 location_t strlenloc
= pss
->second
;
2727 if (strlenloc
!= UNKNOWN_LOCATION
&& strlenloc
!= callloc
)
2728 inform (strlenloc
, "length computed here");
2732 /* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
2733 If strlen of the second argument is known and length of the third argument
2734 is that plus one, strlen of the first argument is the same after this
2738 handle_builtin_memcpy (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
)
2741 tree src
, dst
, len
, lhs
, oldlen
, newlen
;
2742 gimple
*stmt
= gsi_stmt (*gsi
);
2743 strinfo
*si
, *dsi
, *olddsi
;
2745 len
= gimple_call_arg (stmt
, 2);
2746 src
= gimple_call_arg (stmt
, 1);
2747 dst
= gimple_call_arg (stmt
, 0);
2748 idx
= get_stridx (src
);
2752 didx
= get_stridx (dst
);
2755 olddsi
= get_strinfo (didx
);
2760 && tree_fits_uhwi_p (len
)
2761 && !integer_zerop (len
))
2762 adjust_last_stmt (olddsi
, stmt
, false);
2769 /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
2771 si
= get_strinfo (idx
);
2772 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
2774 if (TREE_CODE (len
) == INTEGER_CST
2775 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
2777 if (tree_int_cst_le (len
, si
->nonzero_chars
))
2779 /* Copying LEN nonzero characters, where LEN is constant. */
2781 full_string_p
= false;
2785 /* Copying the whole of the analyzed part of SI. */
2786 newlen
= si
->nonzero_chars
;
2787 full_string_p
= si
->full_string_p
;
2792 if (!si
->full_string_p
)
2794 if (TREE_CODE (len
) != SSA_NAME
)
2796 def_stmt
= SSA_NAME_DEF_STMT (len
);
2797 if (!is_gimple_assign (def_stmt
)
2798 || gimple_assign_rhs_code (def_stmt
) != PLUS_EXPR
2799 || gimple_assign_rhs1 (def_stmt
) != si
->nonzero_chars
2800 || !integer_onep (gimple_assign_rhs2 (def_stmt
)))
2802 /* Copying variable-length string SI (and no more). */
2803 newlen
= si
->nonzero_chars
;
2804 full_string_p
= true;
2810 /* Handle memcpy (x, "abcd", 5) or
2811 memcpy (x, "abc\0uvw", 7). */
2812 if (!tree_fits_uhwi_p (len
))
2815 unsigned HOST_WIDE_INT clen
= tree_to_uhwi (len
);
2816 unsigned HOST_WIDE_INT nonzero_chars
= ~idx
;
2817 newlen
= build_int_cst (size_type_node
, MIN (nonzero_chars
, clen
));
2818 full_string_p
= clen
> nonzero_chars
;
2823 && olddsi
->nonzero_chars
2824 && TREE_CODE (olddsi
->nonzero_chars
) == INTEGER_CST
2825 && tree_int_cst_le (newlen
, olddsi
->nonzero_chars
))
2827 /* The SRC substring being written strictly overlaps
2828 a subsequence of the existing string OLDDSI. */
2829 newlen
= olddsi
->nonzero_chars
;
2830 full_string_p
= olddsi
->full_string_p
;
2833 if (olddsi
!= NULL
&& TREE_CODE (len
) == SSA_NAME
)
2834 adjust_last_stmt (olddsi
, stmt
, false);
2838 didx
= new_stridx (dst
);
2845 dsi
= unshare_strinfo (olddsi
);
2846 oldlen
= olddsi
->nonzero_chars
;
2847 dsi
->nonzero_chars
= newlen
;
2848 dsi
->full_string_p
= full_string_p
;
2849 /* Break the chain, so adjust_related_strinfo on later pointers in
2850 the chain won't adjust this one anymore. */
2853 dsi
->endptr
= NULL_TREE
;
2857 dsi
= new_strinfo (dst
, didx
, newlen
, full_string_p
);
2858 set_strinfo (didx
, dsi
);
2859 find_equal_ptrs (dst
, didx
);
2861 dsi
->writable
= true;
2862 dsi
->dont_invalidate
= true;
2865 tree adj
= NULL_TREE
;
2866 location_t loc
= gimple_location (stmt
);
2867 if (oldlen
== NULL_TREE
)
2869 else if (integer_zerop (oldlen
))
2871 else if (TREE_CODE (oldlen
) == INTEGER_CST
2872 || TREE_CODE (newlen
) == INTEGER_CST
)
2873 adj
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (newlen
), newlen
,
2874 fold_convert_loc (loc
, TREE_TYPE (newlen
),
2876 if (adj
!= NULL_TREE
)
2877 adjust_related_strinfos (loc
, dsi
, adj
);
2881 /* memcpy src may not overlap dst, so src doesn't need to be
2882 invalidated either. */
2884 si
->dont_invalidate
= true;
2888 lhs
= gimple_call_lhs (stmt
);
2891 case BUILT_IN_MEMCPY
:
2892 case BUILT_IN_MEMCPY_CHK
:
2893 /* Allow adjust_last_stmt to decrease this memcpy's size. */
2894 laststmt
.stmt
= stmt
;
2895 laststmt
.len
= dsi
->nonzero_chars
;
2896 laststmt
.stridx
= dsi
->idx
;
2898 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = didx
;
2900 case BUILT_IN_MEMPCPY
:
2901 case BUILT_IN_MEMPCPY_CHK
:
2909 /* Handle a strcat-like ({strcat,__strcat_chk}) call.
2910 If strlen of the second argument is known, strlen of the first argument
2911 is increased by the length of the second argument. Furthermore, attempt
2912 to convert it to memcpy/strcpy if the length of the first argument
2916 handle_builtin_strcat (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
)
2919 tree srclen
, args
, type
, fn
, objsz
, endptr
;
2921 gimple
*stmt
= gsi_stmt (*gsi
);
2923 location_t loc
= gimple_location (stmt
);
2925 tree src
= gimple_call_arg (stmt
, 1);
2926 tree dst
= gimple_call_arg (stmt
, 0);
2928 /* Bail if the source is the same as destination. It will be diagnosed
2930 if (operand_equal_p (src
, dst
, 0))
2933 tree lhs
= gimple_call_lhs (stmt
);
2935 didx
= get_stridx (dst
);
2941 dsi
= get_strinfo (didx
);
2945 idx
= get_stridx (src
);
2947 srclen
= build_int_cst (size_type_node
, ~idx
);
2950 si
= get_strinfo (idx
);
2952 srclen
= get_string_length (si
);
2955 /* Set the no-warning bit on the transformed statement? */
2956 bool set_no_warning
= false;
2958 if (dsi
== NULL
|| get_string_length (dsi
) == NULL_TREE
)
2961 /* The concatenation always involves copying at least one byte
2962 (the terminating nul), even if the source string is empty.
2963 If the source is unknown assume it's one character long and
2964 used that as both sizes. */
2968 tree type
= TREE_TYPE (slen
);
2969 slen
= fold_build2 (PLUS_EXPR
, type
, slen
, build_int_cst (type
, 1));
2972 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
2974 if (check_bounds_or_overlap (stmt
, dst
, sptr
, NULL_TREE
, slen
))
2976 gimple_set_no_warning (stmt
, true);
2977 set_no_warning
= true;
2981 /* strcat (p, q) can be transformed into
2982 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
2983 with length endptr - p if we need to compute the length
2984 later on. Don't do this transformation if we don't need
2986 if (builtin_decl_implicit_p (BUILT_IN_STPCPY
) && lhs
== NULL_TREE
)
2990 didx
= new_stridx (dst
);
2996 dsi
= new_strinfo (dst
, didx
, NULL_TREE
, false);
2997 set_strinfo (didx
, dsi
);
2998 find_equal_ptrs (dst
, didx
);
3002 dsi
= unshare_strinfo (dsi
);
3003 dsi
->nonzero_chars
= NULL_TREE
;
3004 dsi
->full_string_p
= false;
3006 dsi
->endptr
= NULL_TREE
;
3008 dsi
->writable
= true;
3010 dsi
->dont_invalidate
= true;
3015 tree dstlen
= dsi
->nonzero_chars
;
3016 endptr
= dsi
->endptr
;
3018 dsi
= unshare_strinfo (dsi
);
3019 dsi
->endptr
= NULL_TREE
;
3021 dsi
->writable
= true;
3023 if (srclen
!= NULL_TREE
)
3025 dsi
->nonzero_chars
= fold_build2_loc (loc
, PLUS_EXPR
,
3026 TREE_TYPE (dsi
->nonzero_chars
),
3027 dsi
->nonzero_chars
, srclen
);
3028 gcc_assert (dsi
->full_string_p
);
3029 adjust_related_strinfos (loc
, dsi
, srclen
);
3030 dsi
->dont_invalidate
= true;
3034 dsi
->nonzero_chars
= NULL
;
3035 dsi
->full_string_p
= false;
3036 if (lhs
== NULL_TREE
&& builtin_decl_implicit_p (BUILT_IN_STPCPY
))
3037 dsi
->dont_invalidate
= true;
3041 /* strcat src may not overlap dst, so src doesn't need to be
3042 invalidated either. */
3043 si
->dont_invalidate
= true;
3045 /* For now. Could remove the lhs from the call and add
3046 lhs = dst; afterwards. */
3054 case BUILT_IN_STRCAT
:
3055 if (srclen
!= NULL_TREE
)
3056 fn
= builtin_decl_implicit (BUILT_IN_MEMCPY
);
3058 fn
= builtin_decl_implicit (BUILT_IN_STRCPY
);
3060 case BUILT_IN_STRCAT_CHK
:
3061 if (srclen
!= NULL_TREE
)
3062 fn
= builtin_decl_explicit (BUILT_IN_MEMCPY_CHK
);
3064 fn
= builtin_decl_explicit (BUILT_IN_STRCPY_CHK
);
3065 objsz
= gimple_call_arg (stmt
, 2);
3071 if (fn
== NULL_TREE
)
3076 tree type
= TREE_TYPE (dstlen
);
3078 /* Compute the size of the source sequence, including the nul. */
3079 tree srcsize
= srclen
? srclen
: size_zero_node
;
3080 tree one
= build_int_cst (type
, 1);
3081 srcsize
= fold_build2 (PLUS_EXPR
, type
, srcsize
, one
);
3082 tree dstsize
= fold_build2 (PLUS_EXPR
, type
, dstlen
, one
);
3083 tree sptr
= si
&& si
->ptr
? si
->ptr
: src
;
3085 if (check_bounds_or_overlap (stmt
, dst
, sptr
, dstsize
, srcsize
))
3087 gimple_set_no_warning (stmt
, true);
3088 set_no_warning
= true;
3092 tree len
= NULL_TREE
;
3093 if (srclen
!= NULL_TREE
)
3095 args
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
3096 type
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args
)));
3098 len
= fold_convert_loc (loc
, type
, unshare_expr (srclen
));
3099 len
= fold_build2_loc (loc
, PLUS_EXPR
, type
, len
,
3100 build_int_cst (type
, 1));
3101 len
= force_gimple_operand_gsi (gsi
, len
, true, NULL_TREE
, true,
3105 dst
= fold_convert_loc (loc
, TREE_TYPE (dst
), unshare_expr (endptr
));
3107 dst
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
, TREE_TYPE (dst
), dst
,
3108 fold_convert_loc (loc
, sizetype
,
3109 unshare_expr (dstlen
)));
3110 dst
= force_gimple_operand_gsi (gsi
, dst
, true, NULL_TREE
, true,
3114 objsz
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (objsz
), objsz
,
3115 fold_convert_loc (loc
, TREE_TYPE (objsz
),
3116 unshare_expr (dstlen
)));
3117 objsz
= force_gimple_operand_gsi (gsi
, objsz
, true, NULL_TREE
, true,
3120 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3122 fprintf (dump_file
, "Optimizing: ");
3123 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3125 if (srclen
!= NULL_TREE
)
3126 success
= update_gimple_call (gsi
, fn
, 3 + (objsz
!= NULL_TREE
),
3127 dst
, src
, len
, objsz
);
3129 success
= update_gimple_call (gsi
, fn
, 2 + (objsz
!= NULL_TREE
),
3133 stmt
= gsi_stmt (*gsi
);
3135 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3137 fprintf (dump_file
, "into: ");
3138 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
3140 /* If srclen == NULL, note that current string length can be
3141 computed by transforming this strcpy into stpcpy. */
3142 if (srclen
== NULL_TREE
&& dsi
->dont_invalidate
)
3144 adjust_last_stmt (dsi
, stmt
, true);
3145 if (srclen
!= NULL_TREE
)
3147 laststmt
.stmt
= stmt
;
3148 laststmt
.len
= srclen
;
3149 laststmt
.stridx
= dsi
->idx
;
3152 else if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
3153 fprintf (dump_file
, "not possible.\n");
3156 gimple_set_no_warning (stmt
, true);
3159 /* Handle a call to malloc or calloc. */
3162 handle_builtin_malloc (enum built_in_function bcode
, gimple_stmt_iterator
*gsi
)
3164 gimple
*stmt
= gsi_stmt (*gsi
);
3165 tree lhs
= gimple_call_lhs (stmt
);
3166 if (lhs
== NULL_TREE
)
3169 gcc_assert (get_stridx (lhs
) == 0);
3170 int idx
= new_stridx (lhs
);
3171 tree length
= NULL_TREE
;
3172 if (bcode
== BUILT_IN_CALLOC
)
3173 length
= build_int_cst (size_type_node
, 0);
3174 strinfo
*si
= new_strinfo (lhs
, idx
, length
, length
!= NULL_TREE
);
3175 if (bcode
== BUILT_IN_CALLOC
)
3177 set_strinfo (idx
, si
);
3178 si
->writable
= true;
3180 si
->dont_invalidate
= true;
3183 /* Handle a call to memset.
3184 After a call to calloc, memset(,0,) is unnecessary.
3185 memset(malloc(n),0,n) is calloc(n,1).
3186 return true when the call is transfomred, false otherwise. */
3189 handle_builtin_memset (gimple_stmt_iterator
*gsi
)
3191 gimple
*stmt2
= gsi_stmt (*gsi
);
3192 if (!integer_zerop (gimple_call_arg (stmt2
, 1)))
3194 tree ptr
= gimple_call_arg (stmt2
, 0);
3195 int idx1
= get_stridx (ptr
);
3198 strinfo
*si1
= get_strinfo (idx1
);
3201 gimple
*stmt1
= si1
->stmt
;
3202 if (!stmt1
|| !is_gimple_call (stmt1
))
3204 tree callee1
= gimple_call_fndecl (stmt1
);
3205 if (!valid_builtin_call (stmt1
))
3207 enum built_in_function code1
= DECL_FUNCTION_CODE (callee1
);
3208 tree size
= gimple_call_arg (stmt2
, 2);
3209 if (code1
== BUILT_IN_CALLOC
)
3210 /* Not touching stmt1 */ ;
3211 else if (code1
== BUILT_IN_MALLOC
3212 && operand_equal_p (gimple_call_arg (stmt1
, 0), size
, 0))
3214 gimple_stmt_iterator gsi1
= gsi_for_stmt (stmt1
);
3215 update_gimple_call (&gsi1
, builtin_decl_implicit (BUILT_IN_CALLOC
), 2,
3216 size
, build_one_cst (size_type_node
));
3217 si1
->nonzero_chars
= build_int_cst (size_type_node
, 0);
3218 si1
->full_string_p
= true;
3219 si1
->stmt
= gsi_stmt (gsi1
);
3223 tree lhs
= gimple_call_lhs (stmt2
);
3224 unlink_stmt_vdef (stmt2
);
3227 gimple
*assign
= gimple_build_assign (lhs
, ptr
);
3228 gsi_replace (gsi
, assign
, false);
3232 gsi_remove (gsi
, true);
3233 release_defs (stmt2
);
3239 /* Return a pointer to the first such equality expression if RES is used
3240 only in expressions testing its equality to zero, and null otherwise. */
3243 used_only_for_zero_equality (tree res
)
3245 gimple
*first_use
= NULL
;
3247 use_operand_p use_p
;
3248 imm_use_iterator iter
;
3250 FOR_EACH_IMM_USE_FAST (use_p
, iter
, res
)
3252 gimple
*use_stmt
= USE_STMT (use_p
);
3254 if (is_gimple_debug (use_stmt
))
3256 if (gimple_code (use_stmt
) == GIMPLE_ASSIGN
)
3258 tree_code code
= gimple_assign_rhs_code (use_stmt
);
3259 if (code
== COND_EXPR
)
3261 tree cond_expr
= gimple_assign_rhs1 (use_stmt
);
3262 if ((TREE_CODE (cond_expr
) != EQ_EXPR
3263 && (TREE_CODE (cond_expr
) != NE_EXPR
))
3264 || !integer_zerop (TREE_OPERAND (cond_expr
, 1)))
3267 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
3269 if (!integer_zerop (gimple_assign_rhs2 (use_stmt
)))
3275 else if (gimple_code (use_stmt
) == GIMPLE_COND
)
3277 tree_code code
= gimple_cond_code (use_stmt
);
3278 if ((code
!= EQ_EXPR
&& code
!= NE_EXPR
)
3279 || !integer_zerop (gimple_cond_rhs (use_stmt
)))
3286 first_use
= use_stmt
;
3292 /* Handle a call to memcmp. We try to handle small comparisons by
3293 converting them to load and compare, and replacing the call to memcmp
3294 with a __builtin_memcmp_eq call where possible.
3295 return true when call is transformed, return false otherwise. */
3298 handle_builtin_memcmp (gimple_stmt_iterator
*gsi
)
3300 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (*gsi
));
3301 tree res
= gimple_call_lhs (stmt
);
3303 if (!res
|| !used_only_for_zero_equality (res
))
3306 tree arg1
= gimple_call_arg (stmt
, 0);
3307 tree arg2
= gimple_call_arg (stmt
, 1);
3308 tree len
= gimple_call_arg (stmt
, 2);
3309 unsigned HOST_WIDE_INT leni
;
3311 if (tree_fits_uhwi_p (len
)
3312 && (leni
= tree_to_uhwi (len
)) <= GET_MODE_SIZE (word_mode
)
3313 && pow2p_hwi (leni
))
3315 leni
*= CHAR_TYPE_SIZE
;
3316 unsigned align1
= get_pointer_alignment (arg1
);
3317 unsigned align2
= get_pointer_alignment (arg2
);
3318 unsigned align
= MIN (align1
, align2
);
3319 scalar_int_mode mode
;
3320 if (int_mode_for_size (leni
, 1).exists (&mode
)
3321 && (align
>= leni
|| !targetm
.slow_unaligned_access (mode
, align
)))
3323 location_t loc
= gimple_location (stmt
);
3325 type
= build_nonstandard_integer_type (leni
, 1);
3326 gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type
)), leni
));
3327 tree ptrtype
= build_pointer_type_for_mode (char_type_node
,
3329 off
= build_int_cst (ptrtype
, 0);
3330 arg1
= build2_loc (loc
, MEM_REF
, type
, arg1
, off
);
3331 arg2
= build2_loc (loc
, MEM_REF
, type
, arg2
, off
);
3332 tree tem1
= fold_const_aggregate_ref (arg1
);
3335 tree tem2
= fold_const_aggregate_ref (arg2
);
3338 res
= fold_convert_loc (loc
, TREE_TYPE (res
),
3339 fold_build2_loc (loc
, NE_EXPR
,
3342 gimplify_and_update_call_from_tree (gsi
, res
);
3347 gimple_call_set_fndecl (stmt
, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ
));
3351 /* Given an index to the strinfo vector, compute the string length
3352 for the corresponding string. Return -1 when unknown. */
3354 static HOST_WIDE_INT
3355 compute_string_length (int idx
)
3357 HOST_WIDE_INT string_leni
= -1;
3358 gcc_assert (idx
!= 0);
3363 strinfo
*si
= get_strinfo (idx
);
3366 tree const_string_len
= get_string_length (si
);
3367 if (const_string_len
&& tree_fits_shwi_p (const_string_len
))
3368 string_leni
= tree_to_shwi (const_string_len
);
3371 if (string_leni
< 0)
3377 /* Determine the minimum size of the object referenced by DEST expression
3378 which must have a pointer type.
3379 Return the minimum size of the object if successful or HWI_M1U when
3380 the size cannot be determined. */
3382 static unsigned HOST_WIDE_INT
3383 determine_min_objsize (tree dest
)
3385 unsigned HOST_WIDE_INT size
= 0;
3387 if (compute_builtin_object_size (dest
, 2, &size
))
3390 /* Try to determine the size of the object through the RHS
3391 of the assign statement. */
3392 if (TREE_CODE (dest
) == SSA_NAME
)
3394 gimple
*stmt
= SSA_NAME_DEF_STMT (dest
);
3395 if (!is_gimple_assign (stmt
))
3396 return HOST_WIDE_INT_M1U
;
3398 if (!gimple_assign_single_p (stmt
)
3399 && !gimple_assign_unary_nop_p (stmt
))
3400 return HOST_WIDE_INT_M1U
;
3402 dest
= gimple_assign_rhs1 (stmt
);
3403 return determine_min_objsize (dest
);
3406 /* Try to determine the size of the object from its type. */
3407 if (TREE_CODE (dest
) != ADDR_EXPR
)
3408 return HOST_WIDE_INT_M1U
;
3410 tree type
= TREE_TYPE (dest
);
3411 if (TREE_CODE (type
) == POINTER_TYPE
)
3412 type
= TREE_TYPE (type
);
3414 type
= TYPE_MAIN_VARIANT (type
);
3416 /* The size of a flexible array cannot be determined. Otherwise,
3417 for arrays with more than one element, return the size of its
3418 type. GCC itself misuses arrays of both zero and one elements
3419 as flexible array members so they are excluded as well. */
3420 if (TREE_CODE (type
) != ARRAY_TYPE
3421 || !array_at_struct_end_p (dest
))
3423 tree type_size
= TYPE_SIZE_UNIT (type
);
3424 if (type_size
&& TREE_CODE (type_size
) == INTEGER_CST
3425 && !integer_onep (type_size
)
3426 && !integer_zerop (type_size
))
3427 return tree_to_uhwi (type_size
);
3430 return HOST_WIDE_INT_M1U
;
3433 /* Given strinfo IDX for ARG, set LENRNG[] to the range of lengths
3434 of the string(s) referenced by ARG if it can be determined.
3435 If the length cannot be determined, set *SIZE to the size of
3436 the array the string is stored in, if any. If no such array is
3437 known, set *SIZE to -1. When the strings are nul-terminated set
3438 *NULTERM to true, otherwise to false. Return true on success. */
3441 get_len_or_size (tree arg
, int idx
, unsigned HOST_WIDE_INT lenrng
[2],
3442 unsigned HOST_WIDE_INT
*size
, bool *nulterm
)
3444 /* Set so that both LEN and ~LEN are invalid lengths, i.e.,
3445 maximum possible length + 1. */
3446 lenrng
[0] = lenrng
[1] = HOST_WIDE_INT_MAX
;
3448 *size
= HOST_WIDE_INT_M1U
;
3452 /* IDX is the inverted constant string length. */
3454 lenrng
[1] = lenrng
[0];
3458 ; /* Handled below. */
3459 else if (strinfo
*si
= get_strinfo (idx
))
3461 if (!si
->nonzero_chars
)
3463 else if (tree_fits_uhwi_p (si
->nonzero_chars
))
3465 lenrng
[0] = tree_to_uhwi (si
->nonzero_chars
);
3466 *nulterm
= si
->full_string_p
;
3467 /* Set the upper bound only if the string is known to be
3468 nul-terminated, otherwise leave it at maximum + 1. */
3470 lenrng
[1] = lenrng
[0];
3472 else if (TREE_CODE (si
->nonzero_chars
) == SSA_NAME
)
3475 value_range_kind rng
= get_range_info (si
->nonzero_chars
, &min
, &max
);
3476 if (rng
== VR_RANGE
)
3478 lenrng
[0] = min
.to_uhwi ();
3479 lenrng
[1] = max
.to_uhwi ();
3480 *nulterm
= si
->full_string_p
;
3487 if (lenrng
[0] == HOST_WIDE_INT_MAX
)
3489 /* Compute the minimum and maximum real or possible lengths. */
3490 c_strlen_data lendata
= { };
3491 if (get_range_strlen (arg
, &lendata
, /* eltsize = */1))
3493 if (tree_fits_shwi_p (lendata
.maxlen
) && !lendata
.maxbound
)
3495 lenrng
[0] = tree_to_shwi (lendata
.minlen
);
3496 lenrng
[1] = tree_to_shwi (lendata
.maxlen
);
3499 else if (lendata
.maxbound
&& tree_fits_shwi_p (lendata
.maxbound
))
3501 /* Set *SIZE to the conservative LENDATA.MAXBOUND which
3502 is a conservative estimate of the longest string based
3503 on the sizes of the arrays referenced by ARG. */
3504 *size
= tree_to_uhwi (lendata
.maxbound
) + 1;
3510 /* Set *SIZE to the size of the smallest object referenced
3511 by ARG if ARG denotes a single object, or to HWI_M1U
3513 *size
= determine_min_objsize (arg
);
3518 return lenrng
[0] != HOST_WIDE_INT_MAX
|| *size
!= HOST_WIDE_INT_M1U
;
3521 /* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
3522 the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
3523 for a sufficiently large BOUND). If the result is based on the length
3524 of one string being greater than the longest string that would fit in
3525 the array pointer to by the argument, set *PLEN and *PSIZE to
3526 the corresponding length (or its complement when the string is known
3527 to be at least as long and need not be nul-terminated) and size.
3528 Otherwise return null. */
3531 strxcmp_eqz_result (tree arg1
, int idx1
, tree arg2
, int idx2
,
3532 unsigned HOST_WIDE_INT bound
, unsigned HOST_WIDE_INT len
[2],
3533 unsigned HOST_WIDE_INT
*psize
)
3535 /* Determine the range the length of each string is in and whether it's
3536 known to be nul-terminated, or the size of the array it's stored in. */
3538 unsigned HOST_WIDE_INT siz1
, siz2
;
3539 unsigned HOST_WIDE_INT len1rng
[2], len2rng
[2];
3540 if (!get_len_or_size (arg1
, idx1
, len1rng
, &siz1
, &nul1
)
3541 || !get_len_or_size (arg2
, idx2
, len2rng
, &siz2
, &nul2
))
3544 /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
3545 to HWI_MAX when invalid. Adjust the length of each string to consider
3546 to be no more than BOUND. */
3547 if (len1rng
[0] < HOST_WIDE_INT_MAX
&& len1rng
[0] > bound
)
3549 if (len1rng
[1] < HOST_WIDE_INT_MAX
&& len1rng
[1] > bound
)
3551 if (len2rng
[0] < HOST_WIDE_INT_MAX
&& len2rng
[0] > bound
)
3553 if (len2rng
[1] < HOST_WIDE_INT_MAX
&& len2rng
[1] > bound
)
3556 /* Two empty strings are equal. */
3557 if (len1rng
[1] == 0 && len2rng
[1] == 0)
3558 return integer_one_node
;
3560 /* The strings are definitely unequal when the lower bound of the length
3561 of one of them is greater than the length of the longest string that
3562 would fit into the other array. */
3563 if (len1rng
[0] == HOST_WIDE_INT_MAX
3564 && len2rng
[0] != HOST_WIDE_INT_MAX
3565 && ((len2rng
[0] < bound
&& len2rng
[0] >= siz1
)
3566 || len2rng
[0] > siz1
))
3569 len
[0] = len1rng
[0];
3570 /* Set LEN[0] to the lower bound of ARG1's length when it's
3571 nul-terminated or to the complement of its minimum length
3573 len
[1] = nul2
? len2rng
[0] : ~len2rng
[0];
3574 return integer_zero_node
;
3577 if (len2rng
[0] == HOST_WIDE_INT_MAX
3578 && len1rng
[0] != HOST_WIDE_INT_MAX
3579 && ((len1rng
[0] < bound
&& len1rng
[0] >= siz2
)
3580 || len1rng
[0] > siz2
))
3583 len
[0] = nul1
? len1rng
[0] : ~len1rng
[0];
3584 len
[1] = len2rng
[0];
3585 return integer_zero_node
;
3588 /* The strings are also definitely unequal when their lengths are unequal
3589 and at least one is nul-terminated. */
3590 if (len1rng
[0] != HOST_WIDE_INT_MAX
3591 && len2rng
[0] != HOST_WIDE_INT_MAX
3592 && ((len1rng
[1] < len2rng
[0] && nul1
)
3593 || (len2rng
[1] < len1rng
[0] && nul2
)))
3595 if (bound
<= len1rng
[0] || bound
<= len2rng
[0])
3598 *psize
= HOST_WIDE_INT_M1U
;
3600 len
[0] = len1rng
[0];
3601 len
[1] = len2rng
[0];
3602 return integer_zero_node
;
3605 /* The string lengths may be equal or unequal. Even when equal and
3606 both strings nul-terminated, without the string contents there's
3607 no way to determine whether they are equal. */
3611 /* Diagnose pointless calls to strcmp or strncmp STMT with string
3612 arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
3613 whose result is used in equality expressions that evaluate to
3614 a constant due to one argument being longer than the size of
3618 maybe_warn_pointless_strcmp (gimple
*stmt
, HOST_WIDE_INT bound
,
3619 unsigned HOST_WIDE_INT len
[2],
3620 unsigned HOST_WIDE_INT siz
)
3622 gimple
*use
= used_only_for_zero_equality (gimple_call_lhs (stmt
));
3626 bool at_least
= false;
3628 /* Excessive LEN[i] indicates a lower bound. */
3629 if (len
[0] > HOST_WIDE_INT_MAX
)
3635 if (len
[1] > HOST_WIDE_INT_MAX
)
3641 unsigned HOST_WIDE_INT minlen
= MIN (len
[0], len
[1]);
3643 /* FIXME: Include a note pointing to the declaration of the smaller
3645 location_t stmt_loc
= gimple_location (stmt
);
3646 tree callee
= gimple_call_fndecl (stmt
);
3647 bool warned
= false;
3648 if (siz
<= minlen
&& bound
== -1)
3649 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
3651 ? G_("%G%qD of a string of length %wu or more and "
3652 "an array of size %wu evaluates to nonzero")
3653 : G_("%G%qD of a string of length %wu and an array "
3654 "of size %wu evaluates to nonzero")),
3655 stmt
, callee
, minlen
, siz
);
3656 else if (!at_least
&& siz
<= HOST_WIDE_INT_MAX
)
3658 if (len
[0] != HOST_WIDE_INT_MAX
&& len
[1] != HOST_WIDE_INT_MAX
)
3659 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
3660 "%G%qD of strings of length %wu and %wu "
3661 "and bound of %wu evaluates to nonzero",
3662 stmt
, callee
, len
[0], len
[1], bound
);
3664 warned
= warning_at (stmt_loc
, OPT_Wstring_compare
,
3665 "%G%qD of a string of length %wu, an array "
3666 "of size %wu and bound of %wu evaluates to "
3668 stmt
, callee
, minlen
, siz
, bound
);
3673 location_t use_loc
= gimple_location (use
);
3674 if (LOCATION_LINE (stmt_loc
) != LOCATION_LINE (use_loc
))
3675 inform (use_loc
, "in this expression");
3680 /* Optimize a call to strcmp or strncmp either by folding it to a constant
3681 when possible or by transforming the latter to the former. Warn about
3682 calls where the length of one argument is greater than the size of
3683 the array to which the other argument points if the latter's length
3684 is not known. Return true when the call has been transformed into
3685 another and false otherwise. */
3688 handle_builtin_string_cmp (gimple_stmt_iterator
*gsi
)
3690 gcall
*stmt
= as_a
<gcall
*> (gsi_stmt (*gsi
));
3691 tree lhs
= gimple_call_lhs (stmt
);
3696 tree arg1
= gimple_call_arg (stmt
, 0);
3697 tree arg2
= gimple_call_arg (stmt
, 1);
3698 int idx1
= get_stridx (arg1
);
3699 int idx2
= get_stridx (arg2
);
3701 /* For strncmp set to the the value of the third argument if known. */
3702 HOST_WIDE_INT bound
= -1;
3704 /* Extract the strncmp bound. */
3705 if (gimple_call_num_args (stmt
) == 3)
3707 tree len
= gimple_call_arg (stmt
, 2);
3708 if (tree_fits_shwi_p (len
))
3709 bound
= tree_to_shwi (len
);
3711 /* If the bound argument is NOT known, do nothing. */
3717 /* Set to the length of one argument (or its complement if it's
3718 the lower bound of a range) and the size of the array storing
3719 the other if the result is based on the former being equal to
3720 or greater than the latter. */
3721 unsigned HOST_WIDE_INT len
[2] = { HOST_WIDE_INT_MAX
, HOST_WIDE_INT_MAX
};
3722 unsigned HOST_WIDE_INT siz
= HOST_WIDE_INT_M1U
;
3724 /* Try to determine if the two strings are either definitely equal
3725 or definitely unequal and if so, either fold the result to zero
3726 (when equal) or set the range of the result to ~[0, 0] otherwise. */
3727 if (tree eqz
= strxcmp_eqz_result (arg1
, idx1
, arg2
, idx2
, bound
,
3730 if (integer_zerop (eqz
))
3732 maybe_warn_pointless_strcmp (stmt
, bound
, len
, siz
);
3734 /* When the lengths of the first two string arguments are
3735 known to be unequal set the range of the result to non-zero.
3736 This allows the call to be eliminated if its result is only
3737 used in tests for equality to zero. */
3738 wide_int zero
= wi::zero (TYPE_PRECISION (TREE_TYPE (lhs
)));
3739 set_range_info (lhs
, VR_ANTI_RANGE
, zero
, zero
);
3742 /* When the two strings are definitely equal (such as when they
3743 are both empty) fold the call to the constant result. */
3744 replace_call_with_value (gsi
, integer_zero_node
);
3749 /* Return if nothing is known about the strings pointed to by ARG1
3751 if (idx1
== 0 && idx2
== 0)
3754 /* Determine either the length or the size of each of the strings,
3755 whichever is available. */
3756 HOST_WIDE_INT cstlen1
= -1, cstlen2
= -1;
3757 HOST_WIDE_INT arysiz1
= -1, arysiz2
= -1;
3760 cstlen1
= compute_string_length (idx1
) + 1;
3762 arysiz1
= determine_min_objsize (arg1
);
3764 /* Bail if neither the string length nor the size of the array
3765 it is stored in can be determined. */
3766 if (cstlen1
< 0 && arysiz1
< 0)
3769 /* Repeat for the second argument. */
3771 cstlen2
= compute_string_length (idx2
) + 1;
3773 arysiz2
= determine_min_objsize (arg2
);
3775 if (cstlen2
< 0 && arysiz2
< 0)
3778 /* The exact number of characters to compare. */
3779 HOST_WIDE_INT cmpsiz
= bound
< 0 ? cstlen1
< 0 ? cstlen2
: cstlen1
: bound
;
3780 /* The size of the array in which the unknown string is stored. */
3781 HOST_WIDE_INT varsiz
= arysiz1
< 0 ? arysiz2
: arysiz1
;
3783 if (cmpsiz
< varsiz
&& used_only_for_zero_equality (lhs
))
3785 /* If the known length is less than the size of the other array
3786 and the strcmp result is only used to test equality to zero,
3787 transform the call to the equivalent _eq call. */
3788 if (tree fn
= builtin_decl_implicit (bound
< 0 ? BUILT_IN_STRCMP_EQ
3789 : BUILT_IN_STRNCMP_EQ
))
3791 tree n
= build_int_cst (size_type_node
, cmpsiz
);
3792 update_gimple_call (gsi
, fn
, 3, arg1
, arg2
, n
);
3800 /* Handle a POINTER_PLUS_EXPR statement.
3801 For p = "abcd" + 2; compute associated length, or if
3802 p = q + off is pointing to a '\0' character of a string, call
3803 zero_length_string on it. */
3806 handle_pointer_plus (gimple_stmt_iterator
*gsi
)
3808 gimple
*stmt
= gsi_stmt (*gsi
);
3809 tree lhs
= gimple_assign_lhs (stmt
), off
;
3810 int idx
= get_stridx (gimple_assign_rhs1 (stmt
));
3818 tree off
= gimple_assign_rhs2 (stmt
);
3819 if (tree_fits_uhwi_p (off
)
3820 && tree_to_uhwi (off
) <= (unsigned HOST_WIDE_INT
) ~idx
)
3821 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)]
3822 = ~(~idx
- (int) tree_to_uhwi (off
));
3826 si
= get_strinfo (idx
);
3827 if (si
== NULL
|| si
->nonzero_chars
== NULL_TREE
)
3830 off
= gimple_assign_rhs2 (stmt
);
3832 if (si
->full_string_p
&& operand_equal_p (si
->nonzero_chars
, off
, 0))
3833 zsi
= zero_length_string (lhs
, si
);
3834 else if (TREE_CODE (off
) == SSA_NAME
)
3836 gimple
*def_stmt
= SSA_NAME_DEF_STMT (off
);
3837 if (gimple_assign_single_p (def_stmt
)
3838 && si
->full_string_p
3839 && operand_equal_p (si
->nonzero_chars
,
3840 gimple_assign_rhs1 (def_stmt
), 0))
3841 zsi
= zero_length_string (lhs
, si
);
3844 && si
->endptr
!= NULL_TREE
3845 && si
->endptr
!= lhs
3846 && TREE_CODE (si
->endptr
) == SSA_NAME
)
3848 enum tree_code rhs_code
3849 = useless_type_conversion_p (TREE_TYPE (lhs
), TREE_TYPE (si
->endptr
))
3850 ? SSA_NAME
: NOP_EXPR
;
3851 gimple_assign_set_rhs_with_ops (gsi
, rhs_code
, si
->endptr
);
3852 gcc_assert (gsi_stmt (*gsi
) == stmt
);
3857 /* Describes recursion limits used by count_nonzero_bytes. */
3859 class ssa_name_limit_t
3861 bitmap visited
; /* Bitmap of visited SSA_NAMEs. */
3862 unsigned ssa_def_max
; /* Longest chain of SSA_NAMEs to follow. */
3864 /* Not copyable or assignable. */
3865 ssa_name_limit_t (ssa_name_limit_t
&);
3866 void operator= (ssa_name_limit_t
&);
3872 ssa_def_max (PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT
)) { }
3874 int next_ssa_name (tree
);
3876 ~ssa_name_limit_t ()
3879 BITMAP_FREE (visited
);
3883 /* If the SSA_NAME has already been "seen" return a positive value.
3884 Otherwise add it to VISITED. If the SSA_NAME limit has been
3885 reached, return a negative value. Otherwise return zero. */
3887 int ssa_name_limit_t::next_ssa_name (tree ssa_name
)
3890 visited
= BITMAP_ALLOC (NULL
);
3892 /* Return a positive value if SSA_NAME has already been visited. */
3893 if (!bitmap_set_bit (visited
, SSA_NAME_VERSION (ssa_name
)))
3896 /* Return a negative value to let caller avoid recursing beyond
3897 the specified limit. */
3898 if (ssa_def_max
== 0)
3906 /* Determines the minimum and maximum number of leading non-zero bytes
3907 in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
3908 to each. Sets LENRANGE[2] to the total number of bytes in
3909 the representation. Sets *NULTREM if the representation contains
3910 a zero byte, and sets *ALLNUL if all the bytes are zero.
3911 OFFSET and NBYTES are the offset into the representation and
3912 the size of the access to it determined from a MEM_REF or zero
3913 for other expressions.
3914 Avoid recursing deeper than the limits in SNLIM allow.
3915 Returns true on success and false otherwise. */
3918 count_nonzero_bytes (tree exp
, unsigned HOST_WIDE_INT offset
,
3919 unsigned HOST_WIDE_INT nbytes
,
3920 unsigned lenrange
[3], bool *nulterm
,
3921 bool *allnul
, bool *allnonnul
, ssa_name_limit_t
&snlim
)
3923 int idx
= get_stridx (exp
);
3926 strinfo
*si
= get_strinfo (idx
);
3927 /* FIXME: Handle non-constant lengths in some range. */
3928 if (!si
|| !tree_fits_shwi_p (si
->nonzero_chars
))
3931 unsigned len
= tree_to_shwi (si
->nonzero_chars
);
3932 unsigned size
= len
+ si
->full_string_p
;
3938 if (len
< lenrange
[0])
3940 if (lenrange
[1] < len
)
3942 if (lenrange
[2] < nbytes
)
3943 lenrange
[2] = nbytes
;
3945 if (!si
->full_string_p
)
3948 /* Since only the length of the string are known and
3949 its contents, clear ALLNUL and ALLNONNUL purely on
3950 the basis of the length. */
3958 if (TREE_CODE (exp
) == ADDR_EXPR
)
3959 exp
= TREE_OPERAND (exp
, 0);
3961 if (TREE_CODE (exp
) == SSA_NAME
)
3963 /* Handle a single-character specially. */
3964 tree type
= TREE_TYPE (exp
);
3965 if (TREE_CODE (type
) == INTEGER_TYPE
3966 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
3967 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
)
3968 && tree_expr_nonzero_p (exp
))
3970 /* If the character EXP is known to be non-zero (even if its
3971 exact value is not known) recurse once to set the range
3972 for an arbitrary constant. */
3973 exp
= build_int_cst (type
, 1);
3974 return count_nonzero_bytes (exp
, offset
, 1, lenrange
,
3975 nulterm
, allnul
, allnonnul
, snlim
);
3978 gimple
*stmt
= SSA_NAME_DEF_STMT (exp
);
3979 if (gimple_assign_single_p (stmt
))
3981 exp
= gimple_assign_rhs1 (stmt
);
3982 if (TREE_CODE (exp
) != MEM_REF
)
3985 else if (gimple_code (stmt
) == GIMPLE_PHI
)
3987 /* Avoid processing an SSA_NAME that has already been visited
3988 or if an SSA_NAME limit has been reached. Indicate success
3989 if the former and failure if the latter. */
3990 if (int res
= snlim
.next_ssa_name (exp
))
3993 /* Determine the minimum and maximum from the PHI arguments. */
3994 unsigned int n
= gimple_phi_num_args (stmt
);
3995 for (unsigned i
= 0; i
!= n
; i
++)
3997 tree def
= gimple_phi_arg_def (stmt
, i
);
3998 if (!count_nonzero_bytes (def
, offset
, nbytes
, lenrange
, nulterm
,
3999 allnul
, allnonnul
, snlim
))
4007 if (TREE_CODE (exp
) == MEM_REF
)
4012 tree arg
= TREE_OPERAND (exp
, 0);
4013 tree off
= TREE_OPERAND (exp
, 1);
4015 if (TREE_CODE (off
) != INTEGER_CST
4016 || !tree_fits_uhwi_p (off
))
4019 unsigned HOST_WIDE_INT wioff
= tree_to_uhwi (off
);
4020 if (INT_MAX
< wioff
)
4024 if (INT_MAX
< offset
)
4027 /* The size of the MEM_REF access determines the number of bytes. */
4028 tree type
= TREE_TYPE (exp
);
4029 if (tree typesize
= TYPE_SIZE_UNIT (type
))
4030 nbytes
= tree_to_uhwi (typesize
);
4034 /* Handle MEM_REF = SSA_NAME types of assignments. */
4035 return count_nonzero_bytes (arg
, offset
, nbytes
, lenrange
, nulterm
,
4036 allnul
, allnonnul
, snlim
);
4039 if (TREE_CODE (exp
) == VAR_DECL
&& TREE_READONLY (exp
))
4041 exp
= DECL_INITIAL (exp
);
4046 const char *prep
= NULL
;
4047 if (TREE_CODE (exp
) == STRING_CST
)
4049 unsigned nchars
= TREE_STRING_LENGTH (exp
);
4050 if (nchars
< offset
)
4054 /* If NBYTES hasn't been determined earlier from MEM_REF,
4055 set it here. It includes all internal nuls, including
4056 the terminating one if the string has one. */
4057 nbytes
= nchars
- offset
;
4059 prep
= TREE_STRING_POINTER (exp
) + offset
;
4062 unsigned char buf
[256];
4065 /* If the pointer to representation hasn't been set above
4066 for STRING_CST point it at the buffer. */
4067 prep
= reinterpret_cast <char *>(buf
);
4068 /* Try to extract the representation of the constant object
4069 or expression starting from the offset. */
4070 unsigned repsize
= native_encode_expr (exp
, buf
, sizeof buf
, offset
);
4071 if (repsize
< nbytes
)
4073 /* This should only happen when REPSIZE is zero because EXP
4074 doesn't denote an object with a known initializer, except
4075 perhaps when the reference reads past its end. */
4081 else if (nbytes
< repsize
)
4088 /* Compute the number of leading nonzero bytes in the representation
4089 and update the minimum and maximum. */
4090 unsigned n
= prep
? strnlen (prep
, nbytes
) : nbytes
;
4092 if (n
< lenrange
[0])
4094 if (lenrange
[1] < n
)
4097 /* Set the size of the representation. */
4098 if (lenrange
[2] < nbytes
)
4099 lenrange
[2] = nbytes
;
4101 /* Clear NULTERM if none of the bytes is zero. */
4107 /* When the initial number of non-zero bytes N is non-zero, reset
4108 *ALLNUL; if N is less than that the size of the representation
4109 also clear *ALLNONNUL. */
4114 else if (*allnul
|| *allnonnul
)
4120 /* When either ALLNUL is set and N is zero, also determine
4121 whether all subsequent bytes after the first one (which
4122 is nul) are zero or nonzero and clear ALLNUL if not. */
4123 for (const char *p
= prep
; p
!= prep
+ nbytes
; ++p
)
4135 /* Same as above except with an implicit SSA_NAME limit. */
4138 count_nonzero_bytes (tree exp
, unsigned lenrange
[3], bool *nulterm
,
4139 bool *allnul
, bool *allnonnul
)
4141 /* Set to optimistic values so the caller doesn't have to worry about
4142 initializing these and to what. On success, the function will clear
4143 these if it determines their values are different but being recursive
4144 it never sets either to true. On failure, their values are
4150 ssa_name_limit_t snlim
;
4151 return count_nonzero_bytes (exp
, 0, 0, lenrange
, nulterm
, allnul
, allnonnul
,
4155 /* Handle a single or multibyte store other than by a built-in function,
4156 either via a single character assignment or by multi-byte assignment
4157 either via MEM_REF or via a type other than char (such as in
4158 '*(int*)a = 12345'). Return true when handled. */
4161 handle_store (gimple_stmt_iterator
*gsi
)
4165 gimple
*stmt
= gsi_stmt (*gsi
);
4166 tree ssaname
= NULL_TREE
, lhs
= gimple_assign_lhs (stmt
);
4167 tree rhs
= gimple_assign_rhs1 (stmt
);
4169 /* The offset of the first byte in LHS modified by the the store. */
4170 unsigned HOST_WIDE_INT offset
= 0;
4172 if (TREE_CODE (lhs
) == MEM_REF
4173 && TREE_CODE (TREE_OPERAND (lhs
, 0)) == SSA_NAME
)
4175 tree mem_offset
= TREE_OPERAND (lhs
, 1);
4176 if (tree_fits_uhwi_p (mem_offset
))
4178 /* Get the strinfo for the base, and use it if it starts with at
4179 least OFFSET nonzero characters. This is trivially true if
4181 offset
= tree_to_uhwi (mem_offset
);
4182 idx
= get_stridx (TREE_OPERAND (lhs
, 0));
4184 si
= get_strinfo (idx
);
4186 ssaname
= TREE_OPERAND (lhs
, 0);
4187 else if (si
== NULL
|| compare_nonzero_chars (si
, offset
) < 0)
4193 idx
= get_addr_stridx (lhs
, NULL_TREE
, &offset
);
4195 si
= get_strinfo (idx
);
4198 /* Minimum and maximum leading non-zero bytes and the size of the store. */
4199 unsigned lenrange
[] = { UINT_MAX
, 0, 0 };
4201 /* Set to the minimum length of the string being assigned if known. */
4202 unsigned HOST_WIDE_INT rhs_minlen
;
4204 /* STORING_NONZERO_P is true iff not all stored characters are zero.
4205 STORING_ALL_NONZERO_P is true if all stored characters are zero.
4206 STORING_ALL_ZEROS_P is true iff all stored characters are zero.
4207 Both are false when it's impossible to determine which is true. */
4208 bool storing_nonzero_p
;
4209 bool storing_all_nonzero_p
;
4210 bool storing_all_zeros_p
;
4211 /* FULL_STRING_P is set when the stored sequence of characters form
4212 a nul-terminated string. */
4215 const bool ranges_valid
4216 = count_nonzero_bytes (rhs
, lenrange
, &full_string_p
,
4217 &storing_all_zeros_p
, &storing_all_nonzero_p
);
4220 rhs_minlen
= lenrange
[0];
4221 storing_nonzero_p
= lenrange
[1] > 0;
4223 /* Avoid issuing multiple warnings for the same LHS or statement.
4224 For example, -Warray-bounds may have already been issued for
4225 an out-of-bounds subscript. */
4226 if (!TREE_NO_WARNING (lhs
) && !gimple_no_warning_p (stmt
))
4228 /* Set to the declaration referenced by LHS (if known). */
4229 tree decl
= NULL_TREE
;
4230 if (tree dstsize
= compute_objsize (lhs
, 1, &decl
))
4231 if (compare_tree_int (dstsize
, lenrange
[2]) < 0)
4233 /* Fall back on the LHS location if the statement
4234 doesn't have one. */
4235 location_t loc
= gimple_nonartificial_location (stmt
);
4236 if (loc
== UNKNOWN_LOCATION
)
4237 loc
= tree_nonartificial_location (lhs
);
4238 loc
= expansion_point_location_if_in_system_header (loc
);
4239 if (warning_n (loc
, OPT_Wstringop_overflow_
,
4241 "%Gwriting %u byte into a region of size %E",
4242 "%Gwriting %u bytes into a region of size %E",
4243 stmt
, lenrange
[2], dstsize
))
4246 inform (DECL_SOURCE_LOCATION (decl
),
4247 "destination object declared here");
4248 gimple_set_no_warning (stmt
, true);
4255 rhs_minlen
= HOST_WIDE_INT_M1U
;
4256 full_string_p
= false;
4257 storing_nonzero_p
= false;
4258 storing_all_zeros_p
= false;
4259 storing_all_nonzero_p
= false;
4264 /* The corresponding element is set to 1 if the first and last
4265 element, respectively, of the sequence of characters being
4266 written over the string described by SI ends before
4267 the terminating nul (if it has one), to zero if the nul is
4268 being overwritten but not beyond, or negative otherwise. */
4269 int store_before_nul
[2];
4272 /* The offset of the last stored byte. */
4273 unsigned HOST_WIDE_INT endoff
= offset
+ lenrange
[2] - 1;
4274 store_before_nul
[0] = compare_nonzero_chars (si
, offset
);
4275 if (endoff
== offset
)
4276 store_before_nul
[1] = store_before_nul
[0];
4278 store_before_nul
[1] = compare_nonzero_chars (si
, endoff
);
4282 store_before_nul
[0] = compare_nonzero_chars (si
, offset
);
4283 store_before_nul
[1] = store_before_nul
[0];
4284 gcc_assert (offset
== 0 || store_before_nul
[0] >= 0);
4287 if (storing_all_zeros_p
4288 && store_before_nul
[0] == 0
4289 && store_before_nul
[1] == 0
4290 && si
->full_string_p
)
4292 /* When overwriting a '\0' with a '\0', the store can be removed
4293 if we know it has been stored in the current function. */
4294 if (!stmt_could_throw_p (cfun
, stmt
) && si
->writable
)
4296 unlink_stmt_vdef (stmt
);
4297 release_defs (stmt
);
4298 gsi_remove (gsi
, true);
4303 si
->writable
= true;
4309 if (store_before_nul
[1] > 0
4310 && storing_nonzero_p
4311 && lenrange
[0] == lenrange
[1]
4312 && lenrange
[0] == lenrange
[2]
4313 && TREE_CODE (TREE_TYPE (rhs
)) == INTEGER_TYPE
)
4315 /* Handle a store of one or more non-nul characters that ends
4316 before the terminating nul of the destination and so does
4317 not affect its length
4318 If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
4319 and if we aren't storing '\0', we know that the length of
4320 the string and any other zero terminated string in memory
4321 remains the same. In that case we move to the next gimple
4322 statement and return to signal the caller that it shouldn't
4323 invalidate anything.
4325 This is benefical for cases like:
4330 strcpy (p, "foobar");
4331 size_t len = strlen (p); // can be folded to 6
4332 size_t len2 = strlen (q); // has to be computed
4334 size_t len3 = strlen (p); // can be folded to 6
4335 size_t len4 = strlen (q); // can be folded to len2
4336 bar (len, len2, len3, len4);
4342 if (storing_all_zeros_p
4343 || storing_nonzero_p
4344 || (offset
!= 0 && store_before_nul
[1] > 0))
4346 /* When STORING_NONZERO_P, we know that the string will start
4347 with at least OFFSET + 1 nonzero characters. If storing
4348 a single character, set si->NONZERO_CHARS to the result.
4349 If storing multiple characters, try to determine the number
4350 of leading non-zero characters and set si->NONZERO_CHARS to
4353 When STORING_ALL_ZEROS_P, we know that the string is now
4354 OFFSET characters long.
4356 Otherwise, we're storing an unknown value at offset OFFSET,
4357 so need to clip the nonzero_chars to OFFSET.
4358 Use the minimum length of the string (or individual character)
4359 being stored if it's known. Otherwise, STORING_NONZERO_P
4360 guarantees it's at least 1. */
4362 = storing_nonzero_p
&& ranges_valid
? lenrange
[0] : 1;
4363 location_t loc
= gimple_location (stmt
);
4364 tree oldlen
= si
->nonzero_chars
;
4365 if (store_before_nul
[1] == 0 && si
->full_string_p
)
4366 /* We're overwriting the nul terminator with a nonzero or
4367 unknown character. If the previous stmt was a memcpy,
4368 its length may be decreased. */
4369 adjust_last_stmt (si
, stmt
, false);
4370 si
= unshare_strinfo (si
);
4371 if (storing_nonzero_p
)
4373 gcc_assert (len
>= 0);
4374 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
+ len
);
4377 si
->nonzero_chars
= build_int_cst (size_type_node
, offset
);
4379 /* Set FULL_STRING_P only if the length of the strings being
4380 written is the same, and clear it if the strings have
4381 different lengths. In the latter case the length stored
4382 in si->NONZERO_CHARS becomes the lower bound.
4383 FIXME: Handle the upper bound of the length if possible. */
4384 si
->full_string_p
= full_string_p
&& lenrange
[0] == lenrange
[1];
4386 if (storing_all_zeros_p
4388 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
4389 si
->endptr
= ssaname
;
4394 si
->writable
= true;
4395 si
->dont_invalidate
= true;
4398 tree adj
= fold_build2_loc (loc
, MINUS_EXPR
, size_type_node
,
4399 si
->nonzero_chars
, oldlen
);
4400 adjust_related_strinfos (loc
, si
, adj
);
4406 else if (idx
== 0 && (storing_all_zeros_p
|| storing_nonzero_p
))
4409 idx
= new_stridx (ssaname
);
4411 idx
= new_addr_stridx (lhs
);
4414 tree ptr
= (ssaname
? ssaname
: build_fold_addr_expr (lhs
));
4417 if (storing_all_zeros_p
)
4419 else if (storing_nonzero_p
&& ranges_valid
)
4421 /* FIXME: Handle the upper bound of the length when
4422 LENRANGE[0] != LENRANGE[1]. */
4424 if (lenrange
[0] != lenrange
[1])
4425 /* Set the minimum length but ignore the maximum
4427 full_string_p
= false;
4432 tree len
= (slen
<= 0
4434 : build_int_cst (size_type_node
, slen
));
4435 si
= new_strinfo (ptr
, idx
, len
, slen
>= 0 && full_string_p
);
4436 set_strinfo (idx
, si
);
4437 if (storing_all_zeros_p
4439 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname
))
4440 si
->endptr
= ssaname
;
4441 si
->dont_invalidate
= true;
4442 si
->writable
= true;
4446 && rhs_minlen
< HOST_WIDE_INT_M1U
4447 && ssaname
== NULL_TREE
4448 && TREE_CODE (TREE_TYPE (lhs
)) == ARRAY_TYPE
)
4450 HOST_WIDE_INT a
= int_size_in_bytes (TREE_TYPE (lhs
));
4451 if (a
> 0 && (unsigned HOST_WIDE_INT
) a
> rhs_minlen
)
4453 int idx
= new_addr_stridx (lhs
);
4456 si
= new_strinfo (build_fold_addr_expr (lhs
), idx
,
4457 build_int_cst (size_type_node
, rhs_minlen
),
4459 set_strinfo (idx
, si
);
4460 si
->dont_invalidate
= true;
4465 if (si
!= NULL
&& offset
== 0 && storing_all_zeros_p
)
4467 /* Allow adjust_last_stmt to remove it if the stored '\0'
4468 is immediately overwritten. */
4469 laststmt
.stmt
= stmt
;
4470 laststmt
.len
= build_int_cst (size_type_node
, 1);
4471 laststmt
.stridx
= si
->idx
;
4476 /* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0. */
4479 fold_strstr_to_strncmp (tree rhs1
, tree rhs2
, gimple
*stmt
)
4481 if (TREE_CODE (rhs1
) != SSA_NAME
4482 || TREE_CODE (rhs2
) != SSA_NAME
)
4485 gimple
*call_stmt
= NULL
;
4486 for (int pass
= 0; pass
< 2; pass
++)
4488 gimple
*g
= SSA_NAME_DEF_STMT (rhs1
);
4489 if (gimple_call_builtin_p (g
, BUILT_IN_STRSTR
)
4490 && has_single_use (rhs1
)
4491 && gimple_call_arg (g
, 0) == rhs2
)
4496 std::swap (rhs1
, rhs2
);
4501 tree arg0
= gimple_call_arg (call_stmt
, 0);
4505 tree arg1
= gimple_call_arg (call_stmt
, 1);
4506 tree arg1_len
= NULL_TREE
;
4507 int idx
= get_stridx (arg1
);
4512 arg1_len
= build_int_cst (size_type_node
, ~idx
);
4515 strinfo
*si
= get_strinfo (idx
);
4517 arg1_len
= get_string_length (si
);
4521 if (arg1_len
!= NULL_TREE
)
4523 gimple_stmt_iterator gsi
= gsi_for_stmt (call_stmt
);
4524 tree strncmp_decl
= builtin_decl_explicit (BUILT_IN_STRNCMP
);
4526 if (!is_gimple_val (arg1_len
))
4528 tree arg1_len_tmp
= make_ssa_name (TREE_TYPE (arg1_len
));
4529 gassign
*arg1_stmt
= gimple_build_assign (arg1_len_tmp
,
4531 gsi_insert_before (&gsi
, arg1_stmt
, GSI_SAME_STMT
);
4532 arg1_len
= arg1_len_tmp
;
4535 gcall
*strncmp_call
= gimple_build_call (strncmp_decl
, 3,
4536 arg0
, arg1
, arg1_len
);
4537 tree strncmp_lhs
= make_ssa_name (integer_type_node
);
4538 gimple_set_vuse (strncmp_call
, gimple_vuse (call_stmt
));
4539 gimple_call_set_lhs (strncmp_call
, strncmp_lhs
);
4540 gsi_remove (&gsi
, true);
4541 gsi_insert_before (&gsi
, strncmp_call
, GSI_SAME_STMT
);
4542 tree zero
= build_zero_cst (TREE_TYPE (strncmp_lhs
));
4544 if (is_gimple_assign (stmt
))
4546 if (gimple_assign_rhs_code (stmt
) == COND_EXPR
)
4548 tree cond
= gimple_assign_rhs1 (stmt
);
4549 TREE_OPERAND (cond
, 0) = strncmp_lhs
;
4550 TREE_OPERAND (cond
, 1) = zero
;
4554 gimple_assign_set_rhs1 (stmt
, strncmp_lhs
);
4555 gimple_assign_set_rhs2 (stmt
, zero
);
4560 gcond
*cond
= as_a
<gcond
*> (stmt
);
4561 gimple_cond_set_lhs (cond
, strncmp_lhs
);
4562 gimple_cond_set_rhs (cond
, zero
);
4570 /* Return true if TYPE corresponds to a narrow character type. */
4573 is_char_type (tree type
)
4575 return (TREE_CODE (type
) == INTEGER_TYPE
4576 && TYPE_MODE (type
) == TYPE_MODE (char_type_node
)
4577 && TYPE_PRECISION (type
) == TYPE_PRECISION (char_type_node
));
4580 /* Check the built-in call at GSI for validity and optimize it.
4581 Return true to let the caller advance *GSI to the statement
4582 in the CFG and false otherwise. */
4585 strlen_check_and_optimize_call (gimple_stmt_iterator
*gsi
,
4586 const vr_values
*rvals
)
4588 gimple
*stmt
= gsi_stmt (*gsi
);
4590 if (!flag_optimize_strlen
4592 || !valid_builtin_call (stmt
))
4594 /* When not optimizing we must be checking printf calls which
4595 we do even for user-defined functions when they are declared
4596 with attribute format. */
4597 handle_printf_call (gsi
, rvals
);
4601 tree callee
= gimple_call_fndecl (stmt
);
4602 switch (DECL_FUNCTION_CODE (callee
))
4604 case BUILT_IN_STRLEN
:
4605 case BUILT_IN_STRNLEN
:
4606 handle_builtin_strlen (gsi
);
4608 case BUILT_IN_STRCHR
:
4609 handle_builtin_strchr (gsi
);
4611 case BUILT_IN_STRCPY
:
4612 case BUILT_IN_STRCPY_CHK
:
4613 case BUILT_IN_STPCPY
:
4614 case BUILT_IN_STPCPY_CHK
:
4615 handle_builtin_strcpy (DECL_FUNCTION_CODE (callee
), gsi
);
4618 case BUILT_IN_STRNCAT
:
4619 case BUILT_IN_STRNCAT_CHK
:
4620 handle_builtin_strncat (DECL_FUNCTION_CODE (callee
), gsi
);
4623 case BUILT_IN_STPNCPY
:
4624 case BUILT_IN_STPNCPY_CHK
:
4625 case BUILT_IN_STRNCPY
:
4626 case BUILT_IN_STRNCPY_CHK
:
4627 handle_builtin_stxncpy (DECL_FUNCTION_CODE (callee
), gsi
);
4630 case BUILT_IN_MEMCPY
:
4631 case BUILT_IN_MEMCPY_CHK
:
4632 case BUILT_IN_MEMPCPY
:
4633 case BUILT_IN_MEMPCPY_CHK
:
4634 handle_builtin_memcpy (DECL_FUNCTION_CODE (callee
), gsi
);
4636 case BUILT_IN_STRCAT
:
4637 case BUILT_IN_STRCAT_CHK
:
4638 handle_builtin_strcat (DECL_FUNCTION_CODE (callee
), gsi
);
4640 case BUILT_IN_MALLOC
:
4641 case BUILT_IN_CALLOC
:
4642 handle_builtin_malloc (DECL_FUNCTION_CODE (callee
), gsi
);
4644 case BUILT_IN_MEMSET
:
4645 if (handle_builtin_memset (gsi
))
4648 case BUILT_IN_MEMCMP
:
4649 if (handle_builtin_memcmp (gsi
))
4652 case BUILT_IN_STRCMP
:
4653 case BUILT_IN_STRNCMP
:
4654 if (handle_builtin_string_cmp (gsi
))
4658 handle_printf_call (gsi
, rvals
);
4665 /* Handle an assignment statement at *GSI to a LHS of integral type.
4666 If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true. */
4669 handle_integral_assign (gimple_stmt_iterator
*gsi
, bool *cleanup_eh
)
4671 gimple
*stmt
= gsi_stmt (*gsi
);
4672 tree lhs
= gimple_assign_lhs (stmt
);
4673 tree lhs_type
= TREE_TYPE (lhs
);
4675 enum tree_code code
= gimple_assign_rhs_code (stmt
);
4676 if (code
== COND_EXPR
)
4678 tree cond
= gimple_assign_rhs1 (stmt
);
4679 enum tree_code cond_code
= TREE_CODE (cond
);
4681 if (cond_code
== EQ_EXPR
|| cond_code
== NE_EXPR
)
4682 fold_strstr_to_strncmp (TREE_OPERAND (cond
, 0),
4683 TREE_OPERAND (cond
, 1), stmt
);
4685 else if (code
== EQ_EXPR
|| code
== NE_EXPR
)
4686 fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt
),
4687 gimple_assign_rhs2 (stmt
), stmt
);
4688 else if (gimple_assign_load_p (stmt
)
4689 && TREE_CODE (lhs_type
) == INTEGER_TYPE
4690 && TYPE_MODE (lhs_type
) == TYPE_MODE (char_type_node
)
4691 && (TYPE_PRECISION (lhs_type
)
4692 == TYPE_PRECISION (char_type_node
))
4693 && !gimple_has_volatile_ops (stmt
))
4695 tree off
= integer_zero_node
;
4696 unsigned HOST_WIDE_INT coff
= 0;
4698 tree rhs1
= gimple_assign_rhs1 (stmt
);
4699 if (code
== MEM_REF
)
4701 idx
= get_stridx (TREE_OPERAND (rhs1
, 0));
4704 strinfo
*si
= get_strinfo (idx
);
4706 && si
->nonzero_chars
4707 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
4708 && (wi::to_widest (si
->nonzero_chars
)
4709 >= wi::to_widest (off
)))
4710 off
= TREE_OPERAND (rhs1
, 1);
4712 /* This case is not useful. See if get_addr_stridx
4713 returns something usable. */
4718 idx
= get_addr_stridx (rhs1
, NULL_TREE
, &coff
);
4721 strinfo
*si
= get_strinfo (idx
);
4723 && si
->nonzero_chars
4724 && TREE_CODE (si
->nonzero_chars
) == INTEGER_CST
)
4726 widest_int w1
= wi::to_widest (si
->nonzero_chars
);
4727 widest_int w2
= wi::to_widest (off
) + coff
;
4729 && si
->full_string_p
)
4731 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
4733 fprintf (dump_file
, "Optimizing: ");
4734 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
4737 /* Reading the final '\0' character. */
4738 tree zero
= build_int_cst (lhs_type
, 0);
4739 gimple_set_vuse (stmt
, NULL_TREE
);
4740 gimple_assign_set_rhs_from_tree (gsi
, zero
);
4742 |= maybe_clean_or_replace_eh_stmt (stmt
,
4744 stmt
= gsi_stmt (*gsi
);
4747 if (dump_file
&& (dump_flags
& TDF_DETAILS
) != 0)
4749 fprintf (dump_file
, "into: ");
4750 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
4755 /* Reading a character before the final '\0'
4756 character. Just set the value range to ~[0, 0]
4757 if we don't have anything better. */
4759 signop sign
= TYPE_SIGN (lhs_type
);
4760 int prec
= TYPE_PRECISION (lhs_type
);
4761 value_range_kind vr
= get_range_info (lhs
, &min
, &max
);
4762 if (vr
== VR_VARYING
4764 && min
== wi::min_value (prec
, sign
)
4765 && max
== wi::max_value (prec
, sign
)))
4766 set_range_info (lhs
, VR_ANTI_RANGE
,
4767 wi::zero (prec
), wi::zero (prec
));
4773 if (strlen_to_stridx
)
4775 tree rhs1
= gimple_assign_rhs1 (stmt
);
4776 if (stridx_strlenloc
*ps
= strlen_to_stridx
->get (rhs1
))
4777 strlen_to_stridx
->put (lhs
, stridx_strlenloc (*ps
));
4781 /* Attempt to check for validity of the performed access a single statement
4782 at *GSI using string length knowledge, and to optimize it.
4783 If the given basic block needs clean-up of EH, CLEANUP_EH is set to
4787 check_and_optimize_stmt (gimple_stmt_iterator
*gsi
, bool *cleanup_eh
,
4788 const vr_values
*rvals
)
4790 gimple
*stmt
= gsi_stmt (*gsi
);
4792 if (is_gimple_call (stmt
))
4794 if (!strlen_check_and_optimize_call (gsi
, rvals
))
4797 else if (!flag_optimize_strlen
|| !strlen_optimize
)
4799 else if (is_gimple_assign (stmt
) && !gimple_clobber_p (stmt
))
4801 /* Handle non-clobbering assignment. */
4802 tree lhs
= gimple_assign_lhs (stmt
);
4803 tree lhs_type
= TREE_TYPE (lhs
);
4805 if (TREE_CODE (lhs
) == SSA_NAME
&& POINTER_TYPE_P (lhs_type
))
4807 if (gimple_assign_single_p (stmt
)
4808 || (gimple_assign_cast_p (stmt
)
4809 && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt
)))))
4811 int idx
= get_stridx (gimple_assign_rhs1 (stmt
));
4812 ssa_ver_to_stridx
[SSA_NAME_VERSION (lhs
)] = idx
;
4814 else if (gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
4815 handle_pointer_plus (gsi
);
4817 else if (TREE_CODE (lhs
) == SSA_NAME
&& INTEGRAL_TYPE_P (lhs_type
))
4818 /* Handle assignment to a character. */
4819 handle_integral_assign (gsi
, cleanup_eh
);
4820 else if (TREE_CODE (lhs
) != SSA_NAME
&& !TREE_SIDE_EFFECTS (lhs
))
4822 tree type
= TREE_TYPE (lhs
);
4823 if (TREE_CODE (type
) == ARRAY_TYPE
)
4824 type
= TREE_TYPE (type
);
4826 bool is_char_store
= is_char_type (type
);
4827 if (!is_char_store
&& TREE_CODE (lhs
) == MEM_REF
)
4829 /* To consider stores into char objects via integer types
4830 other than char but not those to non-character objects,
4831 determine the type of the destination rather than just
4832 the type of the access. */
4833 tree ref
= TREE_OPERAND (lhs
, 0);
4834 type
= TREE_TYPE (ref
);
4835 if (TREE_CODE (type
) == POINTER_TYPE
)
4836 type
= TREE_TYPE (type
);
4837 if (TREE_CODE (type
) == ARRAY_TYPE
)
4838 type
= TREE_TYPE (type
);
4839 if (is_char_type (type
))
4840 is_char_store
= true;
4843 /* Handle a single or multibyte assignment. */
4844 if (is_char_store
&& !handle_store (gsi
))
4848 else if (gcond
*cond
= dyn_cast
<gcond
*> (stmt
))
4850 enum tree_code code
= gimple_cond_code (cond
);
4851 if (code
== EQ_EXPR
|| code
== NE_EXPR
)
4852 fold_strstr_to_strncmp (gimple_cond_lhs (stmt
),
4853 gimple_cond_rhs (stmt
), stmt
);
4856 if (gimple_vdef (stmt
))
4857 maybe_invalidate (stmt
);
4861 /* Recursively call maybe_invalidate on stmts that might be executed
4862 in between dombb and current bb and that contain a vdef. Stop when
4863 *count stmts are inspected, or if the whole strinfo vector has
4864 been invalidated. */
4867 do_invalidate (basic_block dombb
, gimple
*phi
, bitmap visited
, int *count
)
4869 unsigned int i
, n
= gimple_phi_num_args (phi
);
4871 for (i
= 0; i
< n
; i
++)
4873 tree vuse
= gimple_phi_arg_def (phi
, i
);
4874 gimple
*stmt
= SSA_NAME_DEF_STMT (vuse
);
4875 basic_block bb
= gimple_bb (stmt
);
4878 || !bitmap_set_bit (visited
, bb
->index
)
4879 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
4883 if (gimple_code (stmt
) == GIMPLE_PHI
)
4885 do_invalidate (dombb
, stmt
, visited
, count
);
4892 if (!maybe_invalidate (stmt
))
4897 vuse
= gimple_vuse (stmt
);
4898 stmt
= SSA_NAME_DEF_STMT (vuse
);
4899 if (gimple_bb (stmt
) != bb
)
4901 bb
= gimple_bb (stmt
);
4904 || !bitmap_set_bit (visited
, bb
->index
)
4905 || !dominated_by_p (CDI_DOMINATORS
, bb
, dombb
))
4912 class strlen_dom_walker
: public dom_walker
4915 strlen_dom_walker (cdi_direction direction
)
4916 : dom_walker (direction
),
4918 m_cleanup_cfg (false)
4921 virtual edge
before_dom_children (basic_block
);
4922 virtual void after_dom_children (basic_block
);
4924 /* EVRP analyzer used for printf argument range processing, and
4925 to track strlen results across integer variable assignments. */
4926 evrp_range_analyzer evrp
;
4928 /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
4929 execute function. */
4933 /* Callback for walk_dominator_tree. Attempt to optimize various
4934 string ops by remembering string lengths pointed by pointer SSA_NAMEs. */
4937 strlen_dom_walker::before_dom_children (basic_block bb
)
4941 basic_block dombb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
4944 stridx_to_strinfo
= NULL
;
4947 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) dombb
->aux
);
4948 if (stridx_to_strinfo
)
4950 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
4953 gphi
*phi
= gsi
.phi ();
4954 if (virtual_operand_p (gimple_phi_result (phi
)))
4956 bitmap visited
= BITMAP_ALLOC (NULL
);
4957 int count_vdef
= 100;
4958 do_invalidate (dombb
, phi
, visited
, &count_vdef
);
4959 BITMAP_FREE (visited
);
4960 if (count_vdef
== 0)
4962 /* If there were too many vdefs in between immediate
4963 dominator and current bb, invalidate everything.
4964 If stridx_to_strinfo has been unshared, we need
4965 to free it, otherwise just set it to NULL. */
4966 if (!strinfo_shared ())
4972 vec_safe_iterate (stridx_to_strinfo
, i
, &si
);
4976 (*stridx_to_strinfo
)[i
] = NULL
;
4980 stridx_to_strinfo
= NULL
;
4988 /* If all PHI arguments have the same string index, the PHI result
4990 for (gphi_iterator gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
);
4993 gphi
*phi
= gsi
.phi ();
4994 tree result
= gimple_phi_result (phi
);
4995 if (!virtual_operand_p (result
) && POINTER_TYPE_P (TREE_TYPE (result
)))
4997 int idx
= get_stridx (gimple_phi_arg_def (phi
, 0));
5000 unsigned int i
, n
= gimple_phi_num_args (phi
);
5001 for (i
= 1; i
< n
; i
++)
5002 if (idx
!= get_stridx (gimple_phi_arg_def (phi
, i
)))
5005 ssa_ver_to_stridx
[SSA_NAME_VERSION (result
)] = idx
;
5010 bool cleanup_eh
= false;
5012 /* Attempt to optimize individual statements. */
5013 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); )
5015 gimple
*stmt
= gsi_stmt (gsi
);
5017 /* First record ranges generated by this statement so they
5018 can be used by printf argument processing. */
5019 evrp
.record_ranges_from_stmt (stmt
, false);
5021 if (check_and_optimize_stmt (&gsi
, &cleanup_eh
, evrp
.get_vr_values ()))
5025 if (cleanup_eh
&& gimple_purge_dead_eh_edges (bb
))
5026 m_cleanup_cfg
= true;
5028 bb
->aux
= stridx_to_strinfo
;
5029 if (vec_safe_length (stridx_to_strinfo
) && !strinfo_shared ())
5030 (*stridx_to_strinfo
)[0] = (strinfo
*) bb
;
5034 /* Callback for walk_dominator_tree. Free strinfo vector if it is
5035 owned by the current bb, clear bb->aux. */
5038 strlen_dom_walker::after_dom_children (basic_block bb
)
5044 stridx_to_strinfo
= ((vec
<strinfo
*, va_heap
, vl_embed
> *) bb
->aux
);
5045 if (vec_safe_length (stridx_to_strinfo
)
5046 && (*stridx_to_strinfo
)[0] == (strinfo
*) bb
)
5051 for (i
= 1; vec_safe_iterate (stridx_to_strinfo
, i
, &si
); ++i
)
5053 vec_free (stridx_to_strinfo
);
5062 printf_strlen_execute (function
*fun
, bool warn_only
)
5064 strlen_optimize
= !warn_only
;
5066 calculate_dominance_info (CDI_DOMINATORS
);
5068 bool use_scev
= optimize
> 0 && flag_printf_return_value
;
5071 loop_optimizer_init (LOOPS_NORMAL
);
5075 gcc_assert (!strlen_to_stridx
);
5076 if (warn_stringop_overflow
|| warn_stringop_truncation
)
5077 strlen_to_stridx
= new hash_map
<tree
, stridx_strlenloc
> ();
5079 /* This has to happen after initializing the loop optimizer
5080 and initializing SCEV as they create new SSA_NAMEs. */
5081 ssa_ver_to_stridx
.safe_grow_cleared (num_ssa_names
);
5084 /* String length optimization is implemented as a walk of the dominator
5085 tree and a forward walk of statements within each block. */
5086 strlen_dom_walker
walker (CDI_DOMINATORS
);
5087 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));
5089 ssa_ver_to_stridx
.release ();
5090 strinfo_pool
.release ();
5091 if (decl_to_stridxlist_htab
)
5093 obstack_free (&stridx_obstack
, NULL
);
5094 delete decl_to_stridxlist_htab
;
5095 decl_to_stridxlist_htab
= NULL
;
5097 laststmt
.stmt
= NULL
;
5098 laststmt
.len
= NULL_TREE
;
5099 laststmt
.stridx
= 0;
5101 if (strlen_to_stridx
)
5103 strlen_to_stridx
->empty ();
5104 delete strlen_to_stridx
;
5105 strlen_to_stridx
= NULL
;
5111 loop_optimizer_finalize ();
5114 /* Clean up object size info. */
5115 fini_object_sizes ();
5117 return walker
.m_cleanup_cfg
? TODO_cleanup_cfg
: 0;
5120 /* This file defines two passes: one for warnings that runs only when
5121 optimization is disabled, and another that implements optimizations
5122 and also issues warnings. */
5124 const pass_data pass_data_warn_printf
=
5126 GIMPLE_PASS
, /* type */
5127 "warn-printf", /* name */
5128 OPTGROUP_NONE
, /* optinfo_flags */
5129 TV_NONE
, /* tv_id */
5130 /* Normally an optimization pass would require PROP_ssa but because
5131 this pass runs early, with no optimization, to do sprintf format
5132 checking, it only requires PROP_cfg. */
5133 PROP_cfg
, /* properties_required */
5134 0, /* properties_provided */
5135 0, /* properties_destroyed */
5136 0, /* todo_flags_start */
5137 0, /* todo_flags_finish */
5140 class pass_warn_printf
: public gimple_opt_pass
5143 pass_warn_printf (gcc::context
*ctxt
)
5144 : gimple_opt_pass (pass_data_warn_printf
, ctxt
)
5147 virtual bool gate (function
*);
5148 virtual unsigned int execute (function
*fun
)
5150 return printf_strlen_execute (fun
, true);
5155 /* Return true to run the warning pass only when not optimizing and
5156 iff either -Wformat-overflow or -Wformat-truncation is specified. */
5159 pass_warn_printf::gate (function
*)
5161 return !optimize
&& (warn_format_overflow
> 0 || warn_format_trunc
> 0);
5164 const pass_data pass_data_strlen
=
5166 GIMPLE_PASS
, /* type */
5167 "strlen", /* name */
5168 OPTGROUP_NONE
, /* optinfo_flags */
5169 TV_TREE_STRLEN
, /* tv_id */
5170 PROP_cfg
| PROP_ssa
, /* properties_required */
5171 0, /* properties_provided */
5172 0, /* properties_destroyed */
5173 0, /* todo_flags_start */
5174 0, /* todo_flags_finish */
5177 class pass_strlen
: public gimple_opt_pass
5180 pass_strlen (gcc::context
*ctxt
)
5181 : gimple_opt_pass (pass_data_strlen
, ctxt
)
5184 opt_pass
* clone () { return new pass_strlen (m_ctxt
); }
5186 virtual bool gate (function
*);
5187 virtual unsigned int execute (function
*fun
)
5189 return printf_strlen_execute (fun
, false);
5193 /* Return true to run the pass only when the sprintf and/or strlen
5194 optimizations are enabled and -Wformat-overflow or -Wformat-truncation
5198 pass_strlen::gate (function
*)
5200 return ((warn_format_overflow
> 0
5201 || warn_format_trunc
> 0
5202 || flag_optimize_strlen
> 0
5203 || flag_printf_return_value
)
5210 make_pass_warn_printf (gcc::context
*ctxt
)
5212 return new pass_warn_printf (ctxt
);
5216 make_pass_strlen (gcc::context
*ctxt
)
5218 return new pass_strlen (ctxt
);