d: Merge upstream dmd 56589f0f4, druntime 651389b5, phobos 1516ecad9.
[official-gcc.git] / gcc / tree-ssa-uninit.cc
blob06a19821e1836214343c75fb99a96d7fa1c41742
1 /* Predicate aware uninitialized variable warning.
2 Copyright (C) 2001-2022 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"
45 /* This implements the pass that does predicate aware warning on uses of
46 possibly uninitialized variables. The pass first collects the set of
47 possibly uninitialized SSA names. For each such name, it walks through
48 all its immediate uses. For each immediate use, it rebuilds the condition
49 expression (the predicate) that guards the use. The predicate is then
50 examined to see if the variable is always defined under that same condition.
51 This is done either by pruning the unrealizable paths that lead to the
52 default definitions or by checking if the predicate set that guards the
53 defining paths is a superset of the use predicate. */
55 /* Pointer set of potentially undefined ssa names, i.e.,
56 ssa names that are defined by phi with operands that
57 are not defined or potentially undefined. */
58 static hash_set<tree> *possibly_undefined_names = 0;
60 /* Returns the first bit position (starting from LSB)
61 in mask that is non zero. Returns -1 if the mask is empty. */
62 static int
63 get_mask_first_set_bit (unsigned mask)
65 int pos = 0;
66 if (mask == 0)
67 return -1;
69 while ((mask & (1 << pos)) == 0)
70 pos++;
72 return pos;
74 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
76 /* Return true if T, an SSA_NAME, has an undefined value. */
77 static bool
78 has_undefined_value_p (tree t)
80 return (ssa_undefined_value_p (t)
81 || (possibly_undefined_names
82 && possibly_undefined_names->contains (t)));
85 /* Return true if EXPR should suppress either uninitialized warning. */
87 static inline bool
88 get_no_uninit_warning (tree expr)
90 return warning_suppressed_p (expr, OPT_Wuninitialized);
93 /* Suppress both uninitialized warnings for EXPR. */
95 static inline void
96 set_no_uninit_warning (tree expr)
98 suppress_warning (expr, OPT_Wuninitialized);
101 /* Like has_undefined_value_p, but don't return true if the no-warning
102 bit is set on SSA_NAME_VAR for either uninit warning. */
104 static inline bool
105 uninit_undefined_value_p (tree t)
107 if (!has_undefined_value_p (t))
108 return false;
109 if (!SSA_NAME_VAR (t))
110 return true;
111 return !get_no_uninit_warning (SSA_NAME_VAR (t));
114 /* Emit warnings for uninitialized variables. This is done in two passes.
116 The first pass notices real uses of SSA names with undefined values.
117 Such uses are unconditionally uninitialized, and we can be certain that
118 such a use is a mistake. This pass is run before most optimizations,
119 so that we catch as many as we can.
121 The second pass follows PHI nodes to find uses that are potentially
122 uninitialized. In this case we can't necessarily prove that the use
123 is really uninitialized. This pass is run after most optimizations,
124 so that we thread as many jumps and possible, and delete as much dead
125 code as possible, in order to reduce false positives. We also look
126 again for plain uninitialized variables, since optimization may have
127 changed conditionally uninitialized to unconditionally uninitialized. */
129 /* Emit warning OPT for variable VAR at the point in the program where
130 the SSA_NAME T is being used uninitialized. The warning text is in
131 MSGID and STMT is the statement that does the uninitialized read.
132 PHI_ARG_LOC is the location of the PHI argument if T and VAR are one,
133 or UNKNOWN_LOCATION otherwise. */
135 static void
136 warn_uninit (opt_code opt, tree t, tree var, gimple *context,
137 location_t phi_arg_loc = UNKNOWN_LOCATION)
139 /* Bail if the value isn't provably uninitialized. */
140 if (!has_undefined_value_p (t))
141 return;
143 /* Ignore COMPLEX_EXPR as initializing only a part of a complex
144 turns in a COMPLEX_EXPR with the not initialized part being
145 set to its previous (undefined) value. */
146 if (is_gimple_assign (context)
147 && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
148 return;
150 /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
151 .DEFERRED_INIT. This is for handling the following case correctly:
153 1 typedef _Complex float C;
154 2 C foo (int cond)
156 4 C f;
157 5 __imag__ f = 0;
158 6 if (cond)
160 8 __real__ f = 1;
161 9 return f;
162 10 }
163 11 return f;
164 12 }
166 with -ftrivial-auto-var-init, compiler will insert the following
167 artificial initialization at line 4:
168 f = .DEFERRED_INIT (f, 2);
169 _1 = REALPART_EXPR <f>;
171 without the following special handling, _1 = REALPART_EXPR <f> will
172 be treated as the uninitialized use point, which is incorrect. (the
173 real uninitialized use point is at line 11). */
174 if (is_gimple_assign (context)
175 && (gimple_assign_rhs_code (context) == REALPART_EXPR
176 || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
178 tree v = gimple_assign_rhs1 (context);
179 if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
180 && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
181 IFN_DEFERRED_INIT))
182 return;
185 /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
186 can return true if the def stmt of an anonymous SSA_NAME is
187 1. A COMPLEX_EXPR created for conversion from scalar to complex. Use the
188 underlying var of the COMPLEX_EXPRs real part in that case. See PR71581.
192 2. A call to .DEFERRED_INIT internal function. Since the original variable
193 has been eliminated by optimziation, we need to get the variable name,
194 and variable declaration location from this call. We recorded variable
195 name into VAR_NAME_STR, and will get location info and record warning
196 suppressed info to VAR_DEF_STMT, which is the .DEFERRED_INIT call. */
198 const char *var_name_str = NULL;
199 gimple *var_def_stmt = NULL;
201 if (!var && !SSA_NAME_VAR (t))
203 var_def_stmt = SSA_NAME_DEF_STMT (t);
205 if (is_gimple_assign (var_def_stmt)
206 && gimple_assign_rhs_code (var_def_stmt) == COMPLEX_EXPR)
208 tree v = gimple_assign_rhs1 (var_def_stmt);
209 if (TREE_CODE (v) == SSA_NAME
210 && has_undefined_value_p (v)
211 && zerop (gimple_assign_rhs2 (var_def_stmt)))
212 var = SSA_NAME_VAR (v);
215 if (gimple_call_internal_p (var_def_stmt, IFN_DEFERRED_INIT))
217 /* Ignore the call to .DEFERRED_INIT that define the original
218 var itself as the following case:
219 temp = .DEFERRED_INIT (4, 2, “alt_reloc");
220 alt_reloc = temp;
221 In order to avoid generating warning for the fake usage
222 at alt_reloc = temp.
224 tree lhs_var = NULL_TREE;
225 tree lhs_var_name = NULL_TREE;
226 const char *lhs_var_name_str = NULL;
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 (TREE_CODE (gimple_assign_lhs (context)) == VAR_DECL)
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
241 && (lhs_var_name = DECL_NAME (lhs_var))
242 && (lhs_var_name_str = IDENTIFIER_POINTER (lhs_var_name))
243 && (strcmp (lhs_var_name_str, var_name_str) == 0))
244 return;
245 gcc_assert (var_name_str && var_def_stmt);
249 if (var == NULL_TREE && var_name_str == NULL)
250 return;
252 /* Avoid warning if we've already done so or if the warning has been
253 suppressed. */
254 if (((warning_suppressed_p (context, OPT_Wuninitialized)
255 || (gimple_assign_single_p (context)
256 && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
257 || (var && get_no_uninit_warning (var))
258 || (var_name_str
259 && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
260 return;
262 /* Use either the location of the read statement or that of the PHI
263 argument, or that of the uninitialized variable, in that order,
264 whichever is valid. */
265 location_t location = UNKNOWN_LOCATION;
266 if (gimple_has_location (context))
267 location = gimple_location (context);
268 else if (phi_arg_loc != UNKNOWN_LOCATION)
269 location = phi_arg_loc;
270 else if (var)
271 location = DECL_SOURCE_LOCATION (var);
272 else if (var_name_str)
273 location = gimple_location (var_def_stmt);
275 location = linemap_resolve_location (line_table, location,
276 LRK_SPELLING_LOCATION, NULL);
278 auto_diagnostic_group d;
279 gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
280 if (var)
282 if ((opt == OPT_Wuninitialized
283 && !warning_at (location, opt, "%qD is used uninitialized", var))
284 || (opt == OPT_Wmaybe_uninitialized
285 && !warning_at (location, opt, "%qD may be used uninitialized",
286 var)))
287 return;
289 else if (var_name_str)
291 if ((opt == OPT_Wuninitialized
292 && !warning_at (location, opt, "%qs is used uninitialized",
293 var_name_str))
294 || (opt == OPT_Wmaybe_uninitialized
295 && !warning_at (location, opt, "%qs may be used uninitialized",
296 var_name_str)))
297 return;
300 /* Avoid subsequent warnings for reads of the same variable again. */
301 if (var)
302 suppress_warning (var, opt);
303 else if (var_name_str)
304 suppress_warning (var_def_stmt, opt);
306 /* Issue a note pointing to the read variable unless the warning
307 is at the same location. */
308 location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
309 : gimple_location (var_def_stmt);
310 if (location == var_loc)
311 return;
313 if (var)
314 inform (var_loc, "%qD was declared here", var);
315 else if (var_name_str)
316 inform (var_loc, "%qs was declared here", var_name_str);
319 struct check_defs_data
321 /* If we found any may-defs besides must-def clobbers. */
322 bool found_may_defs;
325 /* Return true if STMT is a call to built-in function all of whose
326 by-reference arguments are const-qualified (i.e., the function can
327 be assumed not to modify them). */
329 static bool
330 builtin_call_nomodifying_p (gimple *stmt)
332 if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
333 return false;
335 tree fndecl = gimple_call_fndecl (stmt);
336 if (!fndecl)
337 return false;
339 tree fntype = TREE_TYPE (fndecl);
340 if (!fntype)
341 return false;
343 /* Check the called function's signature for non-constc pointers.
344 If one is found, return false. */
345 unsigned argno = 0;
346 tree argtype;
347 function_args_iterator it;
348 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
350 if (VOID_TYPE_P (argtype))
351 return true;
353 ++argno;
355 if (!POINTER_TYPE_P (argtype))
356 continue;
358 if (TYPE_READONLY (TREE_TYPE (argtype)))
359 continue;
361 return false;
364 /* If the number of actual arguments to the call is less than or
365 equal to the number of parameters, return false. */
366 unsigned nargs = gimple_call_num_args (stmt);
367 if (nargs <= argno)
368 return false;
370 /* Check arguments passed through the ellipsis in calls to variadic
371 functions for pointers. If one is found that's a non-constant
372 pointer, return false. */
373 for (; argno < nargs; ++argno)
375 tree arg = gimple_call_arg (stmt, argno);
376 argtype = TREE_TYPE (arg);
377 if (!POINTER_TYPE_P (argtype))
378 continue;
380 if (TYPE_READONLY (TREE_TYPE (argtype)))
381 continue;
383 return false;
386 return true;
389 /* If ARG is a FNDECL parameter declared with attribute access none or
390 write_only issue a warning for its read access via PTR. */
392 static void
393 maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
395 if (!fndecl)
396 return;
398 if (get_no_uninit_warning (arg))
399 return;
401 tree fntype = TREE_TYPE (fndecl);
402 if (!fntype)
403 return;
405 /* Initialize a map of attribute access specifications for arguments
406 to the function call. */
407 rdwr_map rdwr_idx;
408 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
410 unsigned argno = 0;
411 tree parms = DECL_ARGUMENTS (fndecl);
412 for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
414 if (parm != arg)
415 continue;
417 const attr_access* access = rdwr_idx.get (argno);
418 if (!access)
419 break;
421 if (access->mode != access_none
422 && access->mode != access_write_only)
423 continue;
425 location_t stmtloc
426 = linemap_resolve_location (line_table, gimple_location (stmt),
427 LRK_SPELLING_LOCATION, NULL);
429 if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
430 "%qE may be used uninitialized", ptr))
431 break;
433 suppress_warning (arg, OPT_Wmaybe_uninitialized);
435 const char* const access_str =
436 TREE_STRING_POINTER (access->to_external_string ());
438 location_t parmloc = DECL_SOURCE_LOCATION (parm);
439 inform (parmloc, "accessing argument %u of a function declared with "
440 "attribute %<%s%>",
441 argno + 1, access_str);
443 break;
447 /* Callback for walk_aliased_vdefs. */
449 static bool
450 check_defs (ao_ref *ref, tree vdef, void *data_)
452 check_defs_data *data = (check_defs_data *)data_;
453 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
455 /* Ignore the vdef if the definition statement is a call
456 to .DEFERRED_INIT function. */
457 if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
458 return false;
460 /* For address taken variable, a temporary variable is added between
461 the variable and the call to .DEFERRED_INIT function as:
462 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
463 i1 = _1;
464 Ignore this vdef as well. */
465 if (is_gimple_assign (def_stmt)
466 && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
468 tree tmp_var = gimple_assign_rhs1 (def_stmt);
469 if (gimple_call_internal_p (SSA_NAME_DEF_STMT (tmp_var),
470 IFN_DEFERRED_INIT))
471 return false;
474 /* The ASAN_MARK intrinsic doesn't modify the variable. */
475 if (is_gimple_call (def_stmt))
477 /* The ASAN_MARK intrinsic doesn't modify the variable. */
478 if (gimple_call_internal_p (def_stmt)
479 && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
480 return false;
482 if (tree fndecl = gimple_call_fndecl (def_stmt))
484 /* Some sanitizer calls pass integer arguments to built-ins
485 that expect pointets. Avoid using gimple_call_builtin_p()
486 which fails for such calls. */
487 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
489 built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
490 if (fncode > BEGIN_SANITIZER_BUILTINS
491 && fncode < END_SANITIZER_BUILTINS)
492 return false;
497 /* End of VLA scope is not a kill. */
498 if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
499 return false;
501 /* If this is a clobber then if it is not a kill walk past it. */
502 if (gimple_clobber_p (def_stmt))
504 if (stmt_kills_ref_p (def_stmt, ref))
505 return true;
506 return false;
509 if (builtin_call_nomodifying_p (def_stmt))
510 return false;
512 /* Found a may-def on this path. */
513 data->found_may_defs = true;
514 return true;
517 /* Counters and limits controlling the depth of analysis and
518 strictness of the warning. */
519 struct wlimits
521 /* Number of VDEFs encountered. */
522 unsigned int vdef_cnt;
523 /* Number of statements examined by walk_aliased_vdefs. */
524 unsigned int oracle_cnt;
525 /* Limit on the number of statements visited by walk_aliased_vdefs. */
526 unsigned limit;
527 /* Set when basic block with statement is executed unconditionally. */
528 bool always_executed;
529 /* Set to issue -Wmaybe-uninitialized. */
530 bool wmaybe_uninit;
533 /* Determine if REF references an uninitialized operand and diagnose
534 it if so. STMS is the referencing statement. LHS is the result
535 of the access and may be null. RHS is the variable referenced by
536 the access; it may not be null. */
538 static tree
539 maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
540 wlimits &wlims)
542 bool has_bit_insert = false;
543 use_operand_p luse_p;
544 imm_use_iterator liter;
546 if (get_no_uninit_warning (rhs))
547 return NULL_TREE;
549 /* Do not warn if the base was marked so or this is a
550 hard register var. */
551 tree base = ao_ref_base (&ref);
552 if ((VAR_P (base)
553 && DECL_HARD_REGISTER (base))
554 || get_no_uninit_warning (base))
555 return NULL_TREE;
557 /* Do not warn if the access is zero size or if it's fully outside
558 the object. */
559 poly_int64 decl_size;
560 if (known_size_p (ref.size)
561 && known_eq (ref.max_size, ref.size)
562 && (known_eq (ref.size, 0)
563 || known_le (ref.offset + ref.size, 0)))
564 return NULL_TREE;
566 if (DECL_P (base)
567 && known_ge (ref.offset, 0)
568 && DECL_SIZE (base)
569 && poly_int_tree_p (DECL_SIZE (base), &decl_size)
570 && known_le (decl_size, ref.offset))
571 return NULL_TREE;
573 /* Do not warn if the result of the access is then used for
574 a BIT_INSERT_EXPR. */
575 if (lhs && TREE_CODE (lhs) == SSA_NAME)
576 FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
578 gimple *use_stmt = USE_STMT (luse_p);
579 /* BIT_INSERT_EXPR first operand should not be considered
580 a use for the purpose of uninit warnings. */
581 if (gassign *ass = dyn_cast <gassign *> (use_stmt))
583 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
584 && luse_p->use == gimple_assign_rhs1_ptr (ass))
586 has_bit_insert = true;
587 break;
592 if (has_bit_insert)
593 return NULL_TREE;
595 /* Limit the walking to a constant number of stmts after
596 we overcommit quadratic behavior for small functions
597 and O(n) behavior. */
598 if (wlims.oracle_cnt > 128 * 128
599 && wlims.oracle_cnt > wlims.vdef_cnt * 2)
600 wlims.limit = 32;
602 check_defs_data data;
603 bool fentry_reached = false;
604 data.found_may_defs = false;
605 tree use = gimple_vuse (stmt);
606 if (!use)
607 return NULL_TREE;
608 int res = walk_aliased_vdefs (&ref, use,
609 check_defs, &data, NULL,
610 &fentry_reached, wlims.limit);
611 if (res == -1)
613 wlims.oracle_cnt += wlims.limit;
614 return NULL_TREE;
617 wlims.oracle_cnt += res;
618 if (data.found_may_defs)
619 return NULL_TREE;
621 bool found_alloc = false;
623 if (fentry_reached)
625 if (TREE_CODE (base) == MEM_REF)
626 base = TREE_OPERAND (base, 0);
628 /* Follow the chain of SSA_NAME assignments looking for an alloca
629 call (or VLA) or malloc/realloc, or for decls. If any is found
630 (and in the latter case, the operand is a local variable) issue
631 a warning. */
632 while (TREE_CODE (base) == SSA_NAME)
634 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
636 if (is_gimple_call (def_stmt)
637 && gimple_call_builtin_p (def_stmt))
639 /* Detect uses of uninitialized alloca/VLAs. */
640 tree fndecl = gimple_call_fndecl (def_stmt);
641 const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
642 if (fncode == BUILT_IN_ALLOCA
643 || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
644 || fncode == BUILT_IN_MALLOC)
645 found_alloc = true;
646 break;
649 if (!is_gimple_assign (def_stmt))
650 break;
652 tree_code code = gimple_assign_rhs_code (def_stmt);
653 if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
654 break;
656 base = gimple_assign_rhs1 (def_stmt);
657 if (TREE_CODE (base) == ADDR_EXPR)
658 base = TREE_OPERAND (base, 0);
660 if (DECL_P (base)
661 || TREE_CODE (base) == COMPONENT_REF)
662 rhs = base;
664 if (TREE_CODE (base) == MEM_REF)
665 base = TREE_OPERAND (base, 0);
667 if (tree ba = get_base_address (base))
668 base = ba;
671 /* Replace the RHS expression with BASE so that it
672 refers to it in the diagnostic (instead of to
673 '<unknown>'). */
674 if (DECL_P (base)
675 && EXPR_P (rhs)
676 && TREE_CODE (rhs) != COMPONENT_REF)
677 rhs = base;
680 /* Do not warn if it can be initialized outside this function.
681 If we did not reach function entry then we found killing
682 clobbers on all paths to entry. */
683 if (!found_alloc && fentry_reached)
685 if (TREE_CODE (base) == SSA_NAME)
687 tree var = SSA_NAME_VAR (base);
688 if (var && TREE_CODE (var) == PARM_DECL)
690 maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
691 return NULL_TREE;
695 if (!VAR_P (base)
696 || is_global_var (base))
697 /* ??? We'd like to use ref_may_alias_global_p but that
698 excludes global readonly memory and thus we get bogus
699 warnings from p = cond ? "a" : "b" for example. */
700 return NULL_TREE;
703 /* Strip the address-of expression from arrays passed to functions. */
704 if (TREE_CODE (rhs) == ADDR_EXPR)
705 rhs = TREE_OPERAND (rhs, 0);
707 /* Check again since RHS may have changed above. */
708 if (get_no_uninit_warning (rhs))
709 return NULL_TREE;
711 /* Avoid warning about empty types such as structs with no members.
712 The first_field() test is important for C++ where the predicate
713 alone isn't always sufficient. */
714 tree rhstype = TREE_TYPE (rhs);
715 if (POINTER_TYPE_P (rhstype))
716 rhstype = TREE_TYPE (rhstype);
717 if (is_empty_type (rhstype))
718 return NULL_TREE;
720 bool warned = false;
721 /* We didn't find any may-defs so on all paths either
722 reached function entry or a killing clobber. */
723 location_t location
724 = linemap_resolve_location (line_table, gimple_location (stmt),
725 LRK_SPELLING_LOCATION, NULL);
726 if (wlims.always_executed)
728 if (warning_at (location, OPT_Wuninitialized,
729 "%qE is used uninitialized", rhs))
731 /* ??? This is only effective for decls as in
732 gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
733 uses or accesses by functions as it may hide important
734 locations. */
735 if (lhs)
736 set_no_uninit_warning (rhs);
737 warned = true;
740 else if (wlims.wmaybe_uninit)
741 warned = warning_at (location, OPT_Wmaybe_uninitialized,
742 "%qE may be used uninitialized", rhs);
744 return warned ? base : NULL_TREE;
748 /* Diagnose passing addresses of uninitialized objects to either const
749 pointer arguments to functions, or to functions declared with attribute
750 access implying read access to those objects. */
752 static void
753 maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
755 if (!wlims.wmaybe_uninit)
756 return;
758 unsigned nargs = gimple_call_num_args (stmt);
759 if (!nargs)
760 return;
762 tree fndecl = gimple_call_fndecl (stmt);
763 tree fntype = gimple_call_fntype (stmt);
764 if (!fntype)
765 return;
767 /* Const function do not read their arguments. */
768 if (gimple_call_flags (stmt) & ECF_CONST)
769 return;
771 const built_in_function fncode
772 = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
773 ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
775 if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
776 /* Avoid diagnosing calls to raw memory functions (this is overly
777 permissive; consider tightening it up). */
778 return;
780 /* Save the current warning setting and replace it either a "maybe"
781 when passing addresses of uninitialized variables to const-qualified
782 pointers or arguments declared with attribute read_write, or with
783 a "certain" when passing them to arguments declared with attribute
784 read_only. */
785 const bool save_always_executed = wlims.always_executed;
787 /* Initialize a map of attribute access specifications for arguments
788 to the function call. */
789 rdwr_map rdwr_idx;
790 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
792 tree argtype;
793 unsigned argno = 0;
794 function_args_iterator it;
796 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
798 ++argno;
800 if (argno > nargs)
801 break;
803 if (!POINTER_TYPE_P (argtype))
804 continue;
806 tree access_size = NULL_TREE;
807 const attr_access* access = rdwr_idx.get (argno - 1);
808 if (access)
810 if (access->mode == access_none
811 || access->mode == access_write_only)
812 continue;
814 if (access->mode == access_deferred
815 && !TYPE_READONLY (TREE_TYPE (argtype)))
816 continue;
818 if (save_always_executed && access->mode == access_read_only)
819 /* Attribute read_only arguments imply read access. */
820 wlims.always_executed = true;
821 else
822 /* Attribute read_write arguments are documented as requiring
823 initialized objects but it's expected that aggregates may
824 be only partially initialized regardless. */
825 wlims.always_executed = false;
827 if (access->sizarg < nargs)
828 access_size = gimple_call_arg (stmt, access->sizarg);
830 else if (!TYPE_READONLY (TREE_TYPE (argtype)))
831 continue;
832 else if (save_always_executed && fncode != BUILT_IN_LAST)
833 /* Const-qualified arguments to built-ins imply read access. */
834 wlims.always_executed = true;
835 else
836 /* Const-qualified arguments to ordinary functions imply a likely
837 (but not definitive) read access. */
838 wlims.always_executed = false;
840 /* Ignore args we are not going to read from. */
841 if (gimple_call_arg_flags (stmt, argno - 1)
842 & (EAF_UNUSED | EAF_NO_DIRECT_READ))
843 continue;
845 tree arg = gimple_call_arg (stmt, argno - 1);
846 if (!POINTER_TYPE_P (TREE_TYPE (arg)))
847 /* Avoid actual arguments with invalid types. */
848 continue;
850 ao_ref ref;
851 ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
852 tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
853 if (!argbase)
854 continue;
856 if (access && access->mode != access_deferred)
858 const char* const access_str =
859 TREE_STRING_POINTER (access->to_external_string ());
861 if (fndecl)
863 location_t loc = DECL_SOURCE_LOCATION (fndecl);
864 inform (loc, "in a call to %qD declared with "
865 "attribute %<%s%> here", fndecl, access_str);
867 else
869 /* Handle calls through function pointers. */
870 location_t loc = gimple_location (stmt);
871 inform (loc, "in a call to %qT declared with "
872 "attribute %<%s%>", fntype, access_str);
875 else
877 /* For a declaration with no relevant attribute access create
878 a dummy object and use the formatting function to avoid
879 having to complicate things here. */
880 attr_access ptr_access = { };
881 if (!access)
882 access = &ptr_access;
883 const std::string argtypestr = access->array_as_string (argtype);
884 if (fndecl)
886 location_t loc (DECL_SOURCE_LOCATION (fndecl));
887 inform (loc, "by argument %u of type %s to %qD "
888 "declared here",
889 argno, argtypestr.c_str (), fndecl);
891 else
893 /* Handle calls through function pointers. */
894 location_t loc (gimple_location (stmt));
895 inform (loc, "by argument %u of type %s to %qT",
896 argno, argtypestr.c_str (), fntype);
900 if (DECL_P (argbase))
902 location_t loc = DECL_SOURCE_LOCATION (argbase);
903 inform (loc, "%qD declared here", argbase);
907 wlims.always_executed = save_always_executed;
910 /* Warn about an uninitialized PHI argument on the fallthru path to
911 an always executed block BB. */
913 static void
914 warn_uninit_phi_uses (basic_block bb)
916 edge_iterator ei;
917 edge e, found = NULL, found_back = NULL;
918 /* Look for a fallthru and possibly a single backedge. */
919 FOR_EACH_EDGE (e, ei, bb->preds)
921 /* Ignore backedges. */
922 if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
924 if (found_back)
926 found = NULL;
927 break;
929 found_back = e;
930 continue;
932 if (found)
934 found = NULL;
935 break;
937 found = e;
939 if (!found)
940 return;
942 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
943 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
944 gsi_next (&si))
946 gphi *phi = si.phi ();
947 tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
948 if (TREE_CODE (def) != SSA_NAME
949 || !SSA_NAME_IS_DEFAULT_DEF (def)
950 || virtual_operand_p (def))
951 continue;
952 /* If there's a default def on the fallthru edge PHI
953 value and there's a use that post-dominates entry
954 then that use is uninitialized and we can warn. */
955 imm_use_iterator iter;
956 use_operand_p use_p;
957 gimple *use_stmt = NULL;
958 FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
960 use_stmt = USE_STMT (use_p);
961 if (gimple_location (use_stmt) != UNKNOWN_LOCATION
962 && dominated_by_p (CDI_POST_DOMINATORS, succ,
963 gimple_bb (use_stmt))
964 /* If we found a non-fallthru edge make sure the
965 use is inside the loop, otherwise the backedge
966 can serve as initialization. */
967 && (!found_back
968 || dominated_by_p (CDI_DOMINATORS, found_back->src,
969 gimple_bb (use_stmt))))
970 break;
971 use_stmt = NULL;
973 if (use_stmt)
974 warn_uninit (OPT_Wuninitialized, def,
975 SSA_NAME_VAR (def), use_stmt);
979 /* Issue warnings about reads of uninitialized variables. WMAYBE_UNINIT
980 is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized. */
982 static void
983 warn_uninitialized_vars (bool wmaybe_uninit)
985 /* Counters and limits controlling the depth of the warning. */
986 wlimits wlims = { };
987 wlims.wmaybe_uninit = wmaybe_uninit;
989 gimple_stmt_iterator gsi;
990 basic_block bb;
991 FOR_EACH_BB_FN (bb, cfun)
993 edge_iterator ei;
994 edge e;
995 FOR_EACH_EDGE (e, ei, bb->preds)
996 if (e->flags & EDGE_EXECUTABLE)
997 break;
998 /* Skip unreachable blocks. For early analysis we use VN to
999 determine edge executability when wmaybe_uninit. */
1000 if (!e)
1001 continue;
1003 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1004 /* ??? This could be improved when we use a greedy walk and have
1005 some edges marked as not executable. */
1006 wlims.always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
1008 if (wlims.always_executed)
1009 warn_uninit_phi_uses (bb);
1011 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1013 gimple *stmt = gsi_stmt (gsi);
1015 /* The call is an artificial use, will not provide meaningful
1016 error message. If the result of the call is used somewhere
1017 else, we warn there instead. */
1018 if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
1019 continue;
1021 if (is_gimple_debug (stmt))
1022 continue;
1024 /* We only do data flow with SSA_NAMEs, so that's all we
1025 can warn about. */
1026 use_operand_p use_p;
1027 ssa_op_iter op_iter;
1028 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
1030 /* BIT_INSERT_EXPR first operand should not be considered
1031 a use for the purpose of uninit warnings. */
1032 if (gassign *ass = dyn_cast <gassign *> (stmt))
1034 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
1035 && use_p->use == gimple_assign_rhs1_ptr (ass))
1036 continue;
1038 tree use = USE_FROM_PTR (use_p);
1039 if (wlims.always_executed)
1040 warn_uninit (OPT_Wuninitialized, use,
1041 SSA_NAME_VAR (use), stmt);
1042 else if (wmaybe_uninit)
1043 warn_uninit (OPT_Wmaybe_uninitialized, use,
1044 SSA_NAME_VAR (use), stmt);
1047 /* For limiting the alias walk below we count all
1048 vdefs in the function. */
1049 if (gimple_vdef (stmt))
1050 wlims.vdef_cnt++;
1052 if (gcall *call = dyn_cast <gcall *> (stmt))
1053 maybe_warn_pass_by_reference (call, wlims);
1054 else if (gimple_assign_load_p (stmt)
1055 && gimple_has_location (stmt))
1057 tree rhs = gimple_assign_rhs1 (stmt);
1058 tree lhs = gimple_assign_lhs (stmt);
1060 ao_ref ref;
1061 ao_ref_init (&ref, rhs);
1062 tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
1063 if (!var)
1064 continue;
1066 if (DECL_P (var))
1068 location_t loc = DECL_SOURCE_LOCATION (var);
1069 inform (loc, "%qD declared here", var);
1076 /* Checks if the operand OPND of PHI is defined by
1077 another phi with one operand defined by this PHI,
1078 but the rest operands are all defined. If yes,
1079 returns true to skip this operand as being
1080 redundant. Can be enhanced to be more general. */
1082 static bool
1083 can_skip_redundant_opnd (tree opnd, gimple *phi)
1085 tree phi_def = gimple_phi_result (phi);
1086 gimple *op_def = SSA_NAME_DEF_STMT (opnd);
1087 if (gimple_code (op_def) != GIMPLE_PHI)
1088 return false;
1090 unsigned n = gimple_phi_num_args (op_def);
1091 for (unsigned i = 0; i < n; ++i)
1093 tree op = gimple_phi_arg_def (op_def, i);
1094 if (TREE_CODE (op) != SSA_NAME)
1095 continue;
1096 if (op != phi_def && uninit_undefined_value_p (op))
1097 return false;
1100 return true;
1103 /* Return a bitset holding the positions of arguments in PHI with empty
1104 (or possibly empty) definitions. */
1106 static unsigned
1107 compute_uninit_opnds_pos (gphi *phi)
1109 unsigned uninit_opnds = 0;
1111 unsigned n = gimple_phi_num_args (phi);
1112 /* Bail out for phi with too many args. */
1113 if (n > predicate::func_t::max_phi_args)
1114 return 0;
1116 for (unsigned i = 0; i < n; ++i)
1118 tree op = gimple_phi_arg_def (phi, i);
1119 if (TREE_CODE (op) == SSA_NAME
1120 && uninit_undefined_value_p (op)
1121 && !can_skip_redundant_opnd (op, phi))
1123 if (cfun->has_nonlocal_label || cfun->calls_setjmp)
1125 /* Ignore SSA_NAMEs that appear on abnormal edges
1126 somewhere. */
1127 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
1128 continue;
1130 MASK_SET_BIT (uninit_opnds, i);
1133 return uninit_opnds;
1136 /* Function object type used to determine whether an expression
1137 is of interest to the predicate analyzer. */
1139 struct uninit_undef_val_t: public predicate::func_t
1141 virtual bool operator()(tree) override;
1142 virtual unsigned phi_arg_set (gphi *) override;
1145 /* Return true if the argument is an expression of interest. */
1147 bool
1148 uninit_undef_val_t::operator()(tree val)
1150 if (TREE_CODE (val) == SSA_NAME)
1151 return uninit_undefined_value_p (val);
1153 return false;
1156 /* Return a bitset of PHI arguments of interest. */
1158 unsigned
1159 uninit_undef_val_t::phi_arg_set (gphi *phi)
1161 return compute_uninit_opnds_pos (phi);
1164 /* Searches through all uses of a potentially
1165 uninitialized variable defined by PHI and returns a use
1166 statement if the use is not properly guarded. It returns
1167 NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
1168 holding the position(s) of uninit PHI operands. WORKLIST
1169 is the vector of candidate phis that may be updated by this
1170 function. ADDED_TO_WORKLIST is the pointer set tracking
1171 if the new phi is already in the worklist. */
1173 static gimple *
1174 find_uninit_use (gphi *phi, unsigned uninit_opnds,
1175 vec<gphi *> *worklist, hash_set<gphi *> *added_to_worklist)
1177 /* The Boolean predicate guarding the PHI definition. Initialized
1178 lazily from PHI in the first call to is_use_guarded() and cached
1179 for subsequent iterations. */
1180 uninit_undef_val_t eval;
1181 predicate def_preds (eval);
1183 use_operand_p use_p;
1184 imm_use_iterator iter;
1185 tree phi_result = gimple_phi_result (phi);
1186 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1188 gimple *use_stmt = USE_STMT (use_p);
1189 if (is_gimple_debug (use_stmt))
1190 continue;
1192 basic_block use_bb;
1193 if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1194 use_bb = gimple_phi_arg_edge (use_phi,
1195 PHI_ARG_INDEX_FROM_USE (use_p))->src;
1196 else
1197 use_bb = gimple_bb (use_stmt);
1199 if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1200 continue;
1202 if (dump_file && (dump_flags & TDF_DETAILS))
1204 fprintf (dump_file, "Found unguarded use in bb %u: ",
1205 use_bb->index);
1206 print_gimple_stmt (dump_file, use_stmt, 0);
1208 /* Found one real use, return. */
1209 if (gimple_code (use_stmt) != GIMPLE_PHI)
1210 return use_stmt;
1212 /* Found a phi use that is not guarded,
1213 add the phi to the worklist. */
1214 if (!added_to_worklist->add (as_a<gphi *> (use_stmt)))
1216 if (dump_file && (dump_flags & TDF_DETAILS))
1218 fprintf (dump_file, "[WORKLIST]: Update worklist with phi: ");
1219 print_gimple_stmt (dump_file, use_stmt, 0);
1222 worklist->safe_push (as_a<gphi *> (use_stmt));
1223 possibly_undefined_names->add (phi_result);
1227 return NULL;
1230 /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1231 and gives warning if there exists a runtime path from the entry to a
1232 use of the PHI def that does not contain a definition. In other words,
1233 the warning is on the real use. The more dead paths that can be pruned
1234 by the compiler, the fewer false positives the warning is. WORKLIST
1235 is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is
1236 a pointer set tracking if the new phi is added to the worklist or not. */
1238 static void
1239 warn_uninitialized_phi (gphi *phi, vec<gphi *> *worklist,
1240 hash_set<gphi *> *added_to_worklist)
1242 /* Don't look at virtual operands. */
1243 if (virtual_operand_p (gimple_phi_result (phi)))
1244 return;
1246 unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1247 if (MASK_EMPTY (uninit_opnds))
1248 return;
1250 if (dump_file && (dump_flags & TDF_DETAILS))
1252 fprintf (dump_file, "Examining phi: ");
1253 print_gimple_stmt (dump_file, phi, 0);
1256 gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds,
1257 worklist, added_to_worklist);
1259 /* All uses are properly guarded but a new PHI may have been added
1260 to WORKLIST. */
1261 if (!uninit_use_stmt)
1262 return;
1264 unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1265 tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1266 if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
1267 return;
1269 location_t loc = UNKNOWN_LOCATION;
1270 if (gimple_phi_arg_has_location (phi, phiarg_index))
1271 loc = gimple_phi_arg_location (phi, phiarg_index);
1272 else
1274 tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1275 if (TREE_CODE (arg_def) == SSA_NAME)
1277 gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1278 if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1280 unsigned uop = compute_uninit_opnds_pos (arg_phi);
1281 unsigned idx = MASK_FIRST_SET_BIT (uop);
1282 if (idx < gimple_phi_num_args (arg_phi)
1283 && gimple_phi_arg_has_location (arg_phi, idx))
1284 loc = gimple_phi_arg_location (arg_phi, idx);
1289 warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1290 SSA_NAME_VAR (uninit_op),
1291 uninit_use_stmt, loc);
1294 static bool
1295 gate_warn_uninitialized (void)
1297 return warn_uninitialized || warn_maybe_uninitialized;
1300 namespace {
1302 const pass_data pass_data_late_warn_uninitialized =
1304 GIMPLE_PASS, /* type */
1305 "uninit", /* name */
1306 OPTGROUP_NONE, /* optinfo_flags */
1307 TV_NONE, /* tv_id */
1308 PROP_ssa, /* properties_required */
1309 0, /* properties_provided */
1310 0, /* properties_destroyed */
1311 0, /* todo_flags_start */
1312 0, /* todo_flags_finish */
1315 class pass_late_warn_uninitialized : public gimple_opt_pass
1317 public:
1318 pass_late_warn_uninitialized (gcc::context *ctxt)
1319 : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1322 /* opt_pass methods: */
1323 opt_pass *clone () final override
1325 return new pass_late_warn_uninitialized (m_ctxt);
1327 bool gate (function *) final override { return gate_warn_uninitialized (); }
1328 unsigned int execute (function *) final override;
1330 }; // class pass_late_warn_uninitialized
1332 static void
1333 execute_late_warn_uninitialized (function *fun)
1335 basic_block bb;
1336 gphi_iterator gsi;
1337 vec<gphi *> worklist = vNULL;
1339 calculate_dominance_info (CDI_DOMINATORS);
1340 calculate_dominance_info (CDI_POST_DOMINATORS);
1342 /* Mark all edges executable, warn_uninitialized_vars will skip
1343 unreachable blocks. */
1344 set_all_edges_as_executable (fun);
1346 /* Re-do the plain uninitialized variable check, as optimization may have
1347 straightened control flow. Do this first so that we don't accidentally
1348 get a "may be" warning when we'd have seen an "is" warning later. */
1349 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1351 timevar_push (TV_TREE_UNINIT);
1353 possibly_undefined_names = new hash_set<tree>;
1354 hash_set<gphi *> added_to_worklist;
1356 /* Initialize worklist */
1357 FOR_EACH_BB_FN (bb, fun)
1358 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1360 gphi *phi = gsi.phi ();
1362 /* Don't look at virtual operands. */
1363 if (virtual_operand_p (gimple_phi_result (phi)))
1364 continue;
1366 unsigned n = gimple_phi_num_args (phi);
1367 for (unsigned i = 0; i < n; ++i)
1369 tree op = gimple_phi_arg_def (phi, i);
1370 if (TREE_CODE (op) == SSA_NAME && uninit_undefined_value_p (op))
1372 worklist.safe_push (phi);
1373 added_to_worklist.add (phi);
1374 if (dump_file && (dump_flags & TDF_DETAILS))
1376 fprintf (dump_file, "[WORKLIST]: add to initial list "
1377 "for operand %u of: ", i);
1378 print_gimple_stmt (dump_file, phi, 0);
1380 break;
1385 while (worklist.length () != 0)
1387 gphi *cur_phi = 0;
1388 cur_phi = worklist.pop ();
1389 warn_uninitialized_phi (cur_phi, &worklist, &added_to_worklist);
1392 worklist.release ();
1393 delete possibly_undefined_names;
1394 possibly_undefined_names = NULL;
1395 free_dominance_info (CDI_POST_DOMINATORS);
1396 timevar_pop (TV_TREE_UNINIT);
1399 unsigned int
1400 pass_late_warn_uninitialized::execute (function *fun)
1402 execute_late_warn_uninitialized (fun);
1403 return 0;
1406 } // anon namespace
1408 gimple_opt_pass *
1409 make_pass_late_warn_uninitialized (gcc::context *ctxt)
1411 return new pass_late_warn_uninitialized (ctxt);
1414 static unsigned int
1415 execute_early_warn_uninitialized (struct function *fun)
1417 /* Currently, this pass runs always but
1418 execute_late_warn_uninitialized only runs with optimization. With
1419 optimization we want to warn about possible uninitialized as late
1420 as possible, thus don't do it here. However, without
1421 optimization we need to warn here about "may be uninitialized". */
1422 calculate_dominance_info (CDI_DOMINATORS);
1423 calculate_dominance_info (CDI_POST_DOMINATORS);
1425 /* Use VN in its cheapest incarnation and without doing any
1426 elimination to compute edge reachability. Don't bother when
1427 we only warn for unconditionally executed code though. */
1428 if (!optimize)
1430 do_rpo_vn (fun, NULL, NULL, false, false, VN_NOWALK);
1431 free_rpo_vn ();
1433 else
1434 set_all_edges_as_executable (fun);
1436 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1438 /* Post-dominator information cannot be reliably updated. Free it
1439 after the use. */
1441 free_dominance_info (CDI_POST_DOMINATORS);
1442 return 0;
1445 namespace {
1447 const pass_data pass_data_early_warn_uninitialized =
1449 GIMPLE_PASS, /* type */
1450 "early_uninit", /* name */
1451 OPTGROUP_NONE, /* optinfo_flags */
1452 TV_TREE_UNINIT, /* tv_id */
1453 PROP_ssa, /* properties_required */
1454 0, /* properties_provided */
1455 0, /* properties_destroyed */
1456 0, /* todo_flags_start */
1457 0, /* todo_flags_finish */
1460 class pass_early_warn_uninitialized : public gimple_opt_pass
1462 public:
1463 pass_early_warn_uninitialized (gcc::context *ctxt)
1464 : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1467 /* opt_pass methods: */
1468 bool gate (function *) final override { return gate_warn_uninitialized (); }
1469 unsigned int execute (function *fun) final override
1471 return execute_early_warn_uninitialized (fun);
1474 }; // class pass_early_warn_uninitialized
1476 } // anon namespace
1478 gimple_opt_pass *
1479 make_pass_early_warn_uninitialized (gcc::context *ctxt)
1481 return new pass_early_warn_uninitialized (ctxt);