x86: Add a test for PR rtl-optimization/111673
[official-gcc.git] / gcc / tree-ssa-uninit.cc
blobcb82001770e855641b8c76bf14455150ee569545
1 /* Predicate aware uninitialized variable warning.
2 Copyright (C) 2001-2025 Free Software Foundation, Inc.
3 Contributed by Xinliang David Li <davidxl@google.com>
5 This file is part of GCC.
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.
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.
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/>. */
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"
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. */
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;
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 get_mask_first_set_bit (unsigned mask)
68 int pos = 0;
69 if (mask == 0)
70 return -1;
72 while ((mask & (1 << pos)) == 0)
73 pos++;
75 return pos;
77 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
79 /* Return true if T, an SSA_NAME, has an undefined value. */
80 static bool
81 has_undefined_value_p (tree t)
83 return (ssa_undefined_value_p (t)
84 || (possibly_undefined_names
85 && possibly_undefined_names->contains (t)));
88 /* Return true if EXPR should suppress either uninitialized warning. */
90 static inline bool
91 get_no_uninit_warning (tree expr)
93 return warning_suppressed_p (expr, OPT_Wuninitialized);
96 /* Suppress both uninitialized warnings for EXPR. */
98 static inline void
99 set_no_uninit_warning (tree expr)
101 suppress_warning (expr, OPT_Wuninitialized);
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. */
107 static inline bool
108 uninit_undefined_value_p (tree t)
110 if (!has_undefined_value_p (t))
111 return false;
112 if (!SSA_NAME_VAR (t))
113 return true;
114 return !get_no_uninit_warning (SSA_NAME_VAR (t));
117 /* Emit warnings for uninitialized variables. This is done in two passes.
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.
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. */
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. */
138 static void
139 warn_uninit (opt_code opt, tree t, tree var, gimple *context,
140 location_t phi_arg_loc = UNKNOWN_LOCATION)
142 /* Bail if the value isn't provably uninitialized. */
143 if (!has_undefined_value_p (t))
144 return;
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 if (is_gimple_assign (context)
150 && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
151 return;
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:
156 1 typedef _Complex float C;
157 2 C foo (int cond)
159 4 C f;
160 5 __imag__ f = 0;
161 6 if (cond)
163 8 __real__ f = 1;
164 9 return f;
165 10 }
166 11 return f;
167 12 }
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>;
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 if (is_gimple_assign (context)
178 && (gimple_assign_rhs_code (context) == REALPART_EXPR
179 || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
181 tree v = gimple_assign_rhs1 (context);
182 if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
183 && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
184 IFN_DEFERRED_INIT))
185 return;
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.
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. */
201 const char *var_name_str = NULL;
202 gimple *var_def_stmt = NULL;
204 if (!var && !SSA_NAME_VAR (t))
206 var_def_stmt = SSA_NAME_DEF_STMT (t);
208 if (gassign *ass = dyn_cast <gassign *> (var_def_stmt))
210 switch (gimple_assign_rhs_code (var_def_stmt))
212 case COMPLEX_EXPR:
214 tree v = gimple_assign_rhs1 (ass);
215 if (TREE_CODE (v) == SSA_NAME
216 && has_undefined_value_p (v)
217 && zerop (gimple_assign_rhs2 (ass)))
218 var = SSA_NAME_VAR (v);
219 break;
221 case SSA_NAME:
223 tree v = gimple_assign_rhs1 (ass);
224 if (TREE_CODE (v) == SSA_NAME
225 && SSA_NAME_VAR (v))
226 var = SSA_NAME_VAR (v);
227 break;
229 default:;
233 if (gimple_call_internal_p (var_def_stmt, IFN_DEFERRED_INIT))
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.
242 tree lhs_var = NULL_TREE;
244 /* Get the variable name from the 3rd argument of call. */
245 tree var_name = gimple_call_arg (var_def_stmt, 2);
246 var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
247 var_name_str = TREE_STRING_POINTER (var_name);
249 if (is_gimple_assign (context))
251 if (VAR_P (gimple_assign_lhs (context)))
252 lhs_var = gimple_assign_lhs (context);
253 else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME)
254 lhs_var = SSA_NAME_VAR (gimple_assign_lhs (context));
256 if (lhs_var)
258 /* Get the name string for the LHS_VAR.
259 Refer to routine gimple_add_init_for_auto_var. */
260 if (DECL_NAME (lhs_var)
261 && (strcmp (IDENTIFIER_POINTER (DECL_NAME (lhs_var)),
262 var_name_str) == 0))
263 return;
264 else if (!DECL_NAME (lhs_var))
266 char lhs_var_name_str_buf[3 + (HOST_BITS_PER_INT + 2) / 3];
267 sprintf (lhs_var_name_str_buf, "D.%u", DECL_UID (lhs_var));
268 if (strcmp (lhs_var_name_str_buf, var_name_str) == 0)
269 return;
272 gcc_assert (var_name_str && var_def_stmt);
276 if (var == NULL_TREE && var_name_str == NULL)
277 return;
279 /* Avoid warning if we've already done so or if the warning has been
280 suppressed. */
281 if (((warning_suppressed_p (context, OPT_Wuninitialized)
282 || (gimple_assign_single_p (context)
283 && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
284 || (var && get_no_uninit_warning (var))
285 || (var_name_str
286 && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
287 return;
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 location_t location = UNKNOWN_LOCATION;
293 if (gimple_has_location (context))
294 location = gimple_location (context);
295 else if (phi_arg_loc != UNKNOWN_LOCATION)
296 location = phi_arg_loc;
297 else if (var)
298 location = DECL_SOURCE_LOCATION (var);
299 else if (var_name_str)
300 location = gimple_location (var_def_stmt);
302 auto_diagnostic_group d;
303 gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
304 if (var)
306 if ((opt == OPT_Wuninitialized
307 && !warning_at (location, opt, "%qD is used uninitialized", var))
308 || (opt == OPT_Wmaybe_uninitialized
309 && !warning_at (location, opt, "%qD may be used uninitialized",
310 var)))
311 return;
313 else if (var_name_str)
315 if ((opt == OPT_Wuninitialized
316 && !warning_at (location, opt, "%qs is used uninitialized",
317 var_name_str))
318 || (opt == OPT_Wmaybe_uninitialized
319 && !warning_at (location, opt, "%qs may be used uninitialized",
320 var_name_str)))
321 return;
324 /* Avoid subsequent warnings for reads of the same variable again. */
325 if (var)
326 suppress_warning (var, opt);
327 else if (var_name_str)
328 suppress_warning (var_def_stmt, opt);
330 /* Issue a note pointing to the read variable unless the warning
331 is at the same location. */
332 location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
333 : gimple_location (var_def_stmt);
334 if (location == var_loc)
335 return;
337 if (var)
338 inform (var_loc, "%qD was declared here", var);
339 else if (var_name_str)
340 inform (var_loc, "%qs was declared here", var_name_str);
343 struct check_defs_data
345 /* If we found any may-defs besides must-def clobbers. */
346 bool found_may_defs;
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). */
353 static bool
354 builtin_call_nomodifying_p (gimple *stmt)
356 if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
357 return false;
359 tree fndecl = gimple_call_fndecl (stmt);
360 if (!fndecl)
361 return false;
363 tree fntype = TREE_TYPE (fndecl);
364 if (!fntype)
365 return false;
367 /* Check the called function's signature for non-constc pointers.
368 If one is found, return false. */
369 unsigned argno = 0;
370 tree argtype;
371 function_args_iterator it;
372 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
374 if (VOID_TYPE_P (argtype))
375 return true;
377 ++argno;
379 if (!POINTER_TYPE_P (argtype))
380 continue;
382 if (TYPE_READONLY (TREE_TYPE (argtype)))
383 continue;
385 return false;
388 /* If the number of actual arguments to the call is less than or
389 equal to the number of parameters, return false. */
390 unsigned nargs = gimple_call_num_args (stmt);
391 if (nargs <= argno)
392 return false;
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 for (; argno < nargs; ++argno)
399 tree arg = gimple_call_arg (stmt, argno);
400 argtype = TREE_TYPE (arg);
401 if (!POINTER_TYPE_P (argtype))
402 continue;
404 if (TYPE_READONLY (TREE_TYPE (argtype)))
405 continue;
407 return false;
410 return true;
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. */
416 static void
417 maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
419 if (!fndecl)
420 return;
422 if (get_no_uninit_warning (arg))
423 return;
425 tree fntype = TREE_TYPE (fndecl);
426 if (!fntype)
427 return;
429 /* Initialize a map of attribute access specifications for arguments
430 to the function call. */
431 rdwr_map rdwr_idx;
432 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
434 unsigned argno = 0;
435 tree parms = DECL_ARGUMENTS (fndecl);
436 for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
438 if (parm != arg)
439 continue;
441 const attr_access* access = rdwr_idx.get (argno);
442 if (!access)
443 break;
445 if (access->mode != access_none
446 && access->mode != access_write_only)
447 continue;
449 location_t stmtloc = gimple_location (stmt);
450 if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
451 "%qE may be used uninitialized", ptr))
452 break;
454 suppress_warning (arg, OPT_Wmaybe_uninitialized);
456 const char* const access_str =
457 TREE_STRING_POINTER (access->to_external_string ());
459 auto_urlify_attributes sentinel;
460 location_t parmloc = DECL_SOURCE_LOCATION (parm);
461 inform (parmloc, "accessing argument %u of a function declared with "
462 "attribute %qs",
463 argno + 1, access_str);
465 break;
469 /* Callback for walk_aliased_vdefs. */
471 static bool
472 check_defs (ao_ref *ref, tree vdef, void *data_)
474 check_defs_data *data = (check_defs_data *)data_;
475 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
477 /* Ignore the vdef if the definition statement is a call
478 to .DEFERRED_INIT function. */
479 if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
480 return false;
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 if (is_gimple_assign (def_stmt)
488 && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
490 tree tmp_var = gimple_assign_rhs1 (def_stmt);
491 if (gimple_call_internal_p (SSA_NAME_DEF_STMT (tmp_var),
492 IFN_DEFERRED_INIT))
493 return false;
496 /* The ASAN_MARK intrinsic doesn't modify the variable. */
497 if (is_gimple_call (def_stmt))
499 /* The ASAN_MARK intrinsic doesn't modify the variable. */
500 if (gimple_call_internal_p (def_stmt)
501 && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
502 return false;
504 if (tree fndecl = gimple_call_fndecl (def_stmt))
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 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
511 built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
512 if (fncode > BEGIN_SANITIZER_BUILTINS
513 && fncode < END_SANITIZER_BUILTINS)
514 return false;
519 /* End of VLA scope is not a kill. */
520 if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
521 return false;
523 /* If this is a clobber then if it is not a kill walk past it. */
524 if (gimple_clobber_p (def_stmt))
526 if (stmt_kills_ref_p (def_stmt, ref))
527 return true;
528 return false;
531 if (builtin_call_nomodifying_p (def_stmt))
532 return false;
534 /* Found a may-def on this path. */
535 data->found_may_defs = true;
536 return true;
539 /* Counters and limits controlling the depth of analysis and
540 strictness of the warning. */
541 struct wlimits
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;
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. */
560 static tree
561 maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
562 wlimits &wlims)
564 bool has_bit_insert = false;
565 use_operand_p luse_p;
566 imm_use_iterator liter;
568 if (get_no_uninit_warning (rhs))
569 return NULL_TREE;
571 /* Do not warn if the base was marked so or this is a
572 hard register var. */
573 tree base = ao_ref_base (&ref);
574 if ((VAR_P (base)
575 && DECL_HARD_REGISTER (base))
576 || get_no_uninit_warning (base))
577 return NULL_TREE;
579 /* Do not warn if the access is zero size or if it's fully outside
580 the object. */
581 poly_int64 decl_size;
582 if (known_size_p (ref.size)
583 && known_eq (ref.max_size, ref.size)
584 && (known_eq (ref.size, 0)
585 || known_le (ref.offset + ref.size, 0)))
586 return NULL_TREE;
588 if (DECL_P (base)
589 && known_ge (ref.offset, 0)
590 && DECL_SIZE (base)
591 && poly_int_tree_p (DECL_SIZE (base), &decl_size)
592 && known_le (decl_size, ref.offset))
593 return NULL_TREE;
595 /* Do not warn if the result of the access is then used for
596 a BIT_INSERT_EXPR. */
597 if (lhs && TREE_CODE (lhs) == SSA_NAME)
598 FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
600 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 if (gassign *ass = dyn_cast <gassign *> (use_stmt))
605 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
606 && luse_p->use == gimple_assign_rhs1_ptr (ass))
608 has_bit_insert = true;
609 break;
614 if (has_bit_insert)
615 return NULL_TREE;
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 if (wlims.oracle_cnt > 128 * 128
621 && wlims.oracle_cnt > wlims.vdef_cnt * 2)
622 wlims.limit = 32;
624 check_defs_data data;
625 bool fentry_reached = false;
626 data.found_may_defs = false;
627 tree use = gimple_vuse (stmt);
628 if (!use)
629 return NULL_TREE;
630 int res = walk_aliased_vdefs (&ref, use,
631 check_defs, &data, NULL,
632 &fentry_reached, wlims.limit);
633 if (res == -1)
635 wlims.oracle_cnt += wlims.limit;
636 return NULL_TREE;
639 wlims.oracle_cnt += res;
640 if (data.found_may_defs)
641 return NULL_TREE;
643 bool found_alloc = false;
645 if (fentry_reached)
647 if (TREE_CODE (base) == MEM_REF)
648 base = TREE_OPERAND (base, 0);
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 while (TREE_CODE (base) == SSA_NAME)
656 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
658 if (is_gimple_call (def_stmt)
659 && gimple_call_builtin_p (def_stmt))
661 /* Detect uses of uninitialized alloca/VLAs. */
662 tree fndecl = gimple_call_fndecl (def_stmt);
663 const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
664 if (fncode == BUILT_IN_ALLOCA
665 || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
666 || fncode == BUILT_IN_MALLOC)
667 found_alloc = true;
668 break;
671 if (!is_gimple_assign (def_stmt))
672 break;
674 tree_code code = gimple_assign_rhs_code (def_stmt);
675 if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
676 break;
678 base = gimple_assign_rhs1 (def_stmt);
679 if (TREE_CODE (base) == ADDR_EXPR)
680 base = TREE_OPERAND (base, 0);
682 if (DECL_P (base)
683 || TREE_CODE (base) == COMPONENT_REF)
684 rhs = base;
686 if (TREE_CODE (base) == MEM_REF)
687 base = TREE_OPERAND (base, 0);
689 if (tree ba = get_base_address (base))
690 base = ba;
693 /* Replace the RHS expression with BASE so that it
694 refers to it in the diagnostic (instead of to
695 '<unknown>'). */
696 if (DECL_P (base)
697 && EXPR_P (rhs)
698 && TREE_CODE (rhs) != COMPONENT_REF)
699 rhs = base;
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 if (!found_alloc && fentry_reached)
707 if (TREE_CODE (base) == SSA_NAME)
709 tree var = SSA_NAME_VAR (base);
710 if (var && TREE_CODE (var) == PARM_DECL)
712 maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
713 return NULL_TREE;
717 if (!VAR_P (base)
718 || 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;
725 /* Strip the address-of expression from arrays passed to functions. */
726 if (TREE_CODE (rhs) == ADDR_EXPR)
727 rhs = TREE_OPERAND (rhs, 0);
729 /* Check again since RHS may have changed above. */
730 if (get_no_uninit_warning (rhs))
731 return NULL_TREE;
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 tree rhstype = TREE_TYPE (rhs);
737 if (POINTER_TYPE_P (rhstype))
738 rhstype = TREE_TYPE (rhstype);
739 if (is_empty_type (rhstype))
740 return NULL_TREE;
742 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 location_t location = gimple_location (stmt);
746 if (wlims.always_executed)
748 if (warning_at (location, OPT_Wuninitialized,
749 "%qE is used uninitialized", rhs))
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 if (lhs)
756 set_no_uninit_warning (rhs);
757 warned = true;
760 else if (wlims.wmaybe_uninit)
761 warned = warning_at (location, OPT_Wmaybe_uninitialized,
762 "%qE may be used uninitialized", rhs);
764 return warned ? base : NULL_TREE;
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. */
772 static void
773 maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
775 if (!wlims.wmaybe_uninit)
776 return;
778 unsigned nargs = gimple_call_num_args (stmt);
779 if (!nargs)
780 return;
782 tree fndecl = gimple_call_fndecl (stmt);
783 tree fntype = gimple_call_fntype (stmt);
784 if (!fntype)
785 return;
787 /* Const function do not read their arguments. */
788 if (gimple_call_flags (stmt) & ECF_CONST)
789 return;
791 const built_in_function fncode
792 = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
793 ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
795 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;
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 const bool save_always_executed = wlims.always_executed;
807 /* Initialize a map of attribute access specifications for arguments
808 to the function call. */
809 rdwr_map rdwr_idx;
810 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
812 tree argtype;
813 unsigned argno = 0;
814 function_args_iterator it;
816 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
818 ++argno;
820 if (argno > nargs)
821 break;
823 if (!POINTER_TYPE_P (argtype))
824 continue;
826 tree access_size = NULL_TREE;
827 const attr_access* access = rdwr_idx.get (argno - 1);
828 if (access)
830 if (access->mode == access_none
831 || access->mode == access_write_only)
832 continue;
834 if (access->mode == access_deferred
835 && !TYPE_READONLY (TREE_TYPE (argtype)))
836 continue;
838 if (save_always_executed && access->mode == access_read_only)
839 /* Attribute read_only arguments imply read access. */
840 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 wlims.always_executed = false;
847 if (access->sizarg < nargs)
848 access_size = gimple_call_arg (stmt, access->sizarg);
850 else if (!TYPE_READONLY (TREE_TYPE (argtype)))
851 continue;
852 else if (save_always_executed && fncode != BUILT_IN_LAST)
853 /* Const-qualified arguments to built-ins imply read access. */
854 wlims.always_executed = true;
855 else
856 /* Const-qualified arguments to ordinary functions imply a likely
857 (but not definitive) read access. */
858 wlims.always_executed = false;
860 /* Ignore args we are not going to read from. */
861 if (gimple_call_arg_flags (stmt, argno - 1)
862 & (EAF_UNUSED | EAF_NO_DIRECT_READ))
863 continue;
865 tree arg = gimple_call_arg (stmt, argno - 1);
866 if (!POINTER_TYPE_P (TREE_TYPE (arg)))
867 /* Avoid actual arguments with invalid types. */
868 continue;
870 ao_ref ref;
871 ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
872 tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
873 if (!argbase)
874 continue;
876 if (access && access->mode != access_deferred)
878 const char* const access_str =
879 TREE_STRING_POINTER (access->to_external_string ());
881 auto_urlify_attributes sentinel;
882 if (fndecl)
884 location_t loc = DECL_SOURCE_LOCATION (fndecl);
885 inform (loc, "in a call to %qD declared with "
886 "attribute %qs here", fndecl, access_str);
888 else
890 /* Handle calls through function pointers. */
891 location_t loc = gimple_location (stmt);
892 inform (loc, "in a call to %qT declared with "
893 "attribute %qs", fntype, access_str);
896 else
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 attr_access ptr_access = { };
902 if (!access)
903 access = &ptr_access;
904 const std::string argtypestr = access->array_as_string (argtype);
905 if (fndecl)
907 location_t loc (DECL_SOURCE_LOCATION (fndecl));
908 inform (loc, "by argument %u of type %s to %qD "
909 "declared here",
910 argno, argtypestr.c_str (), fndecl);
912 else
914 /* Handle calls through function pointers. */
915 location_t loc (gimple_location (stmt));
916 inform (loc, "by argument %u of type %s to %qT",
917 argno, argtypestr.c_str (), fntype);
921 if (DECL_P (argbase))
923 location_t loc = DECL_SOURCE_LOCATION (argbase);
924 inform (loc, "%qD declared here", argbase);
928 wlims.always_executed = save_always_executed;
931 /* Warn about an uninitialized PHI argument on the fallthru path to
932 an always executed block BB. */
934 static void
935 warn_uninit_phi_uses (basic_block bb)
937 edge_iterator ei;
938 edge e, found = NULL, found_back = NULL;
939 /* Look for a fallthru and possibly a single backedge. */
940 FOR_EACH_EDGE (e, ei, bb->preds)
942 /* Ignore backedges. */
943 if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
945 if (found_back)
947 found = NULL;
948 break;
950 found_back = e;
951 continue;
953 if (found)
955 found = NULL;
956 break;
958 found = e;
960 if (!found)
961 return;
963 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
964 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
965 gsi_next (&si))
967 gphi *phi = si.phi ();
968 tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
969 if (TREE_CODE (def) != SSA_NAME
970 || !SSA_NAME_IS_DEFAULT_DEF (def)
971 || virtual_operand_p (def))
972 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 imm_use_iterator iter;
977 use_operand_p use_p;
978 gimple *use_stmt = NULL;
979 FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
981 use_stmt = USE_STMT (use_p);
982 if (gimple_location (use_stmt) != UNKNOWN_LOCATION
983 && dominated_by_p (CDI_POST_DOMINATORS, succ,
984 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 && (!found_back
989 || dominated_by_p (CDI_DOMINATORS, found_back->src,
990 gimple_bb (use_stmt))))
991 break;
992 use_stmt = NULL;
994 if (use_stmt)
995 warn_uninit (OPT_Wuninitialized, def,
996 SSA_NAME_VAR (def), use_stmt);
1000 /* Issue warnings about reads of uninitialized variables. WMAYBE_UNINIT
1001 is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized. */
1003 static void
1004 warn_uninitialized_vars (bool wmaybe_uninit)
1006 /* Counters and limits controlling the depth of the warning. */
1007 wlimits wlims = { };
1008 wlims.wmaybe_uninit = wmaybe_uninit;
1010 auto_bb_flag ft_reachable (cfun);
1012 /* Mark blocks that are always executed when we ignore provably
1013 not executed and EH and abnormal edges. */
1014 basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1015 while (!(bb->flags & ft_reachable))
1017 bb->flags |= ft_reachable;
1018 edge e = find_fallthru_edge (bb->succs);
1019 if (e && e->flags & EDGE_EXECUTABLE)
1021 bb = e->dest;
1022 continue;
1024 /* Find a single executable edge. */
1025 edge_iterator ei;
1026 edge ee = NULL;
1027 FOR_EACH_EDGE (e, ei, bb->succs)
1028 if (e->flags & EDGE_EXECUTABLE)
1030 if (!ee)
1031 ee = e;
1032 else
1034 ee = NULL;
1035 break;
1038 if (ee)
1039 bb = ee->dest;
1040 else
1041 bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1042 if (!bb || bb->index == EXIT_BLOCK)
1043 break;
1046 FOR_EACH_BB_FN (bb, cfun)
1048 wlims.always_executed = (bb->flags & ft_reachable);
1049 bb->flags &= ~ft_reachable;
1051 edge_iterator ei;
1052 edge e;
1053 FOR_EACH_EDGE (e, ei, bb->preds)
1054 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 if (!e)
1059 continue;
1061 if (wlims.always_executed)
1062 warn_uninit_phi_uses (bb);
1064 gimple_stmt_iterator gsi;
1065 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1067 gimple *stmt = gsi_stmt (gsi);
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 if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
1073 continue;
1075 if (is_gimple_debug (stmt))
1076 continue;
1078 /* We only do data flow with SSA_NAMEs, so that's all we
1079 can warn about. */
1080 use_operand_p use_p;
1081 ssa_op_iter op_iter;
1082 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
1084 /* BIT_INSERT_EXPR first operand should not be considered
1085 a use for the purpose of uninit warnings. */
1086 if (gassign *ass = dyn_cast <gassign *> (stmt))
1088 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
1089 && use_p->use == gimple_assign_rhs1_ptr (ass))
1090 continue;
1092 tree use = USE_FROM_PTR (use_p);
1093 if (wlims.always_executed)
1094 warn_uninit (OPT_Wuninitialized, use,
1095 SSA_NAME_VAR (use), stmt);
1096 else if (wlims.wmaybe_uninit)
1097 warn_uninit (OPT_Wmaybe_uninitialized, use,
1098 SSA_NAME_VAR (use), stmt);
1101 /* For limiting the alias walk below we count all
1102 vdefs in the function. */
1103 if (gimple_vdef (stmt))
1104 wlims.vdef_cnt++;
1106 if (gcall *call = dyn_cast <gcall *> (stmt))
1107 maybe_warn_pass_by_reference (call, wlims);
1108 else if (gimple_assign_load_p (stmt)
1109 && gimple_has_location (stmt))
1111 tree rhs = gimple_assign_rhs1 (stmt);
1112 tree lhs = gimple_assign_lhs (stmt);
1114 ao_ref ref;
1115 ao_ref_init (&ref, rhs);
1116 tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
1117 if (!var)
1118 continue;
1120 if (DECL_P (var))
1122 location_t loc = DECL_SOURCE_LOCATION (var);
1123 inform (loc, "%qD declared here", var);
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. */
1136 static bool
1137 can_skip_redundant_opnd (tree opnd, gimple *phi)
1139 tree phi_def = gimple_phi_result (phi);
1140 gimple *op_def = SSA_NAME_DEF_STMT (opnd);
1141 if (gimple_code (op_def) != GIMPLE_PHI)
1142 return false;
1144 unsigned n = gimple_phi_num_args (op_def);
1145 for (unsigned i = 0; i < n; ++i)
1147 tree op = gimple_phi_arg_def (op_def, i);
1148 if (TREE_CODE (op) != SSA_NAME)
1149 continue;
1150 if (op != phi_def && uninit_undefined_value_p (op))
1151 return false;
1154 return true;
1157 /* Return a bitset holding the positions of arguments in PHI with empty
1158 (or possibly empty) definitions. */
1160 static unsigned
1161 compute_uninit_opnds_pos (gphi *phi)
1163 unsigned uninit_opnds = 0;
1165 unsigned n = gimple_phi_num_args (phi);
1166 /* Bail out for phi with too many args. */
1167 if (n > uninit_analysis::func_t::max_phi_args)
1168 return 0;
1170 for (unsigned i = 0; i < n; ++i)
1172 tree op = gimple_phi_arg_def (phi, i);
1173 if (TREE_CODE (op) == SSA_NAME
1174 && uninit_undefined_value_p (op)
1175 && !can_skip_redundant_opnd (op, phi))
1177 if (cfun->has_nonlocal_label || cfun->calls_setjmp)
1179 /* Ignore SSA_NAMEs that appear on abnormal edges
1180 somewhere. */
1181 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
1182 continue;
1184 MASK_SET_BIT (uninit_opnds, i);
1187 /* If we have recorded guarded uses of may-uninit values mask those. */
1188 if (auto *def_mask = defined_args->get (phi))
1189 uninit_opnds &= ~*def_mask;
1190 return uninit_opnds;
1193 /* Function object type used to determine whether an expression
1194 is of interest to the predicate analyzer. */
1196 struct uninit_undef_val_t: public uninit_analysis::func_t
1198 virtual unsigned phi_arg_set (gphi *) override;
1201 /* Return a bitset of PHI arguments of interest. */
1203 unsigned
1204 uninit_undef_val_t::phi_arg_set (gphi *phi)
1206 return compute_uninit_opnds_pos (phi);
1209 /* sort helper for find_uninit_use. */
1211 static int
1212 cand_cmp (const void *a, const void *b, void *data)
1214 int *bb_to_rpo = (int *)data;
1215 const gimple *sa = *(const gimple * const *)a;
1216 const gimple *sb = *(const gimple * const *)b;
1217 if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
1218 return -1;
1219 else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
1220 return 1;
1221 return 0;
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. */
1230 static gimple *
1231 find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
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 uninit_undef_val_t eval;
1237 uninit_analysis def_preds (eval);
1239 /* First process PHIs and record other candidates. */
1240 auto_vec<gimple *, 64> cands;
1241 use_operand_p use_p;
1242 imm_use_iterator iter;
1243 tree phi_result = gimple_phi_result (phi);
1244 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1246 gimple *use_stmt = USE_STMT (use_p);
1247 if (is_gimple_debug (use_stmt))
1248 continue;
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 use_operand_p use2_p;
1254 gimple *use2_stmt;
1255 if (gimple_assign_ssa_name_copy_p (use_stmt)
1256 && single_imm_use (gimple_assign_lhs (use_stmt), &use2_p, &use2_stmt))
1258 use_p = use2_p;
1259 use_stmt = use2_stmt;
1262 if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1264 unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p);
1265 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 if (e->flags & EDGE_DFS_BACK)
1270 continue;
1272 basic_block use_bb = e->src;
1273 if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1275 /* For a guarded use in a PHI record the PHI argument as
1276 initialized. */
1277 if (idx < uninit_analysis::func_t::max_phi_args)
1279 bool existed_p;
1280 auto &def_mask
1281 = defined_args->get_or_insert (use_phi, &existed_p);
1282 if (!existed_p)
1283 def_mask = 0;
1284 MASK_SET_BIT (def_mask, idx);
1286 continue;
1289 if (dump_file && (dump_flags & TDF_DETAILS))
1291 fprintf (dump_file, "Found unguarded use on edge %u -> %u: ",
1292 e->src->index, e->dest->index);
1293 print_gimple_stmt (dump_file, use_stmt, 0);
1295 /* Found a phi use that is not guarded, mark the use as
1296 possibly undefined. */
1297 possibly_undefined_names->add (USE_FROM_PTR (use_p));
1299 else
1300 cands.safe_push (use_stmt);
1303 /* Sort candidates after RPO. */
1304 cands.stablesort (cand_cmp, bb_to_rpo);
1305 basic_block use_bb = NULL;
1306 for (gimple *use_stmt : cands)
1308 /* We only have to try diagnosing the first use in each block. */
1309 if (gimple_bb (use_stmt) == use_bb)
1310 continue;
1312 use_bb = gimple_bb (use_stmt);
1313 if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1314 continue;
1316 if (dump_file && (dump_flags & TDF_DETAILS))
1318 fprintf (dump_file, "Found unguarded use in bb %u: ",
1319 use_bb->index);
1320 print_gimple_stmt (dump_file, use_stmt, 0);
1322 return use_stmt;
1325 return NULL;
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. */
1334 static void
1335 warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1337 if (dump_file && (dump_flags & TDF_DETAILS))
1339 fprintf (dump_file, "Examining phi: ");
1340 print_gimple_stmt (dump_file, phi, 0);
1343 gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);
1345 /* All uses are properly guarded. */
1346 if (!uninit_use_stmt)
1347 return;
1349 unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1350 tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1352 location_t loc = UNKNOWN_LOCATION;
1353 if (gimple_phi_arg_has_location (phi, phiarg_index))
1354 loc = gimple_phi_arg_location (phi, phiarg_index);
1355 else
1357 tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1358 if (TREE_CODE (arg_def) == SSA_NAME)
1360 gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1361 if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1363 unsigned uop = compute_uninit_opnds_pos (arg_phi);
1364 unsigned idx = MASK_FIRST_SET_BIT (uop);
1365 if (idx < gimple_phi_num_args (arg_phi)
1366 && gimple_phi_arg_has_location (arg_phi, idx))
1367 loc = gimple_phi_arg_location (arg_phi, idx);
1372 warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1373 SSA_NAME_VAR (uninit_op),
1374 uninit_use_stmt, loc);
1377 static bool
1378 gate_warn_uninitialized (void)
1380 return warn_uninitialized || warn_maybe_uninitialized;
1383 namespace {
1385 const pass_data pass_data_late_warn_uninitialized =
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 */
1398 class pass_late_warn_uninitialized : public gimple_opt_pass
1400 public:
1401 pass_late_warn_uninitialized (gcc::context *ctxt)
1402 : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1405 /* opt_pass methods: */
1406 opt_pass *clone () final override
1408 return new pass_late_warn_uninitialized (m_ctxt);
1410 bool gate (function *) final override { return gate_warn_uninitialized (); }
1411 unsigned int execute (function *) final override;
1413 }; // class pass_late_warn_uninitialized
1415 static void
1416 execute_late_warn_uninitialized (function *fun)
1418 calculate_dominance_info (CDI_DOMINATORS);
1419 calculate_dominance_info (CDI_POST_DOMINATORS);
1421 /* Mark all edges executable, warn_uninitialized_vars will skip
1422 unreachable blocks. */
1423 set_all_edges_as_executable (fun);
1424 mark_dfs_back_edges (fun);
1425 int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
1426 int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
1427 int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
1428 for (int i = 0; i < n; ++i)
1429 bb_to_rpo[rpo[i]] = i;
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 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1436 timevar_push (TV_TREE_UNINIT);
1438 /* Avoid quadratic beahvior when looking up case labels for edges. */
1439 start_recording_case_labels ();
1441 possibly_undefined_names = new hash_set<tree>;
1442 defined_args = new hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t>;
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 for (int i = 0; i < n; ++i)
1449 for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
1450 !gsi_end_p (gsi); gsi_next (&gsi))
1452 gphi *phi = gsi.phi ();
1454 /* Don't look at virtual operands. */
1455 if (virtual_operand_p (gimple_phi_result (phi)))
1456 continue;
1458 unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1459 if (MASK_EMPTY (uninit_opnds))
1460 continue;
1462 warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
1465 free (rpo);
1466 free (bb_to_rpo);
1467 delete possibly_undefined_names;
1468 possibly_undefined_names = NULL;
1469 delete defined_args;
1470 defined_args = NULL;
1471 end_recording_case_labels ();
1472 free_dominance_info (CDI_POST_DOMINATORS);
1473 timevar_pop (TV_TREE_UNINIT);
1476 unsigned int
1477 pass_late_warn_uninitialized::execute (function *fun)
1479 execute_late_warn_uninitialized (fun);
1480 return 0;
1483 } // anon namespace
1485 gimple_opt_pass *
1486 make_pass_late_warn_uninitialized (gcc::context *ctxt)
1488 return new pass_late_warn_uninitialized (ctxt);
1491 static unsigned int
1492 execute_early_warn_uninitialized (struct function *fun)
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 calculate_dominance_info (CDI_DOMINATORS);
1500 calculate_dominance_info (CDI_POST_DOMINATORS);
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 if (!optimize)
1506 do_rpo_vn (fun, NULL, NULL, false, false, false, VN_NOWALK);
1507 else
1508 set_all_edges_as_executable (fun);
1510 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1512 /* Post-dominator information cannot be reliably updated. Free it
1513 after the use. */
1515 free_dominance_info (CDI_POST_DOMINATORS);
1516 return 0;
1519 namespace {
1521 const pass_data pass_data_early_warn_uninitialized =
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 */
1534 class pass_early_warn_uninitialized : public gimple_opt_pass
1536 public:
1537 pass_early_warn_uninitialized (gcc::context *ctxt)
1538 : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1541 /* opt_pass methods: */
1542 bool gate (function *) final override { return gate_warn_uninitialized (); }
1543 unsigned int execute (function *fun) final override
1545 return execute_early_warn_uninitialized (fun);
1548 }; // class pass_early_warn_uninitialized
1550 } // anon namespace
1552 gimple_opt_pass *
1553 make_pass_early_warn_uninitialized (gcc::context *ctxt)
1555 return new pass_early_warn_uninitialized (ctxt);