]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-uninit.c
x86: Remove "%!" before ret
[thirdparty/gcc.git] / gcc / tree-ssa-uninit.c
CommitLineData
34f97b94 1/* Predicate aware uninitialized variable warning.
99dee823 2 Copyright (C) 2001-2021 Free Software Foundation, Inc.
34f97b94
XDL
3 Contributed by Xinliang David Li <davidxl@google.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
72be80e4 21#define INCLUDE_STRING
34f97b94
XDL
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
c7131fb2 25#include "backend.h"
34f97b94 26#include "tree.h"
c7131fb2 27#include "gimple.h"
957060b5 28#include "tree-pass.h"
c7131fb2 29#include "ssa.h"
957060b5
AM
30#include "gimple-pretty-print.h"
31#include "diagnostic-core.h"
40e23961 32#include "fold-const.h"
5be5c238 33#include "gimple-iterator.h"
442b4905 34#include "tree-ssa.h"
666e8e06 35#include "tree-cfg.h"
11ef0b22 36#include "cfghooks.h"
b825a228
MS
37#include "attribs.h"
38#include "builtins.h"
39#include "calls.h"
45f4e2b0 40#include "gimple-range.h"
34f97b94 41
94c12ffa
MS
42#include "gimple-predicate-analysis.h"
43
34f97b94 44/* This implements the pass that does predicate aware warning on uses of
ac0e4fde
ML
45 possibly uninitialized variables. The pass first collects the set of
46 possibly uninitialized SSA names. For each such name, it walks through
47 all its immediate uses. For each immediate use, it rebuilds the condition
48 expression (the predicate) that guards the use. The predicate is then
34f97b94
XDL
49 examined to see if the variable is always defined under that same condition.
50 This is done either by pruning the unrealizable paths that lead to the
51 default definitions or by checking if the predicate set that guards the
52 defining paths is a superset of the use predicate. */
53
34f97b94
XDL
54/* Pointer set of potentially undefined ssa names, i.e.,
55 ssa names that are defined by phi with operands that
56 are not defined or potentially undefined. */
6e2830c3 57static hash_set<tree> *possibly_undefined_names = 0;
34f97b94 58
34f97b94 59/* Returns the first bit position (starting from LSB)
ac0e4fde 60 in mask that is non zero. Returns -1 if the mask is empty. */
34f97b94
XDL
61static int
62get_mask_first_set_bit (unsigned mask)
63{
64 int pos = 0;
65 if (mask == 0)
66 return -1;
67
68 while ((mask & (1 << pos)) == 0)
69 pos++;
70
71 return pos;
72}
73#define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
74
34f97b94 75/* Return true if T, an SSA_NAME, has an undefined value. */
c152901f
AM
76static bool
77has_undefined_value_p (tree t)
34f97b94 78{
c152901f 79 return (ssa_undefined_value_p (t)
5e48d8a0
ML
80 || (possibly_undefined_names
81 && possibly_undefined_names->contains (t)));
34f97b94
XDL
82}
83
e9e2bad7
MS
84/* Return true if EXPR should suppress either uninitialized warning. */
85
86static inline bool
87get_no_uninit_warning (tree expr)
88{
89 return warning_suppressed_p (expr, OPT_Wuninitialized);
90}
91
92/* Suppress both uninitialized warnings for EXPR. */
93
94static inline void
95set_no_uninit_warning (tree expr)
96{
97 suppress_warning (expr, OPT_Wuninitialized);
98}
99
100/* Like has_undefined_value_p, but don't return true if the no-warning
101 bit is set on SSA_NAME_VAR for either uninit warning. */
ba7e83f8
JJ
102
103static inline bool
ac0e4fde
ML
104uninit_undefined_value_p (tree t)
105{
c152901f 106 if (!has_undefined_value_p (t))
ba7e83f8 107 return false;
e9e2bad7
MS
108 if (!SSA_NAME_VAR (t))
109 return true;
110 return !get_no_uninit_warning (SSA_NAME_VAR (t));
ba7e83f8
JJ
111}
112
c152901f
AM
113/* Emit warnings for uninitialized variables. This is done in two passes.
114
115 The first pass notices real uses of SSA names with undefined values.
116 Such uses are unconditionally uninitialized, and we can be certain that
117 such a use is a mistake. This pass is run before most optimizations,
118 so that we catch as many as we can.
119
120 The second pass follows PHI nodes to find uses that are potentially
121 uninitialized. In this case we can't necessarily prove that the use
122 is really uninitialized. This pass is run after most optimizations,
123 so that we thread as many jumps and possible, and delete as much dead
124 code as possible, in order to reduce false positives. We also look
125 again for plain uninitialized variables, since optimization may have
126 changed conditionally uninitialized to unconditionally uninitialized. */
127
4e84e381
MS
128/* Emit warning OPT for variable VAR at the point in the program where
129 the SSA_NAME T is being used uninitialized. The warning text is in
130 MSGID and STMT is the statement that does the uninitialized read.
131 PHI_ARG_LOC is the location of the PHI argument if T and VAR are one,
132 or UNKNOWN_LOCATION otherwise. */
c152901f
AM
133
134static void
4e84e381
MS
135warn_uninit (opt_code opt, tree t, tree var, const char *gmsgid,
136 gimple *context, location_t phi_arg_loc = UNKNOWN_LOCATION)
c152901f 137{
4e84e381
MS
138 /* Bail if the value isn't provably uninitialized. */
139 if (!has_undefined_value_p (t))
140 return;
c152901f 141
e1ec47c4
TP
142 /* Ignore COMPLEX_EXPR as initializing only a part of a complex
143 turns in a COMPLEX_EXPR with the not initialized part being
144 set to its previous (undefined) value. */
145 if (is_gimple_assign (context)
146 && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
147 return;
a25e0b5e 148
149 /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
150 .DEFERRED_INIT. This is for handling the following case correctly:
151
152 1 typedef _Complex float C;
153 2 C foo (int cond)
154 3 {
155 4 C f;
156 5 __imag__ f = 0;
157 6 if (cond)
158 7 {
159 8 __real__ f = 1;
160 9 return f;
161 10 }
162 11 return f;
163 12 }
164
165 with -ftrivial-auto-var-init, compiler will insert the following
166 artificial initialization at line 4:
167 f = .DEFERRED_INIT (f, 2);
168 _1 = REALPART_EXPR <f>;
169
170 without the following special handling, _1 = REALPART_EXPR <f> will
171 be treated as the uninitialized use point, which is incorrect. (the
172 real uninitialized use point is at line 11). */
173 if (is_gimple_assign (context)
174 && (gimple_assign_rhs_code (context) == REALPART_EXPR
175 || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
176 {
177 tree v = gimple_assign_rhs1 (context);
178 if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
179 && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
180 IFN_DEFERRED_INIT))
181 return;
182 }
183
50aa64d5 184 /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
4e84e381 185 can return true if the def stmt of an anonymous SSA_NAME is COMPLEX_EXPR
50aa64d5
JJ
186 created for conversion from scalar to complex. Use the underlying var of
187 the COMPLEX_EXPRs real part in that case. See PR71581. */
4e84e381
MS
188 if (!var && !SSA_NAME_VAR (t))
189 {
190 gimple *def_stmt = SSA_NAME_DEF_STMT (t);
191 if (is_gimple_assign (def_stmt)
192 && gimple_assign_rhs_code (def_stmt) == COMPLEX_EXPR)
50aa64d5 193 {
4e84e381
MS
194 tree v = gimple_assign_rhs1 (def_stmt);
195 if (TREE_CODE (v) == SSA_NAME
196 && has_undefined_value_p (v)
197 && zerop (gimple_assign_rhs2 (def_stmt)))
198 var = SSA_NAME_VAR (v);
50aa64d5
JJ
199 }
200 }
201
4e84e381 202 if (var == NULL_TREE)
50aa64d5
JJ
203 return;
204
4e84e381
MS
205 /* Avoid warning if we've already done so or if the warning has been
206 suppressed. */
207 if (((warning_suppressed_p (context, OPT_Wuninitialized)
208 || (gimple_assign_single_p (context)
209 && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
210 || get_no_uninit_warning (var))
c152901f
AM
211 return;
212
4e84e381
MS
213 /* Use either the location of the read statement or that of the PHI
214 argument, or that of the uninitialized variable, in that order,
215 whichever is valid. */
216 location_t location;
217 if (gimple_has_location (context))
e1ec47c4 218 location = gimple_location (context);
4e84e381
MS
219 else if (phi_arg_loc != UNKNOWN_LOCATION)
220 location = phi_arg_loc;
e1ec47c4
TP
221 else
222 location = DECL_SOURCE_LOCATION (var);
c152901f 223 location = linemap_resolve_location (line_table, location,
ac0e4fde 224 LRK_SPELLING_LOCATION, NULL);
4e84e381 225
097f82ec 226 auto_diagnostic_group d;
4e84e381
MS
227 if (!warning_at (location, opt, gmsgid, var))
228 return;
229
230 /* Avoid subsequent warnings for reads of the same variable again. */
231 suppress_warning (var, opt);
232
233 /* Issue a note pointing to the read variable unless the warning
234 is at the same location. */
235 location_t var_loc = DECL_SOURCE_LOCATION (var);
236 if (location == var_loc)
237 return;
c152901f 238
9695e1c2 239 inform (var_loc, "%qD was declared here", var);
c152901f
AM
240}
241
e80facb4
RB
242struct check_defs_data
243{
244 /* If we found any may-defs besides must-def clobbers. */
245 bool found_may_defs;
246};
247
6aacd901
MS
248/* Return true if STMT is a call to built-in function all of whose
249 by-reference arguments are const-qualified (i.e., the function can
250 be assumed not to modify them). */
251
252static bool
253builtin_call_nomodifying_p (gimple *stmt)
254{
255 if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
256 return false;
257
258 tree fndecl = gimple_call_fndecl (stmt);
259 if (!fndecl)
260 return false;
261
262 tree fntype = TREE_TYPE (fndecl);
263 if (!fntype)
264 return false;
265
266 /* Check the called function's signature for non-constc pointers.
267 If one is found, return false. */
268 unsigned argno = 0;
269 tree argtype;
270 function_args_iterator it;
271 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
272 {
273 if (VOID_TYPE_P (argtype))
274 return true;
275
276 ++argno;
277
278 if (!POINTER_TYPE_P (argtype))
279 continue;
280
281 if (TYPE_READONLY (TREE_TYPE (argtype)))
282 continue;
283
284 return false;
285 }
286
287 /* If the number of actual arguments to the call is less than or
288 equal to the number of parameters, return false. */
289 unsigned nargs = gimple_call_num_args (stmt);
290 if (nargs <= argno)
291 return false;
292
293 /* Check arguments passed through the ellipsis in calls to variadic
294 functions for pointers. If one is found that's a non-constant
295 pointer, return false. */
296 for (; argno < nargs; ++argno)
297 {
298 tree arg = gimple_call_arg (stmt, argno);
299 argtype = TREE_TYPE (arg);
300 if (!POINTER_TYPE_P (argtype))
301 continue;
302
303 if (TYPE_READONLY (TREE_TYPE (argtype)))
304 continue;
305
306 return false;
307 }
308
309 return true;
310}
311
fb85d6eb
MS
312/* If ARG is a FNDECL parameter declared with attribute access none or
313 write_only issue a warning for its read access via PTR. */
314
315static void
316maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
317{
318 if (!fndecl)
319 return;
320
321 if (get_no_uninit_warning (arg))
322 return;
323
324 tree fntype = TREE_TYPE (fndecl);
325 if (!fntype)
326 return;
327
328 /* Initialize a map of attribute access specifications for arguments
329 to the function function call. */
330 rdwr_map rdwr_idx;
331 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
332
333 unsigned argno = 0;
334 tree parms = DECL_ARGUMENTS (fndecl);
335 for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
336 {
337 if (parm != arg)
338 continue;
339
340 const attr_access* access = rdwr_idx.get (argno);
341 if (!access)
342 break;
343
344 if (access->mode != access_none
345 && access->mode != access_write_only)
346 continue;
347
348 location_t stmtloc
349 = linemap_resolve_location (line_table, gimple_location (stmt),
350 LRK_SPELLING_LOCATION, NULL);
351
352 if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
353 "%qE may be used uninitialized", ptr))
354 break;
355
356 suppress_warning (arg, OPT_Wmaybe_uninitialized);
357
358 const char* const access_str =
359 TREE_STRING_POINTER (access->to_external_string ());
360
361 location_t parmloc = DECL_SOURCE_LOCATION (parm);
362 inform (parmloc, "accessing argument %u of a function declared with "
363 "attribute %<%s%>",
364 argno + 1, access_str);
365
366 break;
367 }
368}
369
e80facb4
RB
370/* Callback for walk_aliased_vdefs. */
371
372static bool
373check_defs (ao_ref *ref, tree vdef, void *data_)
374{
375 check_defs_data *data = (check_defs_data *)data_;
376 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
2efe245b 377
a25e0b5e 378 /* Ignore the vdef if the definition statement is a call
379 to .DEFERRED_INIT function. */
380 if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
381 return false;
382
2efe245b 383 /* The ASAN_MARK intrinsic doesn't modify the variable. */
e07d30fd
MS
384 if (is_gimple_call (def_stmt))
385 {
94c12ffa 386 /* The ASAN_MARK intrinsic doesn't modify the variable. */
e07d30fd
MS
387 if (gimple_call_internal_p (def_stmt)
388 && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
94c12ffa 389 return false;
e07d30fd
MS
390
391 if (tree fndecl = gimple_call_fndecl (def_stmt))
94c12ffa
MS
392 {
393 /* Some sanitizer calls pass integer arguments to built-ins
394 that expect pointets. Avoid using gimple_call_builtin_p()
395 which fails for such calls. */
396 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
397 {
398 built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
399 if (fncode > BEGIN_SANITIZER_BUILTINS
400 && fncode < END_SANITIZER_BUILTINS)
401 return false;
402 }
403 }
e07d30fd 404 }
2efe245b
MS
405
406 /* End of VLA scope is not a kill. */
407 if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
408 return false;
409
e80facb4
RB
410 /* If this is a clobber then if it is not a kill walk past it. */
411 if (gimple_clobber_p (def_stmt))
412 {
413 if (stmt_kills_ref_p (def_stmt, ref))
414 return true;
415 return false;
416 }
2efe245b 417
6aacd901
MS
418 if (builtin_call_nomodifying_p (def_stmt))
419 return false;
420
e80facb4
RB
421 /* Found a may-def on this path. */
422 data->found_may_defs = true;
423 return true;
424}
425
b825a228
MS
426/* Counters and limits controlling the the depth of analysis and
427 strictness of the warning. */
428struct wlimits
429{
430 /* Number of VDEFs encountered. */
431 unsigned int vdef_cnt;
432 /* Number of statements examined by walk_aliased_vdefs. */
433 unsigned int oracle_cnt;
434 /* Limit on the number of statements visited by walk_aliased_vdefs. */
435 unsigned limit;
436 /* Set when basic block with statement is executed unconditionally. */
437 bool always_executed;
438 /* Set to issue -Wmaybe-uninitialized. */
439 bool wmaybe_uninit;
440};
441
442/* Determine if REF references an uninitialized operand and diagnose
fb85d6eb
MS
443 it if so. STMS is the referencing statement. LHS is the result
444 of the access and may be null. RHS is the variable referenced by
445 the access; it may not be null. */
b825a228
MS
446
447static tree
448maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
449 wlimits &wlims)
450{
451 bool has_bit_insert = false;
452 use_operand_p luse_p;
453 imm_use_iterator liter;
454
e9e2bad7 455 if (get_no_uninit_warning (rhs))
b825a228
MS
456 return NULL_TREE;
457
458 /* Do not warn if the base was marked so or this is a
459 hard register var. */
460 tree base = ao_ref_base (&ref);
461 if ((VAR_P (base)
462 && DECL_HARD_REGISTER (base))
e9e2bad7 463 || get_no_uninit_warning (base))
b825a228
MS
464 return NULL_TREE;
465
1121e495
MS
466 /* Do not warn if the access is zero size or if it's fully outside
467 the object. */
b825a228 468 poly_int64 decl_size;
1121e495
MS
469 if (known_size_p (ref.size)
470 && known_eq (ref.max_size, ref.size)
471 && (known_eq (ref.size, 0)
472 || known_le (ref.offset + ref.size, 0)))
473 return NULL_TREE;
474
b825a228 475 if (DECL_P (base)
1121e495
MS
476 && known_ge (ref.offset, 0)
477 && DECL_SIZE (base)
478 && poly_int_tree_p (DECL_SIZE (base), &decl_size)
479 && known_le (decl_size, ref.offset))
b825a228
MS
480 return NULL_TREE;
481
482 /* Do not warn if the result of the access is then used for
483 a BIT_INSERT_EXPR. */
484 if (lhs && TREE_CODE (lhs) == SSA_NAME)
485 FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
486 {
487 gimple *use_stmt = USE_STMT (luse_p);
488 /* BIT_INSERT_EXPR first operand should not be considered
489 a use for the purpose of uninit warnings. */
490 if (gassign *ass = dyn_cast <gassign *> (use_stmt))
491 {
492 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
493 && luse_p->use == gimple_assign_rhs1_ptr (ass))
494 {
495 has_bit_insert = true;
496 break;
497 }
498 }
499 }
500
501 if (has_bit_insert)
502 return NULL_TREE;
503
504 /* Limit the walking to a constant number of stmts after
505 we overcommit quadratic behavior for small functions
506 and O(n) behavior. */
507 if (wlims.oracle_cnt > 128 * 128
508 && wlims.oracle_cnt > wlims.vdef_cnt * 2)
509 wlims.limit = 32;
510
511 check_defs_data data;
512 bool fentry_reached = false;
513 data.found_may_defs = false;
514 tree use = gimple_vuse (stmt);
515 if (!use)
516 return NULL_TREE;
517 int res = walk_aliased_vdefs (&ref, use,
518 check_defs, &data, NULL,
519 &fentry_reached, wlims.limit);
520 if (res == -1)
521 {
522 wlims.oracle_cnt += wlims.limit;
523 return NULL_TREE;
524 }
525
526 wlims.oracle_cnt += res;
527 if (data.found_may_defs)
528 return NULL_TREE;
529
530 bool found_alloc = false;
531
532 if (fentry_reached)
533 {
534 if (TREE_CODE (base) == MEM_REF)
535 base = TREE_OPERAND (base, 0);
536
537 /* Follow the chain of SSA_NAME assignments looking for an alloca
538 call (or VLA) or malloc/realloc, or for decls. If any is found
539 (and in the latter case, the operand is a local variable) issue
540 a warning. */
541 while (TREE_CODE (base) == SSA_NAME)
542 {
543 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
544
545 if (is_gimple_call (def_stmt)
546 && gimple_call_builtin_p (def_stmt))
547 {
548 /* Detect uses of uninitialized alloca/VLAs. */
549 tree fndecl = gimple_call_fndecl (def_stmt);
550 const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
551 if (fncode == BUILT_IN_ALLOCA
552 || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
553 || fncode == BUILT_IN_MALLOC)
554 found_alloc = true;
555 break;
556 }
557
558 if (!is_gimple_assign (def_stmt))
559 break;
560
561 tree_code code = gimple_assign_rhs_code (def_stmt);
562 if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
563 break;
564
565 base = gimple_assign_rhs1 (def_stmt);
566 if (TREE_CODE (base) == ADDR_EXPR)
567 base = TREE_OPERAND (base, 0);
568
569 if (DECL_P (base)
570 || TREE_CODE (base) == COMPONENT_REF)
571 rhs = base;
572
573 if (TREE_CODE (base) == MEM_REF)
574 base = TREE_OPERAND (base, 0);
575
576 if (tree ba = get_base_address (base))
577 base = ba;
578 }
579
580 /* Replace the RHS expression with BASE so that it
581 refers to it in the diagnostic (instead of to
582 '<unknown>'). */
583 if (DECL_P (base)
584 && EXPR_P (rhs)
585 && TREE_CODE (rhs) != COMPONENT_REF)
586 rhs = base;
587 }
588
589 /* Do not warn if it can be initialized outside this function.
590 If we did not reach function entry then we found killing
591 clobbers on all paths to entry. */
fb85d6eb
MS
592 if (!found_alloc && fentry_reached)
593 {
594 if (TREE_CODE (base) == SSA_NAME)
595 {
596 tree var = SSA_NAME_VAR (base);
597 if (var && TREE_CODE (var) == PARM_DECL)
598 {
599 maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
600 return NULL_TREE;
601 }
602 }
603
604 if (!VAR_P (base)
605 || is_global_var (base))
606 /* ??? We'd like to use ref_may_alias_global_p but that
607 excludes global readonly memory and thus we get bogus
608 warnings from p = cond ? "a" : "b" for example. */
609 return NULL_TREE;
610 }
b825a228
MS
611
612 /* Strip the address-of expression from arrays passed to functions. */
613 if (TREE_CODE (rhs) == ADDR_EXPR)
614 rhs = TREE_OPERAND (rhs, 0);
615
616 /* Check again since RHS may have changed above. */
e9e2bad7 617 if (get_no_uninit_warning (rhs))
b825a228
MS
618 return NULL_TREE;
619
620 /* Avoid warning about empty types such as structs with no members.
621 The first_field() test is important for C++ where the predicate
622 alone isn't always sufficient. */
623 tree rhstype = TREE_TYPE (rhs);
8b75204b
MS
624 if (POINTER_TYPE_P (rhstype))
625 rhstype = TREE_TYPE (rhstype);
3072125a 626 if (is_empty_type (rhstype))
b825a228
MS
627 return NULL_TREE;
628
629 bool warned = false;
630 /* We didn't find any may-defs so on all paths either
631 reached function entry or a killing clobber. */
632 location_t location
633 = linemap_resolve_location (line_table, gimple_location (stmt),
634 LRK_SPELLING_LOCATION, NULL);
635 if (wlims.always_executed)
636 {
637 if (warning_at (location, OPT_Wuninitialized,
6d3bab5d 638 "%qE is used uninitialized", rhs))
b825a228
MS
639 {
640 /* ??? This is only effective for decls as in
641 gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
642 uses or accesses by functions as it may hide important
643 locations. */
644 if (lhs)
e9e2bad7 645 set_no_uninit_warning (rhs);
b825a228
MS
646 warned = true;
647 }
648 }
649 else if (wlims.wmaybe_uninit)
650 warned = warning_at (location, OPT_Wmaybe_uninitialized,
6d3bab5d 651 "%qE may be used uninitialized", rhs);
b825a228
MS
652
653 return warned ? base : NULL_TREE;
654}
655
656
657/* Diagnose passing addresses of uninitialized objects to either const
658 pointer arguments to functions, or to functions declared with attribute
659 access implying read access to those objects. */
660
661static void
0c9687d0 662maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
b825a228
MS
663{
664 if (!wlims.wmaybe_uninit)
665 return;
666
667 unsigned nargs = gimple_call_num_args (stmt);
668 if (!nargs)
669 return;
670
671 tree fndecl = gimple_call_fndecl (stmt);
672 tree fntype = gimple_call_fntype (stmt);
673 if (!fntype)
674 return;
675
0c9687d0
JH
676 /* Const function do not read their arguments. */
677 if (gimple_call_flags (stmt) & ECF_CONST)
678 return;
679
b825a228
MS
680 const built_in_function fncode
681 = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
682 ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
683
684 if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
685 /* Avoid diagnosing calls to raw memory functions (this is overly
686 permissive; consider tightening it up). */
687 return;
688
689 /* Save the current warning setting and replace it either a "maybe"
690 when passing addresses of uninitialized variables to const-qualified
691 pointers or arguments declared with attribute read_write, or with
692 a "certain" when passing them to arguments declared with attribute
693 read_only. */
694 const bool save_always_executed = wlims.always_executed;
695
72be80e4
MS
696 /* Initialize a map of attribute access specifications for arguments
697 to the function function call. */
b825a228 698 rdwr_map rdwr_idx;
6450f073 699 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
b825a228
MS
700
701 tree argtype;
702 unsigned argno = 0;
703 function_args_iterator it;
704
705 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
706 {
707 ++argno;
708
709 if (!POINTER_TYPE_P (argtype))
710 continue;
711
712 tree access_size = NULL_TREE;
72be80e4 713 const attr_access* access = rdwr_idx.get (argno - 1);
b825a228
MS
714 if (access)
715 {
d14c547a
MS
716 if (access->mode == access_none
717 || access->mode == access_write_only)
b825a228 718 continue;
72be80e4
MS
719
720 if (access->mode == access_deferred
721 && !TYPE_READONLY (TREE_TYPE (argtype)))
722 continue;
723
d14c547a 724 if (save_always_executed && access->mode == access_read_only)
b825a228
MS
725 /* Attribute read_only arguments imply read access. */
726 wlims.always_executed = true;
727 else
728 /* Attribute read_write arguments are documented as requiring
729 initialized objects but it's expected that aggregates may
730 be only partially initialized regardless. */
731 wlims.always_executed = false;
732
733 if (access->sizarg < nargs)
734 access_size = gimple_call_arg (stmt, access->sizarg);
735 }
736 else if (!TYPE_READONLY (TREE_TYPE (argtype)))
737 continue;
738 else if (save_always_executed && fncode != BUILT_IN_LAST)
739 /* Const-qualified arguments to built-ins imply read access. */
740 wlims.always_executed = true;
741 else
742 /* Const-qualified arguments to ordinary functions imply a likely
743 (but not definitive) read access. */
744 wlims.always_executed = false;
745
0c9687d0 746 /* Ignore args we are not going to read from. */
d70ef656
JH
747 if (gimple_call_arg_flags (stmt, argno - 1)
748 & (EAF_UNUSED | EAF_NO_DIRECT_READ))
0c9687d0
JH
749 continue;
750
b825a228 751 tree arg = gimple_call_arg (stmt, argno - 1);
9816f509
MS
752 if (!POINTER_TYPE_P (TREE_TYPE (arg)))
753 /* Avoid actual arguments with invalid types. */
754 continue;
b825a228
MS
755
756 ao_ref ref;
757 ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
758 tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
759 if (!argbase)
760 continue;
761
72be80e4 762 if (access && access->mode != access_deferred)
b825a228 763 {
72be80e4
MS
764 const char* const access_str =
765 TREE_STRING_POINTER (access->to_external_string ());
b825a228
MS
766
767 if (fndecl)
768 {
769 location_t loc = DECL_SOURCE_LOCATION (fndecl);
72be80e4
MS
770 inform (loc, "in a call to %qD declared with "
771 "attribute %<%s%> here", fndecl, access_str);
b825a228
MS
772 }
773 else
774 {
775 /* Handle calls through function pointers. */
776 location_t loc = gimple_location (stmt);
777 inform (loc, "in a call to %qT declared with "
72be80e4 778 "attribute %<%s%>", fntype, access_str);
b825a228
MS
779 }
780 }
b825a228
MS
781 else
782 {
72be80e4
MS
783 /* For a declaration with no relevant attribute access create
784 a dummy object and use the formatting function to avoid
785 having to complicate things here. */
786 attr_access ptr_access = { };
787 if (!access)
788 access = &ptr_access;
789 const std::string argtypestr = access->array_as_string (argtype);
790 if (fndecl)
791 {
792 location_t loc (DECL_SOURCE_LOCATION (fndecl));
baad4c48 793 inform (loc, "by argument %u of type %s to %qD "
72be80e4
MS
794 "declared here",
795 argno, argtypestr.c_str (), fndecl);
796 }
797 else
798 {
799 /* Handle calls through function pointers. */
800 location_t loc (gimple_location (stmt));
baad4c48 801 inform (loc, "by argument %u of type %s to %qT",
72be80e4
MS
802 argno, argtypestr.c_str (), fntype);
803 }
b825a228
MS
804 }
805
806 if (DECL_P (argbase))
807 {
808 location_t loc = DECL_SOURCE_LOCATION (argbase);
809 inform (loc, "%qD declared here", argbase);
810 }
811 }
812
813 wlims.always_executed = save_always_executed;
814}
815
66030d68
RB
816/* Warn about an uninitialized PHI argument on the fallthru path to
817 an always executed block BB. */
818
819static void
820warn_uninit_phi_uses (basic_block bb)
821{
822 edge_iterator ei;
823 edge e, found = NULL, found_back = NULL;
824 /* Look for a fallthru and possibly a single backedge. */
825 FOR_EACH_EDGE (e, ei, bb->preds)
826 {
827 /* Ignore backedges. */
828 if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
829 {
830 if (found_back)
831 {
832 found = NULL;
833 break;
834 }
835 found_back = e;
836 continue;
837 }
838 if (found)
839 {
840 found = NULL;
841 break;
842 }
843 found = e;
844 }
845 if (!found)
846 return;
847
848 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
849 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
850 gsi_next (&si))
851 {
852 gphi *phi = si.phi ();
853 tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
854 if (TREE_CODE (def) != SSA_NAME
855 || !SSA_NAME_IS_DEFAULT_DEF (def)
856 || virtual_operand_p (def))
857 continue;
858 /* If there's a default def on the fallthru edge PHI
859 value and there's a use that post-dominates entry
860 then that use is uninitialized and we can warn. */
861 imm_use_iterator iter;
862 use_operand_p use_p;
863 gimple *use_stmt = NULL;
864 FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
865 {
866 use_stmt = USE_STMT (use_p);
867 if (gimple_location (use_stmt) != UNKNOWN_LOCATION
868 && dominated_by_p (CDI_POST_DOMINATORS, succ,
869 gimple_bb (use_stmt))
870 /* If we found a non-fallthru edge make sure the
871 use is inside the loop, otherwise the backedge
872 can serve as initialization. */
873 && (!found_back
874 || dominated_by_p (CDI_DOMINATORS, found_back->src,
875 gimple_bb (use_stmt))))
876 break;
877 use_stmt = NULL;
878 }
879 if (use_stmt)
880 warn_uninit (OPT_Wuninitialized, def, SSA_NAME_VAR (def),
4e84e381 881 "%qD is used uninitialized", use_stmt);
66030d68
RB
882 }
883}
b825a228 884
4e84e381
MS
885/* Issue warnings about reads of uninitialized variables. WMAYBE_UNINIT
886 is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized. */
887
888static void
b825a228 889warn_uninitialized_vars (bool wmaybe_uninit)
c152901f 890{
b825a228
MS
891 /* Counters and limits controlling the the depth of the warning. */
892 wlimits wlims = { };
893 wlims.wmaybe_uninit = wmaybe_uninit;
894
c152901f
AM
895 gimple_stmt_iterator gsi;
896 basic_block bb;
11cd3bed 897 FOR_EACH_BB_FN (bb, cfun)
c152901f 898 {
ac0e4fde 899 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
b825a228 900 wlims.always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
66030d68
RB
901
902 if (wlims.always_executed)
903 warn_uninit_phi_uses (bb);
904
c152901f
AM
905 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
906 {
355fe088 907 gimple *stmt = gsi_stmt (gsi);
a25e0b5e 908
909 /* The call is an artificial use, will not provide meaningful
910 error message. If the result of the call is used somewhere
911 else, we warn there instead. */
912 if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
913 continue;
914
c152901f
AM
915 if (is_gimple_debug (stmt))
916 continue;
917
918 /* We only do data flow with SSA_NAMEs, so that's all we
919 can warn about. */
4e84e381
MS
920 use_operand_p use_p;
921 ssa_op_iter op_iter;
c152901f
AM
922 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
923 {
d07f8c59
RB
924 /* BIT_INSERT_EXPR first operand should not be considered
925 a use for the purpose of uninit warnings. */
926 if (gassign *ass = dyn_cast <gassign *> (stmt))
927 {
928 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
929 && use_p->use == gimple_assign_rhs1_ptr (ass))
930 continue;
931 }
4e84e381 932 tree use = USE_FROM_PTR (use_p);
b825a228 933 if (wlims.always_executed)
ac0e4fde 934 warn_uninit (OPT_Wuninitialized, use, SSA_NAME_VAR (use),
4e84e381 935 "%qD is used uninitialized", stmt);
b825a228 936 else if (wmaybe_uninit)
ac0e4fde 937 warn_uninit (OPT_Wmaybe_uninitialized, use, SSA_NAME_VAR (use),
4e84e381 938 "%qD may be used uninitialized", stmt);
c152901f
AM
939 }
940
e80facb4
RB
941 /* For limiting the alias walk below we count all
942 vdefs in the function. */
943 if (gimple_vdef (stmt))
b825a228 944 wlims.vdef_cnt++;
e80facb4 945
0c9687d0
JH
946 if (gcall *call = dyn_cast <gcall *> (stmt))
947 maybe_warn_pass_by_reference (call, wlims);
b825a228
MS
948 else if (gimple_assign_load_p (stmt)
949 && gimple_has_location (stmt))
c152901f
AM
950 {
951 tree rhs = gimple_assign_rhs1 (stmt);
6d20bf18 952 tree lhs = gimple_assign_lhs (stmt);
e80facb4
RB
953
954 ao_ref ref;
955 ao_ref_init (&ref, rhs);
b825a228
MS
956 tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
957 if (!var)
d21a8e3b 958 continue;
c152901f 959
b825a228 960 if (DECL_P (var))
e80facb4 961 {
b825a228
MS
962 location_t loc = DECL_SOURCE_LOCATION (var);
963 inform (loc, "%qD declared here", var);
e80facb4 964 }
c152901f
AM
965 }
966 }
967 }
c152901f
AM
968}
969
927734cf
XDL
970/* Checks if the operand OPND of PHI is defined by
971 another phi with one operand defined by this PHI,
ac0e4fde 972 but the rest operands are all defined. If yes,
026c3cfd 973 returns true to skip this operand as being
ac0e4fde 974 redundant. Can be enhanced to be more general. */
34f97b94
XDL
975
976static bool
355fe088 977can_skip_redundant_opnd (tree opnd, gimple *phi)
34f97b94 978{
4e84e381
MS
979 tree phi_def = gimple_phi_result (phi);
980 gimple *op_def = SSA_NAME_DEF_STMT (opnd);
34f97b94
XDL
981 if (gimple_code (op_def) != GIMPLE_PHI)
982 return false;
4e84e381
MS
983
984 unsigned n = gimple_phi_num_args (op_def);
985 for (unsigned i = 0; i < n; ++i)
34f97b94
XDL
986 {
987 tree op = gimple_phi_arg_def (op_def, i);
988 if (TREE_CODE (op) != SSA_NAME)
5e48d8a0 989 continue;
ba7e83f8 990 if (op != phi_def && uninit_undefined_value_p (op))
5e48d8a0 991 return false;
34f97b94
XDL
992 }
993
994 return true;
995}
996
94c12ffa
MS
997/* Return a bitset holding the positions of arguments in PHI with empty
998 (or possibly empty) definitions. */
34f97b94
XDL
999
1000static unsigned
538dd0b7 1001compute_uninit_opnds_pos (gphi *phi)
34f97b94 1002{
34f97b94
XDL
1003 unsigned uninit_opnds = 0;
1004
4e84e381 1005 unsigned n = gimple_phi_num_args (phi);
98d30e4f 1006 /* Bail out for phi with too many args. */
94c12ffa 1007 if (n > predicate::func_t::max_phi_args)
98d30e4f 1008 return 0;
34f97b94 1009
4e84e381 1010 for (unsigned i = 0; i < n; ++i)
34f97b94
XDL
1011 {
1012 tree op = gimple_phi_arg_def (phi, i);
1013 if (TREE_CODE (op) == SSA_NAME
5e48d8a0
ML
1014 && uninit_undefined_value_p (op)
1015 && !can_skip_redundant_opnd (op, phi))
e7d764f3 1016 {
5e48d8a0 1017 if (cfun->has_nonlocal_label || cfun->calls_setjmp)
e7d764f3 1018 {
aea0101d
RB
1019 /* Ignore SSA_NAMEs that appear on abnormal edges
1020 somewhere. */
1021 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
1022 continue;
e7d764f3
JJ
1023 }
1024 MASK_SET_BIT (uninit_opnds, i);
1025 }
34f97b94
XDL
1026 }
1027 return uninit_opnds;
1028}
1029
94c12ffa
MS
1030/* Function object type used to determine whether an expression
1031 is of interest to the predicate analyzer. */
34f97b94 1032
94c12ffa 1033struct uninit_undef_val_t: public predicate::func_t
34f97b94 1034{
94c12ffa
MS
1035 virtual bool operator()(tree) override;
1036 virtual unsigned phi_arg_set (gphi *) override;
1037};
34f97b94 1038
94c12ffa 1039/* Return true if the argument is an expression of interest. */
34f97b94 1040
94c12ffa
MS
1041bool
1042uninit_undef_val_t::operator()(tree val)
34f97b94 1043{
94c12ffa
MS
1044 if (TREE_CODE (val) == SSA_NAME)
1045 return uninit_undefined_value_p (val);
34f97b94 1046
94c12ffa 1047 return false;
34f97b94
XDL
1048}
1049
94c12ffa 1050/* Return a bitset of PHI arguments of interest. */
34f97b94 1051
94c12ffa
MS
1052unsigned
1053uninit_undef_val_t::phi_arg_set (gphi *phi)
34f97b94 1054{
94c12ffa 1055 return compute_uninit_opnds_pos (phi);
34f97b94
XDL
1056}
1057
94c12ffa
MS
1058/* Searches through all uses of a potentially
1059 uninitialized variable defined by PHI and returns a use
1060 statement if the use is not properly guarded. It returns
1061 NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
1062 holding the position(s) of uninit PHI operands. WORKLIST
1063 is the vector of candidate phis that may be updated by this
1064 function. ADDED_TO_WORKLIST is the pointer set tracking
1065 if the new phi is already in the worklist. */
34f97b94 1066
94c12ffa
MS
1067static gimple *
1068find_uninit_use (gphi *phi, unsigned uninit_opnds,
1069 vec<gphi *> *worklist, hash_set<gphi *> *added_to_worklist)
34f97b94 1070{
94c12ffa
MS
1071 /* The Boolean predicate guarding the PHI definition. Initialized
1072 lazily from PHI in the first call to is_use_guarded() and cached
1073 for subsequent iterations. */
1074 uninit_undef_val_t eval;
1075 predicate def_preds (eval);
34f97b94 1076
94c12ffa
MS
1077 use_operand_p use_p;
1078 imm_use_iterator iter;
1079 tree phi_result = gimple_phi_result (phi);
1080 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
34f97b94 1081 {
94c12ffa
MS
1082 gimple *use_stmt = USE_STMT (use_p);
1083 if (is_gimple_debug (use_stmt))
5e48d8a0 1084 continue;
34f97b94 1085
94c12ffa
MS
1086 basic_block use_bb;
1087 if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1088 use_bb = gimple_phi_arg_edge (use_phi,
1089 PHI_ARG_INDEX_FROM_USE (use_p))->src;
1090 else
1091 use_bb = gimple_bb (use_stmt);
5e48d8a0 1092
94c12ffa
MS
1093 if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1094 continue;
34f97b94 1095
94c12ffa
MS
1096 if (dump_file && (dump_flags & TDF_DETAILS))
1097 {
1098 fprintf (dump_file, "Found unguarded use in bb %u: ",
1099 use_bb->index);
1100 print_gimple_stmt (dump_file, use_stmt, 0);
5e48d8a0 1101 }
94c12ffa
MS
1102 /* Found one real use, return. */
1103 if (gimple_code (use_stmt) != GIMPLE_PHI)
1104 return use_stmt;
c375a3a4 1105
94c12ffa
MS
1106 /* Found a phi use that is not guarded,
1107 add the phi to the worklist. */
1108 if (!added_to_worklist->add (as_a<gphi *> (use_stmt)))
5e48d8a0 1109 {
94c12ffa 1110 if (dump_file && (dump_flags & TDF_DETAILS))
e7c6abad 1111 {
94c12ffa
MS
1112 fprintf (dump_file, "[WORKLIST]: Update worklist with phi: ");
1113 print_gimple_stmt (dump_file, use_stmt, 0);
e7c6abad 1114 }
5e48d8a0 1115
94c12ffa
MS
1116 worklist->safe_push (as_a<gphi *> (use_stmt));
1117 possibly_undefined_names->add (phi_result);
5e48d8a0 1118 }
34f97b94
XDL
1119 }
1120
94c12ffa 1121 return NULL;
34f97b94
XDL
1122}
1123
94c12ffa
MS
1124/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1125 and gives warning if there exists a runtime path from the entry to a
1126 use of the PHI def that does not contain a definition. In other words,
1127 the warning is on the real use. The more dead paths that can be pruned
1128 by the compiler, the fewer false positives the warning is. WORKLIST
1129 is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is
1130 a pointer set tracking if the new phi is added to the worklist or not. */
34f97b94
XDL
1131
1132static void
94c12ffa
MS
1133warn_uninitialized_phi (gphi *phi, vec<gphi *> *worklist,
1134 hash_set<gphi *> *added_to_worklist)
34f97b94 1135{
94c12ffa
MS
1136 /* Don't look at virtual operands. */
1137 if (virtual_operand_p (gimple_phi_result (phi)))
1138 return;
34f97b94 1139
94c12ffa
MS
1140 unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1141 if (MASK_EMPTY (uninit_opnds))
34f97b94
XDL
1142 return;
1143
94c12ffa 1144 if (dump_file && (dump_flags & TDF_DETAILS))
34f97b94 1145 {
94c12ffa
MS
1146 fprintf (dump_file, "Examining phi: ");
1147 print_gimple_stmt (dump_file, phi, 0);
34f97b94 1148 }
34f97b94 1149
94c12ffa
MS
1150 gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds,
1151 worklist, added_to_worklist);
34f97b94 1152
94c12ffa
MS
1153 /* All uses are properly guarded but a new PHI may have been added
1154 to WORKLIST. */
1155 if (!uninit_use_stmt)
1156 return;
34f97b94 1157
94c12ffa
MS
1158 unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1159 tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1160 if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
1161 return;
34f97b94 1162
94c12ffa
MS
1163 location_t loc = UNKNOWN_LOCATION;
1164 if (gimple_phi_arg_has_location (phi, phiarg_index))
1165 loc = gimple_phi_arg_location (phi, phiarg_index);
1166 else
34f97b94 1167 {
94c12ffa
MS
1168 tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1169 if (TREE_CODE (arg_def) == SSA_NAME)
5e48d8a0 1170 {
94c12ffa
MS
1171 gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1172 if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1173 {
1174 unsigned uop = compute_uninit_opnds_pos (arg_phi);
1175 unsigned idx = MASK_FIRST_SET_BIT (uop);
1176 if (idx < gimple_phi_num_args (arg_phi)
1177 && gimple_phi_arg_has_location (arg_phi, idx))
1178 loc = gimple_phi_arg_location (arg_phi, idx);
1179 }
5e48d8a0 1180 }
34f97b94
XDL
1181 }
1182
94c12ffa
MS
1183 warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1184 SSA_NAME_VAR (uninit_op),
1185 "%qD may be used uninitialized in this function",
1186 uninit_use_stmt, loc);
34f97b94
XDL
1187}
1188
94c12ffa
MS
1189static bool
1190gate_warn_uninitialized (void)
11ef0b22 1191{
94c12ffa 1192 return warn_uninitialized || warn_maybe_uninitialized;
11ef0b22
AH
1193}
1194
94c12ffa 1195namespace {
11ef0b22 1196
94c12ffa 1197const pass_data pass_data_late_warn_uninitialized =
11ef0b22 1198{
94c12ffa
MS
1199 GIMPLE_PASS, /* type */
1200 "uninit", /* name */
1201 OPTGROUP_NONE, /* optinfo_flags */
1202 TV_NONE, /* tv_id */
1203 PROP_ssa, /* properties_required */
1204 0, /* properties_provided */
1205 0, /* properties_destroyed */
1206 0, /* todo_flags_start */
1207 0, /* todo_flags_finish */
1208};
34f97b94 1209
94c12ffa 1210class pass_late_warn_uninitialized : public gimple_opt_pass
34f97b94 1211{
94c12ffa
MS
1212public:
1213 pass_late_warn_uninitialized (gcc::context *ctxt)
1214 : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1215 {}
1216
1217 /* opt_pass methods: */
1218 opt_pass *clone () { return new pass_late_warn_uninitialized (m_ctxt); }
1219 virtual bool gate (function *) { return gate_warn_uninitialized (); }
1220 virtual unsigned int execute (function *);
34f97b94 1221
94c12ffa 1222}; // class pass_late_warn_uninitialized
34f97b94
XDL
1223
1224static void
94c12ffa 1225execute_late_warn_uninitialized (function *fun)
34f97b94 1226{
94c12ffa
MS
1227 basic_block bb;
1228 gphi_iterator gsi;
1229 vec<gphi *> worklist = vNULL;
34f97b94 1230
94c12ffa
MS
1231 calculate_dominance_info (CDI_DOMINATORS);
1232 calculate_dominance_info (CDI_POST_DOMINATORS);
1233 /* Re-do the plain uninitialized variable check, as optimization may have
1234 straightened control flow. Do this first so that we don't accidentally
1235 get a "may be" warning when we'd have seen an "is" warning later. */
1236 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
34f97b94 1237
94c12ffa 1238 timevar_push (TV_TREE_UNINIT);
34f97b94 1239
94c12ffa
MS
1240 possibly_undefined_names = new hash_set<tree>;
1241 hash_set<gphi *> added_to_worklist;
34f97b94 1242
94c12ffa
MS
1243 /* Initialize worklist */
1244 FOR_EACH_BB_FN (bb, fun)
1245 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1246 {
1247 gphi *phi = gsi.phi ();
be55bfe6
TS
1248
1249 /* Don't look at virtual operands. */
1250 if (virtual_operand_p (gimple_phi_result (phi)))
1251 continue;
1252
94c12ffa
MS
1253 unsigned n = gimple_phi_num_args (phi);
1254 for (unsigned i = 0; i < n; ++i)
be55bfe6
TS
1255 {
1256 tree op = gimple_phi_arg_def (phi, i);
ac0e4fde 1257 if (TREE_CODE (op) == SSA_NAME && uninit_undefined_value_p (op))
be55bfe6
TS
1258 {
1259 worklist.safe_push (phi);
6e2830c3 1260 added_to_worklist.add (phi);
be55bfe6
TS
1261 if (dump_file && (dump_flags & TDF_DETAILS))
1262 {
94c12ffa
MS
1263 fprintf (dump_file, "[WORKLIST]: add to initial list "
1264 "for operand %u of: ", i);
ef6cb4c7 1265 print_gimple_stmt (dump_file, phi, 0);
be55bfe6
TS
1266 }
1267 break;
1268 }
1269 }
34f97b94
XDL
1270 }
1271
9771b263 1272 while (worklist.length () != 0)
34f97b94 1273 {
538dd0b7 1274 gphi *cur_phi = 0;
9771b263 1275 cur_phi = worklist.pop ();
6e2830c3 1276 warn_uninitialized_phi (cur_phi, &worklist, &added_to_worklist);
34f97b94 1277 }
e74780a3 1278
9771b263 1279 worklist.release ();
6e2830c3 1280 delete possibly_undefined_names;
34f97b94
XDL
1281 possibly_undefined_names = NULL;
1282 free_dominance_info (CDI_POST_DOMINATORS);
1283 timevar_pop (TV_TREE_UNINIT);
94c12ffa
MS
1284}
1285
1286unsigned int
1287pass_late_warn_uninitialized::execute (function *fun)
1288{
1289 execute_late_warn_uninitialized (fun);
34f97b94
XDL
1290 return 0;
1291}
1292
27a4cd48
DM
1293} // anon namespace
1294
1295gimple_opt_pass *
1296make_pass_late_warn_uninitialized (gcc::context *ctxt)
1297{
1298 return new pass_late_warn_uninitialized (ctxt);
1299}
c152901f 1300
c152901f
AM
1301static unsigned int
1302execute_early_warn_uninitialized (void)
1303{
1304 /* Currently, this pass runs always but
ac0e4fde 1305 execute_late_warn_uninitialized only runs with optimization. With
c152901f
AM
1306 optimization we want to warn about possible uninitialized as late
1307 as possible, thus don't do it here. However, without
927734cf 1308 optimization we need to warn here about "may be uninitialized". */
66030d68 1309 calculate_dominance_info (CDI_DOMINATORS);
c152901f
AM
1310 calculate_dominance_info (CDI_POST_DOMINATORS);
1311
b825a228 1312 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
c152901f 1313
67914693 1314 /* Post-dominator information cannot be reliably updated. Free it
c152901f
AM
1315 after the use. */
1316
1317 free_dominance_info (CDI_POST_DOMINATORS);
1318 return 0;
1319}
1320
c152901f
AM
1321namespace {
1322
1323const pass_data pass_data_early_warn_uninitialized =
1324{
1325 GIMPLE_PASS, /* type */
1326 "*early_warn_uninitialized", /* name */
1327 OPTGROUP_NONE, /* optinfo_flags */
c152901f
AM
1328 TV_TREE_UNINIT, /* tv_id */
1329 PROP_ssa, /* properties_required */
1330 0, /* properties_provided */
1331 0, /* properties_destroyed */
1332 0, /* todo_flags_start */
1333 0, /* todo_flags_finish */
1334};
1335
1336class pass_early_warn_uninitialized : public gimple_opt_pass
1337{
1338public:
c3284718
RS
1339 pass_early_warn_uninitialized (gcc::context *ctxt)
1340 : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
c152901f
AM
1341 {}
1342
1343 /* opt_pass methods: */
1a3d085c 1344 virtual bool gate (function *) { return gate_warn_uninitialized (); }
be55bfe6 1345 virtual unsigned int execute (function *)
ac0e4fde
ML
1346 {
1347 return execute_early_warn_uninitialized ();
1348 }
c152901f
AM
1349
1350}; // class pass_early_warn_uninitialized
1351
1352} // anon namespace
1353
1354gimple_opt_pass *
1355make_pass_early_warn_uninitialized (gcc::context *ctxt)
1356{
1357 return new pass_early_warn_uninitialized (ctxt);
1358}