GCC Middle and Back End API Reference
tree-ssa-uninit.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 "ssa.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
#include "tree-cfg.h"
#include "cfghooks.h"
#include "attribs.h"
#include "builtins.h"
#include "calls.h"
#include "gimple-range.h"
#include "gimple-predicate-analysis.h"
#include "domwalk.h"
#include "tree-ssa-sccvn.h"
#include "cfganal.h"
Include dependency graph for tree-ssa-uninit.cc:

Data Structures

struct  check_defs_data
struct  wlimits
struct  uninit_undef_val_t


#define MASK_FIRST_SET_BIT(mask)   get_mask_first_set_bit (mask)


static int get_mask_first_set_bit (unsigned mask)
static bool has_undefined_value_p (tree t)
static bool get_no_uninit_warning (tree expr)
static void set_no_uninit_warning (tree expr)
static bool uninit_undefined_value_p (tree t)
static void warn_uninit (opt_code opt, tree t, tree var, gimple *context, location_t phi_arg_loc=UNKNOWN_LOCATION)
static bool builtin_call_nomodifying_p (gimple *stmt)
static void maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
static bool check_defs (ao_ref *ref, tree vdef, void *data_)
static tree maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, wlimits &wlims)
static void maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
static void warn_uninit_phi_uses (basic_block bb)
static void warn_uninitialized_vars (bool wmaybe_uninit)
static bool can_skip_redundant_opnd (tree opnd, gimple *phi)
static unsigned compute_uninit_opnds_pos (gphi *phi)
static int cand_cmp (const void *a, const void *b, void *data)
static gimplefind_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
static void warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
static bool gate_warn_uninitialized (void)
gimple_opt_passmake_pass_late_warn_uninitialized (gcc::context *ctxt)
static unsigned int execute_early_warn_uninitialized (struct function *fun)
gimple_opt_passmake_pass_early_warn_uninitialized (gcc::context *ctxt)


static hash_set< tree > * possibly_undefined_names
static hash_map< gphi *, uninit_analysis::func_t::phi_arg_set_t > * defined_args

Macro Definition Documentation


Predicate aware uninitialized variable warning.
   Copyright (C) 2001-2024 Free Software Foundation, Inc.
   Contributed by Xinliang David Li <davidxl@google.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
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


#define MASK_FIRST_SET_BIT ( mask)    get_mask_first_set_bit (mask)

Referenced by warn_uninitialized_phi().

Function Documentation

◆ builtin_call_nomodifying_p()

static bool builtin_call_nomodifying_p ( gimple * stmt)
Return true if STMT is a call to built-in function all of whose
by-reference arguments are const-qualified (i.e., the function can
be assumed not to modify them).   

References BUILT_IN_NORMAL, FOREACH_FUNCTION_ARGS, gimple_call_arg(), gimple_call_builtin_p(), gimple_call_fndecl(), gimple_call_num_args(), POINTER_TYPE_P, TREE_TYPE, TYPE_READONLY, and VOID_TYPE_P.

Referenced by check_defs().

◆ can_skip_redundant_opnd()

static bool can_skip_redundant_opnd ( tree opnd,
gimple * phi )
Checks if the operand OPND of PHI is defined by
another phi with one operand defined by this PHI,
but the rest operands are all defined.  If yes,
returns true to skip this operand as being
redundant.  Can be enhanced to be more general.   

References gimple_phi_arg_def(), gimple_phi_num_args(), gimple_phi_result(), i, SSA_NAME_DEF_STMT, TREE_CODE, and uninit_undefined_value_p().

Referenced by compute_uninit_opnds_pos().

◆ cand_cmp()

static int cand_cmp ( const void * a,
const void * b,
void * data )
sort helper for find_uninit_use.   

References a, b, gimple_bb(), and basic_block_def::index.

Referenced by find_uninit_use().

◆ check_defs()

◆ compute_uninit_opnds_pos()

static unsigned compute_uninit_opnds_pos ( gphi * phi)

◆ execute_early_warn_uninitialized()

static unsigned int execute_early_warn_uninitialized ( struct function * fun)

◆ find_uninit_use()

static gimple * find_uninit_use ( gphi * phi,
unsigned uninit_opnds,
int * bb_to_rpo )
Searches through all uses of a potentially
uninitialized variable defined by PHI and returns a use
statement if the use is not properly guarded.  It returns
NULL if all uses are guarded.  UNINIT_OPNDS is a bitvector
holding the position(s) of uninit PHI operands.   

References hash_set< KeyId, Lazy, Traits >::add(), cand_cmp(), defined_args, dump_file, dump_flags, dyn_cast(), FOR_EACH_IMM_USE_FAST, gimple_assign_lhs(), gimple_assign_ssa_name_copy_p(), gimple_bb(), gimple_phi_arg_edge(), gimple_phi_result(), basic_block_def::index, is_gimple_debug(), uninit_analysis::is_use_guarded(), MASK_SET_BIT, uninit_analysis::func_t::max_phi_args, NULL, PHI_ARG_INDEX_FROM_USE, possibly_undefined_names, print_gimple_stmt(), single_imm_use(), TDF_DETAILS, USE_FROM_PTR, and USE_STMT.

Referenced by warn_uninitialized_phi().

◆ gate_warn_uninitialized()

static bool gate_warn_uninitialized ( void )

◆ get_mask_first_set_bit()

static int get_mask_first_set_bit ( unsigned mask)
Returns the first bit position (starting from LSB)
in mask that is non zero.  Returns -1 if the mask is empty.   

◆ get_no_uninit_warning()

static bool get_no_uninit_warning ( tree expr)
Return true if EXPR should suppress either uninitialized warning.   

References warning_suppressed_p().

Referenced by maybe_warn_operand(), maybe_warn_read_write_only(), uninit_undefined_value_p(), and warn_uninit().

◆ has_undefined_value_p()

static bool has_undefined_value_p ( tree t)
Return true if T, an SSA_NAME, has an undefined value.   

References hash_set< KeyId, Lazy, Traits >::contains(), possibly_undefined_names, and ssa_undefined_value_p().

Referenced by uninit_undefined_value_p(), and warn_uninit().

◆ make_pass_early_warn_uninitialized()

gimple_opt_pass * make_pass_early_warn_uninitialized ( gcc::context * ctxt)

◆ make_pass_late_warn_uninitialized()

gimple_opt_pass * make_pass_late_warn_uninitialized ( gcc::context * ctxt)

◆ maybe_warn_operand()

◆ maybe_warn_pass_by_reference()

◆ maybe_warn_read_write_only()

static void maybe_warn_read_write_only ( tree fndecl,
gimple * stmt,
tree arg,
tree ptr )
If ARG is a FNDECL parameter declared with attribute access none or
write_only issue a warning for its read access via PTR.   

References access_none, access_write_only, DECL_ARGUMENTS, DECL_SOURCE_LOCATION, hash_map< KeyId, Value, Traits >::get(), get_no_uninit_warning(), gimple_location(), inform(), init_attr_rdwr_indices(), suppress_warning(), TREE_CHAIN, TREE_STRING_POINTER, TREE_TYPE, TYPE_ATTRIBUTES, and warning_at().

Referenced by maybe_warn_operand().

◆ set_no_uninit_warning()

static void set_no_uninit_warning ( tree expr)
Suppress both uninitialized warnings for EXPR.   

References suppress_warning().

Referenced by maybe_warn_operand().

◆ uninit_undefined_value_p()

static bool uninit_undefined_value_p ( tree t)
Like has_undefined_value_p, but don't return true if the no-warning
bit is set on SSA_NAME_VAR for either uninit warning.   

References get_no_uninit_warning(), has_undefined_value_p(), and SSA_NAME_VAR.

Referenced by can_skip_redundant_opnd(), and compute_uninit_opnds_pos().

◆ warn_uninit()

static void warn_uninit ( opt_code opt,
tree t,
tree var,
gimple * context,
location_t phi_arg_loc = UNKNOWN_LOCATION )
Emit warnings for uninitialized variables.  This is done in two passes.

The first pass notices real uses of SSA names with undefined values.
Such uses are unconditionally uninitialized, and we can be certain that
such a use is a mistake.  This pass is run before most optimizations,
so that we catch as many as we can.

The second pass follows PHI nodes to find uses that are potentially
uninitialized.  In this case we can't necessarily prove that the use
is really uninitialized.  This pass is run after most optimizations,
so that we thread as many jumps and possible, and delete as much dead
code as possible, in order to reduce false positives.  We also look
again for plain uninitialized variables, since optimization may have
changed conditionally uninitialized to unconditionally uninitialized.   
Emit warning OPT for variable VAR at the point in the program where
the SSA_NAME T is being used uninitialized.  The warning text is in
MSGID and STMT is the statement that does the uninitialized read.
PHI_ARG_LOC is the location of the PHI argument if T and VAR are one,
or UNKNOWN_LOCATION otherwise.   

References DECL_NAME, DECL_SOURCE_LOCATION, DECL_UID, dyn_cast(), gcc_assert, get_no_uninit_warning(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_single_p(), gimple_call_arg(), gimple_call_internal_p(), gimple_has_location(), gimple_location(), has_undefined_value_p(), HOST_BITS_PER_INT, IDENTIFIER_POINTER, inform(), is_gimple_assign(), NULL, NULL_TREE, SSA_NAME_DEF_STMT, SSA_NAME_VAR, suppress_warning(), TREE_CODE, TREE_OPERAND, TREE_STRING_POINTER, UNKNOWN_LOCATION, VAR_P, warning_at(), warning_suppressed_p(), and zerop().

Referenced by warn_uninit_phi_uses(), warn_uninitialized_phi(), and warn_uninitialized_vars().

◆ warn_uninit_phi_uses()

◆ warn_uninitialized_phi()

static void warn_uninitialized_phi ( gphi * phi,
unsigned uninit_opnds,
int * bb_to_rpo )
Look for inputs to PHI that are SSA_NAMEs that have empty definitions
and gives warning if there exists a runtime path from the entry to a
use of the PHI def that does not contain a definition.  In other words,
the warning is on the real use.  The more dead paths that can be pruned
by the compiler, the fewer false positives the warning is.   

References compute_uninit_opnds_pos(), dump_file, dump_flags, dyn_cast(), find_uninit_use(), gimple_phi_arg_def(), gimple_phi_arg_has_location(), gimple_phi_arg_location(), gimple_phi_num_args(), MASK_FIRST_SET_BIT, print_gimple_stmt(), SSA_NAME_DEF_STMT, SSA_NAME_VAR, TDF_DETAILS, TREE_CODE, UNKNOWN_LOCATION, and warn_uninit().

◆ warn_uninitialized_vars()

Variable Documentation

◆ defined_args

◆ possibly_undefined_names

hash_set<tree>* possibly_undefined_names
This implements the pass that does predicate aware warning on uses of
possibly uninitialized variables.  The pass first collects the set of
possibly uninitialized SSA names.  For each such name, it walks through
all its immediate uses.  For each immediate use, it rebuilds the condition
expression (the predicate) that guards the use.  The predicate is then
examined to see if the variable is always defined under that same condition.
This is done either by pruning the unrealizable paths that lead to the
default definitions or by checking if the predicate set that guards the
defining paths is a superset of the use predicate.   
Pointer set of potentially undefined ssa names, i.e.,
ssa names that are defined by phi with operands that
are not defined or potentially undefined.   

Referenced by find_uninit_use(), and has_undefined_value_p().