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 : : }
|