hppa: Revise REG+D address support to allow long displacements before reload
[official-gcc.git] / gcc / tree-ssa-uninit.cc
blobf42f76cd5c62dbd43ccaff2adc729f081b13a919
1 /* Predicate aware uninitialized variable warning.
2 Copyright (C) 2001-2023 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"
46 /* This implements the pass that does predicate aware warning on uses of
47 possibly uninitialized variables. The pass first collects the set of
48 possibly uninitialized SSA names. For each such name, it walks through
49 all its immediate uses. For each immediate use, it rebuilds the condition
50 expression (the predicate) that guards the use. The predicate is then
51 examined to see if the variable is always defined under that same condition.
52 This is done either by pruning the unrealizable paths that lead to the
53 default definitions or by checking if the predicate set that guards the
54 defining paths is a superset of the use predicate. */
56 /* Pointer set of potentially undefined ssa names, i.e.,
57 ssa names that are defined by phi with operands that
58 are not defined or potentially undefined. */
59 static hash_set<tree> *possibly_undefined_names;
60 static hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t> *defined_args;
62 /* Returns the first bit position (starting from LSB)
63 in mask that is non zero. Returns -1 if the mask is empty. */
64 static int
65 get_mask_first_set_bit (unsigned mask)
67 int pos = 0;
68 if (mask == 0)
69 return -1;
71 while ((mask & (1 << pos)) == 0)
72 pos++;
74 return pos;
76 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
78 /* Return true if T, an SSA_NAME, has an undefined value. */
79 static bool
80 has_undefined_value_p (tree t)
82 return (ssa_undefined_value_p (t)
83 || (possibly_undefined_names
84 && possibly_undefined_names->contains (t)));
87 /* Return true if EXPR should suppress either uninitialized warning. */
89 static inline bool
90 get_no_uninit_warning (tree expr)
92 return warning_suppressed_p (expr, OPT_Wuninitialized);
95 /* Suppress both uninitialized warnings for EXPR. */
97 static inline void
98 set_no_uninit_warning (tree expr)
100 suppress_warning (expr, OPT_Wuninitialized);
103 /* Like has_undefined_value_p, but don't return true if the no-warning
104 bit is set on SSA_NAME_VAR for either uninit warning. */
106 static inline bool
107 uninit_undefined_value_p (tree t)
109 if (!has_undefined_value_p (t))
110 return false;
111 if (!SSA_NAME_VAR (t))
112 return true;
113 return !get_no_uninit_warning (SSA_NAME_VAR (t));
116 /* Emit warnings for uninitialized variables. This is done in two passes.
118 The first pass notices real uses of SSA names with undefined values.
119 Such uses are unconditionally uninitialized, and we can be certain that
120 such a use is a mistake. This pass is run before most optimizations,
121 so that we catch as many as we can.
123 The second pass follows PHI nodes to find uses that are potentially
124 uninitialized. In this case we can't necessarily prove that the use
125 is really uninitialized. This pass is run after most optimizations,
126 so that we thread as many jumps and possible, and delete as much dead
127 code as possible, in order to reduce false positives. We also look
128 again for plain uninitialized variables, since optimization may have
129 changed conditionally uninitialized to unconditionally uninitialized. */
131 /* Emit warning OPT for variable VAR at the point in the program where
132 the SSA_NAME T is being used uninitialized. The warning text is in
133 MSGID and STMT is the statement that does the uninitialized read.
134 PHI_ARG_LOC is the location of the PHI argument if T and VAR are one,
135 or UNKNOWN_LOCATION otherwise. */
137 static void
138 warn_uninit (opt_code opt, tree t, tree var, gimple *context,
139 location_t phi_arg_loc = UNKNOWN_LOCATION)
141 /* Bail if the value isn't provably uninitialized. */
142 if (!has_undefined_value_p (t))
143 return;
145 /* Ignore COMPLEX_EXPR as initializing only a part of a complex
146 turns in a COMPLEX_EXPR with the not initialized part being
147 set to its previous (undefined) value. */
148 if (is_gimple_assign (context)
149 && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
150 return;
152 /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
153 .DEFERRED_INIT. This is for handling the following case correctly:
155 1 typedef _Complex float C;
156 2 C foo (int cond)
158 4 C f;
159 5 __imag__ f = 0;
160 6 if (cond)
162 8 __real__ f = 1;
163 9 return f;
164 10 }
165 11 return f;
166 12 }
168 with -ftrivial-auto-var-init, compiler will insert the following
169 artificial initialization at line 4:
170 f = .DEFERRED_INIT (f, 2);
171 _1 = REALPART_EXPR <f>;
173 without the following special handling, _1 = REALPART_EXPR <f> will
174 be treated as the uninitialized use point, which is incorrect. (the
175 real uninitialized use point is at line 11). */
176 if (is_gimple_assign (context)
177 && (gimple_assign_rhs_code (context) == REALPART_EXPR
178 || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
180 tree v = gimple_assign_rhs1 (context);
181 if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
182 && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
183 IFN_DEFERRED_INIT))
184 return;
187 /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
188 can return true if the def stmt of an anonymous SSA_NAME is
189 1. A COMPLEX_EXPR created for conversion from scalar to complex. Use the
190 underlying var of the COMPLEX_EXPRs real part in that case. See PR71581.
194 2. A call to .DEFERRED_INIT internal function. Since the original variable
195 has been eliminated by optimziation, we need to get the variable name,
196 and variable declaration location from this call. We recorded variable
197 name into VAR_NAME_STR, and will get location info and record warning
198 suppressed info to VAR_DEF_STMT, which is the .DEFERRED_INIT call. */
200 const char *var_name_str = NULL;
201 gimple *var_def_stmt = NULL;
203 if (!var && !SSA_NAME_VAR (t))
205 var_def_stmt = SSA_NAME_DEF_STMT (t);
207 if (is_gimple_assign (var_def_stmt)
208 && gimple_assign_rhs_code (var_def_stmt) == COMPLEX_EXPR)
210 tree v = gimple_assign_rhs1 (var_def_stmt);
211 if (TREE_CODE (v) == SSA_NAME
212 && has_undefined_value_p (v)
213 && zerop (gimple_assign_rhs2 (var_def_stmt)))
214 var = SSA_NAME_VAR (v);
217 if (gimple_call_internal_p (var_def_stmt, IFN_DEFERRED_INIT))
219 /* Ignore the call to .DEFERRED_INIT that define the original
220 var itself as the following case:
221 temp = .DEFERRED_INIT (4, 2, “alt_reloc");
222 alt_reloc = temp;
223 In order to avoid generating warning for the fake usage
224 at alt_reloc = temp.
226 tree lhs_var = NULL_TREE;
228 /* Get the variable name from the 3rd argument of call. */
229 tree var_name = gimple_call_arg (var_def_stmt, 2);
230 var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
231 var_name_str = TREE_STRING_POINTER (var_name);
233 if (is_gimple_assign (context))
235 if (VAR_P (gimple_assign_lhs (context)))
236 lhs_var = gimple_assign_lhs (context);
237 else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME)
238 lhs_var = SSA_NAME_VAR (gimple_assign_lhs (context));
240 if (lhs_var)
242 /* Get the name string for the LHS_VAR.
243 Refer to routine gimple_add_init_for_auto_var. */
244 if (DECL_NAME (lhs_var)
245 && (strcmp (IDENTIFIER_POINTER (DECL_NAME (lhs_var)),
246 var_name_str) == 0))
247 return;
248 else if (!DECL_NAME (lhs_var))
250 char lhs_var_name_str_buf[3 + (HOST_BITS_PER_INT + 2) / 3];
251 sprintf (lhs_var_name_str_buf, "D.%u", DECL_UID (lhs_var));
252 if (strcmp (lhs_var_name_str_buf, var_name_str) == 0)
253 return;
256 gcc_assert (var_name_str && var_def_stmt);
260 if (var == NULL_TREE && var_name_str == NULL)
261 return;
263 /* Avoid warning if we've already done so or if the warning has been
264 suppressed. */
265 if (((warning_suppressed_p (context, OPT_Wuninitialized)
266 || (gimple_assign_single_p (context)
267 && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
268 || (var && get_no_uninit_warning (var))
269 || (var_name_str
270 && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
271 return;
273 /* Use either the location of the read statement or that of the PHI
274 argument, or that of the uninitialized variable, in that order,
275 whichever is valid. */
276 location_t location = UNKNOWN_LOCATION;
277 if (gimple_has_location (context))
278 location = gimple_location (context);
279 else if (phi_arg_loc != UNKNOWN_LOCATION)
280 location = phi_arg_loc;
281 else if (var)
282 location = DECL_SOURCE_LOCATION (var);
283 else if (var_name_str)
284 location = gimple_location (var_def_stmt);
286 auto_diagnostic_group d;
287 gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
288 if (var)
290 if ((opt == OPT_Wuninitialized
291 && !warning_at (location, opt, "%qD is used uninitialized", var))
292 || (opt == OPT_Wmaybe_uninitialized
293 && !warning_at (location, opt, "%qD may be used uninitialized",
294 var)))
295 return;
297 else if (var_name_str)
299 if ((opt == OPT_Wuninitialized
300 && !warning_at (location, opt, "%qs is used uninitialized",
301 var_name_str))
302 || (opt == OPT_Wmaybe_uninitialized
303 && !warning_at (location, opt, "%qs may be used uninitialized",
304 var_name_str)))
305 return;
308 /* Avoid subsequent warnings for reads of the same variable again. */
309 if (var)
310 suppress_warning (var, opt);
311 else if (var_name_str)
312 suppress_warning (var_def_stmt, opt);
314 /* Issue a note pointing to the read variable unless the warning
315 is at the same location. */
316 location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
317 : gimple_location (var_def_stmt);
318 if (location == var_loc)
319 return;
321 if (var)
322 inform (var_loc, "%qD was declared here", var);
323 else if (var_name_str)
324 inform (var_loc, "%qs was declared here", var_name_str);
327 struct check_defs_data
329 /* If we found any may-defs besides must-def clobbers. */
330 bool found_may_defs;
333 /* Return true if STMT is a call to built-in function all of whose
334 by-reference arguments are const-qualified (i.e., the function can
335 be assumed not to modify them). */
337 static bool
338 builtin_call_nomodifying_p (gimple *stmt)
340 if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
341 return false;
343 tree fndecl = gimple_call_fndecl (stmt);
344 if (!fndecl)
345 return false;
347 tree fntype = TREE_TYPE (fndecl);
348 if (!fntype)
349 return false;
351 /* Check the called function's signature for non-constc pointers.
352 If one is found, return false. */
353 unsigned argno = 0;
354 tree argtype;
355 function_args_iterator it;
356 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
358 if (VOID_TYPE_P (argtype))
359 return true;
361 ++argno;
363 if (!POINTER_TYPE_P (argtype))
364 continue;
366 if (TYPE_READONLY (TREE_TYPE (argtype)))
367 continue;
369 return false;
372 /* If the number of actual arguments to the call is less than or
373 equal to the number of parameters, return false. */
374 unsigned nargs = gimple_call_num_args (stmt);
375 if (nargs <= argno)
376 return false;
378 /* Check arguments passed through the ellipsis in calls to variadic
379 functions for pointers. If one is found that's a non-constant
380 pointer, return false. */
381 for (; argno < nargs; ++argno)
383 tree arg = gimple_call_arg (stmt, argno);
384 argtype = TREE_TYPE (arg);
385 if (!POINTER_TYPE_P (argtype))
386 continue;
388 if (TYPE_READONLY (TREE_TYPE (argtype)))
389 continue;
391 return false;
394 return true;
397 /* If ARG is a FNDECL parameter declared with attribute access none or
398 write_only issue a warning for its read access via PTR. */
400 static void
401 maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
403 if (!fndecl)
404 return;
406 if (get_no_uninit_warning (arg))
407 return;
409 tree fntype = TREE_TYPE (fndecl);
410 if (!fntype)
411 return;
413 /* Initialize a map of attribute access specifications for arguments
414 to the function call. */
415 rdwr_map rdwr_idx;
416 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
418 unsigned argno = 0;
419 tree parms = DECL_ARGUMENTS (fndecl);
420 for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
422 if (parm != arg)
423 continue;
425 const attr_access* access = rdwr_idx.get (argno);
426 if (!access)
427 break;
429 if (access->mode != access_none
430 && access->mode != access_write_only)
431 continue;
433 location_t stmtloc = gimple_location (stmt);
434 if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
435 "%qE may be used uninitialized", ptr))
436 break;
438 suppress_warning (arg, OPT_Wmaybe_uninitialized);
440 const char* const access_str =
441 TREE_STRING_POINTER (access->to_external_string ());
443 location_t parmloc = DECL_SOURCE_LOCATION (parm);
444 inform (parmloc, "accessing argument %u of a function declared with "
445 "attribute %<%s%>",
446 argno + 1, access_str);
448 break;
452 /* Callback for walk_aliased_vdefs. */
454 static bool
455 check_defs (ao_ref *ref, tree vdef, void *data_)
457 check_defs_data *data = (check_defs_data *)data_;
458 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
460 /* Ignore the vdef if the definition statement is a call
461 to .DEFERRED_INIT function. */
462 if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
463 return false;
465 /* For address taken variable, a temporary variable is added between
466 the variable and the call to .DEFERRED_INIT function as:
467 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
468 i1 = _1;
469 Ignore this vdef as well. */
470 if (is_gimple_assign (def_stmt)
471 && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
473 tree tmp_var = gimple_assign_rhs1 (def_stmt);
474 if (gimple_call_internal_p (SSA_NAME_DEF_STMT (tmp_var),
475 IFN_DEFERRED_INIT))
476 return false;
479 /* The ASAN_MARK intrinsic doesn't modify the variable. */
480 if (is_gimple_call (def_stmt))
482 /* The ASAN_MARK intrinsic doesn't modify the variable. */
483 if (gimple_call_internal_p (def_stmt)
484 && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
485 return false;
487 if (tree fndecl = gimple_call_fndecl (def_stmt))
489 /* Some sanitizer calls pass integer arguments to built-ins
490 that expect pointets. Avoid using gimple_call_builtin_p()
491 which fails for such calls. */
492 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
494 built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
495 if (fncode > BEGIN_SANITIZER_BUILTINS
496 && fncode < END_SANITIZER_BUILTINS)
497 return false;
502 /* End of VLA scope is not a kill. */
503 if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
504 return false;
506 /* If this is a clobber then if it is not a kill walk past it. */
507 if (gimple_clobber_p (def_stmt))
509 if (stmt_kills_ref_p (def_stmt, ref))
510 return true;
511 return false;
514 if (builtin_call_nomodifying_p (def_stmt))
515 return false;
517 /* Found a may-def on this path. */
518 data->found_may_defs = true;
519 return true;
522 /* Counters and limits controlling the depth of analysis and
523 strictness of the warning. */
524 struct wlimits
526 /* Number of VDEFs encountered. */
527 unsigned int vdef_cnt;
528 /* Number of statements examined by walk_aliased_vdefs. */
529 unsigned int oracle_cnt;
530 /* Limit on the number of statements visited by walk_aliased_vdefs. */
531 unsigned limit;
532 /* Set when basic block with statement is executed unconditionally. */
533 bool always_executed;
534 /* Set to issue -Wmaybe-uninitialized. */
535 bool wmaybe_uninit;
538 /* Determine if REF references an uninitialized operand and diagnose
539 it if so. STMS is the referencing statement. LHS is the result
540 of the access and may be null. RHS is the variable referenced by
541 the access; it may not be null. */
543 static tree
544 maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
545 wlimits &wlims)
547 bool has_bit_insert = false;
548 use_operand_p luse_p;
549 imm_use_iterator liter;
551 if (get_no_uninit_warning (rhs))
552 return NULL_TREE;
554 /* Do not warn if the base was marked so or this is a
555 hard register var. */
556 tree base = ao_ref_base (&ref);
557 if ((VAR_P (base)
558 && DECL_HARD_REGISTER (base))
559 || get_no_uninit_warning (base))
560 return NULL_TREE;
562 /* Do not warn if the access is zero size or if it's fully outside
563 the object. */
564 poly_int64 decl_size;
565 if (known_size_p (ref.size)
566 && known_eq (ref.max_size, ref.size)
567 && (known_eq (ref.size, 0)
568 || known_le (ref.offset + ref.size, 0)))
569 return NULL_TREE;
571 if (DECL_P (base)
572 && known_ge (ref.offset, 0)
573 && DECL_SIZE (base)
574 && poly_int_tree_p (DECL_SIZE (base), &decl_size)
575 && known_le (decl_size, ref.offset))
576 return NULL_TREE;
578 /* Do not warn if the result of the access is then used for
579 a BIT_INSERT_EXPR. */
580 if (lhs && TREE_CODE (lhs) == SSA_NAME)
581 FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
583 gimple *use_stmt = USE_STMT (luse_p);
584 /* BIT_INSERT_EXPR first operand should not be considered
585 a use for the purpose of uninit warnings. */
586 if (gassign *ass = dyn_cast <gassign *> (use_stmt))
588 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
589 && luse_p->use == gimple_assign_rhs1_ptr (ass))
591 has_bit_insert = true;
592 break;
597 if (has_bit_insert)
598 return NULL_TREE;
600 /* Limit the walking to a constant number of stmts after
601 we overcommit quadratic behavior for small functions
602 and O(n) behavior. */
603 if (wlims.oracle_cnt > 128 * 128
604 && wlims.oracle_cnt > wlims.vdef_cnt * 2)
605 wlims.limit = 32;
607 check_defs_data data;
608 bool fentry_reached = false;
609 data.found_may_defs = false;
610 tree use = gimple_vuse (stmt);
611 if (!use)
612 return NULL_TREE;
613 int res = walk_aliased_vdefs (&ref, use,
614 check_defs, &data, NULL,
615 &fentry_reached, wlims.limit);
616 if (res == -1)
618 wlims.oracle_cnt += wlims.limit;
619 return NULL_TREE;
622 wlims.oracle_cnt += res;
623 if (data.found_may_defs)
624 return NULL_TREE;
626 bool found_alloc = false;
628 if (fentry_reached)
630 if (TREE_CODE (base) == MEM_REF)
631 base = TREE_OPERAND (base, 0);
633 /* Follow the chain of SSA_NAME assignments looking for an alloca
634 call (or VLA) or malloc/realloc, or for decls. If any is found
635 (and in the latter case, the operand is a local variable) issue
636 a warning. */
637 while (TREE_CODE (base) == SSA_NAME)
639 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
641 if (is_gimple_call (def_stmt)
642 && gimple_call_builtin_p (def_stmt))
644 /* Detect uses of uninitialized alloca/VLAs. */
645 tree fndecl = gimple_call_fndecl (def_stmt);
646 const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
647 if (fncode == BUILT_IN_ALLOCA
648 || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
649 || fncode == BUILT_IN_MALLOC)
650 found_alloc = true;
651 break;
654 if (!is_gimple_assign (def_stmt))
655 break;
657 tree_code code = gimple_assign_rhs_code (def_stmt);
658 if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
659 break;
661 base = gimple_assign_rhs1 (def_stmt);
662 if (TREE_CODE (base) == ADDR_EXPR)
663 base = TREE_OPERAND (base, 0);
665 if (DECL_P (base)
666 || TREE_CODE (base) == COMPONENT_REF)
667 rhs = base;
669 if (TREE_CODE (base) == MEM_REF)
670 base = TREE_OPERAND (base, 0);
672 if (tree ba = get_base_address (base))
673 base = ba;
676 /* Replace the RHS expression with BASE so that it
677 refers to it in the diagnostic (instead of to
678 '<unknown>'). */
679 if (DECL_P (base)
680 && EXPR_P (rhs)
681 && TREE_CODE (rhs) != COMPONENT_REF)
682 rhs = base;
685 /* Do not warn if it can be initialized outside this function.
686 If we did not reach function entry then we found killing
687 clobbers on all paths to entry. */
688 if (!found_alloc && fentry_reached)
690 if (TREE_CODE (base) == SSA_NAME)
692 tree var = SSA_NAME_VAR (base);
693 if (var && TREE_CODE (var) == PARM_DECL)
695 maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
696 return NULL_TREE;
700 if (!VAR_P (base)
701 || is_global_var (base))
702 /* ??? We'd like to use ref_may_alias_global_p but that
703 excludes global readonly memory and thus we get bogus
704 warnings from p = cond ? "a" : "b" for example. */
705 return NULL_TREE;
708 /* Strip the address-of expression from arrays passed to functions. */
709 if (TREE_CODE (rhs) == ADDR_EXPR)
710 rhs = TREE_OPERAND (rhs, 0);
712 /* Check again since RHS may have changed above. */
713 if (get_no_uninit_warning (rhs))
714 return NULL_TREE;
716 /* Avoid warning about empty types such as structs with no members.
717 The first_field() test is important for C++ where the predicate
718 alone isn't always sufficient. */
719 tree rhstype = TREE_TYPE (rhs);
720 if (POINTER_TYPE_P (rhstype))
721 rhstype = TREE_TYPE (rhstype);
722 if (is_empty_type (rhstype))
723 return NULL_TREE;
725 bool warned = false;
726 /* We didn't find any may-defs so on all paths either
727 reached function entry or a killing clobber. */
728 location_t location = gimple_location (stmt);
729 if (wlims.always_executed)
731 if (warning_at (location, OPT_Wuninitialized,
732 "%qE is used uninitialized", rhs))
734 /* ??? This is only effective for decls as in
735 gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
736 uses or accesses by functions as it may hide important
737 locations. */
738 if (lhs)
739 set_no_uninit_warning (rhs);
740 warned = true;
743 else if (wlims.wmaybe_uninit)
744 warned = warning_at (location, OPT_Wmaybe_uninitialized,
745 "%qE may be used uninitialized", rhs);
747 return warned ? base : NULL_TREE;
751 /* Diagnose passing addresses of uninitialized objects to either const
752 pointer arguments to functions, or to functions declared with attribute
753 access implying read access to those objects. */
755 static void
756 maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
758 if (!wlims.wmaybe_uninit)
759 return;
761 unsigned nargs = gimple_call_num_args (stmt);
762 if (!nargs)
763 return;
765 tree fndecl = gimple_call_fndecl (stmt);
766 tree fntype = gimple_call_fntype (stmt);
767 if (!fntype)
768 return;
770 /* Const function do not read their arguments. */
771 if (gimple_call_flags (stmt) & ECF_CONST)
772 return;
774 const built_in_function fncode
775 = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
776 ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
778 if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
779 /* Avoid diagnosing calls to raw memory functions (this is overly
780 permissive; consider tightening it up). */
781 return;
783 /* Save the current warning setting and replace it either a "maybe"
784 when passing addresses of uninitialized variables to const-qualified
785 pointers or arguments declared with attribute read_write, or with
786 a "certain" when passing them to arguments declared with attribute
787 read_only. */
788 const bool save_always_executed = wlims.always_executed;
790 /* Initialize a map of attribute access specifications for arguments
791 to the function call. */
792 rdwr_map rdwr_idx;
793 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
795 tree argtype;
796 unsigned argno = 0;
797 function_args_iterator it;
799 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
801 ++argno;
803 if (argno > nargs)
804 break;
806 if (!POINTER_TYPE_P (argtype))
807 continue;
809 tree access_size = NULL_TREE;
810 const attr_access* access = rdwr_idx.get (argno - 1);
811 if (access)
813 if (access->mode == access_none
814 || access->mode == access_write_only)
815 continue;
817 if (access->mode == access_deferred
818 && !TYPE_READONLY (TREE_TYPE (argtype)))
819 continue;
821 if (save_always_executed && access->mode == access_read_only)
822 /* Attribute read_only arguments imply read access. */
823 wlims.always_executed = true;
824 else
825 /* Attribute read_write arguments are documented as requiring
826 initialized objects but it's expected that aggregates may
827 be only partially initialized regardless. */
828 wlims.always_executed = false;
830 if (access->sizarg < nargs)
831 access_size = gimple_call_arg (stmt, access->sizarg);
833 else if (!TYPE_READONLY (TREE_TYPE (argtype)))
834 continue;
835 else if (save_always_executed && fncode != BUILT_IN_LAST)
836 /* Const-qualified arguments to built-ins imply read access. */
837 wlims.always_executed = true;
838 else
839 /* Const-qualified arguments to ordinary functions imply a likely
840 (but not definitive) read access. */
841 wlims.always_executed = false;
843 /* Ignore args we are not going to read from. */
844 if (gimple_call_arg_flags (stmt, argno - 1)
845 & (EAF_UNUSED | EAF_NO_DIRECT_READ))
846 continue;
848 tree arg = gimple_call_arg (stmt, argno - 1);
849 if (!POINTER_TYPE_P (TREE_TYPE (arg)))
850 /* Avoid actual arguments with invalid types. */
851 continue;
853 ao_ref ref;
854 ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
855 tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
856 if (!argbase)
857 continue;
859 if (access && access->mode != access_deferred)
861 const char* const access_str =
862 TREE_STRING_POINTER (access->to_external_string ());
864 if (fndecl)
866 location_t loc = DECL_SOURCE_LOCATION (fndecl);
867 inform (loc, "in a call to %qD declared with "
868 "attribute %<%s%> here", fndecl, access_str);
870 else
872 /* Handle calls through function pointers. */
873 location_t loc = gimple_location (stmt);
874 inform (loc, "in a call to %qT declared with "
875 "attribute %<%s%>", fntype, access_str);
878 else
880 /* For a declaration with no relevant attribute access create
881 a dummy object and use the formatting function to avoid
882 having to complicate things here. */
883 attr_access ptr_access = { };
884 if (!access)
885 access = &ptr_access;
886 const std::string argtypestr = access->array_as_string (argtype);
887 if (fndecl)
889 location_t loc (DECL_SOURCE_LOCATION (fndecl));
890 inform (loc, "by argument %u of type %s to %qD "
891 "declared here",
892 argno, argtypestr.c_str (), fndecl);
894 else
896 /* Handle calls through function pointers. */
897 location_t loc (gimple_location (stmt));
898 inform (loc, "by argument %u of type %s to %qT",
899 argno, argtypestr.c_str (), fntype);
903 if (DECL_P (argbase))
905 location_t loc = DECL_SOURCE_LOCATION (argbase);
906 inform (loc, "%qD declared here", argbase);
910 wlims.always_executed = save_always_executed;
913 /* Warn about an uninitialized PHI argument on the fallthru path to
914 an always executed block BB. */
916 static void
917 warn_uninit_phi_uses (basic_block bb)
919 edge_iterator ei;
920 edge e, found = NULL, found_back = NULL;
921 /* Look for a fallthru and possibly a single backedge. */
922 FOR_EACH_EDGE (e, ei, bb->preds)
924 /* Ignore backedges. */
925 if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
927 if (found_back)
929 found = NULL;
930 break;
932 found_back = e;
933 continue;
935 if (found)
937 found = NULL;
938 break;
940 found = e;
942 if (!found)
943 return;
945 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
946 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
947 gsi_next (&si))
949 gphi *phi = si.phi ();
950 tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
951 if (TREE_CODE (def) != SSA_NAME
952 || !SSA_NAME_IS_DEFAULT_DEF (def)
953 || virtual_operand_p (def))
954 continue;
955 /* If there's a default def on the fallthru edge PHI
956 value and there's a use that post-dominates entry
957 then that use is uninitialized and we can warn. */
958 imm_use_iterator iter;
959 use_operand_p use_p;
960 gimple *use_stmt = NULL;
961 FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
963 use_stmt = USE_STMT (use_p);
964 if (gimple_location (use_stmt) != UNKNOWN_LOCATION
965 && dominated_by_p (CDI_POST_DOMINATORS, succ,
966 gimple_bb (use_stmt))
967 /* If we found a non-fallthru edge make sure the
968 use is inside the loop, otherwise the backedge
969 can serve as initialization. */
970 && (!found_back
971 || dominated_by_p (CDI_DOMINATORS, found_back->src,
972 gimple_bb (use_stmt))))
973 break;
974 use_stmt = NULL;
976 if (use_stmt)
977 warn_uninit (OPT_Wuninitialized, def,
978 SSA_NAME_VAR (def), use_stmt);
982 /* Issue warnings about reads of uninitialized variables. WMAYBE_UNINIT
983 is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized. */
985 static void
986 warn_uninitialized_vars (bool wmaybe_uninit)
988 /* Counters and limits controlling the depth of the warning. */
989 wlimits wlims = { };
990 wlims.wmaybe_uninit = wmaybe_uninit;
992 auto_bb_flag ft_reachable (cfun);
994 /* Mark blocks that are always executed when we ignore provably
995 not executed and EH and abnormal edges. */
996 basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
997 while (!(bb->flags & ft_reachable))
999 bb->flags |= ft_reachable;
1000 edge e = find_fallthru_edge (bb->succs);
1001 if (e && e->flags & EDGE_EXECUTABLE)
1003 bb = e->dest;
1004 continue;
1006 /* Find a single executable edge. */
1007 edge_iterator ei;
1008 edge ee = NULL;
1009 FOR_EACH_EDGE (e, ei, bb->succs)
1010 if (e->flags & EDGE_EXECUTABLE)
1012 if (!ee)
1013 ee = e;
1014 else
1016 ee = NULL;
1017 break;
1020 if (ee)
1021 bb = ee->dest;
1022 else
1023 bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1024 if (!bb || bb->index == EXIT_BLOCK)
1025 break;
1028 FOR_EACH_BB_FN (bb, cfun)
1030 wlims.always_executed = (bb->flags & ft_reachable);
1031 bb->flags &= ~ft_reachable;
1033 edge_iterator ei;
1034 edge e;
1035 FOR_EACH_EDGE (e, ei, bb->preds)
1036 if (e->flags & EDGE_EXECUTABLE)
1037 break;
1038 /* Skip unreachable blocks. For early analysis we use VN to
1039 determine edge executability when wmaybe_uninit. */
1040 if (!e)
1041 continue;
1043 if (wlims.always_executed)
1044 warn_uninit_phi_uses (bb);
1046 gimple_stmt_iterator gsi;
1047 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1049 gimple *stmt = gsi_stmt (gsi);
1051 /* The call is an artificial use, will not provide meaningful
1052 error message. If the result of the call is used somewhere
1053 else, we warn there instead. */
1054 if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
1055 continue;
1057 if (is_gimple_debug (stmt))
1058 continue;
1060 /* We only do data flow with SSA_NAMEs, so that's all we
1061 can warn about. */
1062 use_operand_p use_p;
1063 ssa_op_iter op_iter;
1064 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
1066 /* BIT_INSERT_EXPR first operand should not be considered
1067 a use for the purpose of uninit warnings. */
1068 if (gassign *ass = dyn_cast <gassign *> (stmt))
1070 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
1071 && use_p->use == gimple_assign_rhs1_ptr (ass))
1072 continue;
1074 tree use = USE_FROM_PTR (use_p);
1075 if (wlims.always_executed)
1076 warn_uninit (OPT_Wuninitialized, use,
1077 SSA_NAME_VAR (use), stmt);
1078 else if (wlims.wmaybe_uninit)
1079 warn_uninit (OPT_Wmaybe_uninitialized, use,
1080 SSA_NAME_VAR (use), stmt);
1083 /* For limiting the alias walk below we count all
1084 vdefs in the function. */
1085 if (gimple_vdef (stmt))
1086 wlims.vdef_cnt++;
1088 if (gcall *call = dyn_cast <gcall *> (stmt))
1089 maybe_warn_pass_by_reference (call, wlims);
1090 else if (gimple_assign_load_p (stmt)
1091 && gimple_has_location (stmt))
1093 tree rhs = gimple_assign_rhs1 (stmt);
1094 tree lhs = gimple_assign_lhs (stmt);
1096 ao_ref ref;
1097 ao_ref_init (&ref, rhs);
1098 tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
1099 if (!var)
1100 continue;
1102 if (DECL_P (var))
1104 location_t loc = DECL_SOURCE_LOCATION (var);
1105 inform (loc, "%qD declared here", var);
1112 /* Checks if the operand OPND of PHI is defined by
1113 another phi with one operand defined by this PHI,
1114 but the rest operands are all defined. If yes,
1115 returns true to skip this operand as being
1116 redundant. Can be enhanced to be more general. */
1118 static bool
1119 can_skip_redundant_opnd (tree opnd, gimple *phi)
1121 tree phi_def = gimple_phi_result (phi);
1122 gimple *op_def = SSA_NAME_DEF_STMT (opnd);
1123 if (gimple_code (op_def) != GIMPLE_PHI)
1124 return false;
1126 unsigned n = gimple_phi_num_args (op_def);
1127 for (unsigned i = 0; i < n; ++i)
1129 tree op = gimple_phi_arg_def (op_def, i);
1130 if (TREE_CODE (op) != SSA_NAME)
1131 continue;
1132 if (op != phi_def && uninit_undefined_value_p (op))
1133 return false;
1136 return true;
1139 /* Return a bitset holding the positions of arguments in PHI with empty
1140 (or possibly empty) definitions. */
1142 static unsigned
1143 compute_uninit_opnds_pos (gphi *phi)
1145 unsigned uninit_opnds = 0;
1147 unsigned n = gimple_phi_num_args (phi);
1148 /* Bail out for phi with too many args. */
1149 if (n > uninit_analysis::func_t::max_phi_args)
1150 return 0;
1152 for (unsigned i = 0; i < n; ++i)
1154 tree op = gimple_phi_arg_def (phi, i);
1155 if (TREE_CODE (op) == SSA_NAME
1156 && uninit_undefined_value_p (op)
1157 && !can_skip_redundant_opnd (op, phi))
1159 if (cfun->has_nonlocal_label || cfun->calls_setjmp)
1161 /* Ignore SSA_NAMEs that appear on abnormal edges
1162 somewhere. */
1163 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
1164 continue;
1166 MASK_SET_BIT (uninit_opnds, i);
1169 /* If we have recorded guarded uses of may-uninit values mask those. */
1170 if (auto *def_mask = defined_args->get (phi))
1171 uninit_opnds &= ~*def_mask;
1172 return uninit_opnds;
1175 /* Function object type used to determine whether an expression
1176 is of interest to the predicate analyzer. */
1178 struct uninit_undef_val_t: public uninit_analysis::func_t
1180 virtual unsigned phi_arg_set (gphi *) override;
1183 /* Return a bitset of PHI arguments of interest. */
1185 unsigned
1186 uninit_undef_val_t::phi_arg_set (gphi *phi)
1188 return compute_uninit_opnds_pos (phi);
1191 /* sort helper for find_uninit_use. */
1193 static int
1194 cand_cmp (const void *a, const void *b, void *data)
1196 int *bb_to_rpo = (int *)data;
1197 const gimple *sa = *(const gimple * const *)a;
1198 const gimple *sb = *(const gimple * const *)b;
1199 if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
1200 return -1;
1201 else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
1202 return 1;
1203 return 0;
1206 /* Searches through all uses of a potentially
1207 uninitialized variable defined by PHI and returns a use
1208 statement if the use is not properly guarded. It returns
1209 NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
1210 holding the position(s) of uninit PHI operands. */
1212 static gimple *
1213 find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1215 /* The Boolean predicate guarding the PHI definition. Initialized
1216 lazily from PHI in the first call to is_use_guarded() and cached
1217 for subsequent iterations. */
1218 uninit_undef_val_t eval;
1219 uninit_analysis def_preds (eval);
1221 /* First process PHIs and record other candidates. */
1222 auto_vec<gimple *, 64> cands;
1223 use_operand_p use_p;
1224 imm_use_iterator iter;
1225 tree phi_result = gimple_phi_result (phi);
1226 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1228 gimple *use_stmt = USE_STMT (use_p);
1229 if (is_gimple_debug (use_stmt))
1230 continue;
1232 if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1234 unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p);
1235 edge e = gimple_phi_arg_edge (use_phi, idx);
1236 /* Do not look for uses in the next iteration of a loop, predicate
1237 analysis will not use the appropriate predicates to prove
1238 reachability. */
1239 if (e->flags & EDGE_DFS_BACK)
1240 continue;
1242 basic_block use_bb = e->src;
1243 if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1245 /* For a guarded use in a PHI record the PHI argument as
1246 initialized. */
1247 if (idx < uninit_analysis::func_t::max_phi_args)
1249 bool existed_p;
1250 auto &def_mask
1251 = defined_args->get_or_insert (use_phi, &existed_p);
1252 if (!existed_p)
1253 def_mask = 0;
1254 MASK_SET_BIT (def_mask, idx);
1256 continue;
1259 if (dump_file && (dump_flags & TDF_DETAILS))
1261 fprintf (dump_file, "Found unguarded use on edge %u -> %u: ",
1262 e->src->index, e->dest->index);
1263 print_gimple_stmt (dump_file, use_stmt, 0);
1265 /* Found a phi use that is not guarded, mark the phi_result as
1266 possibly undefined. */
1267 possibly_undefined_names->add (phi_result);
1269 else
1270 cands.safe_push (use_stmt);
1273 /* Sort candidates after RPO. */
1274 cands.stablesort (cand_cmp, bb_to_rpo);
1275 basic_block use_bb = NULL;
1276 for (gimple *use_stmt : cands)
1278 /* We only have to try diagnosing the first use in each block. */
1279 if (gimple_bb (use_stmt) == use_bb)
1280 continue;
1282 use_bb = gimple_bb (use_stmt);
1283 if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1284 continue;
1286 if (dump_file && (dump_flags & TDF_DETAILS))
1288 fprintf (dump_file, "Found unguarded use in bb %u: ",
1289 use_bb->index);
1290 print_gimple_stmt (dump_file, use_stmt, 0);
1292 return use_stmt;
1295 return NULL;
1298 /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1299 and gives warning if there exists a runtime path from the entry to a
1300 use of the PHI def that does not contain a definition. In other words,
1301 the warning is on the real use. The more dead paths that can be pruned
1302 by the compiler, the fewer false positives the warning is. */
1304 static void
1305 warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1307 if (dump_file && (dump_flags & TDF_DETAILS))
1309 fprintf (dump_file, "Examining phi: ");
1310 print_gimple_stmt (dump_file, phi, 0);
1313 gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);
1315 /* All uses are properly guarded. */
1316 if (!uninit_use_stmt)
1317 return;
1319 unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1320 tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1321 if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
1322 return;
1324 location_t loc = UNKNOWN_LOCATION;
1325 if (gimple_phi_arg_has_location (phi, phiarg_index))
1326 loc = gimple_phi_arg_location (phi, phiarg_index);
1327 else
1329 tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1330 if (TREE_CODE (arg_def) == SSA_NAME)
1332 gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1333 if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1335 unsigned uop = compute_uninit_opnds_pos (arg_phi);
1336 unsigned idx = MASK_FIRST_SET_BIT (uop);
1337 if (idx < gimple_phi_num_args (arg_phi)
1338 && gimple_phi_arg_has_location (arg_phi, idx))
1339 loc = gimple_phi_arg_location (arg_phi, idx);
1344 warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1345 SSA_NAME_VAR (uninit_op),
1346 uninit_use_stmt, loc);
1349 static bool
1350 gate_warn_uninitialized (void)
1352 return warn_uninitialized || warn_maybe_uninitialized;
1355 namespace {
1357 const pass_data pass_data_late_warn_uninitialized =
1359 GIMPLE_PASS, /* type */
1360 "uninit", /* name */
1361 OPTGROUP_NONE, /* optinfo_flags */
1362 TV_NONE, /* tv_id */
1363 PROP_ssa, /* properties_required */
1364 0, /* properties_provided */
1365 0, /* properties_destroyed */
1366 0, /* todo_flags_start */
1367 0, /* todo_flags_finish */
1370 class pass_late_warn_uninitialized : public gimple_opt_pass
1372 public:
1373 pass_late_warn_uninitialized (gcc::context *ctxt)
1374 : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1377 /* opt_pass methods: */
1378 opt_pass *clone () final override
1380 return new pass_late_warn_uninitialized (m_ctxt);
1382 bool gate (function *) final override { return gate_warn_uninitialized (); }
1383 unsigned int execute (function *) final override;
1385 }; // class pass_late_warn_uninitialized
1387 static void
1388 execute_late_warn_uninitialized (function *fun)
1390 calculate_dominance_info (CDI_DOMINATORS);
1391 calculate_dominance_info (CDI_POST_DOMINATORS);
1393 /* Mark all edges executable, warn_uninitialized_vars will skip
1394 unreachable blocks. */
1395 set_all_edges_as_executable (fun);
1396 mark_dfs_back_edges (fun);
1397 int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
1398 int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
1399 int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
1400 for (int i = 0; i < n; ++i)
1401 bb_to_rpo[rpo[i]] = i;
1403 /* Re-do the plain uninitialized variable check, as optimization may have
1404 straightened control flow. Do this first so that we don't accidentally
1405 get a "may be" warning when we'd have seen an "is" warning later. */
1406 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1408 timevar_push (TV_TREE_UNINIT);
1410 /* Avoid quadratic beahvior when looking up case labels for edges. */
1411 start_recording_case_labels ();
1413 possibly_undefined_names = new hash_set<tree>;
1414 defined_args = new hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t>;
1416 /* Walk the CFG in RPO order so we visit PHIs with defs that are
1417 possibly uninitialized from other PHIs after those. The uninit
1418 predicate analysis will then expand the PHIs predicate with
1419 the predicates of the edges from such PHI defs. */
1420 for (int i = 0; i < n; ++i)
1421 for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
1422 !gsi_end_p (gsi); gsi_next (&gsi))
1424 gphi *phi = gsi.phi ();
1426 /* Don't look at virtual operands. */
1427 if (virtual_operand_p (gimple_phi_result (phi)))
1428 continue;
1430 unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1431 if (MASK_EMPTY (uninit_opnds))
1432 continue;
1434 warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
1437 free (rpo);
1438 free (bb_to_rpo);
1439 delete possibly_undefined_names;
1440 possibly_undefined_names = NULL;
1441 delete defined_args;
1442 defined_args = NULL;
1443 end_recording_case_labels ();
1444 free_dominance_info (CDI_POST_DOMINATORS);
1445 timevar_pop (TV_TREE_UNINIT);
1448 unsigned int
1449 pass_late_warn_uninitialized::execute (function *fun)
1451 execute_late_warn_uninitialized (fun);
1452 return 0;
1455 } // anon namespace
1457 gimple_opt_pass *
1458 make_pass_late_warn_uninitialized (gcc::context *ctxt)
1460 return new pass_late_warn_uninitialized (ctxt);
1463 static unsigned int
1464 execute_early_warn_uninitialized (struct function *fun)
1466 /* Currently, this pass runs always but
1467 execute_late_warn_uninitialized only runs with optimization. With
1468 optimization we want to warn about possible uninitialized as late
1469 as possible, thus don't do it here. However, without
1470 optimization we need to warn here about "may be uninitialized". */
1471 calculate_dominance_info (CDI_DOMINATORS);
1472 calculate_dominance_info (CDI_POST_DOMINATORS);
1474 /* Use VN in its cheapest incarnation and without doing any
1475 elimination to compute edge reachability. Don't bother when
1476 we only warn for unconditionally executed code though. */
1477 if (!optimize)
1478 do_rpo_vn (fun, NULL, NULL, false, false, VN_NOWALK);
1479 else
1480 set_all_edges_as_executable (fun);
1482 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1484 /* Post-dominator information cannot be reliably updated. Free it
1485 after the use. */
1487 free_dominance_info (CDI_POST_DOMINATORS);
1488 return 0;
1491 namespace {
1493 const pass_data pass_data_early_warn_uninitialized =
1495 GIMPLE_PASS, /* type */
1496 "early_uninit", /* name */
1497 OPTGROUP_NONE, /* optinfo_flags */
1498 TV_TREE_UNINIT, /* tv_id */
1499 PROP_ssa, /* properties_required */
1500 0, /* properties_provided */
1501 0, /* properties_destroyed */
1502 0, /* todo_flags_start */
1503 0, /* todo_flags_finish */
1506 class pass_early_warn_uninitialized : public gimple_opt_pass
1508 public:
1509 pass_early_warn_uninitialized (gcc::context *ctxt)
1510 : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1513 /* opt_pass methods: */
1514 bool gate (function *) final override { return gate_warn_uninitialized (); }
1515 unsigned int execute (function *fun) final override
1517 return execute_early_warn_uninitialized (fun);
1520 }; // class pass_early_warn_uninitialized
1522 } // anon namespace
1524 gimple_opt_pass *
1525 make_pass_early_warn_uninitialized (gcc::context *ctxt)
1527 return new pass_early_warn_uninitialized (ctxt);