GCC Middle and Back End API Reference
gimple-ssa-warn-access.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "builtins.h"
#include "diagnostic.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "gimple-ssa-warn-access.h"
#include "gimple-ssa-warn-restrict.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "langhooks.h"
#include "memmodel.h"
#include "target.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-cfg.h"
#include "tree-object-size.h"
#include "tree-ssa-strlen.h"
#include "calls.h"
#include "cfganal.h"
#include "intl.h"
#include "gimple-range.h"
#include "stringpool.h"
#include "attribs.h"
#include "demangle.h"
#include "attr-fnspec.h"
#include "pointer-query.h"
Include dependency graph for gimple-ssa-warn-access.cc:

Macros

#define INCLUDE_STRING
 
#define MEMMODEL_PAIR(val, str)    { MEMMODEL_ ## val, "memory_order_" str }
 
#define BUILTIN_ACCESS_SIZE_FNSPEC(N)
 

Functions

static location_t has_location (const_tree x)
 
static location_t get_location (const gimple *stmt)
 
static location_t get_location (tree x)
 
static tree get_callee_fndecl (const gimple *stmt)
 
static unsigned call_nargs (const gimple *stmt)
 
static unsigned call_nargs (const_tree expr)
 
static tree call_arg (const gimple *stmt, unsigned argno)
 
static tree call_arg (tree expr, unsigned argno)
 
template<class GimpleOrTree >
static void warn_string_no_nul (location_t loc, GimpleOrTree expr, const char *fname, tree arg, tree decl, tree size, bool exact, const wide_int bndrng[2])
 
void warn_string_no_nul (location_t loc, gimple *stmt, const char *fname, tree arg, tree decl, tree size, bool exact, const wide_int bndrng[2])
 
void warn_string_no_nul (location_t loc, tree expr, const char *fname, tree arg, tree decl, tree size, bool exact, const wide_int bndrng[2])
 
tree unterminated_array (tree exp, tree *size, bool *exact)
 
template<class GimpleOrTree >
static bool check_nul_terminated_array (GimpleOrTree expr, tree src, tree bound)
 
bool check_nul_terminated_array (gimple *stmt, tree src, tree bound)
 
bool check_nul_terminated_array (tree expr, tree src, tree bound)
 
template<class GimpleOrTree >
static bool maybe_warn_nonstring_arg (tree fndecl, GimpleOrTree exp)
 
bool maybe_warn_nonstring_arg (tree fndecl, gimple *stmt)
 
bool maybe_warn_nonstring_arg (tree fndecl, tree expr)
 
template<class GimpleOrTree >
static bool maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func, tree bndrng[2], tree size, const access_data *pad)
 
bool maybe_warn_for_bound (opt_code opt, location_t loc, gimple *stmt, tree func, tree bndrng[2], tree size, const access_data *pad)
 
bool maybe_warn_for_bound (opt_code opt, location_t loc, tree expr, tree func, tree bndrng[2], tree size, const access_data *pad)
 
template<class GimpleOrTree >
static bool warn_for_access (location_t loc, tree func, GimpleOrTree exp, int opt, tree range[2], tree size, bool write, bool read, bool maybe)
 
static bool warn_for_access (location_t loc, tree func, gimple *stmt, int opt, tree range[2], tree size, bool write, bool read, bool maybe)
 
static bool warn_for_access (location_t loc, tree func, tree expr, int opt, tree range[2], tree size, bool write, bool read, bool maybe)
 
static void get_size_range (range_query *query, tree bound, gimple *stmt, tree range[2], int flags, const offset_int bndrng[2])
 
template<class GimpleOrTree >
static bool check_access (GimpleOrTree exp, tree dstwrite, tree maxread, tree srcstr, tree dstsize, access_mode mode, const access_data *pad, range_query *rvals)
 
static bool check_access (gimple *stmt, tree dstwrite, tree maxread, tree srcstr, tree dstsize, access_mode mode, const access_data *pad, range_query *rvals)
 
bool check_access (tree expr, tree dstwrite, tree maxread, tree srcstr, tree dstsize, access_mode mode, const access_data *pad)
 
static bool fndecl_alloc_p (tree fndecl, bool all_alloc)
 
static bool gimple_call_alloc_p (gimple *stmt, bool all_alloc=false)
 
static bool new_delete_mismatch_p (const demangle_component &newc, const demangle_component &delc)
 
static bool new_delete_mismatch_p (tree new_decl, tree delete_decl)
 
static bool matching_alloc_calls_p (tree alloc_decl, tree dealloc_decl)
 
static bool matching_alloc_calls_p (gimple *alloc, tree dealloc_decl)
 
static bool warn_dealloc_offset (location_t loc, gimple *call, const access_ref &aref)
 
gimple_opt_passmake_pass_warn_access (gcc::context *ctxt)
 

Macro Definition Documentation

◆ BUILTIN_ACCESS_SIZE_FNSPEC

#define BUILTIN_ACCESS_SIZE_FNSPEC ( N)

◆ INCLUDE_STRING

#define INCLUDE_STRING
Pass to detect and issue warnings for invalid accesses, including
invalid or mismatched allocation/deallocation calls.

Copyright (C) 2020-2024 Free Software Foundation, Inc.
Contributed by Martin Sebor <msebor@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/>.   

◆ MEMMODEL_PAIR

#define MEMMODEL_PAIR ( val,
str )    { MEMMODEL_ ## val, "memory_order_" str }

Function Documentation

◆ call_arg() [1/2]

static tree call_arg ( const gimple * stmt,
unsigned argno )
inlinestatic

References gimple_call_arg().

Referenced by maybe_warn_nonstring_arg().

◆ call_arg() [2/2]

static tree call_arg ( tree expr,
unsigned argno )
inlinestatic

References CALL_EXPR_ARG.

◆ call_nargs() [1/2]

static unsigned call_nargs ( const gimple * stmt)
inlinestatic

◆ call_nargs() [2/2]

static unsigned call_nargs ( const_tree expr)
inlinestatic

References call_expr_nargs.

◆ check_access() [1/3]

static bool check_access ( gimple * stmt,
tree dstwrite,
tree maxread,
tree srcstr,
tree dstsize,
access_mode mode,
const access_data * pad,
range_query * rvals )
static

References ggc_alloc().

◆ check_access() [2/3]

template<class GimpleOrTree >
static bool check_access ( GimpleOrTree exp,
tree dstwrite,
tree maxread,
tree srcstr,
tree dstsize,
access_mode mode,
const access_data * pad,
range_query * rvals )
static
Try to verify that the sizes and lengths of the arguments to a string
manipulation function given by EXP are within valid bounds and that
the operation does not lead to buffer overflow or read past the end.
Arguments other than EXP may be null.  When non-null, the arguments
have the following meaning:
DST is the destination of a copy call or NULL otherwise.
SRC is the source of a copy call or NULL otherwise.
DSTWRITE is the number of bytes written into the destination obtained
from the user-supplied size argument to the function (such as in
memcpy(DST, SRCs, DSTWRITE) or strncpy(DST, DRC, DSTWRITE).
MAXREAD is the user-supplied bound on the length of the source sequence
(such as in strncat(d, s, N).  It specifies the upper limit on the number
of bytes to write.  If NULL, it's taken to be the same as DSTWRITE.
SRCSTR is the source string (such as in strcpy(DST, SRC)) when the
expression EXP is a string function call (as opposed to a memory call
like memcpy).  As an exception, SRCSTR can also be an integer denoting
the precomputed size of the source string or object (for functions like
memcpy).
DSTSIZE is the size of the destination object.

When DSTWRITE is null LEN is checked to verify that it doesn't exceed
SIZE_MAX.

WRITE is true for write accesses, READ is true for reads.  Both are
false for simple size checks in calls to functions that neither read
from nor write to the region.

When nonnull, PAD points to a more detailed description of the access.

If the call is successfully verified as safe return true, otherwise
return false.   

References access_read_only, access_read_write, access_write_only, check_nul_terminated_array(), access_data::dst, access_data::dst_bndrng, exp(), fndecl_built_in_p(), fold_build2, get_callee_fndecl(), get_location(), get_range_strlen(), get_size_range(), ggc_alloc(), access_ref::inform_access(), integer_all_onesp(), integer_zerop(), max_object_size(), maybe_warn_for_bound(), maybe_warn_nonstring_arg(), access_data::mode, NULL, NULL_TREE, access_ref::offrng, access_ref::parmarray, POINTER_TYPE_P, access_ref::ref, size_one_node, access_ref::size_remaining(), size_type_node, size_zero_node, sizetype, access_ref::sizrng, SR_ALLOW_ZERO, access_data::src, access_data::src_bndrng, access_data::stmt, suppress_warning(), TREE_CODE, tree_fits_uhwi_p(), tree_int_cst_le(), tree_int_cst_lt(), TREE_TYPE, warn_for_access(), warning_at(), warning_suppressed_p(), and wide_int_to_tree().

Referenced by check_strncat_sizes(), expand_builtin_memory_chk(), maybe_emit_chk_warning(), and maybe_emit_sprintf_chk_warning().

◆ check_access() [3/3]

bool check_access ( tree expr,
tree dstwrite,
tree maxread,
tree srcstr,
tree dstsize,
access_mode mode,
const access_data * pad )

References ggc_alloc().

◆ check_nul_terminated_array() [1/3]

bool check_nul_terminated_array ( gimple * stmt,
tree src,
tree bound )

References ggc_alloc().

◆ check_nul_terminated_array() [2/3]

template<class GimpleOrTree >
static bool check_nul_terminated_array ( GimpleOrTree expr,
tree src,
tree bound )
static
For a call EXPR (which may be null) that expects a string argument
SRC as an argument, returns false if SRC is a character array with
no terminating NUL.  When nonnull, BOUND is the number of characters
in which to expect the terminating NUL.  When EXPR is nonnull also
issues a warning.   

References cfun, get_location(), get_range_query(), ggc_alloc(), wi::leu_p(), wi::lt_p(), NULL, r, path_range_query::range_of_expr(), wi::to_wide(), TREE_TYPE, UNSIGNED, unterminated_array(), and warn_string_no_nul().

Referenced by check_access(), fold_builtin_strcspn(), fold_builtin_strspn(), gimple_fold_builtin_strchr(), gimple_fold_builtin_strstr(), strlen_pass::handle_builtin_strchr(), and strlen_pass::handle_builtin_string_cmp().

◆ check_nul_terminated_array() [3/3]

bool check_nul_terminated_array ( tree expr,
tree src,
tree bound = NULL_TREE )
Pass to detect and issue warnings for invalid accesses, including
invalid or mismatched allocation/deallocation calls.

Copyright (C) 2020-2024 Free Software Foundation, Inc.
Contributed by Martin Sebor <msebor@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/>.   

References ggc_alloc().

◆ fndecl_alloc_p()

static bool fndecl_alloc_p ( tree fndecl,
bool all_alloc )
static
Return true if STMT is a call to an allocation function.  Unless
ALL_ALLOC is set, consider only functions that return dynamically
allocated objects.  Otherwise return true even for all forms of
alloca (including VLA).   

References BUILT_IN_NORMAL, DECL_ATTRIBUTES, DECL_FUNCTION_CODE(), DECL_IS_OPERATOR_NEW_P, fndecl_built_in_p(), ggc_alloc(), lookup_attribute(), TREE_CHAIN, and TREE_VALUE.

Referenced by gimple_call_alloc_p().

◆ get_callee_fndecl()

◆ get_location() [1/2]

static location_t get_location ( const gimple * stmt)
inlinestatic

◆ get_location() [2/2]

static location_t get_location ( tree x)
inlinestatic
Return the associated location of tree node X.   

References DECL_P, DECL_SOURCE_LOCATION, EXPR_LOCATION, EXPR_P, and UNKNOWN_LOCATION.

◆ get_size_range()

static void get_size_range ( range_query * query,
tree bound,
gimple * stmt,
tree range[2],
int flags,
const offset_int bndrng[2] )
static
Helper to set RANGE to the range of BOUND if it's nonnull, bounded
by BNDRNG if nonnull and valid.   

References get_size_range(), ggc_alloc(), HOST_WIDE_INT_M1U, r, sizetype, wi::to_offset(), TREE_CODE, and wide_int_to_tree().

Referenced by check_access(), get_size_range(), and maybe_warn_nonstring_arg().

◆ gimple_call_alloc_p()

static bool gimple_call_alloc_p ( gimple * stmt,
bool all_alloc = false )
static
Return true if STMT is a call to an allocation function.  A wrapper
around fndecl_alloc_p.   

References fndecl_alloc_p(), ggc_alloc(), and gimple_call_fndecl().

◆ has_location()

static location_t has_location ( const_tree x)
inlinestatic
Return true if tree node X has an associated location.   

References DECL_P, DECL_SOURCE_LOCATION, EXPR_HAS_LOCATION, EXPR_P, and UNKNOWN_LOCATION.

Referenced by maybe_warn_for_bound().

◆ make_pass_warn_access()

gimple_opt_pass * make_pass_warn_access ( gcc::context * ctxt)
Return a new instance of the pass.   

References ggc_alloc().

◆ matching_alloc_calls_p() [1/2]

static bool matching_alloc_calls_p ( gimple * alloc,
tree dealloc_decl )
static
Return true if DEALLOC_DECL is a function suitable to deallocate
objects allocated by the ALLOC call.   

References ggc_alloc(), gimple_call_fndecl(), and matching_alloc_calls_p().

◆ matching_alloc_calls_p() [2/2]

static bool matching_alloc_calls_p ( tree alloc_decl,
tree dealloc_decl )
static
ALLOC_DECL and DEALLOC_DECL are pair of allocation and deallocation
functions.  Return true if the latter is suitable to deallocate objects
allocated by calls to the former.   

References alloc_builtin(), BUILT_IN_NORMAL, DECL_ATTRIBUTES, DECL_FUNCTION_CODE(), DECL_IS_OPERATOR_DELETE_P, DECL_IS_OPERATOR_NEW_P, DECL_NAME, DECL_P, fndecl_built_in_p(), gcc_checking_assert, ggc_alloc(), lookup_attribute(), new_delete_mismatch_p(), none, NULL_TREE, TREE_CHAIN, and TREE_VALUE.

Referenced by matching_alloc_calls_p().

◆ maybe_warn_for_bound() [1/3]

bool maybe_warn_for_bound ( opt_code opt,
location_t loc,
gimple * stmt,
tree func,
tree bndrng[2],
tree size,
const access_data * pad )

References ggc_alloc().

◆ maybe_warn_for_bound() [2/3]

template<class GimpleOrTree >
static bool maybe_warn_for_bound ( opt_code opt,
location_t loc,
GimpleOrTree exp,
tree func,
tree bndrng[2],
tree size,
const access_data * pad )
static

◆ maybe_warn_for_bound() [3/3]

bool maybe_warn_for_bound ( opt_code opt,
location_t loc,
tree expr,
tree func,
tree bndrng[2],
tree size,
const access_data * pad )

References ggc_alloc().

◆ maybe_warn_nonstring_arg() [1/3]

bool maybe_warn_nonstring_arg ( tree fndecl,
gimple * stmt )

References ggc_alloc().

◆ maybe_warn_nonstring_arg() [2/3]

◆ maybe_warn_nonstring_arg() [3/3]

bool maybe_warn_nonstring_arg ( tree fndecl,
tree expr )

References ggc_alloc().

◆ new_delete_mismatch_p() [1/2]

static bool new_delete_mismatch_p ( const demangle_component & newc,
const demangle_component & delc )
static
Return true if DELC doesn't refer to an operator delete that's
suitable to call with a pointer returned from the operator new
described by NEWC.   

References free(), ggc_alloc(), and new_delete_mismatch_p().

Referenced by matching_alloc_calls_p(), new_delete_mismatch_p(), and new_delete_mismatch_p().

◆ new_delete_mismatch_p() [2/2]

static bool new_delete_mismatch_p ( tree new_decl,
tree delete_decl )
static
Return true if DELETE_DECL is an operator delete that's not suitable
to call with a pointer returned from NEW_DECL.   

References DECL_ASSEMBLER_NAME, free(), ggc_alloc(), IDENTIFIER_POINTER, new_delete_mismatch_p(), NULL, and valid_new_delete_pair_p().

◆ unterminated_array()

tree unterminated_array ( tree exp,
tree * size,
bool * exact )
If EXP refers to an unterminated constant character array return
the declaration of the object of which the array is a member or
element and if SIZE is not null, set *SIZE to the size of
the unterminated array and set *EXACT if the size is exact or
clear it otherwise.  Otherwise return null.   

References c_strlen(), exp(), fold_build2, fold_convert, ggc_alloc(), NULL_TREE, ssizetype, TREE_CODE, and TREE_OPERAND.

Referenced by check_nul_terminated_array(), expand_builtin_strnlen(), and gimple_fold_builtin_stpcpy().

◆ warn_dealloc_offset()

static bool warn_dealloc_offset ( location_t loc,
gimple * call,
const access_ref & aref )
static
Diagnose a call EXP to deallocate a pointer referenced by AREF if it
includes a nonzero offset.  Such a pointer cannot refer to the beginning
of an allocated object.  A negative offset may refer to it only if
the target pointer is unknown.   

References DECL_IS_OPERATOR_DELETE_P, DECL_IS_OPERATOR_NEW_P, DECL_IS_REPLACEABLE_OPERATOR, DECL_P, wi::fits_shwi_p(), get_location(), ggc_alloc(), gimple_call_fndecl(), gimple_call_fntype(), inform(), is_gimple_call(), SSA_NAME_DEF_STMT, TREE_CODE, and warning_at().

◆ warn_for_access() [1/3]

static bool warn_for_access ( location_t loc,
tree func,
gimple * stmt,
int opt,
tree range[2],
tree size,
bool write,
bool read,
bool maybe )
static

References ggc_alloc().

◆ warn_for_access() [2/3]

template<class GimpleOrTree >
static bool warn_for_access ( location_t loc,
tree func,
GimpleOrTree exp,
int opt,
tree range[2],
tree size,
bool write,
bool read,
bool maybe )
static
For an expression EXP issue an access warning controlled by option OPT
with access to a region SIZE bytes in size in the RANGE of sizes.
WRITE is true for a write access, READ for a read access, neither for
call that may or may not perform an access but for which the range
is expected to valid.
Returns true when a warning has been issued.   

References exp(), G_, ggc_alloc(), suppress_warning(), tree_int_cst_equal(), tree_int_cst_sign_bit(), tree_to_uhwi(), warning_at(), and warning_n().

Referenced by check_access().

◆ warn_for_access() [3/3]

static bool warn_for_access ( location_t loc,
tree func,
tree expr,
int opt,
tree range[2],
tree size,
bool write,
bool read,
bool maybe )
static

References ggc_alloc().

◆ warn_string_no_nul() [1/3]

void warn_string_no_nul ( location_t loc,
gimple * stmt,
const char * fname,
tree arg,
tree decl,
tree size,
bool exact,
const wide_int bndrng[2] )

References ggc_alloc().

◆ warn_string_no_nul() [2/3]

template<class GimpleOrTree >
static void warn_string_no_nul ( location_t loc,
GimpleOrTree expr,
const char * fname,
tree arg,
tree decl,
tree size,
bool exact,
const wide_int bndrng[2] )
static
For a call EXPR at LOC to a function FNAME that expects a string
in the argument ARG, issue a diagnostic due to it being a called
with an argument that is a character array with no terminating
NUL.  SIZE is the EXACT size of the array, and BNDRNG the number
of characters in which the NUL is expected.  Either EXPR or FNAME
may be null but noth both.  SIZE may be null when BNDRNG is null.   

References expansion_point_location_if_in_system_header(), G_, get_callee_fndecl(), get_location(), ggc_alloc(), inform(), wi::ltu_p(), max_object_size(), suppress_warning(), wi::to_wide(), warning_at(), and warning_suppressed_p().

Referenced by check_nul_terminated_array(), fold_builtin_strlen(), gimple_fold_builtin_stpcpy(), and gimple_fold_builtin_strcpy().

◆ warn_string_no_nul() [3/3]

void warn_string_no_nul ( location_t loc,
tree expr,
const char * fname,
tree arg,
tree decl,
tree size,
bool exact,
const wide_int bndrng[2] )

References ggc_alloc().