LCOV - code coverage report
Current view: top level - gcc - tree-ssa-uninit.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.5 % 624 602
Test Date: 2024-04-13 14:00:49 Functions: 92.6 % 27 25
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.