/* Predicate aware uninitialized variable warning.
   Copyright (C) 2001-2022 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
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/>.  */

#define INCLUDE_STRING
#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"

/* 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.  */
static hash_set<tree> *possibly_undefined_names;
static hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t> *defined_args;

/* Returns the first bit position (starting from LSB)
   in mask that is non zero.  Returns -1 if the mask is empty.  */
static int
get_mask_first_set_bit (unsigned mask)
{
  int pos = 0;
  if (mask == 0)
    return -1;

  while ((mask & (1 << pos)) == 0)
    pos++;

  return pos;
}
#define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)

/* Return true if T, an SSA_NAME, has an undefined value.  */
static bool
has_undefined_value_p (tree t)
{
  return (ssa_undefined_value_p (t)
	  || (possibly_undefined_names
	      && possibly_undefined_names->contains (t)));
}

/* Return true if EXPR should suppress either uninitialized warning.  */

static inline bool
get_no_uninit_warning (tree expr)
{
  return warning_suppressed_p (expr, OPT_Wuninitialized);
}

/* Suppress both uninitialized warnings for EXPR.  */

static inline void
set_no_uninit_warning (tree expr)
{
  suppress_warning (expr, OPT_Wuninitialized);
}

/* 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.  */

static inline bool
uninit_undefined_value_p (tree t)
{
  if (!has_undefined_value_p (t))
    return false;
  if (!SSA_NAME_VAR (t))
    return true;
  return !get_no_uninit_warning (SSA_NAME_VAR (t));
}

/* 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.  */

static void
warn_uninit (opt_code opt, tree t, tree var, gimple *context,
	     location_t phi_arg_loc = UNKNOWN_LOCATION)
{
  /* Bail if the value isn't provably uninitialized.  */
  if (!has_undefined_value_p (t))
    return;

  /* Ignore COMPLEX_EXPR as initializing only a part of a complex
     turns in a COMPLEX_EXPR with the not initialized part being
     set to its previous (undefined) value.  */
  if (is_gimple_assign (context)
      && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
    return;

  /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
     .DEFERRED_INIT.  This is for handling the following case correctly:

  1 typedef _Complex float C;
  2 C foo (int cond)
  3 {
  4   C f;
  5   __imag__ f = 0;
  6   if (cond)
  7     {
  8       __real__ f = 1;
  9       return f;
 10     }
 11   return f;
 12 }

    with -ftrivial-auto-var-init, compiler will insert the following
    artificial initialization at line 4:
  f = .DEFERRED_INIT (f, 2);
  _1 = REALPART_EXPR <f>;

    without the following special handling, _1 = REALPART_EXPR <f> will
    be treated as the uninitialized use point, which is incorrect. (the
    real uninitialized use point is at line 11).  */
  if (is_gimple_assign (context)
      && (gimple_assign_rhs_code (context) == REALPART_EXPR
	  || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
    {
      tree v = gimple_assign_rhs1 (context);
      if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
	  && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
				     IFN_DEFERRED_INIT))
	return;
    }

  /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
     can return true if the def stmt of an anonymous SSA_NAME is
     1. A COMPLEX_EXPR created for conversion from scalar to complex.  Use the
     underlying var of the COMPLEX_EXPRs real part in that case.  See PR71581.

     Or

     2. A call to .DEFERRED_INIT internal function. Since the original variable
     has been eliminated by optimziation, we need to get the variable name,
     and variable declaration location from this call.  We recorded variable
     name into VAR_NAME_STR, and will get location info and record warning
     suppressed info to VAR_DEF_STMT, which is the .DEFERRED_INIT call.  */

  const char *var_name_str = NULL;
  gimple *var_def_stmt = NULL;

  if (!var && !SSA_NAME_VAR (t))
    {
      var_def_stmt = SSA_NAME_DEF_STMT (t);

      if (is_gimple_assign (var_def_stmt)
	  && gimple_assign_rhs_code (var_def_stmt) == COMPLEX_EXPR)
	{
	  tree v = gimple_assign_rhs1 (var_def_stmt);
	  if (TREE_CODE (v) == SSA_NAME
	      && has_undefined_value_p (v)
	      && zerop (gimple_assign_rhs2 (var_def_stmt)))
	    var = SSA_NAME_VAR (v);
	}

      if (gimple_call_internal_p (var_def_stmt, IFN_DEFERRED_INIT))
	{
	  /* Ignore the call to .DEFERRED_INIT that define the original
	     var itself as the following case:
		temp = .DEFERRED_INIT (4, 2, “alt_reloc");
		alt_reloc = temp;
	     In order to avoid generating warning for the fake usage
	     at alt_reloc = temp.
	  */
	  tree lhs_var = NULL_TREE;
	  tree lhs_var_name = NULL_TREE;
	  const char *lhs_var_name_str = NULL;

	  /* Get the variable name from the 3rd argument of call.  */
	  tree var_name = gimple_call_arg (var_def_stmt, 2);
	  var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
	  var_name_str = TREE_STRING_POINTER (var_name);

	  if (is_gimple_assign (context))
	    {
	      if (TREE_CODE (gimple_assign_lhs (context)) == VAR_DECL)
		lhs_var = gimple_assign_lhs (context);
	      else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME)
		lhs_var = SSA_NAME_VAR (gimple_assign_lhs (context));
	    }
	  if (lhs_var
	      && (lhs_var_name = DECL_NAME (lhs_var))
	      && (lhs_var_name_str = IDENTIFIER_POINTER (lhs_var_name))
	      && (strcmp (lhs_var_name_str, var_name_str) == 0))
	    return;
	  gcc_assert (var_name_str && var_def_stmt);
	}
    }

  if (var == NULL_TREE && var_name_str == NULL)
    return;

  /* Avoid warning if we've already done so or if the warning has been
     suppressed.  */
  if (((warning_suppressed_p (context, OPT_Wuninitialized)
	|| (gimple_assign_single_p (context)
	    && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
      || (var && get_no_uninit_warning (var))
      || (var_name_str
	  && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
    return;

  /* Use either the location of the read statement or that of the PHI
     argument, or that of the uninitialized variable, in that order,
     whichever is valid.  */
  location_t location = UNKNOWN_LOCATION;
  if (gimple_has_location (context))
    location = gimple_location (context);
  else if (phi_arg_loc != UNKNOWN_LOCATION)
    location = phi_arg_loc;
  else if (var)
    location = DECL_SOURCE_LOCATION (var);
  else if (var_name_str)
    location = gimple_location (var_def_stmt);

  location = linemap_resolve_location (line_table, location,
				       LRK_SPELLING_LOCATION, NULL);

  auto_diagnostic_group d;
  gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
  if (var)
    {
      if ((opt == OPT_Wuninitialized
	   && !warning_at (location, opt, "%qD is used uninitialized", var))
	  || (opt == OPT_Wmaybe_uninitialized
	      && !warning_at (location, opt, "%qD may be used uninitialized",
			      var)))
      return;
    }
  else if (var_name_str)
    {
      if ((opt == OPT_Wuninitialized
	   && !warning_at (location, opt, "%qs is used uninitialized",
			   var_name_str))
	  || (opt == OPT_Wmaybe_uninitialized
	      && !warning_at (location, opt, "%qs may be used uninitialized",
			      var_name_str)))
      return;
    }

  /* Avoid subsequent warnings for reads of the same variable again.  */
  if (var)
    suppress_warning (var, opt);
  else if (var_name_str)
    suppress_warning (var_def_stmt, opt);

  /* Issue a note pointing to the read variable unless the warning
     is at the same location.  */
  location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
			: gimple_location (var_def_stmt);
  if (location == var_loc)
    return;

  if (var)
    inform (var_loc, "%qD was declared here", var);
  else if (var_name_str)
    inform (var_loc, "%qs was declared here", var_name_str);
}

struct check_defs_data
{
  /* If we found any may-defs besides must-def clobbers.  */
  bool found_may_defs;
};

/* 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).  */

static bool
builtin_call_nomodifying_p (gimple *stmt)
{
  if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    return false;

  tree fndecl = gimple_call_fndecl (stmt);
  if (!fndecl)
    return false;

  tree fntype = TREE_TYPE (fndecl);
  if (!fntype)
    return false;

  /* Check the called function's signature for non-constc pointers.
     If one is found, return false.  */
  unsigned argno = 0;
  tree argtype;
  function_args_iterator it;
  FOREACH_FUNCTION_ARGS (fntype, argtype, it)
    {
      if (VOID_TYPE_P (argtype))
	return true;

      ++argno;

      if (!POINTER_TYPE_P (argtype))
	continue;

      if (TYPE_READONLY (TREE_TYPE (argtype)))
	continue;

      return false;
    }

  /* If the number of actual arguments to the call is less than or
     equal to the number of parameters, return false.  */
  unsigned nargs = gimple_call_num_args (stmt);
  if (nargs <= argno)
    return false;

  /* Check arguments passed through the ellipsis in calls to variadic
     functions for pointers.  If one is found that's a non-constant
     pointer, return false.  */
  for (; argno < nargs; ++argno)
    {
      tree arg = gimple_call_arg (stmt, argno);
      argtype = TREE_TYPE (arg);
      if (!POINTER_TYPE_P (argtype))
	continue;

      if (TYPE_READONLY (TREE_TYPE (argtype)))
	continue;

      return false;
    }

  return true;
}

/* If ARG is a FNDECL parameter declared with attribute access none or
   write_only issue a warning for its read access via PTR.  */

static void
maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
{
  if (!fndecl)
    return;

  if (get_no_uninit_warning (arg))
    return;

  tree fntype = TREE_TYPE (fndecl);
  if (!fntype)
    return;

  /* Initialize a map of attribute access specifications for arguments
     to the function call.  */
  rdwr_map rdwr_idx;
  init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));

  unsigned argno = 0;
  tree parms = DECL_ARGUMENTS (fndecl);
  for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
    {
      if (parm != arg)
	continue;

      const attr_access* access = rdwr_idx.get (argno);
      if (!access)
	break;

      if (access->mode != access_none
	  && access->mode != access_write_only)
	continue;

      location_t stmtloc
	= linemap_resolve_location (line_table, gimple_location (stmt),
				    LRK_SPELLING_LOCATION, NULL);

      if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
		       "%qE may be used uninitialized", ptr))
	break;

      suppress_warning (arg, OPT_Wmaybe_uninitialized);

      const char* const access_str =
	TREE_STRING_POINTER (access->to_external_string ());

      location_t parmloc = DECL_SOURCE_LOCATION (parm);
      inform (parmloc, "accessing argument %u of a function declared with "
	      "attribute %<%s%>",
	      argno + 1, access_str);

      break;
    }
}

/* Callback for walk_aliased_vdefs.  */

static bool
check_defs (ao_ref *ref, tree vdef, void *data_)
{
  check_defs_data *data = (check_defs_data *)data_;
  gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);

  /* Ignore the vdef if the definition statement is a call
     to .DEFERRED_INIT function.  */
  if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
    return false;

  /* For address taken variable, a temporary variable is added between
     the variable and the call to .DEFERRED_INIT function as:
      _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
      i1 = _1;
     Ignore this vdef as well.  */
  if (is_gimple_assign (def_stmt)
      && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
    {
      tree tmp_var = gimple_assign_rhs1 (def_stmt);
      if (gimple_call_internal_p (SSA_NAME_DEF_STMT (tmp_var),
				  IFN_DEFERRED_INIT))
	return false;
    }

  /* The ASAN_MARK intrinsic doesn't modify the variable.  */
  if (is_gimple_call (def_stmt))
    {
      /* The ASAN_MARK intrinsic doesn't modify the variable.  */
      if (gimple_call_internal_p (def_stmt)
	  && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
	return false;

      if (tree fndecl = gimple_call_fndecl (def_stmt))
	{
	  /* Some sanitizer calls pass integer arguments to built-ins
	     that expect pointets. Avoid using gimple_call_builtin_p()
	     which fails for such calls.  */
	  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
	    {
	      built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
	      if (fncode > BEGIN_SANITIZER_BUILTINS
		  && fncode < END_SANITIZER_BUILTINS)
		return false;
	    }
	}
    }

  /* End of VLA scope is not a kill.  */
  if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
    return false;

  /* If this is a clobber then if it is not a kill walk past it.  */
  if (gimple_clobber_p (def_stmt))
    {
      if (stmt_kills_ref_p (def_stmt, ref))
	return true;
      return false;
    }

  if (builtin_call_nomodifying_p (def_stmt))
    return false;

  /* Found a may-def on this path.  */
  data->found_may_defs = true;
  return true;
}

/* Counters and limits controlling the depth of analysis and
   strictness of the warning.  */
struct wlimits
{
  /* Number of VDEFs encountered.  */
  unsigned int vdef_cnt;
  /* Number of statements examined by walk_aliased_vdefs.  */
  unsigned int oracle_cnt;
  /* Limit on the number of statements visited by walk_aliased_vdefs.  */
  unsigned limit;
  /* Set when basic block with statement is executed unconditionally.  */
  bool always_executed;
  /* Set to issue -Wmaybe-uninitialized.  */
  bool wmaybe_uninit;
};

/* Determine if REF references an uninitialized operand and diagnose
   it if so.  STMS is the referencing statement.  LHS is the result
   of the access and may be null.  RHS is the variable referenced by
   the access; it may not be null.  */

static tree
maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
		    wlimits &wlims)
{
  bool has_bit_insert = false;
  use_operand_p luse_p;
  imm_use_iterator liter;

  if (get_no_uninit_warning (rhs))
    return NULL_TREE;

  /* Do not warn if the base was marked so or this is a
     hard register var.  */
  tree base = ao_ref_base (&ref);
  if ((VAR_P (base)
       && DECL_HARD_REGISTER (base))
      || get_no_uninit_warning (base))
    return NULL_TREE;

  /* Do not warn if the access is zero size or if it's fully outside
     the object.  */
  poly_int64 decl_size;
  if (known_size_p (ref.size)
      && known_eq (ref.max_size, ref.size)
      && (known_eq (ref.size, 0)
	  || known_le (ref.offset + ref.size, 0)))
    return NULL_TREE;

  if (DECL_P (base)
      && known_ge (ref.offset, 0)
      && DECL_SIZE (base)
      && poly_int_tree_p (DECL_SIZE (base), &decl_size)
      && known_le (decl_size, ref.offset))
    return NULL_TREE;

  /* Do not warn if the result of the access is then used for
     a BIT_INSERT_EXPR. */
  if (lhs && TREE_CODE (lhs) == SSA_NAME)
    FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
      {
	gimple *use_stmt = USE_STMT (luse_p);
	/* BIT_INSERT_EXPR first operand should not be considered
	   a use for the purpose of uninit warnings.  */
	if (gassign *ass = dyn_cast <gassign *> (use_stmt))
	  {
	    if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
		&& luse_p->use == gimple_assign_rhs1_ptr (ass))
	      {
		has_bit_insert = true;
		break;
	      }
	  }
      }

  if (has_bit_insert)
    return NULL_TREE;

  /* Limit the walking to a constant number of stmts after
     we overcommit quadratic behavior for small functions
     and O(n) behavior.  */
  if (wlims.oracle_cnt > 128 * 128
      && wlims.oracle_cnt > wlims.vdef_cnt * 2)
    wlims.limit = 32;

  check_defs_data data;
  bool fentry_reached = false;
  data.found_may_defs = false;
  tree use = gimple_vuse (stmt);
  if (!use)
    return NULL_TREE;
  int res = walk_aliased_vdefs (&ref, use,
				check_defs, &data, NULL,
				&fentry_reached, wlims.limit);
  if (res == -1)
    {
      wlims.oracle_cnt += wlims.limit;
      return NULL_TREE;
    }

  wlims.oracle_cnt += res;
  if (data.found_may_defs)
    return NULL_TREE;

  bool found_alloc = false;

  if (fentry_reached)
    {
      if (TREE_CODE (base) == MEM_REF)
	base = TREE_OPERAND (base, 0);

      /* Follow the chain of SSA_NAME assignments looking for an alloca
	 call (or VLA) or malloc/realloc, or for decls.  If any is found
	 (and in the latter case, the operand is a local variable) issue
	 a warning.  */
      while (TREE_CODE (base) == SSA_NAME)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (base);

	  if (is_gimple_call (def_stmt)
	      && gimple_call_builtin_p (def_stmt))
	    {
	      /* Detect uses of uninitialized alloca/VLAs.  */
	      tree fndecl = gimple_call_fndecl (def_stmt);
	      const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
	      if (fncode == BUILT_IN_ALLOCA
		  || fncode  == BUILT_IN_ALLOCA_WITH_ALIGN
		  || fncode  == BUILT_IN_MALLOC)
		found_alloc = true;
	      break;
	    }

	  if (!is_gimple_assign (def_stmt))
	    break;

	  tree_code code = gimple_assign_rhs_code (def_stmt);
	  if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
	    break;

	  base = gimple_assign_rhs1 (def_stmt);
	  if (TREE_CODE (base) == ADDR_EXPR)
	    base = TREE_OPERAND (base, 0);

	  if (DECL_P (base)
	      || TREE_CODE (base) == COMPONENT_REF)
	    rhs = base;

	  if (TREE_CODE (base) == MEM_REF)
	    base = TREE_OPERAND (base, 0);

	  if (tree ba = get_base_address (base))
	    base = ba;
	}

      /* Replace the RHS expression with BASE so that it
	 refers to it in the diagnostic (instead of to
	 '<unknown>').  */
      if (DECL_P (base)
	  && EXPR_P (rhs)
	  && TREE_CODE (rhs) != COMPONENT_REF)
	rhs = base;
    }

  /* Do not warn if it can be initialized outside this function.
     If we did not reach function entry then we found killing
     clobbers on all paths to entry.  */
  if (!found_alloc && fentry_reached)
    {
      if (TREE_CODE (base) == SSA_NAME)
	{
	  tree var = SSA_NAME_VAR (base);
	  if (var && TREE_CODE (var) == PARM_DECL)
	    {
	      maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
	      return NULL_TREE;
	    }
	}

      if (!VAR_P (base)
	  || is_global_var (base))
	/* ???  We'd like to use ref_may_alias_global_p but that
	   excludes global readonly memory and thus we get bogus
	   warnings from p = cond ? "a" : "b" for example.  */
	return NULL_TREE;
    }

  /* Strip the address-of expression from arrays passed to functions. */
  if (TREE_CODE (rhs) == ADDR_EXPR)
    rhs = TREE_OPERAND (rhs, 0);

  /* Check again since RHS may have changed above.  */
  if (get_no_uninit_warning (rhs))
    return NULL_TREE;

  /* Avoid warning about empty types such as structs with no members.
     The first_field() test is important for C++ where the predicate
     alone isn't always sufficient.  */
  tree rhstype = TREE_TYPE (rhs);
  if (POINTER_TYPE_P (rhstype))
    rhstype = TREE_TYPE (rhstype);
  if (is_empty_type (rhstype))
    return NULL_TREE;

  bool warned = false;
  /* We didn't find any may-defs so on all paths either
     reached function entry or a killing clobber.  */
  location_t location
    = linemap_resolve_location (line_table, gimple_location (stmt),
				LRK_SPELLING_LOCATION, NULL);
  if (wlims.always_executed)
    {
      if (warning_at (location, OPT_Wuninitialized,
		      "%qE is used uninitialized", rhs))
	{
	  /* ???  This is only effective for decls as in
	     gcc.dg/uninit-B-O0.c.  Avoid doing this for maybe-uninit
	     uses or accesses by functions as it may hide important
	     locations.  */
	  if (lhs)
	    set_no_uninit_warning (rhs);
	  warned = true;
	}
    }
  else if (wlims.wmaybe_uninit)
    warned = warning_at (location, OPT_Wmaybe_uninitialized,
			 "%qE may be used uninitialized", rhs);

  return warned ? base : NULL_TREE;
}


/* Diagnose passing addresses of uninitialized objects to either const
   pointer arguments to functions, or to functions declared with attribute
   access implying read access to those objects.  */

static void
maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
{
  if (!wlims.wmaybe_uninit)
    return;

  unsigned nargs = gimple_call_num_args (stmt);
  if (!nargs)
    return;

  tree fndecl = gimple_call_fndecl (stmt);
  tree fntype = gimple_call_fntype (stmt);
  if (!fntype)
    return;

  /* Const function do not read their arguments.  */
  if (gimple_call_flags (stmt) & ECF_CONST)
    return;

  const built_in_function fncode
    = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
       ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);

  if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
    /* Avoid diagnosing calls to raw memory functions (this is overly
       permissive; consider tightening it up).  */
    return;

  /* Save the current warning setting and replace it either a "maybe"
     when passing addresses of uninitialized variables to const-qualified
     pointers or arguments declared with attribute read_write, or with
     a "certain" when passing them to arguments declared with attribute
     read_only.  */
  const bool save_always_executed = wlims.always_executed;

  /* Initialize a map of attribute access specifications for arguments
     to the function call.  */
  rdwr_map rdwr_idx;
  init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));

  tree argtype;
  unsigned argno = 0;
  function_args_iterator it;

  FOREACH_FUNCTION_ARGS (fntype, argtype, it)
    {
      ++argno;

      if (argno > nargs)
	break;

      if (!POINTER_TYPE_P (argtype))
	continue;

      tree access_size = NULL_TREE;
      const attr_access* access = rdwr_idx.get (argno - 1);
      if (access)
	{
	  if (access->mode == access_none
	      || access->mode == access_write_only)
	    continue;

	  if (access->mode == access_deferred
	      && !TYPE_READONLY (TREE_TYPE (argtype)))
	    continue;

	  if (save_always_executed && access->mode == access_read_only)
	    /* Attribute read_only arguments imply read access.  */
	    wlims.always_executed = true;
	  else
	    /* Attribute read_write arguments are documented as requiring
	       initialized objects but it's expected that aggregates may
	       be only partially initialized regardless.  */
	    wlims.always_executed = false;

	  if (access->sizarg < nargs)
	    access_size = gimple_call_arg (stmt, access->sizarg);
	}
      else if (!TYPE_READONLY (TREE_TYPE (argtype)))
	continue;
      else if (save_always_executed && fncode != BUILT_IN_LAST)
	/* Const-qualified arguments to built-ins imply read access.  */
	wlims.always_executed = true;
      else
	/* Const-qualified arguments to ordinary functions imply a likely
	   (but not definitive) read access.  */
	wlims.always_executed = false;

      /* Ignore args we are not going to read from.  */
      if (gimple_call_arg_flags (stmt, argno - 1)
	  & (EAF_UNUSED | EAF_NO_DIRECT_READ))
	continue;

      tree arg = gimple_call_arg (stmt, argno - 1);
      if (!POINTER_TYPE_P (TREE_TYPE (arg)))
	/* Avoid actual arguments with invalid types.  */
	continue;

      ao_ref ref;
      ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
      tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
      if (!argbase)
	continue;

      if (access && access->mode != access_deferred)
	{
	  const char* const access_str =
	    TREE_STRING_POINTER (access->to_external_string ());

	  if (fndecl)
	    {
	      location_t loc = DECL_SOURCE_LOCATION (fndecl);
	      inform (loc, "in a call to %qD declared with "
		      "attribute %<%s%> here", fndecl, access_str);
	    }
	  else
	    {
	      /* Handle calls through function pointers.  */
	      location_t loc = gimple_location (stmt);
	      inform (loc, "in a call to %qT declared with "
		      "attribute %<%s%>", fntype, access_str);
	    }
	}
      else
	{
	  /* For a declaration with no relevant attribute access create
	     a dummy object and use the formatting function to avoid
	     having to complicate things here.  */
	  attr_access ptr_access = { };
	  if (!access)
	    access = &ptr_access;
	  const std::string argtypestr = access->array_as_string (argtype);
	  if (fndecl)
	    {
	      location_t loc (DECL_SOURCE_LOCATION (fndecl));
	      inform (loc, "by argument %u of type %s to %qD "
		      "declared here",
		      argno, argtypestr.c_str (), fndecl);
	    }
	  else
	    {
	      /* Handle calls through function pointers.  */
	      location_t loc (gimple_location (stmt));
	      inform (loc, "by argument %u of type %s to %qT",
		      argno, argtypestr.c_str (), fntype);
	    }
	}

      if (DECL_P (argbase))
	{
	  location_t loc = DECL_SOURCE_LOCATION (argbase);
	  inform (loc, "%qD declared here", argbase);
	}
    }

  wlims.always_executed = save_always_executed;
}

/* Warn about an uninitialized PHI argument on the fallthru path to
   an always executed block BB.  */

static void
warn_uninit_phi_uses (basic_block bb)
{
  edge_iterator ei;
  edge e, found = NULL, found_back = NULL;
  /* Look for a fallthru and possibly a single backedge.  */
  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      /* Ignore backedges.  */
      if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
	{
	  if (found_back)
	    {
	      found = NULL;
	      break;
	    }
	  found_back = e;
	  continue;
	}
      if (found)
	{
	  found = NULL;
	  break;
	}
      found = e;
    }
  if (!found)
    return;

  basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
       gsi_next (&si))
    {
      gphi *phi = si.phi ();
      tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
      if (TREE_CODE (def) != SSA_NAME
	  || !SSA_NAME_IS_DEFAULT_DEF (def)
	  || virtual_operand_p (def))
	continue;
      /* If there's a default def on the fallthru edge PHI
	 value and there's a use that post-dominates entry
	 then that use is uninitialized and we can warn.  */
      imm_use_iterator iter;
      use_operand_p use_p;
      gimple *use_stmt = NULL;
      FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
	{
	  use_stmt = USE_STMT (use_p);
	  if (gimple_location (use_stmt) != UNKNOWN_LOCATION
	      && dominated_by_p (CDI_POST_DOMINATORS, succ,
				 gimple_bb (use_stmt))
	      /* If we found a non-fallthru edge make sure the
		 use is inside the loop, otherwise the backedge
		 can serve as initialization.  */
	      && (!found_back
		  || dominated_by_p (CDI_DOMINATORS, found_back->src,
				     gimple_bb (use_stmt))))
	    break;
	  use_stmt = NULL;
	}
      if (use_stmt)
	warn_uninit (OPT_Wuninitialized, def,
		     SSA_NAME_VAR (def), use_stmt);
    }
}

/* Issue warnings about reads of uninitialized variables.  WMAYBE_UNINIT
   is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized.  */

static void
warn_uninitialized_vars (bool wmaybe_uninit)
{
  /* Counters and limits controlling the depth of the warning.  */
  wlimits wlims = { };
  wlims.wmaybe_uninit = wmaybe_uninit;

  auto_bb_flag ft_reachable (cfun);

  /* Mark blocks that are always executed when we ignore provably
     not executed edges.  */
  basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  while (!(bb->flags & ft_reachable))
    {
      bb->flags |= ft_reachable;
      /* Find a single executable edge.  */
      edge_iterator ei;
      edge e, ee = NULL;
      FOR_EACH_EDGE (e, ei, bb->succs)
	if (e->flags & EDGE_EXECUTABLE)
	  {
	    if (!ee)
	      ee = e;
	    else
	      {
		ee = NULL;
		break;
	      }
	  }
      if (ee)
	bb = ee->dest;
      else
	bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
      if (!bb || bb->index == EXIT_BLOCK)
	break;
    }

  FOR_EACH_BB_FN (bb, cfun)
    {
      wlims.always_executed = (bb->flags & ft_reachable);
      bb->flags &= ~ft_reachable;

      edge_iterator ei;
      edge e;
      FOR_EACH_EDGE (e, ei, bb->preds)
	if (e->flags & EDGE_EXECUTABLE)
	  break;
      /* Skip unreachable blocks.  For early analysis we use VN to
	 determine edge executability when wmaybe_uninit.  */
      if (!e)
	continue;

      if (wlims.always_executed)
	warn_uninit_phi_uses (bb);

      gimple_stmt_iterator gsi;
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);

	  /* The call is an artificial use, will not provide meaningful
	     error message.  If the result of the call is used somewhere
	     else, we warn there instead.  */
	  if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
	    continue;

	  if (is_gimple_debug (stmt))
	    continue;

	  /* We only do data flow with SSA_NAMEs, so that's all we
	     can warn about.  */
	  use_operand_p use_p;
	  ssa_op_iter op_iter;
	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
	    {
	      /* BIT_INSERT_EXPR first operand should not be considered
		 a use for the purpose of uninit warnings.  */
	      if (gassign *ass = dyn_cast <gassign *> (stmt))
		{
		  if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
		      && use_p->use == gimple_assign_rhs1_ptr (ass))
		    continue;
		}
	      tree use = USE_FROM_PTR (use_p);
	      if (wlims.always_executed)
		warn_uninit (OPT_Wuninitialized, use,
			     SSA_NAME_VAR (use), stmt);
	      else if (wlims.wmaybe_uninit)
		warn_uninit (OPT_Wmaybe_uninitialized, use,
			     SSA_NAME_VAR (use), stmt);
	    }

	  /* For limiting the alias walk below we count all
	     vdefs in the function.  */
	  if (gimple_vdef (stmt))
	    wlims.vdef_cnt++;

	  if (gcall *call = dyn_cast <gcall *> (stmt))
	    maybe_warn_pass_by_reference (call, wlims);
	  else if (gimple_assign_load_p (stmt)
		   && gimple_has_location (stmt))
	    {
	      tree rhs = gimple_assign_rhs1 (stmt);
	      tree lhs = gimple_assign_lhs (stmt);

	      ao_ref ref;
	      ao_ref_init (&ref, rhs);
	      tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
	      if (!var)
		continue;

	      if (DECL_P (var))
		{
		  location_t loc = DECL_SOURCE_LOCATION (var);
		  inform (loc, "%qD declared here", var);
		}
	    }
	}
    }
}

/* 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.  */

static bool
can_skip_redundant_opnd (tree opnd, gimple *phi)
{
  tree phi_def = gimple_phi_result (phi);
  gimple *op_def = SSA_NAME_DEF_STMT (opnd);
  if (gimple_code (op_def) != GIMPLE_PHI)
    return false;

  unsigned n = gimple_phi_num_args (op_def);
  for (unsigned i = 0; i < n; ++i)
    {
      tree op = gimple_phi_arg_def (op_def, i);
      if (TREE_CODE (op) != SSA_NAME)
	continue;
      if (op != phi_def && uninit_undefined_value_p (op))
	return false;
    }

  return true;
}

/* Return a bitset holding the positions of arguments in PHI with empty
   (or possibly empty) definitions.  */

static unsigned
compute_uninit_opnds_pos (gphi *phi)
{
  unsigned uninit_opnds = 0;

  unsigned n = gimple_phi_num_args (phi);
  /* Bail out for phi with too many args.  */
  if (n > uninit_analysis::func_t::max_phi_args)
    return 0;

  for (unsigned i = 0; i < n; ++i)
    {
      tree op = gimple_phi_arg_def (phi, i);
      if (TREE_CODE (op) == SSA_NAME
	  && uninit_undefined_value_p (op)
	  && !can_skip_redundant_opnd (op, phi))
	{
	  if (cfun->has_nonlocal_label || cfun->calls_setjmp)
	    {
	      /* Ignore SSA_NAMEs that appear on abnormal edges
		 somewhere.  */
	      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
		continue;
	    }
	  MASK_SET_BIT (uninit_opnds, i);
	}
    }
  /* If we have recorded guarded uses of may-uninit values mask those.  */
  if (auto *def_mask = defined_args->get (phi))
    uninit_opnds &= ~*def_mask;
  return uninit_opnds;
}

/* Function object type used to determine whether an expression
   is of interest to the predicate analyzer.  */

struct uninit_undef_val_t: public uninit_analysis::func_t
{
  virtual unsigned phi_arg_set (gphi *) override;
};

/* Return a bitset of PHI arguments of interest.  */

unsigned
uninit_undef_val_t::phi_arg_set (gphi *phi)
{
  return compute_uninit_opnds_pos (phi);
}

/* sort helper for find_uninit_use.  */

static int
cand_cmp (const void *a, const void *b, void *data)
{
  int *bb_to_rpo = (int *)data;
  const gimple *sa = *(const gimple * const *)a;
  const gimple *sb = *(const gimple * const *)b;
  if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
    return -1;
  else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
    return 1;
  return 0;
}

/* 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.  */

static gimple *
find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
{
  /* The Boolean predicate guarding the PHI definition.  Initialized
     lazily from PHI in the first call to is_use_guarded() and cached
     for subsequent iterations.  */
  uninit_undef_val_t eval;
  uninit_analysis def_preds (eval);

  /* First process PHIs and record other candidates.  */
  auto_vec<gimple *, 64> cands;
  use_operand_p use_p;
  imm_use_iterator iter;
  tree phi_result = gimple_phi_result (phi);
  FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
    {
      gimple *use_stmt = USE_STMT (use_p);
      if (is_gimple_debug (use_stmt))
	continue;

      if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
	{
	  unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p);
	  edge e = gimple_phi_arg_edge (use_phi, idx);
	  /* Do not look for uses in the next iteration of a loop, predicate
	     analysis will not use the appropriate predicates to prove
	     reachability.  */
	  if (e->flags & EDGE_DFS_BACK)
	    continue;

	  basic_block use_bb = e->src;
	  if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
	    {
	      /* For a guarded use in a PHI record the PHI argument as
		 initialized.  */
	      if (idx < uninit_analysis::func_t::max_phi_args)
		{
		  bool existed_p;
		  auto &def_mask
		      = defined_args->get_or_insert (use_phi, &existed_p);
		  if (!existed_p)
		    def_mask = 0;
		  MASK_SET_BIT (def_mask, idx);
		}
	      continue;
	    }

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Found unguarded use in bb %u: ",
		       use_bb->index);
	      print_gimple_stmt (dump_file, use_stmt, 0);
	    }
	  /* Found a phi use that is not guarded, mark the phi_result as
	     possibly undefined.  */
	  possibly_undefined_names->add (phi_result);
	}
      else
	cands.safe_push (use_stmt);
    }

  /* Sort candidates after RPO.  */
  cands.stablesort (cand_cmp, bb_to_rpo);
  basic_block use_bb = NULL;
  for (gimple *use_stmt : cands)
    {
      /* We only have to try diagnosing the first use in each block.  */
      if (gimple_bb (use_stmt) == use_bb)
	continue;

      use_bb = gimple_bb (use_stmt);
      if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
	continue;

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "Found unguarded use in bb %u: ",
		   use_bb->index);
	  print_gimple_stmt (dump_file, use_stmt, 0);
	}
      return use_stmt;
    }

  return NULL;
}

/* 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.  */

static void
warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Examining phi: ");
      print_gimple_stmt (dump_file, phi, 0);
    }

  gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);

  /* All uses are properly guarded.  */
  if (!uninit_use_stmt)
    return;

  unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
  tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
  if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
    return;

  location_t loc = UNKNOWN_LOCATION;
  if (gimple_phi_arg_has_location (phi, phiarg_index))
    loc = gimple_phi_arg_location (phi, phiarg_index);
  else
    {
      tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
      if (TREE_CODE (arg_def) == SSA_NAME)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
	  if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
	    {
	      unsigned uop = compute_uninit_opnds_pos (arg_phi);
	      unsigned idx = MASK_FIRST_SET_BIT (uop);
	      if (idx < gimple_phi_num_args (arg_phi)
		  && gimple_phi_arg_has_location (arg_phi, idx))
		loc = gimple_phi_arg_location (arg_phi, idx);
	    }
	}
    }

  warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
	       SSA_NAME_VAR (uninit_op),
	       uninit_use_stmt, loc);
}

static bool
gate_warn_uninitialized (void)
{
  return warn_uninitialized || warn_maybe_uninitialized;
}

namespace {

const pass_data pass_data_late_warn_uninitialized =
{
  GIMPLE_PASS, /* type */
  "uninit", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_ssa, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_late_warn_uninitialized : public gimple_opt_pass
{
public:
  pass_late_warn_uninitialized (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
  {}

  /* opt_pass methods: */
  opt_pass *clone () final override
  {
    return new pass_late_warn_uninitialized (m_ctxt);
  }
  bool gate (function *) final override { return gate_warn_uninitialized (); }
  unsigned int execute (function *) final override;

}; // class pass_late_warn_uninitialized

static void
execute_late_warn_uninitialized (function *fun)
{
  calculate_dominance_info (CDI_DOMINATORS);
  calculate_dominance_info (CDI_POST_DOMINATORS);

  /* Mark all edges executable, warn_uninitialized_vars will skip
     unreachable blocks.  */
  set_all_edges_as_executable (fun);
  mark_dfs_back_edges (fun);
  int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
  int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
  int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
  for (int i = 0; i < n; ++i)
    bb_to_rpo[rpo[i]] = i;

  /* Re-do the plain uninitialized variable check, as optimization may have
     straightened control flow.  Do this first so that we don't accidentally
     get a "may be" warning when we'd have seen an "is" warning later.  */
  warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);

  timevar_push (TV_TREE_UNINIT);

  /* Avoid quadratic beahvior when looking up case labels for edges.  */
  start_recording_case_labels ();

  possibly_undefined_names = new hash_set<tree>;
  defined_args = new hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t>;

  /* Walk the CFG in RPO order so we visit PHIs with defs that are
     possibly uninitialized from other PHIs after those.  The uninit
     predicate analysis will then expand the PHIs predicate with
     the predicates of the edges from such PHI defs.  */
  for (int i = 0; i < n; ++i)
    for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
	 !gsi_end_p (gsi); gsi_next (&gsi))
      {
	gphi *phi = gsi.phi ();

	/* Don't look at virtual operands.  */
	if (virtual_operand_p (gimple_phi_result (phi)))
	  continue;

	unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
	if (MASK_EMPTY (uninit_opnds))
	  continue;

	warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
      }

  free (rpo);
  free (bb_to_rpo);
  delete possibly_undefined_names;
  possibly_undefined_names = NULL;
  delete defined_args;
  defined_args = NULL;
  end_recording_case_labels ();
  free_dominance_info (CDI_POST_DOMINATORS);
  timevar_pop (TV_TREE_UNINIT);
}

unsigned int
pass_late_warn_uninitialized::execute (function *fun)
{
  execute_late_warn_uninitialized (fun);
  return 0;
}

} // anon namespace

gimple_opt_pass *
make_pass_late_warn_uninitialized (gcc::context *ctxt)
{
  return new pass_late_warn_uninitialized (ctxt);
}

static unsigned int
execute_early_warn_uninitialized (struct function *fun)
{
  /* Currently, this pass runs always but
     execute_late_warn_uninitialized only runs with optimization.  With
     optimization we want to warn about possible uninitialized as late
     as possible, thus don't do it here.  However, without
     optimization we need to warn here about "may be uninitialized".  */
  calculate_dominance_info (CDI_DOMINATORS);
  calculate_dominance_info (CDI_POST_DOMINATORS);

  /* Use VN in its cheapest incarnation and without doing any
     elimination to compute edge reachability.  Don't bother when
     we only warn for unconditionally executed code though.  */
  if (!optimize)
    do_rpo_vn (fun, NULL, NULL, false, false, VN_NOWALK);
  else
    set_all_edges_as_executable (fun);

  warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);

  /* Post-dominator information cannot be reliably updated.  Free it
     after the use.  */

  free_dominance_info (CDI_POST_DOMINATORS);
  return 0;
}

namespace {

const pass_data pass_data_early_warn_uninitialized =
{
  GIMPLE_PASS, /* type */
  "early_uninit", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_UNINIT, /* tv_id */
  PROP_ssa, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_early_warn_uninitialized : public gimple_opt_pass
{
public:
  pass_early_warn_uninitialized (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *) final override { return gate_warn_uninitialized (); }
  unsigned int execute (function *fun) final override
  {
    return execute_early_warn_uninitialized (fun);
  }

}; // class pass_early_warn_uninitialized

} // anon namespace

gimple_opt_pass *
make_pass_early_warn_uninitialized (gcc::context *ctxt)
{
  return new pass_early_warn_uninitialized (ctxt);
}
