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

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.