LCOV - code coverage report
Current view: top level - gcc - tree-ssa-uninit.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.0 % 638 619
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 27 27
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Predicate aware uninitialized variable warning.
       2              :    Copyright (C) 2001-2026 Free Software Foundation, Inc.
       3              :    Contributed by Xinliang David Li <davidxl@google.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #define INCLUDE_STRING
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "backend.h"
      26              : #include "tree.h"
      27              : #include "gimple.h"
      28              : #include "tree-pass.h"
      29              : #include "ssa.h"
      30              : #include "gimple-pretty-print.h"
      31              : #include "diagnostic-core.h"
      32              : #include "fold-const.h"
      33              : #include "gimple-iterator.h"
      34              : #include "tree-ssa.h"
      35              : #include "tree-cfg.h"
      36              : #include "cfghooks.h"
      37              : #include "attribs.h"
      38              : #include "builtins.h"
      39              : #include "calls.h"
      40              : #include "gimple-range.h"
      41              : #include "gimple-predicate-analysis.h"
      42              : #include "domwalk.h"
      43              : #include "tree-ssa-sccvn.h"
      44              : #include "cfganal.h"
      45              : #include "gcc-urlifier.h"
      46              : 
      47              : /* This implements the pass that does predicate aware warning on uses of
      48              :    possibly uninitialized variables.  The pass first collects the set of
      49              :    possibly uninitialized SSA names.  For each such name, it walks through
      50              :    all its immediate uses.  For each immediate use, it rebuilds the condition
      51              :    expression (the predicate) that guards the use.  The predicate is then
      52              :    examined to see if the variable is always defined under that same condition.
      53              :    This is done either by pruning the unrealizable paths that lead to the
      54              :    default definitions or by checking if the predicate set that guards the
      55              :    defining paths is a superset of the use predicate.  */
      56              : 
      57              : /* Pointer set of potentially undefined ssa names, i.e.,
      58              :    ssa names that are defined by phi with operands that
      59              :    are not defined or potentially undefined.  */
      60              : static hash_set<tree> *possibly_undefined_names;
      61              : static hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t> *defined_args;
      62              : 
      63              : /* Returns the first bit position (starting from LSB)
      64              :    in mask that is non zero.  Returns -1 if the mask is empty.  */
      65              : static int
      66          117 : get_mask_first_set_bit (unsigned mask)
      67              : {
      68          117 :   int pos = 0;
      69            0 :   if (mask == 0)
      70              :     return -1;
      71              : 
      72          144 :   while ((mask & (1 << pos)) == 0)
      73           27 :     pos++;
      74              : 
      75              :   return pos;
      76              : }
      77              : #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
      78              : 
      79              : /* Return true if T, an SSA_NAME, has an undefined value.  */
      80              : static bool
      81      6494209 : has_undefined_value_p (tree t)
      82              : {
      83      6494209 :   return (ssa_undefined_value_p (t)
      84      6494209 :           || (possibly_undefined_names
      85       885412 :               && possibly_undefined_names->contains (t)));
      86              : }
      87              : 
      88              : /* Return true if EXPR should suppress either uninitialized warning.  */
      89              : 
      90              : static inline bool
      91      3076431 : get_no_uninit_warning (tree expr)
      92              : {
      93      1449250 :   return warning_suppressed_p (expr, OPT_Wuninitialized);
      94              : }
      95              : 
      96              : /* Suppress both uninitialized warnings for EXPR.  */
      97              : 
      98              : static inline void
      99          402 : set_no_uninit_warning (tree expr)
     100              : {
     101          402 :   suppress_warning (expr, OPT_Wuninitialized);
     102          402 : }
     103              : 
     104              : /* Like has_undefined_value_p, but don't return true if the no-warning
     105              :    bit is set on SSA_NAME_VAR for either uninit warning.  */
     106              : 
     107              : static inline bool
     108       887178 : uninit_undefined_value_p (tree t)
     109              : {
     110       887178 :   if (!has_undefined_value_p (t))
     111              :     return false;
     112         2753 :   if (!SSA_NAME_VAR (t))
     113              :     return true;
     114         2734 :   return !get_no_uninit_warning (SSA_NAME_VAR (t));
     115              : }
     116              : 
     117              : /* Emit warnings for uninitialized variables.  This is done in two passes.
     118              : 
     119              :    The first pass notices real uses of SSA names with undefined values.
     120              :    Such uses are unconditionally uninitialized, and we can be certain that
     121              :    such a use is a mistake.  This pass is run before most optimizations,
     122              :    so that we catch as many as we can.
     123              : 
     124              :    The second pass follows PHI nodes to find uses that are potentially
     125              :    uninitialized.  In this case we can't necessarily prove that the use
     126              :    is really uninitialized.  This pass is run after most optimizations,
     127              :    so that we thread as many jumps and possible, and delete as much dead
     128              :    code as possible, in order to reduce false positives.  We also look
     129              :    again for plain uninitialized variables, since optimization may have
     130              :    changed conditionally uninitialized to unconditionally uninitialized.  */
     131              : 
     132              : /* Emit warning OPT for variable VAR at the point in the program where
     133              :    the SSA_NAME T is being used uninitialized.  The warning text is in
     134              :    MSGID and STMT is the statement that does the uninitialized read.
     135              :    PHI_ARG_LOC is the location of the PHI argument if T and VAR are one,
     136              :    or UNKNOWN_LOCATION otherwise.  */
     137              : 
     138              : static void
     139      5607028 : warn_uninit (opt_code opt, tree t, tree var, gimple *context,
     140              :              location_t phi_arg_loc = UNKNOWN_LOCATION)
     141              : {
     142              :   /* Bail if the value isn't provably uninitialized.  */
     143      5607028 :   if (!has_undefined_value_p (t))
     144      5606471 :     return;
     145              : 
     146              :   /* Ignore COMPLEX_EXPR as initializing only a part of a complex
     147              :      turns in a COMPLEX_EXPR with the not initialized part being
     148              :      set to its previous (undefined) value.  */
     149         4512 :   if (is_gimple_assign (context)
     150         4512 :       && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
     151              :     return;
     152              : 
     153              :   /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
     154              :      .DEFERRED_INIT.  This is for handling the following case correctly:
     155              : 
     156              :   1 typedef _Complex float C;
     157              :   2 C foo (int cond)
     158              :   3 {
     159              :   4   C f;
     160              :   5   __imag__ f = 0;
     161              :   6   if (cond)
     162              :   7     {
     163              :   8       __real__ f = 1;
     164              :   9       return f;
     165              :  10     }
     166              :  11   return f;
     167              :  12 }
     168              : 
     169              :     with -ftrivial-auto-var-init, compiler will insert the following
     170              :     artificial initialization at line 4:
     171              :   f = .DEFERRED_INIT (f, 2);
     172              :   _1 = REALPART_EXPR <f>;
     173              : 
     174              :     without the following special handling, _1 = REALPART_EXPR <f> will
     175              :     be treated as the uninitialized use point, which is incorrect. (the
     176              :     real uninitialized use point is at line 11).  */
     177         4502 :   if (is_gimple_assign (context)
     178         4502 :       && (gimple_assign_rhs_code (context) == REALPART_EXPR
     179         3923 :           || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
     180              :     {
     181           95 :       tree v = gimple_assign_rhs1 (context);
     182           95 :       if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
     183           95 :           && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
     184              :                                      IFN_DEFERRED_INIT))
     185              :         return;
     186              :     }
     187              : 
     188              :   /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
     189              :      can return true if the def stmt of an anonymous SSA_NAME is
     190              :      1. A COMPLEX_EXPR created for conversion from scalar to complex.  Use the
     191              :      underlying var of the COMPLEX_EXPRs real part in that case.  See PR71581.
     192              : 
     193              :      Or
     194              : 
     195              :      2. A call to .DEFERRED_INIT internal function. Since the original variable
     196              :      has been eliminated by optimziation, we need to get the variable name,
     197              :      and variable declaration location from this call.  We recorded variable
     198              :      name into VAR_NAME_STR, and will get location info and record warning
     199              :      suppressed info to VAR_DEF_STMT, which is the .DEFERRED_INIT call.  */
     200              : 
     201         4497 :   const char *var_name_str = NULL;
     202         4497 :   gimple *var_def_stmt = NULL;
     203              : 
     204         4726 :   if (!var && !SSA_NAME_VAR (t))
     205              :     {
     206          229 :       var_def_stmt = SSA_NAME_DEF_STMT (t);
     207              : 
     208          229 :       if (gassign *ass = dyn_cast <gassign *> (var_def_stmt))
     209              :         {
     210            7 :           switch (gimple_assign_rhs_code (var_def_stmt))
     211              :             {
     212            3 :             case COMPLEX_EXPR:
     213            3 :               {
     214            3 :                 tree v = gimple_assign_rhs1 (ass);
     215            3 :                 if (TREE_CODE (v) == SSA_NAME
     216            3 :                     && has_undefined_value_p (v)
     217            6 :                     && zerop (gimple_assign_rhs2 (ass)))
     218            3 :                   var = SSA_NAME_VAR (v);
     219              :                 break;
     220              :               }
     221            4 :             case SSA_NAME:
     222            4 :               {
     223            4 :                 tree v = gimple_assign_rhs1 (ass);
     224            4 :                 if (TREE_CODE (v) == SSA_NAME
     225            4 :                     && SSA_NAME_VAR (v))
     226              :                   var = SSA_NAME_VAR (v);
     227              :                 break;
     228              :               }
     229              :             default:;
     230              :             }
     231              :         }
     232              : 
     233          229 :       if (gimple_call_internal_p (var_def_stmt, IFN_DEFERRED_INIT))
     234              :         {
     235              :           /* Ignore the call to .DEFERRED_INIT that define the original
     236              :              var itself as the following case:
     237              :                 temp = .DEFERRED_INIT (4, 2, “alt_reloc");
     238              :                 alt_reloc = temp;
     239              :              In order to avoid generating warning for the fake usage
     240              :              at alt_reloc = temp.
     241              :           */
     242          222 :           tree lhs_var = NULL_TREE;
     243              : 
     244              :           /* Get the variable name from the 3rd argument of call.  */
     245          222 :           tree var_name = gimple_call_arg (var_def_stmt, 2);
     246          222 :           var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
     247          222 :           var_name_str = TREE_STRING_POINTER (var_name);
     248              : 
     249          222 :           if (is_gimple_assign (context))
     250              :             {
     251          215 :               if (VAR_P (gimple_assign_lhs (context)))
     252              :                 lhs_var = gimple_assign_lhs (context);
     253           14 :               else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME)
     254           14 :                 lhs_var = SSA_NAME_VAR (gimple_assign_lhs (context));
     255              :             }
     256          214 :           if (lhs_var)
     257              :             {
     258              :               /* Get the name string for the LHS_VAR.
     259              :                  Refer to routine gimple_add_init_for_auto_var.  */
     260          214 :               if (DECL_NAME (lhs_var)
     261          214 :                   && (strcmp (IDENTIFIER_POINTER (DECL_NAME (lhs_var)),
     262              :                       var_name_str) == 0))
     263              :                 return;
     264            7 :               else if (!DECL_NAME (lhs_var))
     265              :                 {
     266            6 :                   char lhs_var_name_str_buf[3 + (HOST_BITS_PER_INT + 2) / 3];
     267            6 :                   sprintf (lhs_var_name_str_buf, "D.%u", DECL_UID (lhs_var));
     268            6 :                   if (strcmp (lhs_var_name_str_buf, var_name_str) == 0)
     269            6 :                     return;
     270              :                 }
     271              :             }
     272              :           gcc_assert (var_name_str && var_def_stmt);
     273              :         }
     274              :     }
     275              : 
     276         4284 :   if (var == NULL_TREE && var_name_str == NULL)
     277              :     return;
     278              : 
     279              :   /* Avoid warning if we've already done so or if the warning has been
     280              :      suppressed.  */
     281         4284 :   if (((warning_suppressed_p (context, OPT_Wuninitialized)
     282         4281 :         || (gimple_assign_single_p (context)
     283         3552 :             && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
     284         8374 :       || (var && get_no_uninit_warning (var))
     285         6342 :       || (var_name_str
     286            8 :           && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
     287         2227 :     return;
     288              : 
     289              :   /* Use either the location of the read statement or that of the PHI
     290              :      argument, or that of the uninitialized variable, in that order,
     291              :      whichever is valid.  */
     292         2057 :   location_t location = UNKNOWN_LOCATION;
     293         2057 :   if (gimple_has_location (context))
     294         2044 :     location = gimple_location (context);
     295           13 :   else if (phi_arg_loc != UNKNOWN_LOCATION)
     296              :     location = phi_arg_loc;
     297            8 :   else if (var)
     298            8 :     location = DECL_SOURCE_LOCATION (var);
     299            0 :   else if (var_name_str)
     300            0 :     location = gimple_location (var_def_stmt);
     301              : 
     302         2614 :   auto_diagnostic_group d;
     303         2057 :   gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
     304         2057 :   if (var)
     305              :     {
     306         2050 :       if ((opt == OPT_Wuninitialized
     307         1655 :            && !warning_at (location, opt, "%qD is used uninitialized", var))
     308         2473 :           || (opt == OPT_Wmaybe_uninitialized
     309          818 :               && !warning_at (location, opt, "%qD may be used uninitialized",
     310              :                               var)))
     311         1500 :       return;
     312              :     }
     313            7 :   else if (var_name_str)
     314              :     {
     315            7 :       if ((opt == OPT_Wuninitialized
     316            2 :            && !warning_at (location, opt, "%qs is used uninitialized",
     317              :                            var_name_str))
     318            9 :           || (opt == OPT_Wmaybe_uninitialized
     319            7 :               && !warning_at (location, opt, "%qs may be used uninitialized",
     320              :                               var_name_str)))
     321            0 :       return;
     322              :     }
     323              : 
     324              :   /* Avoid subsequent warnings for reads of the same variable again.  */
     325          562 :   if (var)
     326          555 :     suppress_warning (var, opt);
     327            7 :   else if (var_name_str)
     328            7 :     suppress_warning (var_def_stmt, opt);
     329              : 
     330              :   /* Issue a note pointing to the read variable unless the warning
     331              :      is at the same location.  */
     332          562 :   location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
     333          562 :                         : gimple_location (var_def_stmt);
     334          562 :   if (location == var_loc)
     335              :     return;
     336              : 
     337          557 :   if (var)
     338          550 :     inform (var_loc, "%qD was declared here", var);
     339            7 :   else if (var_name_str)
     340            7 :     inform (var_loc, "%qs was declared here", var_name_str);
     341              : }
     342              : 
     343              : struct check_defs_data
     344              : {
     345              :   /* If we found any may-defs besides must-def clobbers.  */
     346              :   bool found_may_defs;
     347              : };
     348              : 
     349              : /* Return true if STMT is a call to built-in function all of whose
     350              :    by-reference arguments are const-qualified (i.e., the function can
     351              :    be assumed not to modify them).  */
     352              : 
     353              : static bool
     354      3022943 : builtin_call_nomodifying_p (gimple *stmt)
     355              : {
     356      3022943 :   if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
     357              :     return false;
     358              : 
     359       358914 :   tree fndecl = gimple_call_fndecl (stmt);
     360       358914 :   if (!fndecl)
     361              :     return false;
     362              : 
     363       358914 :   tree fntype = TREE_TYPE (fndecl);
     364       358914 :   if (!fntype)
     365              :     return false;
     366              : 
     367              :   /* Check the called function's signature for non-constc pointers.
     368              :      If one is found, return false.  */
     369       358914 :   unsigned argno = 0;
     370       358914 :   tree argtype;
     371       358914 :   function_args_iterator it;
     372       635650 :   FOREACH_FUNCTION_ARGS (fntype, argtype, it)
     373              :     {
     374       440069 :       if (VOID_TYPE_P (argtype))
     375              :         return true;
     376              : 
     377       396783 :       ++argno;
     378              : 
     379       396783 :       if (!POINTER_TYPE_P (argtype))
     380        49092 :         continue;
     381              : 
     382       347691 :       if (TYPE_READONLY (TREE_TYPE (argtype)))
     383       227644 :         continue;
     384              : 
     385              :       return false;
     386              :     }
     387              : 
     388              :   /* If the number of actual arguments to the call is less than or
     389              :      equal to the number of parameters, return false.  */
     390       195581 :   unsigned nargs = gimple_call_num_args (stmt);
     391       195581 :   if (nargs <= argno)
     392              :     return false;
     393              : 
     394              :   /* Check arguments passed through the ellipsis in calls to variadic
     395              :      functions for pointers.  If one is found that's a non-constant
     396              :      pointer, return false.  */
     397       202051 :   for (; argno < nargs; ++argno)
     398              :     {
     399       196830 :       tree arg = gimple_call_arg (stmt, argno);
     400       196830 :       argtype = TREE_TYPE (arg);
     401       196830 :       if (!POINTER_TYPE_P (argtype))
     402         6068 :         continue;
     403              : 
     404       190762 :       if (TYPE_READONLY (TREE_TYPE (argtype)))
     405          402 :         continue;
     406              : 
     407              :       return false;
     408              :     }
     409              : 
     410              :   return true;
     411              : }
     412              : 
     413              : /* If ARG is a FNDECL parameter declared with attribute access none or
     414              :    write_only issue a warning for its read access via PTR.  */
     415              : 
     416              : static void
     417       174100 : maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
     418              : {
     419       174100 :   if (!fndecl)
     420            0 :     return;
     421              : 
     422       174100 :   if (get_no_uninit_warning (arg))
     423              :     return;
     424              : 
     425       174100 :   tree fntype = TREE_TYPE (fndecl);
     426       174100 :   if (!fntype)
     427              :     return;
     428              : 
     429              :   /* Initialize a map of attribute access specifications for arguments
     430              :      to the function call.  */
     431       174100 :   rdwr_map rdwr_idx;
     432       174100 :   init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
     433              : 
     434       174100 :   unsigned argno = 0;
     435       174100 :   tree parms = DECL_ARGUMENTS (fndecl);
     436       314116 :   for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
     437              :     {
     438       313626 :       if (parm != arg)
     439       140016 :         continue;
     440              : 
     441       174082 :       const attr_access* access = rdwr_idx.get (argno);
     442       174082 :       if (!access)
     443              :         break;
     444              : 
     445          486 :       if (access->mode != access_none
     446          484 :           && access->mode != access_write_only)
     447          472 :         continue;
     448              : 
     449           14 :       location_t stmtloc = gimple_location (stmt);
     450           14 :       if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
     451              :                        "%qE may be used uninitialized", ptr))
     452              :         break;
     453              : 
     454           10 :       suppress_warning (arg, OPT_Wmaybe_uninitialized);
     455              : 
     456           10 :       const char* const access_str =
     457           10 :         TREE_STRING_POINTER (access->to_external_string ());
     458              : 
     459           10 :       auto_urlify_attributes sentinel;
     460           10 :       location_t parmloc = DECL_SOURCE_LOCATION (parm);
     461           10 :       inform (parmloc, "accessing argument %u of a function declared with "
     462              :               "attribute %qs",
     463              :               argno + 1, access_str);
     464              : 
     465           10 :       break;
     466           10 :     }
     467       174100 : }
     468              : 
     469              : /* Callback for walk_aliased_vdefs.  */
     470              : 
     471              : static bool
     472      3160361 : check_defs (ao_ref *ref, tree vdef, void *data_)
     473              : {
     474      3160361 :   check_defs_data *data = (check_defs_data *)data_;
     475      3160361 :   gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
     476              : 
     477              :   /* Ignore the vdef if the definition statement is a call
     478              :      to .DEFERRED_INIT function.  */
     479      3160361 :   if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
     480              :     return false;
     481              : 
     482              :   /* For address taken variable, a temporary variable is added between
     483              :      the variable and the call to .DEFERRED_INIT function as:
     484              :       _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
     485              :       i1 = _1;
     486              :      Ignore this vdef as well.  */
     487      3160121 :   if (is_gimple_assign (def_stmt)
     488      3160121 :       && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
     489              :     {
     490      1366100 :       tree tmp_var = gimple_assign_rhs1 (def_stmt);
     491      1366100 :       if (gimple_call_internal_p (SSA_NAME_DEF_STMT (tmp_var),
     492              :                                   IFN_DEFERRED_INIT))
     493              :         return false;
     494              :     }
     495              : 
     496              :   /* The ASAN_MARK intrinsic doesn't modify the variable.  */
     497      3160074 :   if (is_gimple_call (def_stmt))
     498              :     {
     499              :       /* The ASAN_MARK intrinsic doesn't modify the variable.  */
     500      1401797 :       if (gimple_call_internal_p (def_stmt)
     501      1401797 :           && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
     502              :         return false;
     503              : 
     504      1400051 :       if (tree fndecl = gimple_call_fndecl (def_stmt))
     505              :         {
     506              :           /* Some sanitizer calls pass integer arguments to built-ins
     507              :              that expect pointets. Avoid using gimple_call_builtin_p()
     508              :              which fails for such calls.  */
     509      1228150 :           if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
     510              :             {
     511       360208 :               built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
     512       360208 :               if (fncode > BEGIN_SANITIZER_BUILTINS
     513       360208 :                   && fncode < END_SANITIZER_BUILTINS)
     514              :                 return false;
     515              :             }
     516              :         }
     517              :     }
     518              : 
     519              :   /* End of VLA scope is not a kill.  */
     520      3158214 :   if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
     521              :     return false;
     522              : 
     523              :   /* If this is a clobber then if it is not a kill walk past it.  */
     524      3158138 :   if (gimple_clobber_p (def_stmt))
     525              :     {
     526       135195 :       if (stmt_kills_ref_p (def_stmt, ref))
     527              :         return true;
     528              :       return false;
     529              :     }
     530              : 
     531      3022943 :   if (builtin_call_nomodifying_p (def_stmt))
     532              :     return false;
     533              : 
     534              :   /* Found a may-def on this path.  */
     535      2974436 :   data->found_may_defs = true;
     536      2974436 :   return true;
     537              : }
     538              : 
     539              : /* Counters and limits controlling the depth of analysis and
     540              :    strictness of the warning.  */
     541              : struct wlimits
     542              : {
     543              :   /* Number of VDEFs encountered.  */
     544              :   unsigned int vdef_cnt;
     545              :   /* Number of statements examined by walk_aliased_vdefs.  */
     546              :   unsigned int oracle_cnt;
     547              :   /* Limit on the number of statements visited by walk_aliased_vdefs.  */
     548              :   unsigned limit;
     549              :   /* Set when basic block with statement is executed unconditionally.  */
     550              :   bool always_executed;
     551              :   /* Set to issue -Wmaybe-uninitialized.  */
     552              :   bool wmaybe_uninit;
     553              : };
     554              : 
     555              : /* Determine if REF references an uninitialized operand and diagnose
     556              :    it if so.  STMS is the referencing statement.  LHS is the result
     557              :    of the access and may be null.  RHS is the variable referenced by
     558              :    the access; it may not be null.  */
     559              : 
     560              : static tree
     561      1445763 : maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
     562              :                     wlimits &wlims)
     563              : {
     564      1445763 :   bool has_bit_insert = false;
     565      1445763 :   use_operand_p luse_p;
     566      1445763 :   imm_use_iterator liter;
     567              : 
     568      1445763 :   if (get_no_uninit_warning (rhs))
     569              :     return NULL_TREE;
     570              : 
     571              :   /* Do not warn if the base was marked so or this is a
     572              :      hard register var.  */
     573      1445073 :   tree base = ao_ref_base (&ref);
     574      1445073 :   if ((VAR_P (base)
     575       580213 :        && DECL_HARD_REGISTER (base))
     576      2890140 :       || get_no_uninit_warning (base))
     577         4076 :     return NULL_TREE;
     578              : 
     579              :   /* Do not warn if the access is zero size or if it's fully outside
     580              :      the object.  */
     581      1440997 :   poly_int64 decl_size;
     582      1440997 :   if (known_size_p (ref.size)
     583      1216050 :       && known_eq (ref.max_size, ref.size)
     584      2522906 :       && (known_eq (ref.size, 0)
     585      1081895 :           || known_le (ref.offset + ref.size, 0)))
     586              :     return NULL_TREE;
     587              : 
     588      1440933 :   if (DECL_P (base)
     589       596241 :       && known_ge (ref.offset, 0)
     590       596234 :       && DECL_SIZE (base)
     591       579505 :       && poly_int_tree_p (DECL_SIZE (base), &decl_size)
     592      2020437 :       && known_le (decl_size, ref.offset))
     593              :     return NULL_TREE;
     594              : 
     595              :   /* Do not warn if the result of the access is then used for
     596              :      a BIT_INSERT_EXPR. */
     597      1440426 :   if (lhs && TREE_CODE (lhs) == SSA_NAME)
     598      4143324 :     FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
     599              :       {
     600      1734902 :         gimple *use_stmt = USE_STMT (luse_p);
     601              :         /* BIT_INSERT_EXPR first operand should not be considered
     602              :            a use for the purpose of uninit warnings.  */
     603      2573916 :         if (gassign *ass = dyn_cast <gassign *> (use_stmt))
     604              :           {
     605       839016 :             if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
     606       839016 :                 && luse_p->use == gimple_assign_rhs1_ptr (ass))
     607              :               {
     608              :                 has_bit_insert = true;
     609              :                 break;
     610              :               }
     611              :           }
     612      1204212 :       }
     613              : 
     614      1204212 :   if (has_bit_insert)
     615              :     return NULL_TREE;
     616              : 
     617              :   /* Limit the walking to a constant number of stmts after
     618              :      we overcommit quadratic behavior for small functions
     619              :      and O(n) behavior.  */
     620      1440424 :   if (wlims.oracle_cnt > 128 * 128
     621        36673 :       && wlims.oracle_cnt > wlims.vdef_cnt * 2)
     622        36673 :     wlims.limit = 32;
     623              : 
     624      1440424 :   check_defs_data data;
     625      1440424 :   bool fentry_reached = false;
     626      1440424 :   data.found_may_defs = false;
     627      2885484 :   tree use = gimple_vuse (stmt);
     628      1440424 :   if (!use)
     629              :     return NULL_TREE;
     630      1440166 :   int res = walk_aliased_vdefs (&ref, use,
     631              :                                 check_defs, &data, NULL,
     632              :                                 &fentry_reached, wlims.limit);
     633      1440166 :   if (res == -1)
     634              :     {
     635        33587 :       wlims.oracle_cnt += wlims.limit;
     636        33587 :       return NULL_TREE;
     637              :     }
     638              : 
     639      1406579 :   wlims.oracle_cnt += res;
     640      1406579 :   if (data.found_may_defs)
     641              :     return NULL_TREE;
     642              : 
     643       477035 :   bool found_alloc = false;
     644       477035 :   bool found_clobber_deref_this = false;
     645              : 
     646       477035 :   if (fentry_reached)
     647              :     {
     648       477004 :       if (TREE_CODE (base) == MEM_REF)
     649       208415 :         base = TREE_OPERAND (base, 0);
     650              : 
     651              :       /* Follow the chain of SSA_NAME assignments looking for an alloca
     652              :          call (or VLA) or malloc/realloc, or for decls.  If any is found
     653              :          (and in the latter case, the operand is a local variable) issue
     654              :          a warning.  */
     655       486972 :       while (TREE_CODE (base) == SSA_NAME)
     656              :         {
     657       216640 :           gimple *def_stmt = SSA_NAME_DEF_STMT (base);
     658              : 
     659       216640 :           if (is_gimple_call (def_stmt)
     660       216640 :               && gimple_call_builtin_p (def_stmt))
     661              :             {
     662              :               /* Detect uses of uninitialized alloca/VLAs.  */
     663          142 :               tree fndecl = gimple_call_fndecl (def_stmt);
     664          142 :               const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
     665          142 :               if (fncode == BUILT_IN_ALLOCA
     666          142 :                   || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
     667           69 :                   || fncode == BUILT_IN_MALLOC)
     668          113 :                 found_alloc = true;
     669              :               break;
     670              :             }
     671              : 
     672              :           /* The C++ FE for -flifetime-dse=2 marks this parameters
     673              :              of certain constructors with "clobber *this" attribute.
     674              :              Emit uninitialized warnings if we read from what this points
     675              :              to.  This is similar to access (write_only, 1) attribute,
     676              :              except it is a -Wuninitialized warning rather than
     677              :              -Wmaybe-uninitialized and doesn't talk about access
     678              :              attribute.  */
     679       216498 :           if (SSA_NAME_IS_DEFAULT_DEF (base)
     680       173351 :               && POINTER_TYPE_P (TREE_TYPE (base))
     681       173351 :               && SSA_NAME_VAR (base)
     682       173351 :               && TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL
     683       389848 :               && lookup_attribute ("clobber *this",
     684       173350 :                                    DECL_ATTRIBUTES (SSA_NAME_VAR (base))))
     685              :             {
     686              :               found_clobber_deref_this = true;
     687              :               break;
     688              :             }
     689              : 
     690       216481 :           if (!is_gimple_assign (def_stmt))
     691              :             break;
     692              : 
     693        36241 :           tree_code code = gimple_assign_rhs_code (def_stmt);
     694        36241 :           if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
     695              :             break;
     696              : 
     697         9968 :           base = gimple_assign_rhs1 (def_stmt);
     698         9968 :           if (TREE_CODE (base) == ADDR_EXPR)
     699         1397 :             base = TREE_OPERAND (base, 0);
     700              : 
     701         9968 :           if (DECL_P (base)
     702         8972 :               || TREE_CODE (base) == COMPONENT_REF)
     703         1160 :             rhs = base;
     704              : 
     705         9968 :           if (TREE_CODE (base) == MEM_REF)
     706           15 :             base = TREE_OPERAND (base, 0);
     707              : 
     708         9968 :           if (tree ba = get_base_address (base))
     709         9968 :             base = ba;
     710              :         }
     711              : 
     712              :       /* Replace the RHS expression with BASE so that it
     713              :          refers to it in the diagnostic (instead of to
     714              :          '<unknown>').  */
     715       477004 :       if (DECL_P (base)
     716       136736 :           && EXPR_P (rhs)
     717        62449 :           && TREE_CODE (rhs) != COMPONENT_REF)
     718       477004 :         rhs = base;
     719              :     }
     720              : 
     721              :   /* Do not warn if it can be initialized outside this function.
     722              :      If we did not reach function entry then we found killing
     723              :      clobbers on all paths to entry.  */
     724       477035 :   if ((!found_alloc && !found_clobber_deref_this) && fentry_reached)
     725              :     {
     726       476874 :       if (TREE_CODE (base) == SSA_NAME)
     727              :         {
     728       206542 :           tree var = SSA_NAME_VAR (base);
     729       184626 :           if (var && TREE_CODE (var) == PARM_DECL)
     730              :             {
     731       174100 :               maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
     732       174100 :               return NULL_TREE;
     733              :             }
     734              :         }
     735              : 
     736       302774 :       if (!VAR_P (base)
     737       302774 :           || is_global_var (base))
     738              :         /* ???  We'd like to use ref_may_alias_global_p but that
     739              :            excludes global readonly memory and thus we get bogus
     740              :            warnings from p = cond ? "a" : "b" for example.  */
     741              :         return NULL_TREE;
     742              :     }
     743              : 
     744              :   /* Strip the address-of expression from arrays passed to functions. */
     745         1032 :   if (TREE_CODE (rhs) == ADDR_EXPR)
     746            0 :     rhs = TREE_OPERAND (rhs, 0);
     747              : 
     748              :   /* Check again since RHS may have changed above.  */
     749         1032 :   if (get_no_uninit_warning (rhs))
     750              :     return NULL_TREE;
     751              : 
     752              :   /* Avoid warning about empty types such as structs with no members.
     753              :      The first_field() test is important for C++ where the predicate
     754              :      alone isn't always sufficient.  */
     755         1026 :   tree rhstype = TREE_TYPE (rhs);
     756         1026 :   if (POINTER_TYPE_P (rhstype))
     757          149 :     rhstype = TREE_TYPE (rhstype);
     758         1026 :   if (is_empty_type (rhstype))
     759              :     return NULL_TREE;
     760              : 
     761          731 :   bool warned = false;
     762              :   /* We didn't find any may-defs so on all paths either
     763              :      reached function entry or a killing clobber.  */
     764          731 :   location_t location = gimple_location (stmt);
     765          731 :   if (wlims.always_executed)
     766              :     {
     767          580 :       if (warning_at (location, OPT_Wuninitialized,
     768              :                       "%qE is used uninitialized", rhs))
     769              :         {
     770              :           /* ???  This is only effective for decls as in
     771              :              gcc.dg/uninit-B-O0.c.  Avoid doing this for maybe-uninit
     772              :              uses or accesses by functions as it may hide important
     773              :              locations.  */
     774          580 :           if (lhs)
     775          402 :             set_no_uninit_warning (rhs);
     776              :           warned = true;
     777              :         }
     778              :     }
     779          151 :   else if (wlims.wmaybe_uninit)
     780          139 :     warned = warning_at (location, OPT_Wmaybe_uninitialized,
     781              :                          "%qE may be used uninitialized", rhs);
     782              : 
     783          139 :   return warned ? base : NULL_TREE;
     784              : }
     785              : 
     786              : 
     787              : /* Diagnose passing addresses of uninitialized objects to either const
     788              :    pointer arguments to functions, or to functions declared with attribute
     789              :    access implying read access to those objects.  */
     790              : 
     791              : static void
     792      1244399 : maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
     793              : {
     794      1244399 :   if (!wlims.wmaybe_uninit)
     795       765485 :     return;
     796              : 
     797       630766 :   unsigned nargs = gimple_call_num_args (stmt);
     798       630766 :   if (!nargs)
     799              :     return;
     800              : 
     801       574215 :   tree fndecl = gimple_call_fndecl (stmt);
     802      1261689 :   tree fntype = gimple_call_fntype (stmt);
     803       496204 :   if (!fntype)
     804              :     return;
     805              : 
     806              :   /* Const function do not read their arguments.  */
     807       496204 :   if (gimple_call_flags (stmt) & ECF_CONST)
     808              :     return;
     809              : 
     810       485350 :   const built_in_function fncode
     811       436194 :     = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
     812       606045 :        ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
     813              : 
     814       120695 :   if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
     815              :     /* Avoid diagnosing calls to raw memory functions (this is overly
     816              :        permissive; consider tightening it up).  */
     817              :     return;
     818              : 
     819              :   /* Save the current warning setting and replace it either a "maybe"
     820              :      when passing addresses of uninitialized variables to const-qualified
     821              :      pointers or arguments declared with attribute read_write, or with
     822              :      a "certain" when passing them to arguments declared with attribute
     823              :      read_only.  */
     824       478914 :   const bool save_always_executed = wlims.always_executed;
     825              : 
     826              :   /* Initialize a map of attribute access specifications for arguments
     827              :      to the function call.  */
     828       478914 :   rdwr_map rdwr_idx;
     829       478914 :   init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
     830              : 
     831       478914 :   tree argtype;
     832       478914 :   unsigned argno = 0;
     833       478914 :   function_args_iterator it;
     834              : 
     835      1629188 :   FOREACH_FUNCTION_ARGS (fntype, argtype, it)
     836              :     {
     837      1562831 :       ++argno;
     838              : 
     839      1562831 :       if (argno > nargs)
     840              :         break;
     841              : 
     842      1150274 :       if (!POINTER_TYPE_P (argtype))
     843      1150034 :         continue;
     844              : 
     845       578613 :       tree access_size = NULL_TREE;
     846       578613 :       const attr_access* access = rdwr_idx.get (argno - 1);
     847       578613 :       if (access)
     848              :         {
     849         2991 :           if (access->mode == access_none
     850         2828 :               || access->mode == access_write_only)
     851          395 :             continue;
     852              : 
     853         4468 :           if (access->mode == access_deferred
     854         2596 :               && !TYPE_READONLY (TREE_TYPE (argtype)))
     855         1872 :             continue;
     856              : 
     857          724 :           if (save_always_executed && access->mode == access_read_only)
     858              :             /* Attribute read_only arguments imply read access.  */
     859          236 :             wlims.always_executed = true;
     860              :           else
     861              :             /* Attribute read_write arguments are documented as requiring
     862              :                initialized objects but it's expected that aggregates may
     863              :                be only partially initialized regardless.  */
     864          488 :             wlims.always_executed = false;
     865              : 
     866          724 :           if (access->sizarg < nargs)
     867          217 :             access_size = gimple_call_arg (stmt, access->sizarg);
     868              :         }
     869       575622 :       else if (!TYPE_READONLY (TREE_TYPE (argtype)))
     870       348455 :         continue;
     871       227167 :       else if (save_always_executed && fncode != BUILT_IN_LAST)
     872              :         /* Const-qualified arguments to built-ins imply read access.  */
     873        20902 :         wlims.always_executed = true;
     874              :       else
     875              :         /* Const-qualified arguments to ordinary functions imply a likely
     876              :            (but not definitive) read access.  */
     877       206265 :         wlims.always_executed = false;
     878              : 
     879              :       /* Ignore args we are not going to read from.  */
     880       227891 :       if (gimple_call_arg_flags (stmt, argno - 1)
     881       227891 :           & (EAF_UNUSED | EAF_NO_DIRECT_READ))
     882          867 :         continue;
     883              : 
     884       227024 :       tree arg = gimple_call_arg (stmt, argno - 1);
     885       227024 :       if (!POINTER_TYPE_P (TREE_TYPE (arg)))
     886              :         /* Avoid actual arguments with invalid types.  */
     887            0 :         continue;
     888              : 
     889       227024 :       ao_ref ref;
     890       227024 :       ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
     891       227024 :       tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
     892       227024 :       if (!argbase)
     893       226784 :         continue;
     894              : 
     895          240 :       if (access && access->mode != access_deferred)
     896              :         {
     897           48 :           const char* const access_str =
     898           48 :             TREE_STRING_POINTER (access->to_external_string ());
     899              : 
     900           48 :           auto_urlify_attributes sentinel;
     901           48 :           if (fndecl)
     902              :             {
     903           48 :               location_t loc = DECL_SOURCE_LOCATION (fndecl);
     904           48 :               inform (loc, "in a call to %qD declared with "
     905              :                       "attribute %qs here", fndecl, access_str);
     906              :             }
     907              :           else
     908              :             {
     909              :               /* Handle calls through function pointers.  */
     910            0 :               location_t loc = gimple_location (stmt);
     911            0 :               inform (loc, "in a call to %qT declared with "
     912              :                       "attribute %qs", fntype, access_str);
     913              :             }
     914           48 :         }
     915              :       else
     916              :         {
     917              :           /* For a declaration with no relevant attribute access create
     918              :              a dummy object and use the formatting function to avoid
     919              :              having to complicate things here.  */
     920          192 :           attr_access ptr_access = { };
     921          192 :           if (!access)
     922          173 :             access = &ptr_access;
     923          192 :           const std::string argtypestr = access->array_as_string (argtype);
     924          192 :           if (fndecl)
     925              :             {
     926          192 :               location_t loc (DECL_SOURCE_LOCATION (fndecl));
     927          192 :               inform (loc, "by argument %u of type %s to %qD "
     928              :                       "declared here",
     929              :                       argno, argtypestr.c_str (), fndecl);
     930              :             }
     931              :           else
     932              :             {
     933              :               /* Handle calls through function pointers.  */
     934            0 :               location_t loc (gimple_location (stmt));
     935            0 :               inform (loc, "by argument %u of type %s to %qT",
     936              :                       argno, argtypestr.c_str (), fntype);
     937              :             }
     938          192 :         }
     939              : 
     940          240 :       if (DECL_P (argbase))
     941              :         {
     942          219 :           location_t loc = DECL_SOURCE_LOCATION (argbase);
     943          219 :           inform (loc, "%qD declared here", argbase);
     944              :         }
     945              :     }
     946              : 
     947       478914 :   wlims.always_executed = save_always_executed;
     948       478914 : }
     949              : 
     950              : /* Warn about an uninitialized PHI argument on the fallthru path to
     951              :    an always executed block BB.  */
     952              : 
     953              : static void
     954       403534 : warn_uninit_phi_uses (basic_block bb)
     955              : {
     956       403534 :   edge_iterator ei;
     957       403534 :   edge e, found = NULL, found_back = NULL;
     958              :   /* Look for a fallthru and possibly a single backedge.  */
     959       821739 :   FOR_EACH_EDGE (e, ei, bb->preds)
     960              :     {
     961              :       /* Ignore backedges.  */
     962       524444 :       if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
     963              :         {
     964        15153 :           if (found_back)
     965              :             {
     966              :               found = NULL;
     967              :               break;
     968              :             }
     969        14671 :           found_back = e;
     970        14671 :           continue;
     971              :         }
     972       509291 :       if (found)
     973              :         {
     974              :           found = NULL;
     975              :           break;
     976              :         }
     977              :       found = e;
     978              :     }
     979       403534 :   if (!found)
     980       106239 :     return;
     981              : 
     982       297295 :   basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
     983       329659 :   for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
     984        32364 :        gsi_next (&si))
     985              :     {
     986        32364 :       gphi *phi = si.phi ();
     987        32364 :       tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
     988        63110 :       if (TREE_CODE (def) != SSA_NAME
     989        28095 :           || !SSA_NAME_IS_DEFAULT_DEF (def)
     990        37518 :           || virtual_operand_p (def))
     991        30746 :         continue;
     992              :       /* If there's a default def on the fallthru edge PHI
     993              :          value and there's a use that post-dominates entry
     994              :          then that use is uninitialized and we can warn.  */
     995         1618 :       imm_use_iterator iter;
     996         1618 :       use_operand_p use_p;
     997         1618 :       gimple *use_stmt = NULL;
     998         7278 :       FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
     999              :         {
    1000         5102 :           use_stmt = USE_STMT (use_p);
    1001         5102 :           if (gimple_location (use_stmt) != UNKNOWN_LOCATION
    1002         4257 :               && dominated_by_p (CDI_POST_DOMINATORS, succ,
    1003         4257 :                                  gimple_bb (use_stmt))
    1004              :               /* If we found a non-fallthru edge make sure the
    1005              :                  use is inside the loop, otherwise the backedge
    1006              :                  can serve as initialization.  */
    1007         6330 :               && (!found_back
    1008         1228 :                   || dominated_by_p (CDI_DOMINATORS, found_back->src,
    1009         1228 :                                      gimple_bb (use_stmt))))
    1010              :             break;
    1011         4042 :           use_stmt = NULL;
    1012         1618 :         }
    1013         1618 :       if (use_stmt)
    1014         2120 :         warn_uninit (OPT_Wuninitialized, def,
    1015         1060 :                      SSA_NAME_VAR (def), use_stmt);
    1016              :     }
    1017              : }
    1018              : 
    1019              : /* Issue warnings about reads of uninitialized variables.  WMAYBE_UNINIT
    1020              :    is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized.  */
    1021              : 
    1022              : static void
    1023       243306 : warn_uninitialized_vars (bool wmaybe_uninit)
    1024              : {
    1025              :   /* Counters and limits controlling the depth of the warning.  */
    1026       243306 :   wlimits wlims = { };
    1027       243306 :   wlims.wmaybe_uninit = wmaybe_uninit;
    1028              : 
    1029       243306 :   auto_bb_flag ft_reachable (cfun);
    1030              : 
    1031              :   /* Mark blocks that are always executed when we ignore provably
    1032              :      not executed and EH and abnormal edges.  */
    1033       243306 :   basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1034       403597 :   while (!(bb->flags & ft_reachable))
    1035              :     {
    1036       403534 :       bb->flags |= ft_reachable;
    1037       403534 :       edge e = find_fallthru_edge (bb->succs);
    1038       403534 :       if (e && e->flags & EDGE_EXECUTABLE)
    1039              :         {
    1040        43676 :           bb = e->dest;
    1041        43676 :           continue;
    1042              :         }
    1043              :       /* Find a single executable edge.  */
    1044       359858 :       edge_iterator ei;
    1045       359858 :       edge ee = NULL;
    1046       718196 :       FOR_EACH_EDGE (e, ei, bb->succs)
    1047       506303 :         if (e->flags & EDGE_EXECUTABLE)
    1048              :           {
    1049       506100 :             if (!ee)
    1050              :               ee = e;
    1051              :             else
    1052              :               {
    1053              :                 ee = NULL;
    1054              :                 break;
    1055              :               }
    1056              :           }
    1057       359858 :       if (ee)
    1058       210170 :         bb = ee->dest;
    1059              :       else
    1060       149688 :         bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
    1061       359858 :       if (!bb || bb->index == EXIT_BLOCK)
    1062              :         break;
    1063              :     }
    1064              : 
    1065      2767928 :   FOR_EACH_BB_FN (bb, cfun)
    1066              :     {
    1067      2524622 :       wlims.always_executed = (bb->flags & ft_reachable);
    1068      2524622 :       bb->flags &= ~ft_reachable;
    1069              : 
    1070      2524622 :       edge_iterator ei;
    1071      2524622 :       edge e;
    1072      2525429 :       FOR_EACH_EDGE (e, ei, bb->preds)
    1073      2525034 :         if (e->flags & EDGE_EXECUTABLE)
    1074              :           break;
    1075              :       /* Skip unreachable blocks.  For early analysis we use VN to
    1076              :          determine edge executability when wmaybe_uninit.  */
    1077      2524622 :       if (!e)
    1078          395 :         continue;
    1079              : 
    1080      2524227 :       if (wlims.always_executed)
    1081       403534 :         warn_uninit_phi_uses (bb);
    1082              : 
    1083      2524227 :       gimple_stmt_iterator gsi;
    1084     20579691 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1085              :         {
    1086     15531237 :           gimple *stmt = gsi_stmt (gsi);
    1087              : 
    1088              :           /* The call is an artificial use, will not provide meaningful
    1089              :              error message.  If the result of the call is used somewhere
    1090              :              else, we warn there instead.  */
    1091     15531237 :           if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
    1092      8641702 :             continue;
    1093              : 
    1094     15528569 :           if (is_gimple_debug (stmt))
    1095      7420758 :             continue;
    1096              : 
    1097              :           /* We only do data flow with SSA_NAMEs, so that's all we
    1098              :              can warn about.  */
    1099      8107811 :           use_operand_p use_p;
    1100      8107811 :           ssa_op_iter op_iter;
    1101     16668845 :           FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
    1102              :             {
    1103              :               /* BIT_INSERT_EXPR first operand should not be considered
    1104              :                  a use for the purpose of uninit warnings.  */
    1105      8561034 :               if (gassign *ass = dyn_cast <gassign *> (stmt))
    1106              :                 {
    1107      5651706 :                   if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
    1108      5651706 :                       && use_p->use == gimple_assign_rhs1_ptr (ass))
    1109           21 :                     continue;
    1110              :                 }
    1111      8561013 :               tree use = USE_FROM_PTR (use_p);
    1112      8561013 :               if (wlims.always_executed)
    1113      3483032 :                 warn_uninit (OPT_Wuninitialized, use,
    1114      1741516 :                              SSA_NAME_VAR (use), stmt);
    1115      6819497 :               else if (wlims.wmaybe_uninit)
    1116      7728700 :                 warn_uninit (OPT_Wmaybe_uninitialized, use,
    1117      3864350 :                              SSA_NAME_VAR (use), stmt);
    1118              :             }
    1119              : 
    1120              :           /* For limiting the alias walk below we count all
    1121              :              vdefs in the function.  */
    1122     15112195 :           if (gimple_vdef (stmt))
    1123      2026533 :             wlims.vdef_cnt++;
    1124              : 
    1125      8107811 :           if (gcall *call = dyn_cast <gcall *> (stmt))
    1126      1244399 :             maybe_warn_pass_by_reference (call, wlims);
    1127      6863412 :           else if (gimple_assign_load_p (stmt)
    1128      6863412 :                    && gimple_has_location (stmt))
    1129              :             {
    1130      1218739 :               tree rhs = gimple_assign_rhs1 (stmt);
    1131      1218739 :               tree lhs = gimple_assign_lhs (stmt);
    1132              : 
    1133      1218739 :               ao_ref ref;
    1134      1218739 :               ao_ref_init (&ref, rhs);
    1135      1218739 :               tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
    1136      1218739 :               if (!var)
    1137      1218276 :                 continue;
    1138              : 
    1139          463 :               if (DECL_P (var))
    1140              :                 {
    1141          341 :                   location_t loc = DECL_SOURCE_LOCATION (var);
    1142          341 :                   inform (loc, "%qD declared here", var);
    1143              :                 }
    1144              :             }
    1145              :         }
    1146              :     }
    1147       243306 : }
    1148              : 
    1149              : /* Checks if the operand OPND of PHI is defined by
    1150              :    another phi with one operand defined by this PHI,
    1151              :    but the rest operands are all defined.  If yes,
    1152              :    returns true to skip this operand as being
    1153              :    redundant.  Can be enhanced to be more general.  */
    1154              : 
    1155              : static bool
    1156         1775 : can_skip_redundant_opnd (tree opnd, gimple *phi)
    1157              : {
    1158         1775 :   tree phi_def = gimple_phi_result (phi);
    1159         1775 :   gimple *op_def = SSA_NAME_DEF_STMT (opnd);
    1160         1775 :   if (gimple_code (op_def) != GIMPLE_PHI)
    1161              :     return false;
    1162              : 
    1163          717 :   unsigned n = gimple_phi_num_args (op_def);
    1164          899 :   for (unsigned i = 0; i < n; ++i)
    1165              :     {
    1166          898 :       tree op = gimple_phi_arg_def (op_def, i);
    1167          898 :       if (TREE_CODE (op) != SSA_NAME)
    1168            0 :         continue;
    1169          898 :       if (op != phi_def && uninit_undefined_value_p (op))
    1170              :         return false;
    1171              :     }
    1172              : 
    1173              :   return true;
    1174              : }
    1175              : 
    1176              : /* Return a bitset holding the positions of arguments in PHI with empty
    1177              :    (or possibly empty) definitions.  */
    1178              : 
    1179              : static unsigned
    1180       438161 : compute_uninit_opnds_pos (gphi *phi)
    1181              : {
    1182       438161 :   unsigned uninit_opnds = 0;
    1183              : 
    1184       438161 :   unsigned n = gimple_phi_num_args (phi);
    1185              :   /* Bail out for phi with too many args.  */
    1186       438161 :   if (n > uninit_analysis::func_t::max_phi_args)
    1187              :     return 0;
    1188              : 
    1189      1520010 :   for (unsigned i = 0; i < n; ++i)
    1190              :     {
    1191      1082030 :       tree op = gimple_phi_arg_def (phi, i);
    1192      1082030 :       if (TREE_CODE (op) == SSA_NAME
    1193       886355 :           && uninit_undefined_value_p (op)
    1194      1083805 :           && !can_skip_redundant_opnd (op, phi))
    1195              :         {
    1196         1774 :           if (cfun->has_nonlocal_label || cfun->calls_setjmp)
    1197              :             {
    1198              :               /* Ignore SSA_NAMEs that appear on abnormal edges
    1199              :                  somewhere.  */
    1200           91 :               if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
    1201           63 :                 continue;
    1202              :             }
    1203         1711 :           MASK_SET_BIT (uninit_opnds, i);
    1204              :         }
    1205              :     }
    1206              :   /* If we have recorded guarded uses of may-uninit values mask those.  */
    1207       437980 :   if (auto *def_mask = defined_args->get (phi))
    1208           63 :     uninit_opnds &= ~*def_mask;
    1209              :   return uninit_opnds;
    1210              : }
    1211              : 
    1212              : /* Function object type used to determine whether an expression
    1213              :    is of interest to the predicate analyzer.  */
    1214              : 
    1215              : struct uninit_undef_val_t: public uninit_analysis::func_t
    1216              : {
    1217              :   virtual unsigned phi_arg_set (gphi *) override;
    1218              : };
    1219              : 
    1220              : /* Return a bitset of PHI arguments of interest.  */
    1221              : 
    1222              : unsigned
    1223          517 : uninit_undef_val_t::phi_arg_set (gphi *phi)
    1224              : {
    1225          517 :   return compute_uninit_opnds_pos (phi);
    1226              : }
    1227              : 
    1228              : /* sort helper for find_uninit_use.  */
    1229              : 
    1230              : static int
    1231          183 : cand_cmp (const void *a, const void *b, void *data)
    1232              : {
    1233          183 :   int *bb_to_rpo = (int *)data;
    1234          183 :   const gimple *sa = *(const gimple * const *)a;
    1235          183 :   const gimple *sb = *(const gimple * const *)b;
    1236          183 :   if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
    1237              :     return -1;
    1238           92 :   else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
    1239           50 :     return 1;
    1240              :   return 0;
    1241              : }
    1242              : 
    1243              : /* Searches through all uses of a potentially
    1244              :    uninitialized variable defined by PHI and returns a use
    1245              :    statement if the use is not properly guarded.  It returns
    1246              :    NULL if all uses are guarded.  UNINIT_OPNDS is a bitvector
    1247              :    holding the position(s) of uninit PHI operands.  */
    1248              : 
    1249              : static gimple *
    1250          368 : find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
    1251              : {
    1252              :   /* The Boolean predicate guarding the PHI definition.  Initialized
    1253              :      lazily from PHI in the first call to is_use_guarded() and cached
    1254              :      for subsequent iterations.  */
    1255          368 :   uninit_undef_val_t eval;
    1256          368 :   uninit_analysis def_preds (eval);
    1257              : 
    1258              :   /* First process PHIs and record other candidates.  */
    1259          368 :   auto_vec<gimple *, 64> cands;
    1260          368 :   use_operand_p use_p;
    1261          368 :   imm_use_iterator iter;
    1262          368 :   tree phi_result = gimple_phi_result (phi);
    1263         1524 :   FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
    1264              :     {
    1265          788 :       gimple *use_stmt = USE_STMT (use_p);
    1266          788 :       if (is_gimple_debug (use_stmt))
    1267          273 :         continue;
    1268              : 
    1269              :       /* Look through a single level of SSA name copies.  This is
    1270              :          important for copies involving abnormals which we can't always
    1271              :          proapgate out but which result in spurious unguarded uses.  */
    1272          595 :       use_operand_p use2_p;
    1273          595 :       gimple *use2_stmt;
    1274          595 :       if (gimple_assign_ssa_name_copy_p (use_stmt)
    1275          595 :           && single_imm_use (gimple_assign_lhs (use_stmt), &use2_p, &use2_stmt))
    1276              :         {
    1277            8 :           use_p = use2_p;
    1278            8 :           use_stmt = use2_stmt;
    1279              :         }
    1280              : 
    1281          816 :       if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
    1282              :         {
    1283          374 :           unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p);
    1284          374 :           edge e = gimple_phi_arg_edge (use_phi, idx);
    1285              :           /* Do not look for uses in the next iteration of a loop, predicate
    1286              :              analysis will not use the appropriate predicates to prove
    1287              :              reachability.  */
    1288          374 :           if (e->flags & EDGE_DFS_BACK)
    1289           80 :             continue;
    1290              : 
    1291          344 :           basic_block use_bb = e->src;
    1292          344 :           if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
    1293              :             {
    1294              :               /* For a guarded use in a PHI record the PHI argument as
    1295              :                  initialized.  */
    1296           50 :               if (idx < uninit_analysis::func_t::max_phi_args)
    1297              :                 {
    1298           50 :                   bool existed_p;
    1299           50 :                   auto &def_mask
    1300           50 :                       = defined_args->get_or_insert (use_phi, &existed_p);
    1301           50 :                   if (!existed_p)
    1302           50 :                     def_mask = 0;
    1303           50 :                   MASK_SET_BIT (def_mask, idx);
    1304              :                 }
    1305           50 :               continue;
    1306           50 :             }
    1307              : 
    1308          294 :           if (dump_file && (dump_flags & TDF_DETAILS))
    1309              :             {
    1310            0 :               fprintf (dump_file, "Found unguarded use on edge %u -> %u: ",
    1311            0 :                        e->src->index, e->dest->index);
    1312            0 :               print_gimple_stmt (dump_file, use_stmt, 0);
    1313              :             }
    1314              :           /* Found a phi use that is not guarded, mark the use as
    1315              :              possibly undefined.  */
    1316          294 :           possibly_undefined_names->add (USE_FROM_PTR (use_p));
    1317              :         }
    1318              :       else
    1319          221 :         cands.safe_push (use_stmt);
    1320          368 :     }
    1321              : 
    1322              :   /* Sort candidates after RPO.  */
    1323          368 :   cands.stablesort (cand_cmp, bb_to_rpo);
    1324          368 :   basic_block use_bb = NULL;
    1325         1211 :   for (gimple *use_stmt : cands)
    1326              :     {
    1327              :       /* We only have to try diagnosing the first use in each block.  */
    1328          209 :       if (gimple_bb (use_stmt) == use_bb)
    1329            5 :         continue;
    1330              : 
    1331          204 :       use_bb = gimple_bb (use_stmt);
    1332          204 :       if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
    1333          102 :         continue;
    1334              : 
    1335          102 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1336              :         {
    1337            0 :           fprintf (dump_file, "Found unguarded use in bb %u: ",
    1338              :                    use_bb->index);
    1339            0 :           print_gimple_stmt (dump_file, use_stmt, 0);
    1340              :         }
    1341              :       return use_stmt;
    1342              :     }
    1343              : 
    1344              :   return NULL;
    1345          368 : }
    1346              : 
    1347              : /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
    1348              :    and gives warning if there exists a runtime path from the entry to a
    1349              :    use of the PHI def that does not contain a definition.  In other words,
    1350              :    the warning is on the real use.  The more dead paths that can be pruned
    1351              :    by the compiler, the fewer false positives the warning is.  */
    1352              : 
    1353              : static void
    1354          368 : warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
    1355              : {
    1356          368 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1357              :     {
    1358            0 :       fprintf (dump_file, "Examining phi: ");
    1359            0 :       print_gimple_stmt (dump_file, phi, 0);
    1360              :     }
    1361              : 
    1362          368 :   gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);
    1363              : 
    1364              :   /* All uses are properly guarded.  */
    1365          368 :   if (!uninit_use_stmt)
    1366              :     return;
    1367              : 
    1368          102 :   unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
    1369          102 :   tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
    1370              : 
    1371          102 :   location_t loc = UNKNOWN_LOCATION;
    1372          102 :   if (gimple_phi_arg_has_location (phi, phiarg_index))
    1373              :     loc = gimple_phi_arg_location (phi, phiarg_index);
    1374              :   else
    1375              :     {
    1376           87 :       tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
    1377           87 :       if (TREE_CODE (arg_def) == SSA_NAME)
    1378              :         {
    1379           87 :           gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
    1380           87 :           if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
    1381              :             {
    1382           15 :               unsigned uop = compute_uninit_opnds_pos (arg_phi);
    1383           15 :               unsigned idx = MASK_FIRST_SET_BIT (uop);
    1384           15 :               if (idx < gimple_phi_num_args (arg_phi)
    1385           15 :                   && gimple_phi_arg_has_location (arg_phi, idx))
    1386              :                 loc = gimple_phi_arg_location (arg_phi, idx);
    1387              :             }
    1388              :         }
    1389              :     }
    1390              : 
    1391          204 :   warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
    1392          102 :                SSA_NAME_VAR (uninit_op),
    1393              :                uninit_use_stmt, loc);
    1394              : }
    1395              : 
    1396              : static bool
    1397      3892803 : gate_warn_uninitialized (void)
    1398              : {
    1399      3650050 :   return warn_uninitialized || warn_maybe_uninitialized;
    1400              : }
    1401              : 
    1402              : namespace {
    1403              : 
    1404              : const pass_data pass_data_late_warn_uninitialized =
    1405              : {
    1406              :   GIMPLE_PASS, /* type */
    1407              :   "uninit", /* name */
    1408              :   OPTGROUP_NONE, /* optinfo_flags */
    1409              :   TV_NONE, /* tv_id */
    1410              :   PROP_ssa, /* properties_required */
    1411              :   0, /* properties_provided */
    1412              :   0, /* properties_destroyed */
    1413              :   0, /* todo_flags_start */
    1414              :   0, /* todo_flags_finish */
    1415              : };
    1416              : 
    1417              : class pass_late_warn_uninitialized : public gimple_opt_pass
    1418              : {
    1419              : public:
    1420       571444 :   pass_late_warn_uninitialized (gcc::context *ctxt)
    1421      1142888 :     : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
    1422              :   {}
    1423              : 
    1424              :   /* opt_pass methods: */
    1425       285722 :   opt_pass *clone () final override
    1426              :   {
    1427       285722 :     return new pass_late_warn_uninitialized (m_ctxt);
    1428              :   }
    1429      1044139 :   bool gate (function *) final override { return gate_warn_uninitialized (); }
    1430              :   unsigned int execute (function *) final override;
    1431              : 
    1432              : }; // class pass_late_warn_uninitialized
    1433              : 
    1434              : static void
    1435        79696 : execute_late_warn_uninitialized (function *fun)
    1436              : {
    1437        79696 :   calculate_dominance_info (CDI_DOMINATORS);
    1438        79696 :   calculate_dominance_info (CDI_POST_DOMINATORS);
    1439              : 
    1440              :   /* Mark all edges executable, warn_uninitialized_vars will skip
    1441              :      unreachable blocks.  */
    1442        79696 :   set_all_edges_as_executable (fun);
    1443        79696 :   mark_dfs_back_edges (fun);
    1444        79696 :   int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
    1445        79696 :   int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
    1446        79696 :   int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
    1447      1534151 :   for (int i = 0; i < n; ++i)
    1448      1454455 :     bb_to_rpo[rpo[i]] = i;
    1449              : 
    1450              :   /* Re-do the plain uninitialized variable check, as optimization may have
    1451              :      straightened control flow.  Do this first so that we don't accidentally
    1452              :      get a "may be" warning when we'd have seen an "is" warning later.  */
    1453        79696 :   warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
    1454              : 
    1455        79696 :   timevar_push (TV_TREE_UNINIT);
    1456              : 
    1457              :   /* Avoid quadratic beahvior when looking up case labels for edges.  */
    1458        79696 :   start_recording_case_labels ();
    1459              : 
    1460        79696 :   possibly_undefined_names = new hash_set<tree>;
    1461        79696 :   defined_args = new hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t>;
    1462              : 
    1463              :   /* Walk the CFG in RPO order so we visit PHIs with defs that are
    1464              :      possibly uninitialized from other PHIs after those.  The uninit
    1465              :      predicate analysis will then expand the PHIs predicate with
    1466              :      the predicates of the edges from such PHI defs.  */
    1467      1534151 :   for (int i = 0; i < n; ++i)
    1468      1454455 :     for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
    1469      2103679 :          !gsi_end_p (gsi); gsi_next (&gsi))
    1470              :       {
    1471       649224 :         gphi *phi = gsi.phi ();
    1472              : 
    1473              :         /* Don't look at virtual operands.  */
    1474      1298448 :         if (virtual_operand_p (gimple_phi_result (phi)))
    1475       211595 :           continue;
    1476              : 
    1477       437629 :         unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
    1478       437629 :         if (MASK_EMPTY (uninit_opnds))
    1479       437261 :           continue;
    1480              : 
    1481          368 :         warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
    1482              :       }
    1483              : 
    1484        79696 :   free (rpo);
    1485        79696 :   free (bb_to_rpo);
    1486       159392 :   delete possibly_undefined_names;
    1487        79696 :   possibly_undefined_names = NULL;
    1488       159392 :   delete defined_args;
    1489        79696 :   defined_args = NULL;
    1490        79696 :   end_recording_case_labels ();
    1491        79696 :   free_dominance_info (CDI_POST_DOMINATORS);
    1492        79696 :   timevar_pop (TV_TREE_UNINIT);
    1493        79696 : }
    1494              : 
    1495              : unsigned int
    1496        79696 : pass_late_warn_uninitialized::execute (function *fun)
    1497              : {
    1498        79696 :   execute_late_warn_uninitialized (fun);
    1499        79696 :   return 0;
    1500              : }
    1501              : 
    1502              : } // anon namespace
    1503              : 
    1504              : gimple_opt_pass *
    1505       285722 : make_pass_late_warn_uninitialized (gcc::context *ctxt)
    1506              : {
    1507       285722 :   return new pass_late_warn_uninitialized (ctxt);
    1508              : }
    1509              : 
    1510              : static unsigned int
    1511       163610 : execute_early_warn_uninitialized (struct function *fun)
    1512              : {
    1513              :   /* Currently, this pass runs always but
    1514              :      execute_late_warn_uninitialized only runs with optimization.  With
    1515              :      optimization we want to warn about possible uninitialized as late
    1516              :      as possible, thus don't do it here.  However, without
    1517              :      optimization we need to warn here about "may be uninitialized".  */
    1518       163610 :   calculate_dominance_info (CDI_DOMINATORS);
    1519       163610 :   calculate_dominance_info (CDI_POST_DOMINATORS);
    1520              : 
    1521              :   /* Use VN in its cheapest incarnation and without doing any
    1522              :      elimination to compute edge reachability.  Don't bother when
    1523              :      we only warn for unconditionally executed code though.  */
    1524       163610 :   if (!optimize)
    1525        19419 :     do_rpo_vn (fun, NULL, NULL, false, false, false, VN_NOWALK);
    1526              :   else
    1527       144191 :     set_all_edges_as_executable (fun);
    1528              : 
    1529       163610 :   warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
    1530              : 
    1531              :   /* Post-dominator information cannot be reliably updated.  Free it
    1532              :      after the use.  */
    1533              : 
    1534       163610 :   free_dominance_info (CDI_POST_DOMINATORS);
    1535       163610 :   return 0;
    1536              : }
    1537              : 
    1538              : namespace {
    1539              : 
    1540              : const pass_data pass_data_early_warn_uninitialized =
    1541              : {
    1542              :   GIMPLE_PASS, /* type */
    1543              :   "early_uninit", /* name */
    1544              :   OPTGROUP_NONE, /* optinfo_flags */
    1545              :   TV_TREE_UNINIT, /* tv_id */
    1546              :   PROP_ssa, /* properties_required */
    1547              :   0, /* properties_provided */
    1548              :   0, /* properties_destroyed */
    1549              :   0, /* todo_flags_start */
    1550              :   0, /* todo_flags_finish */
    1551              : };
    1552              : 
    1553              : class pass_early_warn_uninitialized : public gimple_opt_pass
    1554              : {
    1555              : public:
    1556       285722 :   pass_early_warn_uninitialized (gcc::context *ctxt)
    1557       571444 :     : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
    1558              :   {}
    1559              : 
    1560              :   /* opt_pass methods: */
    1561      2848664 :   bool gate (function *) final override { return gate_warn_uninitialized (); }
    1562       163610 :   unsigned int execute (function *fun) final override
    1563              :   {
    1564       163610 :     return execute_early_warn_uninitialized (fun);
    1565              :   }
    1566              : 
    1567              : }; // class pass_early_warn_uninitialized
    1568              : 
    1569              : } // anon namespace
    1570              : 
    1571              : gimple_opt_pass *
    1572       285722 : make_pass_early_warn_uninitialized (gcc::context *ctxt)
    1573              : {
    1574       285722 :   return new pass_early_warn_uninitialized (ctxt);
    1575              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.