GCC Middle and Back End API Reference
tree-ssa-strlen.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "gimple-ssa-warn-access.h"
#include "gimple-ssa-warn-restrict.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimplify-me.h"
#include "expr.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "domwalk.h"
#include "tree-ssa-alias.h"
#include "tree-ssa-propagate.h"
#include "tree-ssa-strlen.h"
#include "tree-hash-traits.h"
#include "builtins.h"
#include "pointer-query.h"
#include "target.h"
#include "diagnostic-core.h"
#include "diagnostic.h"
#include "intl.h"
#include "attribs.h"
#include "calls.h"
#include "cfgloop.h"
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
#include "vr-values.h"
#include "gimple-range.h"
#include "tree-ssa.h"
Include dependency graph for tree-ssa-strlen.cc:

Data Structures

struct  strinfo
 
struct  stridxlist
 
struct  decl_stridxlist_map
 
struct  laststmt_struct
 
class  strlen_pass
 

Typedefs

typedef hash_map< tree_decl_hash, stridxlistdecl_to_stridxlist_htab_t
 
typedef std::pair< int, location_tstridx_strlenloc
 

Functions

static int get_stridx_plus_constant (strinfo *, unsigned HOST_WIDE_INT, tree)
 
static bool get_range_strlen_dynamic (tree, gimple *, c_strlen_data *, bitmap, pointer_query *, unsigned *)
 
tree get_range (tree val, gimple *stmt, wide_int minmax[2], range_query *rvals)
 
static int compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off)
 
static int compare_nonzero_chars (strinfo *si, gimple *stmt, unsigned HOST_WIDE_INT off, range_query *rvals)
 
static bool zero_length_string_p (strinfo *si)
 
static strinfoget_strinfo (int idx)
 
static strinfoget_next_strinfo (strinfo *si)
 
static int get_addr_stridx (tree exp, gimple *stmt, tree ptr, unsigned HOST_WIDE_INT *offset_out, range_query *rvals=NULL)
 
static int get_stridx (tree exp, gimple *stmt, wide_int offrng[2]=NULL, range_query *rvals=NULL)
 
static bool strinfo_shared (void)
 
static void unshare_strinfo_vec (void)
 
static int * addr_stridxptr (tree exp)
 
static int new_stridx (tree exp)
 
static int new_addr_stridx (tree exp)
 
static strinfonew_strinfo (tree ptr, int idx, tree nonzero_chars, bool full_string_p)
 
static void free_strinfo (strinfo *si)
 
static void set_strinfo (int idx, strinfo *si)
 
static strinfoverify_related_strinfos (strinfo *origsi)
 
static void set_endptr_and_length (location_t loc, strinfo *si, tree endptr)
 
static tree get_string_length (strinfo *si)
 
DEBUG_FUNCTION void dump_strlen_info (FILE *fp, gimple *stmt, range_query *rvals)
 
static bool get_range_strlen_phi (tree src, gphi *phi, c_strlen_data *pdata, bitmap visited, pointer_query *ptr_qry, unsigned *pssa_def_max)
 
static tree get_maxbound (tree ptr, gimple *stmt, offset_int maxlen, pointer_query *ptr_qry)
 
void get_range_strlen_dynamic (tree src, gimple *stmt, c_strlen_data *pdata, pointer_query &ptr_qry)
 
static bool maybe_invalidate (gimple *stmt, bool zero_write=false)
 
static strinfounshare_strinfo (strinfo *si)
 
static strinfozero_length_string (tree ptr, strinfo *chainsi)
 
static void adjust_related_strinfos (location_t loc, strinfo *origsi, tree adj)
 
static void find_equal_ptrs (tree ptr, int idx)
 
static bool valid_builtin_call (gimple *stmt)
 
tree set_strlen_range (tree lhs, wide_int min, wide_int max, tree bound)
 
static tree maybe_set_strlen_range (tree lhs, tree src, tree bound)
 
bool is_strlen_related_p (tree src, tree len)
 
bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt, pointer_query *ptr_qry)
 
gimpleuse_in_zero_equality (tree res, bool exclusive)
 
static void maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound, unsigned HOST_WIDE_INT len[2], unsigned HOST_WIDE_INT siz)
 
static bool nonzero_bytes_for_type (tree type, unsigned lenrange[3], bool *nulterm, bool *allnul, bool *allnonnul)
 
static void fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
 
static bool is_char_type (tree type)
 
static void do_invalidate (basic_block dombb, gimple *phi, bitmap visited, int *count)
 
gimple_opt_passmake_pass_warn_printf (gcc::context *ctxt)
 
gimple_opt_passmake_pass_strlen (gcc::context *ctxt)
 

Variables

static vec< int > ssa_ver_to_stridx
 
static int max_stridx
 
static bool strlen_optimize
 
static object_allocator< strinfostrinfo_pool ("strinfo pool")
 
static vec< strinfo *, va_heap, vl_embed > * stridx_to_strinfo
 
static decl_to_stridxlist_htab_tdecl_to_stridxlist_htab
 
static hash_map< tree, stridx_strlenloc > * strlen_to_stridx
 
static struct obstack stridx_obstack
 
struct laststmt_struct laststmt
 

Typedef Documentation

◆ decl_to_stridxlist_htab_t

Hash table for mapping decls to a chained list of offset -> idx
mappings.   

◆ stridx_strlenloc

Hash table mapping strlen (or strnlen with constant bound and return
smaller than bound) calls to stridx instances describing
the calls' arguments.  Non-null only when warn_stringop_truncation
is non-zero.   

Function Documentation

◆ addr_stridxptr()

static int * addr_stridxptr ( tree exp)
static
Attempt to create a string index for exp, ADDR_EXPR's operand.
Return a pointer to the location where the string index can
be stored (if 0) or is stored, or NULL if this can't be tracked.   

References DECL_P, decl_to_stridxlist_htab, exp(), gcc_obstack_init, get_addr_base_and_unit_offset(), hash_map< KeyId, Value, Traits >::get_or_insert(), ggc_alloc(), i, stridxlist::idx, stridxlist::next, NULL, NULL_TREE, stridxlist::offset, and stridx_obstack.

Referenced by find_equal_ptrs(), get_stridx_plus_constant(), new_addr_stridx(), and new_stridx().

◆ adjust_related_strinfos()

static void adjust_related_strinfos ( location_t loc,
strinfo * origsi,
tree adj )
static
For strinfo ORIGSI whose length has been just updated, adjust other
related strinfos so that they match the new ORIGSI.  This involves:

- adding ADJ to the nonzero_chars fields
- copying full_string_p from the new ORIGSI.   

References fold_build2_loc(), fold_convert_loc(), gcc_assert, get_next_strinfo(), ggc_alloc(), NULL, NULL_TREE, si, TREE_TYPE, unshare_strinfo(), and verify_related_strinfos().

Referenced by strlen_pass::handle_builtin_memcpy(), strlen_pass::handle_builtin_strcat(), strlen_pass::handle_builtin_strcpy(), strlen_pass::handle_builtin_strlen(), and strlen_pass::handle_store().

◆ compare_nonzero_chars() [1/2]

static int compare_nonzero_chars ( strinfo * si,
gimple * stmt,
unsigned HOST_WIDE_INT off,
range_query * rvals )
static
Same as above but suitable also for strings with non-constant lengths.
Uses RVALS to determine length range.   

References wi::cmp(), compare_tree_int(), ggc_alloc(), irange::lower_bound(), range_query::range_of_expr(), si, irange::singleton_p(), TREE_CODE, irange::type(), TYPE_PRECISION, TYPE_SIGN, wi::uhwi(), vrange::undefined_p(), and vrange::varying_p().

◆ compare_nonzero_chars() [2/2]

static int compare_nonzero_chars ( strinfo * si,
unsigned HOST_WIDE_INT off )
static
Return:

*  +1  if SI is known to start with more than OFF nonzero characters.

*   0  if SI is known to start with exactly OFF nonzero characters.

*  -1  if SI either does not start with OFF nonzero characters
       or the relationship between the number of leading nonzero
       characters in SI and OFF is unknown.   

References compare_tree_int(), ggc_alloc(), si, and TREE_CODE.

Referenced by get_addr_stridx(), get_stridx(), get_stridx_plus_constant(), and strlen_pass::handle_store().

◆ do_invalidate()

static void do_invalidate ( basic_block dombb,
gimple * phi,
bitmap visited,
int * count )
static
Recursively call maybe_invalidate on stmts that might be executed
in between dombb and current bb and that contain a vdef.  Stop when
*count stmts are inspected, or if the whole strinfo vector has
been invalidated.   

References bitmap_set_bit, CDI_DOMINATORS, count, do_invalidate(), dominated_by_p(), ggc_alloc(), gimple_bb(), gimple_phi_arg_def(), gimple_phi_num_args(), gimple_vuse(), i, basic_block_def::index, maybe_invalidate(), NULL, SSA_NAME_DEF_STMT, laststmt_struct::stmt, and visited.

Referenced by strlen_pass::before_dom_children(), and do_invalidate().

◆ dump_strlen_info()

◆ find_equal_ptrs()

◆ fold_strstr_to_strncmp()

◆ free_strinfo()

static void free_strinfo ( strinfo * si)
inlinestatic
Decrease strinfo refcount and free it if not referenced anymore.   

References si, and strinfo_pool.

Referenced by strlen_pass::after_dom_children(), strlen_pass::before_dom_children(), maybe_invalidate(), and unshare_strinfo().

◆ get_addr_stridx()

static int get_addr_stridx ( tree exp,
gimple * stmt,
tree ptr,
unsigned HOST_WIDE_INT * offset_out,
range_query * rvals = NULL )
static
Helper function for get_stridx.  Return the strinfo index of the address
of EXP, which is available in PTR if nonnull.  If OFFSET_OUT, it is
OK to return the index for some X <= &EXP and store &EXP - X in
*OFFSET_OUT.  When RVALS is nonnull uses it to determine range
information.   

References compare_nonzero_chars(), DECL_P, decl_to_stridxlist_htab, exp(), hash_map< KeyId, Value, Traits >::get(), get_addr_base_and_unit_offset(), get_stridx_plus_constant(), get_strinfo(), ggc_alloc(), stridxlist::idx, last, stridxlist::next, NULL, stridxlist::offset, and si.

Referenced by get_stridx(), strlen_pass::handle_integral_assign(), and strlen_pass::handle_store().

◆ get_maxbound()

static tree get_maxbound ( tree ptr,
gimple * stmt,
offset_int maxlen,
pointer_query * ptr_qry )
static
Return the maximum possible length of the string PTR that's less
than MAXLEN given the size of the object of subobject it points
to at the given STMT.  MAXLEN is the maximum length of the string
determined so far.  Return null when no such maximum can be
determined.   

References DECL_SIZE_UNIT, field_at_offset(), wi::fits_shwi_p(), pointer_query::get_ref(), ggc_alloc(), NULL_TREE, RECORD_OR_UNION_TYPE_P, size_type_node, wi::to_offset(), TREE_TYPE, and wide_int_to_tree().

Referenced by get_range_strlen_dynamic().

◆ get_next_strinfo()

static strinfo * get_next_strinfo ( strinfo * si)
inlinestatic
Get the next strinfo in the chain after SI, or null if none.   

References get_strinfo(), ggc_alloc(), NULL, and si.

Referenced by strlen_pass::adjust_last_stmt(), adjust_related_strinfos(), dump_strlen_info(), get_stridx_plus_constant(), get_string_length(), and zero_length_string().

◆ get_range()

tree get_range ( tree val,
gimple * stmt,
wide_int minmax[2],
range_query * rvals )
Sets MINMAX to either the constant value or the range VAL is in
and returns either the constant value or VAL on success or null
when the range couldn't be determined.  Uses RVALS or CFUN for
range info, whichever is nonnull.   

References cfun, get_legacy_range(), get_range_query(), ggc_alloc(), NULL_TREE, range_query::range_of_expr(), wi::to_wide(), TREE_TYPE, and VR_RANGE.

Referenced by get_offset_range(), get_stridx(), known_lower(), strlen_pass::maybe_warn_overflow(), range_query::query_relation(), range_query::query_relation(), and dom_ranger::range_of_stmt().

◆ get_range_strlen_dynamic() [1/2]

void get_range_strlen_dynamic ( tree src,
gimple * stmt,
c_strlen_data * pdata,
pointer_query & ptr_qry )
Analogous to get_range_strlen but for dynamically created strings,
i.e., those created by calls to strcpy as opposed to just string
constants.
Try to obtain the range of the lengths of the string(s) referenced
by SRC, or the size of the largest array SRC refers to if the range
of lengths cannot be determined, and store all in *PDATA.  RVALS
points to the valuation engine used to calculate ranges.   

References build_all_ones_cst(), get_range_strlen_dynamic(), ggc_alloc(), size_type_node, ssize_int, and visited.

◆ get_range_strlen_dynamic() [2/2]

static bool get_range_strlen_dynamic ( tree src,
gimple * stmt,
c_strlen_data * pdata,
bitmap visited,
pointer_query * ptr_qry,
unsigned * pssa_def_max )
static
Attempt to determine the length of the string SRC.  On success, store
the length in *PDATA and return true.  Otherwise, return false.
VISITED is a bitmap of visited PHI nodes.  RVALS points to the valuation
engine used to calculate ranges.  PSSA_DEF_MAX to an SSA_NAME
assignment limit used to prevent runaway recursion.   

References build_all_ones_cst(), build_int_cst(), build_zero_cst(), DECL_P, fold_build2, get_addr_base_and_unit_offset(), get_maxbound(), get_range_strlen(), get_range_strlen_phi(), get_stridx(), get_strinfo(), get_string_length(), ggc_alloc(), stridxlist::idx, irange::lower_bound(), range_query::range_of_expr(), pointer_query::rvals, si, SIGNED, size_type_node, SSA_NAME_DEF_STMT, TREE_CODE, tree_int_cst_lt(), TREE_OPERAND, TREE_TYPE, irange::type(), TYPE_SIZE_UNIT, vrange::undefined_p(), irange::upper_bound(), vrange::varying_p(), visited, and wide_int_to_tree().

Referenced by strlen_pass::get_len_or_size(), get_range_strlen_dynamic(), and get_range_strlen_phi().

◆ get_range_strlen_phi()

◆ get_stridx()

static int get_stridx ( tree exp,
gimple * stmt,
wide_int offrng[2] = NULL,
range_query * rvals = NULL )
static
Returns string index for EXP.  When EXP is an SSA_NAME that refers
to a known strinfo with an offset and OFFRNG is non-null, sets
both elements of the OFFRNG array to the range of the offset and
returns the index of the known strinfo.  In this case the result
must not be used in for functions that modify the string.
When nonnull, uses RVALS to determine range information.   

References c_getstr(), compare_nonzero_chars(), exp(), fold_build2, fold_convert, get_addr_stridx(), get_range(), get_stridx_plus_constant(), get_strinfo(), ggc_alloc(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), i, stridxlist::idx, integer_onep(), integer_zero_node, is_gimple_assign(), NULL, offset, ptrdiff_type_node, wi::shwi(), si, sizetype, SSA_NAME_DEF_STMT, SSA_NAME_VERSION, ssa_ver_to_stridx, ssizetype, wi::to_wide(), TREE_CODE, tree_fits_shwi_p(), TREE_OPERAND, tree_to_shwi(), TREE_TYPE, TYPE_MAX_VALUE, TYPE_PRECISION, TYPE_SIZE_UNIT, and wi::zero().

Referenced by strlen_pass::before_dom_children(), strlen_pass::check_and_optimize_stmt(), strlen_pass::count_nonzero_bytes_addr(), fold_strstr_to_strncmp(), get_range_strlen_dynamic(), strlen_pass::handle_alloc_call(), strlen_pass::handle_builtin_memcpy(), strlen_pass::handle_builtin_memset(), strlen_pass::handle_builtin_strcat(), strlen_pass::handle_builtin_strchr(), strlen_pass::handle_builtin_strcpy(), strlen_pass::handle_builtin_string_cmp(), strlen_pass::handle_builtin_strlen(), strlen_pass::handle_builtin_stxncpy_strncat(), strlen_pass::handle_integral_assign(), strlen_pass::handle_pointer_plus(), strlen_pass::handle_store(), and maybe_diag_stxncpy_trunc().

◆ get_stridx_plus_constant()

◆ get_strinfo()

◆ get_string_length()

◆ is_char_type()

static bool is_char_type ( tree type)
static
Return true if TYPE corresponds to a narrow character type.   

References char_type_node, ggc_alloc(), TREE_CODE, TYPE_MODE, and TYPE_PRECISION.

Referenced by strlen_pass::handle_assign().

◆ is_strlen_related_p()

bool is_strlen_related_p ( tree src,
tree len )
Return true if LEN depends on a call to strlen(SRC) in an interesting
way.  LEN can either be an integer expression, or a pointer (to char).
When it is the latter (such as in recursive calls to self) it is
assumed to be the argument in some call to strlen() whose relationship
to SRC is being ascertained.   

References BUILT_IN_NORMAL, DECL_FUNCTION_CODE(), ggc_alloc(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_call_arg(), gimple_call_builtin_p(), gimple_call_fndecl(), INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_call(), is_strlen_related_p(), laststmt_struct::len, operand_equal_p(), SSA_NAME_DEF_STMT, TREE_CODE, TREE_TYPE, and valid_builtin_call().

Referenced by strlen_pass::handle_builtin_stxncpy_strncat(), is_strlen_related_p(), maybe_diag_stxncpy_trunc(), maybe_warn_nonstring_arg(), and strlen_pass::maybe_warn_overflow().

◆ make_pass_strlen()

gimple_opt_pass * make_pass_strlen ( gcc::context * ctxt)

References ggc_alloc().

◆ make_pass_warn_printf()

gimple_opt_pass * make_pass_warn_printf ( gcc::context * ctxt)

References ggc_alloc().

◆ maybe_diag_stxncpy_trunc()

bool maybe_diag_stxncpy_trunc ( gimple_stmt_iterator gsi,
tree src,
tree cnt,
pointer_query * ptr_qry )
Called by handle_builtin_stxncpy_strncat and by
  gimple_fold_builtin_strncpy in gimple-fold.cc.
  Check to see if the specified bound is a) equal to the size of
  the destination DST and if so, b) if it's immediately followed by
  DST[CNT - 1] = '\0'.  If a) holds and b) does not, warn.  Otherwise,
  do nothing.  Return true if diagnostic has been issued.

  The purpose is to diagnose calls to strncpy and stpncpy that do
  not nul-terminate the copy while allowing for the idiom where
  such a call is immediately followed by setting the last element
  to nul, as in:
    char a[32];
    strncpy (a, s, sizeof a);
    a[sizeof a - 1] = '\0';

References cfun, compute_objsize(), DECL_FUNCTION_CODE(), EDGE_SUCC, get_addr_base_and_unit_offset(), get_attr_nonstring_decl(), get_legacy_range(), get_range_query(), get_range_strlen(), get_stridx(), get_strinfo(), wi::geu_p(), ggc_alloc(), gimple_assign_lhs(), gimple_bb(), gimple_call_arg(), gimple_call_fndecl(), gimple_call_lhs(), gimple_or_expr_nonartificial_location(), gsi_next_nondebug(), gsi_start_bb(), gsi_stmt(), wi::gtu_p(), integer_all_onesp(), is_gimple_assign(), is_gimple_debug(), is_strlen_related_p(), known_eq, wi::leu_p(), wi::ltu_p(), wi::neg_p(), NULL, NULL_TREE, operand_equal_p(), ptrdiff_type_node, r, wi::shwi(), single_succ_p(), ssa_ver_to_stridx, laststmt_struct::stmt, wi::to_wide(), TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_MAX_VALUE, TYPE_PRECISION, VR_ANTI_RANGE, warning_at(), warning_n(), warning_suppressed_p(), and wi::zero().

Referenced by gimple_fold_builtin_strncpy(), and strlen_pass::handle_builtin_stxncpy_strncat().

◆ maybe_invalidate()

static bool maybe_invalidate ( gimple * stmt,
bool zero_write = false )
static
Invalidate string length information for strings whose length might
change due to stores in STMT, except those marked DONT_INVALIDATE.
For string-modifying statements, ZERO_WRITE is set when the statement
wrote only zeros.
Returns true if any STRIDX_TO_STRINFO entries were considered
for invalidation.   

References ao_ref_init_from_ptr_and_size(), DECL_FUNCTION_CODE(), dump_file, dump_flags, fputc(), free_strinfo(), ggc_alloc(), gimple_call_fndecl(), HOST_WIDE_INT_MAX, HOST_WIDE_INT_PRINT_UNSIGNED, i, is_gimple_call(), known_le, NULL, NULL_TREE, POINTER_TYPE_P, print_generic_expr(), print_gimple_stmt(), r, set_strinfo(), si, stmt_may_clobber_ref_p_1(), stridx_to_strinfo, TDF_DETAILS, TDF_LINENO, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, and vec_safe_iterate().

Referenced by strlen_pass::check_and_optimize_stmt(), and do_invalidate().

◆ maybe_set_strlen_range()

static tree maybe_set_strlen_range ( tree lhs,
tree src,
tree bound )
static
For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
a character array A[N] with unknown length bounded by N, and for
strnlen(), by min (N, BOUND).   

References array_ref_flexible_size_p(), DECL_SIZE_UNIT, get_base_address(), ggc_alloc(), gimple_assign_rhs1(), gimple_assign_rhs_code(), integer_zerop(), INTEGRAL_TYPE_P, is_gimple_assign(), NULL_TREE, ptrdiff_type_node, set_strlen_range(), SSA_NAME_DEF_STMT, wi::to_wide(), TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_MAX_VALUE, TYPE_SIZE_UNIT, VAR_P, and wi::zero().

Referenced by strlen_pass::handle_builtin_strlen().

◆ maybe_warn_pointless_strcmp()

static void maybe_warn_pointless_strcmp ( gimple * stmt,
HOST_WIDE_INT bound,
unsigned HOST_WIDE_INT len[2],
unsigned HOST_WIDE_INT siz )
static
Diagnose pointless calls to strcmp or strncmp STMT with string
arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
whose result is used in equality expressions that evaluate to
a constant due to one argument being longer than the size of
the other.   

References G_, ggc_alloc(), gimple_call_fndecl(), gimple_call_lhs(), gimple_location(), gimple_or_expr_nonartificial_location(), HOST_WIDE_INT_MAX, inform(), laststmt_struct::len, LOCATION_LINE, MIN, laststmt_struct::stmt, use_in_zero_equality(), and warning_at().

Referenced by strlen_pass::handle_builtin_string_cmp().

◆ new_addr_stridx()

static int new_addr_stridx ( tree exp)
static
Like new_stridx, but for ADDR_EXPR's operand instead.   

References addr_stridxptr(), exp(), gcc_assert, ggc_alloc(), max_stridx, and NULL.

Referenced by strlen_pass::handle_store().

◆ new_stridx()

◆ new_strinfo()

◆ nonzero_bytes_for_type()

static bool nonzero_bytes_for_type ( tree type,
unsigned lenrange[3],
bool * nulterm,
bool * allnul,
bool * allnonnul )
static
Set LENRANGE to the number of nonzero bytes for a store of TYPE and
clear all flags.  Return true on success and false on failure.   

References ggc_alloc(), tree_fits_uhwi_p(), tree_to_uhwi(), TYPE_SIZE_UNIT, and UINT_MAX.

Referenced by strlen_pass::count_nonzero_bytes(), and strlen_pass::count_nonzero_bytes().

◆ set_endptr_and_length()

static void set_endptr_and_length ( location_t loc,
strinfo * si,
tree endptr )
static
Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
Use LOC for folding.   

References fold_build2_loc(), fold_convert_loc(), ggc_alloc(), NULL, si, and size_type_node.

Referenced by get_string_length().

◆ set_strinfo()

◆ set_strlen_range()

tree set_strlen_range ( tree lhs,
wide_int min,
wide_int max,
tree bound )
For an LHS that is an SSA_NAME that is the result of a strlen()
call, or when BOUND is non-null, of a strnlen() call, set LHS
range info to [0, min (MAX, BOUND)] when the range includes more
than one value and return LHS.  Otherwise, when the range
[MIN, MAX] is such that MIN == MAX, return the tree representation
of (MIN). The latter allows callers to fold suitable strnlen() calls
to constants.   

References cfun, wi::cmpu(), get_range_query(), ggc_alloc(), INTEGRAL_TYPE_P, wi::ltu_p(), wi::ne_p(), NULL_TREE, r, path_range_query::range_of_expr(), set_range_info(), size_type_node, wi::to_wide(), TREE_CODE, TREE_TYPE, and wide_int_to_tree().

Referenced by gimple_fold_builtin_strlen(), strlen_pass::handle_builtin_strlen(), and maybe_set_strlen_range().

◆ strinfo_shared()

static bool strinfo_shared ( void )
inlinestatic
Return true if strinfo vector is shared with the immediate dominator.   

References NULL, stridx_to_strinfo, and vec_safe_length().

Referenced by strlen_pass::before_dom_children(), unshare_strinfo(), and unshare_strinfo_vec().

◆ unshare_strinfo()

◆ unshare_strinfo_vec()

static void unshare_strinfo_vec ( void )
static
Unshare strinfo vector that is shared with the immediate dominator.   

References gcc_assert, i, NULL, si, stridx_to_strinfo, strinfo_shared(), vec_safe_copy(), and vec_safe_iterate().

Referenced by set_strinfo().

◆ use_in_zero_equality()

gimple * use_in_zero_equality ( tree res,
bool exclusive )
Return first such statement if RES is used in statements testing its
equality to zero, and null otherwise.  If EXCLUSIVE is true, return
nonnull if and only RES is used in such expressions exclusively and
in none other.   

References FOR_EACH_IMM_USE_FAST, ggc_alloc(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_cond_code(), gimple_cond_rhs(), integer_zerop(), is_gimple_debug(), NULL, TREE_CODE, TREE_OPERAND, and USE_STMT.

Referenced by strlen_pass::handle_builtin_memcmp(), strlen_pass::handle_builtin_string_cmp(), maybe_warn_pointless_strcmp(), and simplify_builtin_call().

◆ valid_builtin_call()

static bool valid_builtin_call ( gimple * stmt)
static
Return true if STMT is a call to a builtin function with the right
arguments and attributes that should be considered for optimization
by this pass.   

References BUILT_IN_NORMAL, DECL_FUNCTION_CODE(), ggc_alloc(), gimple_call_builtin_p(), gimple_call_fndecl(), gimple_vdef(), gimple_vuse(), and NULL_TREE.

Referenced by strlen_pass::adjust_last_stmt(), strlen_pass::check_and_optimize_call(), strlen_pass::handle_builtin_memset(), and is_strlen_related_p().

◆ verify_related_strinfos()

static strinfo * verify_related_strinfos ( strinfo * origsi)
static
Return the first strinfo in the related strinfo chain
if all strinfos in between belong to the chain, otherwise NULL.   

References get_strinfo(), ggc_alloc(), NULL, and si.

Referenced by strlen_pass::adjust_last_stmt(), adjust_related_strinfos(), get_stridx_plus_constant(), get_string_length(), strlen_pass::handle_builtin_strcpy(), and zero_length_string().

◆ zero_length_string()

static strinfo * zero_length_string ( tree ptr,
strinfo * chainsi )
static

◆ zero_length_string_p()

static bool zero_length_string_p ( strinfo * si)
inlinestatic
Return true if SI is known to be a zero-length string.   

References integer_zerop(), and si.

Referenced by strlen_pass::adjust_last_stmt(), get_stridx_plus_constant(), and zero_length_string().

Variable Documentation

◆ decl_to_stridxlist_htab

decl_to_stridxlist_htab_t* decl_to_stridxlist_htab
static

◆ laststmt

◆ max_stridx

int max_stridx
static
Number of currently active string indexes plus one.   

Referenced by dump_strlen_info(), new_addr_stridx(), and new_stridx().

◆ ssa_ver_to_stridx

vec<int> ssa_ver_to_stridx
static
String length optimization
   Copyright (C) 2011-2024 Free Software Foundation, Inc.
   Contributed by Jakub Jelinek <jakub@redhat.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
A vector indexed by SSA_NAME_VERSION.  0 means unknown, positive value
is an index into strinfo vector, negative value stands for
string length of a string literal (~strlen).   

Referenced by strlen_pass::before_dom_children(), strlen_pass::check_and_optimize_stmt(), dump_strlen_info(), find_equal_ptrs(), get_stridx(), get_stridx_plus_constant(), strlen_pass::handle_builtin_memcpy(), strlen_pass::handle_builtin_strcpy(), strlen_pass::handle_pointer_plus(), maybe_diag_stxncpy_trunc(), new_stridx(), and zero_length_string().

◆ stridx_obstack

struct obstack stridx_obstack
static
Obstack for struct stridxlist and struct decl_stridxlist_map.   

Referenced by addr_stridxptr().

◆ stridx_to_strinfo

vec<strinfo *, va_heap, vl_embed>* stridx_to_strinfo
static
Vector mapping positive string indexes to strinfo, for the
current basic block.  The first pointer in the vector is special,
it is either NULL, meaning the vector isn't shared, or it is
a basic block pointer to the owner basic_block if shared.
If some other bb wants to modify the vector, the vector needs
to be unshared first, and only the owner bb is supposed to free it.   

Referenced by strlen_pass::after_dom_children(), strlen_pass::before_dom_children(), dump_strlen_info(), get_strinfo(), maybe_invalidate(), set_strinfo(), strinfo_shared(), and unshare_strinfo_vec().

◆ strinfo_pool

object_allocator< strinfo > strinfo_pool("strinfo pool") ( "strinfo pool" )
static
Pool for allocating strinfo_struct entries.   

Referenced by free_strinfo(), and new_strinfo().

◆ strlen_optimize

bool strlen_optimize
static
Set to true to optimize, false when just checking.   

Referenced by strlen_pass::check_and_optimize_call(), and strlen_pass::check_and_optimize_stmt().

◆ strlen_to_stridx