Line data Source code
1 : /* Predicate aware uninitialized variable warning.
2 : Copyright (C) 2001-2026 Free Software Foundation, Inc.
3 : Contributed by Xinliang David Li <davidxl@google.com>
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #define INCLUDE_STRING
22 : #include "config.h"
23 : #include "system.h"
24 : #include "coretypes.h"
25 : #include "backend.h"
26 : #include "tree.h"
27 : #include "gimple.h"
28 : #include "tree-pass.h"
29 : #include "ssa.h"
30 : #include "gimple-pretty-print.h"
31 : #include "diagnostic-core.h"
32 : #include "fold-const.h"
33 : #include "gimple-iterator.h"
34 : #include "tree-ssa.h"
35 : #include "tree-cfg.h"
36 : #include "cfghooks.h"
37 : #include "attribs.h"
38 : #include "builtins.h"
39 : #include "calls.h"
40 : #include "gimple-range.h"
41 : #include "gimple-predicate-analysis.h"
42 : #include "domwalk.h"
43 : #include "tree-ssa-sccvn.h"
44 : #include "cfganal.h"
45 : #include "gcc-urlifier.h"
46 :
47 : /* This implements the pass that does predicate aware warning on uses of
48 : possibly uninitialized variables. The pass first collects the set of
49 : possibly uninitialized SSA names. For each such name, it walks through
50 : all its immediate uses. For each immediate use, it rebuilds the condition
51 : expression (the predicate) that guards the use. The predicate is then
52 : examined to see if the variable is always defined under that same condition.
53 : This is done either by pruning the unrealizable paths that lead to the
54 : default definitions or by checking if the predicate set that guards the
55 : defining paths is a superset of the use predicate. */
56 :
57 : /* Pointer set of potentially undefined ssa names, i.e.,
58 : ssa names that are defined by phi with operands that
59 : are not defined or potentially undefined. */
60 : static hash_set<tree> *possibly_undefined_names;
61 : static hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t> *defined_args;
62 :
63 : /* Returns the first bit position (starting from LSB)
64 : in mask that is non zero. Returns -1 if the mask is empty. */
65 : static int
66 112 : get_mask_first_set_bit (unsigned mask)
67 : {
68 112 : int pos = 0;
69 0 : if (mask == 0)
70 : return -1;
71 :
72 139 : while ((mask & (1 << pos)) == 0)
73 27 : pos++;
74 :
75 : return pos;
76 : }
77 : #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
78 :
79 : /* Return true if T, an SSA_NAME, has an undefined value. */
80 : static bool
81 6577353 : has_undefined_value_p (tree t)
82 : {
83 6577353 : return (ssa_undefined_value_p (t)
84 6577353 : || (possibly_undefined_names
85 906078 : && possibly_undefined_names->contains (t)));
86 : }
87 :
88 : /* Return true if EXPR should suppress either uninitialized warning. */
89 :
90 : static inline bool
91 3133892 : get_no_uninit_warning (tree expr)
92 : {
93 1475436 : return warning_suppressed_p (expr, OPT_Wuninitialized);
94 : }
95 :
96 : /* Suppress both uninitialized warnings for EXPR. */
97 :
98 : static inline void
99 405 : set_no_uninit_warning (tree expr)
100 : {
101 405 : suppress_warning (expr, OPT_Wuninitialized);
102 405 : }
103 :
104 : /* Like has_undefined_value_p, but don't return true if the no-warning
105 : bit is set on SSA_NAME_VAR for either uninit warning. */
106 :
107 : static inline bool
108 907849 : uninit_undefined_value_p (tree t)
109 : {
110 907849 : if (!has_undefined_value_p (t))
111 : return false;
112 2752 : if (!SSA_NAME_VAR (t))
113 : return true;
114 2733 : return !get_no_uninit_warning (SSA_NAME_VAR (t));
115 : }
116 :
117 : /* Emit warnings for uninitialized variables. This is done in two passes.
118 :
119 : The first pass notices real uses of SSA names with undefined values.
120 : Such uses are unconditionally uninitialized, and we can be certain that
121 : such a use is a mistake. This pass is run before most optimizations,
122 : so that we catch as many as we can.
123 :
124 : The second pass follows PHI nodes to find uses that are potentially
125 : uninitialized. In this case we can't necessarily prove that the use
126 : is really uninitialized. This pass is run after most optimizations,
127 : so that we thread as many jumps and possible, and delete as much dead
128 : code as possible, in order to reduce false positives. We also look
129 : again for plain uninitialized variables, since optimization may have
130 : changed conditionally uninitialized to unconditionally uninitialized. */
131 :
132 : /* Emit warning OPT for variable VAR at the point in the program where
133 : the SSA_NAME T is being used uninitialized. The warning text is in
134 : MSGID and STMT is the statement that does the uninitialized read.
135 : PHI_ARG_LOC is the location of the PHI argument if T and VAR are one,
136 : or UNKNOWN_LOCATION otherwise. */
137 :
138 : static void
139 5669501 : warn_uninit (opt_code opt, tree t, tree var, gimple *context,
140 : location_t phi_arg_loc = UNKNOWN_LOCATION)
141 : {
142 : /* Bail if the value isn't provably uninitialized. */
143 5669501 : if (!has_undefined_value_p (t))
144 5668944 : return;
145 :
146 : /* Ignore COMPLEX_EXPR as initializing only a part of a complex
147 : turns in a COMPLEX_EXPR with the not initialized part being
148 : set to its previous (undefined) value. */
149 4640 : if (is_gimple_assign (context)
150 4640 : && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
151 : return;
152 :
153 : /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
154 : .DEFERRED_INIT. This is for handling the following case correctly:
155 :
156 : 1 typedef _Complex float C;
157 : 2 C foo (int cond)
158 : 3 {
159 : 4 C f;
160 : 5 __imag__ f = 0;
161 : 6 if (cond)
162 : 7 {
163 : 8 __real__ f = 1;
164 : 9 return f;
165 : 10 }
166 : 11 return f;
167 : 12 }
168 :
169 : with -ftrivial-auto-var-init, compiler will insert the following
170 : artificial initialization at line 4:
171 : f = .DEFERRED_INIT (f, 2);
172 : _1 = REALPART_EXPR <f>;
173 :
174 : without the following special handling, _1 = REALPART_EXPR <f> will
175 : be treated as the uninitialized use point, which is incorrect. (the
176 : real uninitialized use point is at line 11). */
177 4630 : if (is_gimple_assign (context)
178 4630 : && (gimple_assign_rhs_code (context) == REALPART_EXPR
179 4054 : || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
180 : {
181 95 : tree v = gimple_assign_rhs1 (context);
182 95 : if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
183 95 : && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
184 : IFN_DEFERRED_INIT))
185 : return;
186 : }
187 :
188 : /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
189 : can return true if the def stmt of an anonymous SSA_NAME is
190 : 1. A COMPLEX_EXPR created for conversion from scalar to complex. Use the
191 : underlying var of the COMPLEX_EXPRs real part in that case. See PR71581.
192 :
193 : Or
194 :
195 : 2. A call to .DEFERRED_INIT internal function. Since the original variable
196 : has been eliminated by optimization, we need to get the variable name,
197 : and variable declaration location from this call. We recorded variable
198 : name into VAR_NAME_STR, and will get location info and record warning
199 : suppressed info to VAR_DEF_STMT, which is the .DEFERRED_INIT call. */
200 :
201 4625 : const char *var_name_str = NULL;
202 4625 : gimple *var_def_stmt = NULL;
203 :
204 4875 : if (!var && !SSA_NAME_VAR (t))
205 : {
206 250 : var_def_stmt = SSA_NAME_DEF_STMT (t);
207 :
208 250 : if (gassign *ass = dyn_cast <gassign *> (var_def_stmt))
209 : {
210 7 : switch (gimple_assign_rhs_code (var_def_stmt))
211 : {
212 3 : case COMPLEX_EXPR:
213 3 : {
214 3 : tree v = gimple_assign_rhs1 (ass);
215 3 : if (TREE_CODE (v) == SSA_NAME
216 3 : && has_undefined_value_p (v)
217 6 : && zerop (gimple_assign_rhs2 (ass)))
218 3 : var = SSA_NAME_VAR (v);
219 : break;
220 : }
221 4 : case SSA_NAME:
222 4 : {
223 4 : tree v = gimple_assign_rhs1 (ass);
224 4 : if (TREE_CODE (v) == SSA_NAME
225 4 : && SSA_NAME_VAR (v))
226 : var = SSA_NAME_VAR (v);
227 : break;
228 : }
229 : default:;
230 : }
231 : }
232 :
233 250 : if (gimple_call_internal_p (var_def_stmt, IFN_DEFERRED_INIT))
234 : {
235 : /* Ignore the call to .DEFERRED_INIT that define the original
236 : var itself as the following case:
237 : temp = .DEFERRED_INIT (4, 2, “alt_reloc");
238 : alt_reloc = temp;
239 : In order to avoid generating warning for the fake usage
240 : at alt_reloc = temp.
241 : */
242 243 : tree lhs_var = NULL_TREE;
243 :
244 : /* Get the variable name from the 3rd argument of call. */
245 243 : tree var_name = gimple_call_arg (var_def_stmt, 2);
246 243 : var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
247 243 : var_name_str = TREE_STRING_POINTER (var_name);
248 :
249 243 : if (is_gimple_assign (context))
250 : {
251 235 : if (VAR_P (gimple_assign_lhs (context)))
252 : lhs_var = gimple_assign_lhs (context);
253 16 : else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME)
254 16 : lhs_var = SSA_NAME_VAR (gimple_assign_lhs (context));
255 : }
256 234 : if (lhs_var)
257 : {
258 : /* Get the name string for the LHS_VAR.
259 : Refer to routine gimple_add_init_for_auto_var. */
260 234 : if (DECL_NAME (lhs_var)
261 234 : && (strcmp (IDENTIFIER_POINTER (DECL_NAME (lhs_var)),
262 : var_name_str) == 0))
263 : return;
264 8 : else if (!DECL_NAME (lhs_var))
265 : {
266 6 : char lhs_var_name_str_buf[3 + (HOST_BITS_PER_INT + 2) / 3];
267 6 : sprintf (lhs_var_name_str_buf, "D.%u", DECL_UID (lhs_var));
268 6 : if (strcmp (lhs_var_name_str_buf, var_name_str) == 0)
269 6 : return;
270 : }
271 : }
272 : gcc_assert (var_name_str && var_def_stmt);
273 : }
274 : }
275 :
276 4393 : if (var == NULL_TREE && var_name_str == NULL)
277 : return;
278 :
279 : /* Avoid warning if we've already done so or if the warning has been
280 : suppressed. */
281 4393 : if (((warning_suppressed_p (context, OPT_Wuninitialized)
282 4387 : || (gimple_assign_single_p (context)
283 3657 : && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
284 8585 : || (var && get_no_uninit_warning (var))
285 6451 : || (var_name_str
286 9 : && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
287 2336 : return;
288 :
289 : /* Use either the location of the read statement or that of the PHI
290 : argument, or that of the uninitialized variable, in that order,
291 : whichever is valid. */
292 2057 : location_t location = UNKNOWN_LOCATION;
293 2057 : if (gimple_has_location (context))
294 2044 : location = gimple_location (context);
295 13 : else if (phi_arg_loc != UNKNOWN_LOCATION)
296 : location = phi_arg_loc;
297 8 : else if (var)
298 8 : location = DECL_SOURCE_LOCATION (var);
299 0 : else if (var_name_str)
300 0 : location = gimple_location (var_def_stmt);
301 :
302 2614 : auto_diagnostic_group d;
303 2057 : gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
304 2057 : if (var)
305 : {
306 2049 : if ((opt == OPT_Wuninitialized
307 1656 : && !warning_at (location, opt, "%qD is used uninitialized", var))
308 2473 : || (opt == OPT_Wmaybe_uninitialized
309 817 : && !warning_at (location, opt, "%qD may be used uninitialized",
310 : var)))
311 1500 : return;
312 : }
313 8 : else if (var_name_str)
314 : {
315 8 : if ((opt == OPT_Wuninitialized
316 3 : && !warning_at (location, opt, "%qs is used uninitialized",
317 : var_name_str))
318 11 : || (opt == OPT_Wmaybe_uninitialized
319 8 : && !warning_at (location, opt, "%qs may be used uninitialized",
320 : var_name_str)))
321 0 : return;
322 : }
323 :
324 : /* Avoid subsequent warnings for reads of the same variable again. */
325 562 : if (var)
326 554 : suppress_warning (var, opt);
327 8 : else if (var_name_str)
328 8 : suppress_warning (var_def_stmt, opt);
329 :
330 : /* Issue a note pointing to the read variable unless the warning
331 : is at the same location. */
332 562 : location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
333 562 : : gimple_location (var_def_stmt);
334 562 : if (location == var_loc)
335 : return;
336 :
337 557 : if (var)
338 549 : inform (var_loc, "%qD was declared here", var);
339 8 : else if (var_name_str)
340 8 : inform (var_loc, "%qs was declared here", var_name_str);
341 : }
342 :
343 : struct check_defs_data
344 : {
345 : /* If we found any may-defs besides must-def clobbers. */
346 : bool found_may_defs;
347 : };
348 :
349 : /* Return true if STMT is a call to built-in function all of whose
350 : by-reference arguments are const-qualified (i.e., the function can
351 : be assumed not to modify them). */
352 :
353 : static bool
354 3064828 : builtin_call_nomodifying_p (gimple *stmt)
355 : {
356 3064828 : if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
357 : return false;
358 :
359 364327 : tree fndecl = gimple_call_fndecl (stmt);
360 364327 : if (!fndecl)
361 : return false;
362 :
363 364327 : tree fntype = TREE_TYPE (fndecl);
364 364327 : if (!fntype)
365 : return false;
366 :
367 : /* Check the called function's signature for non-constc pointers.
368 : If one is found, return false. */
369 364327 : unsigned argno = 0;
370 364327 : tree argtype;
371 364327 : function_args_iterator it;
372 645839 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
373 : {
374 447235 : if (VOID_TYPE_P (argtype))
375 : return true;
376 :
377 402746 : ++argno;
378 :
379 402746 : if (!POINTER_TYPE_P (argtype))
380 50503 : continue;
381 :
382 352243 : if (TYPE_READONLY (TREE_TYPE (argtype)))
383 231009 : continue;
384 :
385 : return false;
386 : }
387 :
388 : /* If the number of actual arguments to the call is less than or
389 : equal to the number of parameters, return false. */
390 198604 : unsigned nargs = gimple_call_num_args (stmt);
391 198604 : if (nargs <= argno)
392 : return false;
393 :
394 : /* Check arguments passed through the ellipsis in calls to variadic
395 : functions for pointers. If one is found that's a non-constant
396 : pointer, return false. */
397 212891 : for (; argno < nargs; ++argno)
398 : {
399 204771 : tree arg = gimple_call_arg (stmt, argno);
400 204771 : argtype = TREE_TYPE (arg);
401 204771 : if (!POINTER_TYPE_P (argtype))
402 13867 : continue;
403 :
404 190904 : if (TYPE_READONLY (TREE_TYPE (argtype)))
405 420 : continue;
406 :
407 : return false;
408 : }
409 :
410 : return true;
411 : }
412 :
413 : /* If ARG is a FNDECL parameter declared with attribute access none or
414 : write_only issue a warning for its read access via PTR. */
415 :
416 : static void
417 178787 : maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
418 : {
419 178787 : if (!fndecl)
420 0 : return;
421 :
422 178787 : if (get_no_uninit_warning (arg))
423 : return;
424 :
425 178787 : tree fntype = TREE_TYPE (fndecl);
426 178787 : if (!fntype)
427 : return;
428 :
429 : /* Initialize a map of attribute access specifications for arguments
430 : to the function call. */
431 178787 : rdwr_map rdwr_idx;
432 178787 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
433 :
434 178787 : unsigned argno = 0;
435 178787 : tree parms = DECL_ARGUMENTS (fndecl);
436 320267 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
437 : {
438 319777 : if (parm != arg)
439 141480 : continue;
440 :
441 178769 : const attr_access* access = rdwr_idx.get (argno);
442 178769 : if (!access)
443 : break;
444 :
445 486 : if (access->mode != access_none
446 484 : && access->mode != access_write_only)
447 472 : continue;
448 :
449 14 : location_t stmtloc = gimple_location (stmt);
450 14 : if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
451 : "%qE may be used uninitialized", ptr))
452 : break;
453 :
454 10 : suppress_warning (arg, OPT_Wmaybe_uninitialized);
455 :
456 10 : const char* const access_str =
457 10 : TREE_STRING_POINTER (access->to_external_string ());
458 :
459 10 : auto_urlify_attributes sentinel;
460 10 : location_t parmloc = DECL_SOURCE_LOCATION (parm);
461 10 : inform (parmloc, "accessing argument %u of a function declared with "
462 : "attribute %qs",
463 : argno + 1, access_str);
464 :
465 10 : break;
466 10 : }
467 178787 : }
468 :
469 : /* Callback for walk_aliased_vdefs. */
470 :
471 : static bool
472 3202847 : check_defs (ao_ref *ref, tree vdef, void *data_)
473 : {
474 3202847 : check_defs_data *data = (check_defs_data *)data_;
475 3202847 : gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
476 :
477 : /* Ignore the vdef if the definition statement is a call
478 : to .DEFERRED_INIT function. */
479 3202847 : if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
480 : return false;
481 :
482 : /* For address taken variable, a temporary variable is added between
483 : the variable and the call to .DEFERRED_INIT function as:
484 : _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
485 : i1 = _1;
486 : Ignore this vdef as well. */
487 3202407 : if (is_gimple_assign (def_stmt)
488 3202407 : && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
489 : {
490 1348714 : tree tmp_var = gimple_assign_rhs1 (def_stmt);
491 1348714 : if (gimple_call_internal_p (SSA_NAME_DEF_STMT (tmp_var),
492 : IFN_DEFERRED_INIT))
493 : return false;
494 : }
495 :
496 : /* The ASAN_MARK intrinsic doesn't modify the variable. */
497 3202360 : if (is_gimple_call (def_stmt))
498 : {
499 : /* The ASAN_MARK intrinsic doesn't modify the variable. */
500 1455495 : if (gimple_call_internal_p (def_stmt)
501 1455495 : && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
502 : return false;
503 :
504 1453774 : if (tree fndecl = gimple_call_fndecl (def_stmt))
505 : {
506 : /* Some sanitizer calls pass integer arguments to built-ins
507 : that expect pointets. Avoid using gimple_call_builtin_p()
508 : which fails for such calls. */
509 1255070 : if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
510 : {
511 365670 : built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
512 365670 : if (fncode > BEGIN_SANITIZER_BUILTINS
513 365670 : && fncode < END_SANITIZER_BUILTINS)
514 : return false;
515 : }
516 : }
517 : }
518 :
519 : /* End of VLA scope is not a kill. */
520 3200490 : if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
521 : return false;
522 :
523 : /* If this is a clobber then if it is not a kill walk past it. */
524 3200414 : if (gimple_clobber_p (def_stmt))
525 : {
526 135586 : if (stmt_kills_ref_p (def_stmt, ref))
527 : return true;
528 : return false;
529 : }
530 :
531 3064828 : if (builtin_call_nomodifying_p (def_stmt))
532 : return false;
533 :
534 : /* Found a may-def on this path. */
535 3012219 : data->found_may_defs = true;
536 3012219 : return true;
537 : }
538 :
539 : /* Counters and limits controlling the depth of analysis and
540 : strictness of the warning. */
541 : struct wlimits
542 : {
543 : /* Number of VDEFs encountered. */
544 : unsigned int vdef_cnt;
545 : /* Number of statements examined by walk_aliased_vdefs. */
546 : unsigned int oracle_cnt;
547 : /* Limit on the number of statements visited by walk_aliased_vdefs. */
548 : unsigned limit;
549 : /* Set when basic block with statement is executed unconditionally. */
550 : bool always_executed;
551 : /* Set to issue -Wmaybe-uninitialized. */
552 : bool wmaybe_uninit;
553 : };
554 :
555 : /* Determine if REF references an uninitialized operand and diagnose
556 : it if so. STMS is the referencing statement. LHS is the result
557 : of the access and may be null. RHS is the variable referenced by
558 : the access; it may not be null. */
559 :
560 : static tree
561 1472126 : maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
562 : wlimits &wlims)
563 : {
564 1472126 : bool has_bit_insert = false;
565 1472126 : use_operand_p luse_p;
566 1472126 : imm_use_iterator liter;
567 :
568 1472126 : if (get_no_uninit_warning (rhs))
569 : return NULL_TREE;
570 :
571 : /* Do not warn if the base was marked so or this is a
572 : hard register var. */
573 1471154 : tree base = ao_ref_base (&ref);
574 1471154 : if ((VAR_P (base)
575 589539 : && DECL_HARD_REGISTER (base))
576 2942302 : || get_no_uninit_warning (base))
577 4759 : return NULL_TREE;
578 :
579 : /* Do not warn if the access is zero size or if it's fully outside
580 : the object. */
581 1466395 : poly_int64 decl_size;
582 1466395 : if (known_size_p (ref.size)
583 1237334 : && known_eq (ref.max_size, ref.size)
584 2569609 : && (known_eq (ref.size, 0)
585 1103200 : || known_le (ref.offset + ref.size, 0)))
586 : return NULL_TREE;
587 :
588 1466325 : if (DECL_P (base)
589 603328 : && known_ge (ref.offset, 0)
590 603321 : && DECL_SIZE (base)
591 586583 : && poly_int_tree_p (DECL_SIZE (base), &decl_size)
592 2052907 : && known_le (decl_size, ref.offset))
593 : return NULL_TREE;
594 :
595 : /* Do not warn if the result of the access is then used for
596 : a BIT_INSERT_EXPR. */
597 1465813 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
598 2988925 : FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
599 : {
600 1764233 : gimple *use_stmt = USE_STMT (luse_p);
601 : /* BIT_INSERT_EXPR first operand should not be considered
602 : a use for the purpose of uninit warnings. */
603 2615104 : if (gassign *ass = dyn_cast <gassign *> (use_stmt))
604 : {
605 850873 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
606 850873 : && luse_p->use == gimple_assign_rhs1_ptr (ass))
607 : {
608 : has_bit_insert = true;
609 : break;
610 : }
611 : }
612 1224694 : }
613 :
614 1224694 : if (has_bit_insert)
615 : return NULL_TREE;
616 :
617 : /* Limit the walking to a constant number of stmts after
618 : we overcommit quadratic behavior for small functions
619 : and O(n) behavior. */
620 1465811 : if (wlims.oracle_cnt > 128 * 128
621 36553 : && wlims.oracle_cnt > wlims.vdef_cnt * 2)
622 36553 : wlims.limit = 32;
623 :
624 1465811 : check_defs_data data;
625 1465811 : bool fentry_reached = false;
626 1465811 : data.found_may_defs = false;
627 2937231 : tree use = gimple_vuse (stmt);
628 1465811 : if (!use)
629 : return NULL_TREE;
630 1465553 : int res = walk_aliased_vdefs (&ref, use,
631 : check_defs, &data, NULL,
632 : &fentry_reached, wlims.limit);
633 1465553 : if (res == -1)
634 : {
635 33517 : wlims.oracle_cnt += wlims.limit;
636 33517 : return NULL_TREE;
637 : }
638 :
639 1432036 : wlims.oracle_cnt += res;
640 1432036 : if (data.found_may_defs)
641 : return NULL_TREE;
642 :
643 491963 : bool found_alloc = false;
644 491963 : bool found_clobber_deref_this = false;
645 :
646 491963 : if (fentry_reached)
647 : {
648 491932 : if (TREE_CODE (base) == MEM_REF)
649 214328 : base = TREE_OPERAND (base, 0);
650 :
651 : /* Follow the chain of SSA_NAME assignments looking for an alloca
652 : call (or VLA) or malloc/realloc, or for decls. If any is found
653 : (and in the latter case, the operand is a local variable) issue
654 : a warning. */
655 502317 : while (TREE_CODE (base) == SSA_NAME)
656 : {
657 222950 : gimple *def_stmt = SSA_NAME_DEF_STMT (base);
658 :
659 222950 : if (is_gimple_call (def_stmt)
660 222950 : && gimple_call_builtin_p (def_stmt))
661 : {
662 : /* Detect uses of uninitialized alloca/VLAs. */
663 156 : tree fndecl = gimple_call_fndecl (def_stmt);
664 156 : const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
665 156 : if (fncode == BUILT_IN_ALLOCA
666 156 : || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
667 83 : || fncode == BUILT_IN_MALLOC)
668 113 : found_alloc = true;
669 : break;
670 : }
671 :
672 : /* The C++ FE for -flifetime-dse=2 marks this parameters
673 : of certain constructors with "clobber *this" attribute.
674 : Emit uninitialized warnings if we read from what this points
675 : to. This is similar to access (write_only, 1) attribute,
676 : except it is a -Wuninitialized warning rather than
677 : -Wmaybe-uninitialized and doesn't talk about access
678 : attribute. */
679 222794 : if (SSA_NAME_IS_DEFAULT_DEF (base)
680 178012 : && POINTER_TYPE_P (TREE_TYPE (base))
681 178012 : && SSA_NAME_VAR (base)
682 178012 : && TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL
683 400805 : && lookup_attribute ("clobber *this",
684 178011 : DECL_ATTRIBUTES (SSA_NAME_VAR (base))))
685 : {
686 : found_clobber_deref_this = true;
687 : break;
688 : }
689 :
690 222777 : if (!is_gimple_assign (def_stmt))
691 : break;
692 :
693 37647 : tree_code code = gimple_assign_rhs_code (def_stmt);
694 37647 : if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
695 : break;
696 :
697 10385 : base = gimple_assign_rhs1 (def_stmt);
698 10385 : if (TREE_CODE (base) == ADDR_EXPR)
699 1434 : base = TREE_OPERAND (base, 0);
700 :
701 10385 : if (DECL_P (base)
702 9359 : || TREE_CODE (base) == COMPONENT_REF)
703 1196 : rhs = base;
704 :
705 10385 : if (TREE_CODE (base) == MEM_REF)
706 15 : base = TREE_OPERAND (base, 0);
707 :
708 10385 : if (tree ba = get_base_address (base))
709 10385 : base = ba;
710 : }
711 :
712 : /* Replace the RHS expression with BASE so that it
713 : refers to it in the diagnostic (instead of to
714 : '<unknown>'). */
715 491932 : if (DECL_P (base)
716 138486 : && EXPR_P (rhs)
717 64113 : && TREE_CODE (rhs) != COMPONENT_REF)
718 491932 : rhs = base;
719 : }
720 :
721 : /* Do not warn if it can be initialized outside this function.
722 : If we did not reach function entry then we found killing
723 : clobbers on all paths to entry. */
724 491963 : if ((!found_alloc && !found_clobber_deref_this) && fentry_reached)
725 : {
726 491802 : if (TREE_CODE (base) == SSA_NAME)
727 : {
728 212435 : tree var = SSA_NAME_VAR (base);
729 189510 : if (var && TREE_CODE (var) == PARM_DECL)
730 : {
731 178787 : maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
732 178787 : return NULL_TREE;
733 : }
734 : }
735 :
736 313015 : if (!VAR_P (base)
737 313015 : || is_global_var (base))
738 : /* ??? We'd like to use ref_may_alias_global_p but that
739 : excludes global readonly memory and thus we get bogus
740 : warnings from p = cond ? "a" : "b" for example. */
741 : return NULL_TREE;
742 : }
743 :
744 : /* Strip the address-of expression from arrays passed to functions. */
745 1153 : if (TREE_CODE (rhs) == ADDR_EXPR)
746 0 : rhs = TREE_OPERAND (rhs, 0);
747 :
748 : /* Check again since RHS may have changed above. */
749 1153 : if (get_no_uninit_warning (rhs))
750 : return NULL_TREE;
751 :
752 : /* Avoid warning about empty types such as structs with no members.
753 : The first_field() test is important for C++ where the predicate
754 : alone isn't always sufficient. */
755 1147 : tree rhstype = TREE_TYPE (rhs);
756 1147 : if (POINTER_TYPE_P (rhstype))
757 149 : rhstype = TREE_TYPE (rhstype);
758 1147 : if (is_empty_type (rhstype))
759 : return NULL_TREE;
760 :
761 : /* Avoid diagnosing read-modify-write cycles that in the end only
762 : sets a subset of bits to zero or one.
763 : ??? Note that further reads will then appear (partly) initialized
764 : and will not be diagnosed. */
765 738 : gimple *use_stmt;
766 738 : if (gimple_assign_load_p (stmt)
767 486 : && TREE_CODE (lhs) == SSA_NAME
768 1202 : && single_imm_use (lhs, &luse_p, &use_stmt))
769 : {
770 406 : gassign *use_ass = dyn_cast <gassign *> (use_stmt);
771 410 : for (int i = 0; i < 4; ++i)
772 410 : if (use_ass
773 258 : && (gimple_assign_rhs_code (use_ass) == BIT_AND_EXPR
774 : || gimple_assign_rhs_code (use_ass) == BIT_IOR_EXPR
775 : || gimple_assign_rhs_code (use_ass) == VIEW_CONVERT_EXPR)
776 414 : && single_imm_use (gimple_assign_lhs (use_ass), &luse_p,
777 : &use_stmt))
778 4 : use_ass = dyn_cast <gassign *> (use_stmt);
779 : else
780 : break;
781 406 : if (use_ass
782 254 : && gimple_vdef (use_ass)
783 435 : && operand_equal_p (gimple_assign_rhs1 (stmt),
784 29 : gimple_assign_lhs (use_ass)))
785 : return NULL_TREE;
786 : }
787 :
788 734 : bool warned = false;
789 : /* We didn't find any may-defs so on all paths either
790 : reached function entry or a killing clobber. */
791 734 : location_t location = gimple_location (stmt);
792 734 : if (wlims.always_executed)
793 : {
794 583 : if (warning_at (location, OPT_Wuninitialized,
795 : "%qE is used uninitialized", rhs))
796 : {
797 : /* ??? This is only effective for decls as in
798 : gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
799 : uses or accesses by functions as it may hide important
800 : locations. */
801 583 : if (lhs)
802 405 : set_no_uninit_warning (rhs);
803 : warned = true;
804 : }
805 : }
806 151 : else if (wlims.wmaybe_uninit)
807 139 : warned = warning_at (location, OPT_Wmaybe_uninitialized,
808 : "%qE may be used uninitialized", rhs);
809 :
810 139 : return warned ? base : NULL_TREE;
811 : }
812 :
813 :
814 : /* Diagnose passing addresses of uninitialized objects to either const
815 : pointer arguments to functions, or to functions declared with attribute
816 : access implying read access to those objects. */
817 :
818 : static void
819 1270377 : maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
820 : {
821 1270377 : if (!wlims.wmaybe_uninit)
822 783459 : return;
823 :
824 641958 : unsigned nargs = gimple_call_num_args (stmt);
825 641958 : if (!nargs)
826 : return;
827 :
828 583326 : tree fndecl = gimple_call_fndecl (stmt);
829 1288678 : tree fntype = gimple_call_fntype (stmt);
830 505219 : if (!fntype)
831 : return;
832 :
833 : /* Const function do not read their arguments. */
834 505219 : if (gimple_call_flags (stmt) & ECF_CONST)
835 : return;
836 :
837 493813 : const built_in_function fncode
838 444075 : = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
839 618219 : ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
840 :
841 124406 : if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
842 : /* Avoid diagnosing calls to raw memory functions (this is overly
843 : permissive; consider tightening it up). */
844 : return;
845 :
846 : /* Save the current warning setting and replace it either a "maybe"
847 : when passing addresses of uninitialized variables to const-qualified
848 : pointers or arguments declared with attribute read_write, or with
849 : a "certain" when passing them to arguments declared with attribute
850 : read_only. */
851 486918 : const bool save_always_executed = wlims.always_executed;
852 :
853 : /* Initialize a map of attribute access specifications for arguments
854 : to the function call. */
855 486918 : rdwr_map rdwr_idx;
856 486918 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
857 :
858 486918 : tree argtype;
859 486918 : unsigned argno = 0;
860 486918 : function_args_iterator it;
861 :
862 1653744 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
863 : {
864 1584827 : ++argno;
865 :
866 1584827 : if (argno > nargs)
867 : break;
868 :
869 1166826 : if (!POINTER_TYPE_P (argtype))
870 1166586 : continue;
871 :
872 589276 : tree access_size = NULL_TREE;
873 589276 : const attr_access* access = rdwr_idx.get (argno - 1);
874 589276 : if (access)
875 : {
876 3021 : if (access->mode == access_none
877 2850 : || access->mode == access_write_only)
878 403 : continue;
879 :
880 4504 : if (access->mode == access_deferred
881 2618 : && !TYPE_READONLY (TREE_TYPE (argtype)))
882 1886 : continue;
883 :
884 732 : if (save_always_executed && access->mode == access_read_only)
885 : /* Attribute read_only arguments imply read access. */
886 236 : wlims.always_executed = true;
887 : else
888 : /* Attribute read_write arguments are documented as requiring
889 : initialized objects but it's expected that aggregates may
890 : be only partially initialized regardless. */
891 496 : wlims.always_executed = false;
892 :
893 732 : if (access->sizarg < nargs)
894 217 : access_size = gimple_call_arg (stmt, access->sizarg);
895 : }
896 586255 : else if (!TYPE_READONLY (TREE_TYPE (argtype)))
897 353823 : continue;
898 232432 : else if (save_always_executed && fncode != BUILT_IN_LAST)
899 : /* Const-qualified arguments to built-ins imply read access. */
900 20920 : wlims.always_executed = true;
901 : else
902 : /* Const-qualified arguments to ordinary functions imply a likely
903 : (but not definitive) read access. */
904 211512 : wlims.always_executed = false;
905 :
906 : /* Ignore args we are not going to read from. */
907 233164 : if (gimple_call_arg_flags (stmt, argno - 1)
908 233164 : & (EAF_UNUSED | EAF_NO_DIRECT_READ))
909 1995 : continue;
910 :
911 231169 : tree arg = gimple_call_arg (stmt, argno - 1);
912 231169 : if (!POINTER_TYPE_P (TREE_TYPE (arg)))
913 : /* Avoid actual arguments with invalid types. */
914 0 : continue;
915 :
916 231169 : ao_ref ref;
917 231169 : ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
918 231169 : tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
919 231169 : if (!argbase)
920 230929 : continue;
921 :
922 240 : if (access && access->mode != access_deferred)
923 : {
924 48 : const char* const access_str =
925 48 : TREE_STRING_POINTER (access->to_external_string ());
926 :
927 48 : auto_urlify_attributes sentinel;
928 48 : if (fndecl)
929 : {
930 48 : location_t loc = DECL_SOURCE_LOCATION (fndecl);
931 48 : inform (loc, "in a call to %qD declared with "
932 : "attribute %qs here", fndecl, access_str);
933 : }
934 : else
935 : {
936 : /* Handle calls through function pointers. */
937 0 : location_t loc = gimple_location (stmt);
938 0 : inform (loc, "in a call to %qT declared with "
939 : "attribute %qs", fntype, access_str);
940 : }
941 48 : }
942 : else
943 : {
944 : /* For a declaration with no relevant attribute access create
945 : a dummy object and use the formatting function to avoid
946 : having to complicate things here. */
947 192 : attr_access ptr_access = { };
948 192 : if (!access)
949 173 : access = &ptr_access;
950 192 : const std::string argtypestr = access->array_as_string (argtype);
951 192 : if (fndecl)
952 : {
953 192 : location_t loc (DECL_SOURCE_LOCATION (fndecl));
954 192 : inform (loc, "by argument %u of type %s to %qD "
955 : "declared here",
956 : argno, argtypestr.c_str (), fndecl);
957 : }
958 : else
959 : {
960 : /* Handle calls through function pointers. */
961 0 : location_t loc (gimple_location (stmt));
962 0 : inform (loc, "by argument %u of type %s to %qT",
963 : argno, argtypestr.c_str (), fntype);
964 : }
965 192 : }
966 :
967 240 : if (DECL_P (argbase))
968 : {
969 219 : location_t loc = DECL_SOURCE_LOCATION (argbase);
970 219 : inform (loc, "%qD declared here", argbase);
971 : }
972 : }
973 :
974 486918 : wlims.always_executed = save_always_executed;
975 486918 : }
976 :
977 : /* Warn about an uninitialized PHI argument on the fallthru path to
978 : an always executed block BB. */
979 :
980 : static void
981 410879 : warn_uninit_phi_uses (basic_block bb)
982 : {
983 410879 : edge_iterator ei;
984 410879 : edge e, found = NULL, found_back = NULL;
985 : /* Look for a fallthru and possibly a single backedge. */
986 836628 : FOR_EACH_EDGE (e, ei, bb->preds)
987 : {
988 : /* Ignore backedges. */
989 533279 : if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
990 : {
991 15358 : if (found_back)
992 : {
993 : found = NULL;
994 : break;
995 : }
996 14870 : found_back = e;
997 14870 : continue;
998 : }
999 517921 : if (found)
1000 : {
1001 : found = NULL;
1002 : break;
1003 : }
1004 : found = e;
1005 : }
1006 410879 : if (!found)
1007 107530 : return;
1008 :
1009 303349 : basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1010 336178 : for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
1011 32829 : gsi_next (&si))
1012 : {
1013 32829 : gphi *phi = si.phi ();
1014 32829 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
1015 63938 : if (TREE_CODE (def) != SSA_NAME
1016 28584 : || !SSA_NAME_IS_DEFAULT_DEF (def)
1017 38159 : || virtual_operand_p (def))
1018 31109 : continue;
1019 : /* If there's a default def on the fallthru edge PHI
1020 : value and there's a use that post-dominates entry
1021 : then that use is uninitialized and we can warn. */
1022 1720 : imm_use_iterator iter;
1023 1720 : use_operand_p use_p;
1024 1720 : gimple *use_stmt = NULL;
1025 7803 : FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
1026 : {
1027 5471 : use_stmt = USE_STMT (use_p);
1028 5471 : if (gimple_location (use_stmt) != UNKNOWN_LOCATION
1029 4562 : && dominated_by_p (CDI_POST_DOMINATORS, succ,
1030 4562 : gimple_bb (use_stmt))
1031 : /* If we found a non-fallthru edge make sure the
1032 : use is inside the loop, otherwise the backedge
1033 : can serve as initialization. */
1034 6769 : && (!found_back
1035 1298 : || dominated_by_p (CDI_DOMINATORS, found_back->src,
1036 1298 : gimple_bb (use_stmt))))
1037 : break;
1038 4363 : use_stmt = NULL;
1039 1720 : }
1040 1720 : if (use_stmt)
1041 2216 : warn_uninit (OPT_Wuninitialized, def,
1042 1108 : SSA_NAME_VAR (def), use_stmt);
1043 : }
1044 : }
1045 :
1046 : /* Issue warnings about reads of uninitialized variables. WMAYBE_UNINIT
1047 : is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized. */
1048 :
1049 : static void
1050 248390 : warn_uninitialized_vars (bool wmaybe_uninit)
1051 : {
1052 : /* Counters and limits controlling the depth of the warning. */
1053 248390 : wlimits wlims = { };
1054 248390 : wlims.wmaybe_uninit = wmaybe_uninit;
1055 :
1056 248390 : auto_bb_flag ft_reachable (cfun);
1057 :
1058 : /* Mark blocks that are always executed when we ignore provably
1059 : not executed and EH and abnormal edges. */
1060 248390 : basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1061 410941 : while (!(bb->flags & ft_reachable))
1062 : {
1063 410879 : bb->flags |= ft_reachable;
1064 410879 : edge e = find_fallthru_edge (bb->succs);
1065 410879 : if (e && e->flags & EDGE_EXECUTABLE)
1066 : {
1067 44562 : bb = e->dest;
1068 44562 : continue;
1069 : }
1070 : /* Find a single executable edge. */
1071 366317 : edge_iterator ei;
1072 366317 : edge ee = NULL;
1073 730992 : FOR_EACH_EDGE (e, ei, bb->succs)
1074 515218 : if (e->flags & EDGE_EXECUTABLE)
1075 : {
1076 515018 : if (!ee)
1077 : ee = e;
1078 : else
1079 : {
1080 : ee = NULL;
1081 : break;
1082 : }
1083 : }
1084 366317 : if (ee)
1085 213932 : bb = ee->dest;
1086 : else
1087 152385 : bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1088 366317 : if (!bb || bb->index == EXIT_BLOCK)
1089 : break;
1090 : }
1091 :
1092 2825098 : FOR_EACH_BB_FN (bb, cfun)
1093 : {
1094 2576708 : wlims.always_executed = (bb->flags & ft_reachable);
1095 2576708 : bb->flags &= ~ft_reachable;
1096 :
1097 2576708 : edge_iterator ei;
1098 2576708 : edge e;
1099 2577511 : FOR_EACH_EDGE (e, ei, bb->preds)
1100 2577118 : if (e->flags & EDGE_EXECUTABLE)
1101 : break;
1102 : /* Skip unreachable blocks. For early analysis we use VN to
1103 : determine edge executability when wmaybe_uninit. */
1104 2576708 : if (!e)
1105 393 : continue;
1106 :
1107 2576315 : if (wlims.always_executed)
1108 410879 : warn_uninit_phi_uses (bb);
1109 :
1110 2576315 : gimple_stmt_iterator gsi;
1111 20980797 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1112 : {
1113 15828167 : gimple *stmt = gsi_stmt (gsi);
1114 :
1115 : /* The call is an artificial use, will not provide meaningful
1116 : error message. If the result of the call is used somewhere
1117 : else, we warn there instead. */
1118 15828167 : if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
1119 8829797 : continue;
1120 :
1121 15824532 : if (is_gimple_debug (stmt))
1122 7585671 : continue;
1123 :
1124 : /* We only do data flow with SSA_NAMEs, so that's all we
1125 : can warn about. */
1126 8238861 : use_operand_p use_p;
1127 8238861 : ssa_op_iter op_iter;
1128 16896929 : FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
1129 : {
1130 : /* BIT_INSERT_EXPR first operand should not be considered
1131 : a use for the purpose of uninit warnings. */
1132 8658068 : if (gassign *ass = dyn_cast <gassign *> (stmt))
1133 : {
1134 5704477 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
1135 5704477 : && use_p->use == gimple_assign_rhs1_ptr (ass))
1136 21 : continue;
1137 : }
1138 8658047 : tree use = USE_FROM_PTR (use_p);
1139 8658047 : if (wlims.always_executed)
1140 3535162 : warn_uninit (OPT_Wuninitialized, use,
1141 1767581 : SSA_NAME_VAR (use), stmt);
1142 6890466 : else if (wlims.wmaybe_uninit)
1143 7801424 : warn_uninit (OPT_Wmaybe_uninitialized, use,
1144 3900712 : SSA_NAME_VAR (use), stmt);
1145 : }
1146 :
1147 : /* For limiting the alias walk below we count all
1148 : vdefs in the function. */
1149 15348114 : if (gimple_vdef (stmt))
1150 2071807 : wlims.vdef_cnt++;
1151 :
1152 8238861 : if (gcall *call = dyn_cast <gcall *> (stmt))
1153 1270377 : maybe_warn_pass_by_reference (call, wlims);
1154 6968484 : else if (gimple_assign_load_p (stmt)
1155 6968484 : && gimple_has_location (stmt))
1156 : {
1157 1240957 : tree rhs = gimple_assign_rhs1 (stmt);
1158 1240957 : tree lhs = gimple_assign_lhs (stmt);
1159 :
1160 1240957 : ao_ref ref;
1161 1240957 : ao_ref_init (&ref, rhs);
1162 1240957 : tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
1163 1240957 : if (!var)
1164 1240491 : continue;
1165 :
1166 466 : if (DECL_P (var))
1167 : {
1168 344 : location_t loc = DECL_SOURCE_LOCATION (var);
1169 344 : inform (loc, "%qD declared here", var);
1170 : }
1171 : }
1172 : }
1173 : }
1174 248390 : }
1175 :
1176 : /* Checks if the operand OPND of PHI is defined by
1177 : another phi with one operand defined by this PHI,
1178 : but the rest operands are all defined. If yes,
1179 : returns true to skip this operand as being
1180 : redundant. Can be enhanced to be more general. */
1181 :
1182 : static bool
1183 1765 : can_skip_redundant_opnd (tree opnd, gimple *phi)
1184 : {
1185 1765 : tree phi_def = gimple_phi_result (phi);
1186 1765 : gimple *op_def = SSA_NAME_DEF_STMT (opnd);
1187 1765 : if (gimple_code (op_def) != GIMPLE_PHI)
1188 : return false;
1189 :
1190 714 : unsigned n = gimple_phi_num_args (op_def);
1191 896 : for (unsigned i = 0; i < n; ++i)
1192 : {
1193 895 : tree op = gimple_phi_arg_def (op_def, i);
1194 895 : if (TREE_CODE (op) != SSA_NAME)
1195 0 : continue;
1196 895 : if (op != phi_def && uninit_undefined_value_p (op))
1197 : return false;
1198 : }
1199 :
1200 : return true;
1201 : }
1202 :
1203 : /* Return a bitset holding the positions of arguments in PHI with empty
1204 : (or possibly empty) definitions. */
1205 :
1206 : static unsigned
1207 447174 : compute_uninit_opnds_pos (gphi *phi)
1208 : {
1209 447174 : unsigned uninit_opnds = 0;
1210 :
1211 447174 : unsigned n = gimple_phi_num_args (phi);
1212 : /* Bail out for phi with too many args. */
1213 447174 : if (n > uninit_analysis::func_t::max_phi_args)
1214 : return 0;
1215 :
1216 1556798 : for (unsigned i = 0; i < n; ++i)
1217 : {
1218 1109791 : tree op = gimple_phi_arg_def (phi, i);
1219 1109791 : if (TREE_CODE (op) == SSA_NAME
1220 907029 : && uninit_undefined_value_p (op)
1221 1111556 : && !can_skip_redundant_opnd (op, phi))
1222 : {
1223 1764 : if (cfun->has_nonlocal_label || cfun->calls_setjmp)
1224 : {
1225 : /* Ignore SSA_NAMEs that appear on abnormal edges
1226 : somewhere. */
1227 91 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
1228 63 : continue;
1229 : }
1230 1701 : MASK_SET_BIT (uninit_opnds, i);
1231 : }
1232 : }
1233 : /* If we have recorded guarded uses of may-uninit values mask those. */
1234 447007 : if (auto *def_mask = defined_args->get (phi))
1235 63 : uninit_opnds &= ~*def_mask;
1236 : return uninit_opnds;
1237 : }
1238 :
1239 : /* Function object type used to determine whether an expression
1240 : is of interest to the predicate analyzer. */
1241 :
1242 : struct uninit_undef_val_t: public uninit_analysis::func_t
1243 : {
1244 : virtual unsigned phi_arg_set (gphi *) override;
1245 : };
1246 :
1247 : /* Return a bitset of PHI arguments of interest. */
1248 :
1249 : unsigned
1250 519 : uninit_undef_val_t::phi_arg_set (gphi *phi)
1251 : {
1252 519 : return compute_uninit_opnds_pos (phi);
1253 : }
1254 :
1255 : /* sort helper for find_uninit_use. */
1256 :
1257 : static int
1258 195 : cand_cmp (const void *a, const void *b, void *data)
1259 : {
1260 195 : int *bb_to_rpo = (int *)data;
1261 195 : const gimple *sa = *(const gimple * const *)a;
1262 195 : const gimple *sb = *(const gimple * const *)b;
1263 195 : if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
1264 : return -1;
1265 104 : else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
1266 50 : return 1;
1267 : return 0;
1268 : }
1269 :
1270 : /* Searches through all uses of a potentially
1271 : uninitialized variable defined by PHI and returns a use
1272 : statement if the use is not properly guarded. It returns
1273 : NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
1274 : holding the position(s) of uninit PHI operands. */
1275 :
1276 : static gimple *
1277 368 : find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1278 : {
1279 : /* The Boolean predicate guarding the PHI definition. Initialized
1280 : lazily from PHI in the first call to is_use_guarded() and cached
1281 : for subsequent iterations. */
1282 368 : uninit_undef_val_t eval;
1283 368 : uninit_analysis def_preds (eval);
1284 :
1285 : /* First process PHIs and record other candidates. */
1286 368 : auto_vec<gimple *, 64> cands;
1287 368 : use_operand_p use_p;
1288 368 : imm_use_iterator iter;
1289 368 : tree phi_result = gimple_phi_result (phi);
1290 1526 : FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1291 : {
1292 790 : gimple *use_stmt = USE_STMT (use_p);
1293 790 : if (is_gimple_debug (use_stmt))
1294 273 : continue;
1295 :
1296 : /* Look through a single level of SSA name copies. This is
1297 : important for copies involving abnormals which we can't always
1298 : proapgate out but which result in spurious unguarded uses. */
1299 597 : use_operand_p use2_p;
1300 597 : gimple *use2_stmt;
1301 597 : if (gimple_assign_ssa_name_copy_p (use_stmt)
1302 597 : && single_imm_use (gimple_assign_lhs (use_stmt), &use2_p, &use2_stmt))
1303 : {
1304 8 : use_p = use2_p;
1305 8 : use_stmt = use2_stmt;
1306 : }
1307 :
1308 823 : if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1309 : {
1310 371 : unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p);
1311 371 : edge e = gimple_phi_arg_edge (use_phi, idx);
1312 : /* Do not look for uses in the next iteration of a loop, predicate
1313 : analysis will not use the appropriate predicates to prove
1314 : reachability. */
1315 371 : if (e->flags & EDGE_DFS_BACK)
1316 80 : continue;
1317 :
1318 341 : basic_block use_bb = e->src;
1319 341 : if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1320 : {
1321 : /* For a guarded use in a PHI record the PHI argument as
1322 : initialized. */
1323 50 : if (idx < uninit_analysis::func_t::max_phi_args)
1324 : {
1325 50 : bool existed_p;
1326 50 : auto &def_mask
1327 50 : = defined_args->get_or_insert (use_phi, &existed_p);
1328 50 : if (!existed_p)
1329 50 : def_mask = 0;
1330 50 : MASK_SET_BIT (def_mask, idx);
1331 : }
1332 50 : continue;
1333 50 : }
1334 :
1335 291 : if (dump_file && (dump_flags & TDF_DETAILS))
1336 : {
1337 0 : fprintf (dump_file, "Found unguarded use on edge %u -> %u: ",
1338 0 : e->src->index, e->dest->index);
1339 0 : print_gimple_stmt (dump_file, use_stmt, 0);
1340 : }
1341 : /* Found a phi use that is not guarded, mark the use as
1342 : possibly undefined. */
1343 291 : possibly_undefined_names->add (USE_FROM_PTR (use_p));
1344 : }
1345 : else
1346 226 : cands.safe_push (use_stmt);
1347 368 : }
1348 :
1349 : /* Sort candidates after RPO. */
1350 368 : cands.stablesort (cand_cmp, bb_to_rpo);
1351 368 : basic_block use_bb = NULL;
1352 1216 : for (gimple *use_stmt : cands)
1353 : {
1354 : /* We only have to try diagnosing the first use in each block. */
1355 212 : if (gimple_bb (use_stmt) == use_bb)
1356 5 : continue;
1357 :
1358 207 : use_bb = gimple_bb (use_stmt);
1359 207 : if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1360 107 : continue;
1361 :
1362 100 : if (dump_file && (dump_flags & TDF_DETAILS))
1363 : {
1364 0 : fprintf (dump_file, "Found unguarded use in bb %u: ",
1365 : use_bb->index);
1366 0 : print_gimple_stmt (dump_file, use_stmt, 0);
1367 : }
1368 : return use_stmt;
1369 : }
1370 :
1371 : return NULL;
1372 368 : }
1373 :
1374 : /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1375 : and gives warning if there exists a runtime path from the entry to a
1376 : use of the PHI def that does not contain a definition. In other words,
1377 : the warning is on the real use. The more dead paths that can be pruned
1378 : by the compiler, the fewer false positives the warning is. */
1379 :
1380 : static void
1381 368 : warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1382 : {
1383 368 : if (dump_file && (dump_flags & TDF_DETAILS))
1384 : {
1385 0 : fprintf (dump_file, "Examining phi: ");
1386 0 : print_gimple_stmt (dump_file, phi, 0);
1387 : }
1388 :
1389 368 : gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);
1390 :
1391 : /* All uses are properly guarded. */
1392 368 : if (!uninit_use_stmt)
1393 : return;
1394 :
1395 100 : unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1396 100 : tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1397 :
1398 100 : location_t loc = UNKNOWN_LOCATION;
1399 100 : if (gimple_phi_arg_has_location (phi, phiarg_index))
1400 : loc = gimple_phi_arg_location (phi, phiarg_index);
1401 : else
1402 : {
1403 85 : tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1404 85 : if (TREE_CODE (arg_def) == SSA_NAME)
1405 : {
1406 85 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1407 85 : if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1408 : {
1409 12 : unsigned uop = compute_uninit_opnds_pos (arg_phi);
1410 12 : unsigned idx = MASK_FIRST_SET_BIT (uop);
1411 12 : if (idx < gimple_phi_num_args (arg_phi)
1412 12 : && gimple_phi_arg_has_location (arg_phi, idx))
1413 : loc = gimple_phi_arg_location (arg_phi, idx);
1414 : }
1415 : }
1416 : }
1417 :
1418 200 : warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1419 100 : SSA_NAME_VAR (uninit_op),
1420 : uninit_use_stmt, loc);
1421 : }
1422 :
1423 : static bool
1424 4043052 : gate_warn_uninitialized (void)
1425 : {
1426 3795215 : return warn_uninitialized || warn_maybe_uninitialized;
1427 : }
1428 :
1429 : namespace {
1430 :
1431 : const pass_data pass_data_late_warn_uninitialized =
1432 : {
1433 : GIMPLE_PASS, /* type */
1434 : "uninit", /* name */
1435 : OPTGROUP_NONE, /* optinfo_flags */
1436 : TV_NONE, /* tv_id */
1437 : PROP_ssa, /* properties_required */
1438 : 0, /* properties_provided */
1439 : 0, /* properties_destroyed */
1440 : 0, /* todo_flags_start */
1441 : 0, /* todo_flags_finish */
1442 : };
1443 :
1444 : class pass_late_warn_uninitialized : public gimple_opt_pass
1445 : {
1446 : public:
1447 584742 : pass_late_warn_uninitialized (gcc::context *ctxt)
1448 1169484 : : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1449 : {}
1450 :
1451 : /* opt_pass methods: */
1452 292371 : opt_pass *clone () final override
1453 : {
1454 292371 : return new pass_late_warn_uninitialized (m_ctxt);
1455 : }
1456 1057512 : bool gate (function *) final override { return gate_warn_uninitialized (); }
1457 : unsigned int execute (function *) final override;
1458 :
1459 : }; // class pass_late_warn_uninitialized
1460 :
1461 : static void
1462 80582 : execute_late_warn_uninitialized (function *fun)
1463 : {
1464 80582 : calculate_dominance_info (CDI_DOMINATORS);
1465 80582 : calculate_dominance_info (CDI_POST_DOMINATORS);
1466 :
1467 : /* Mark all edges executable, warn_uninitialized_vars will skip
1468 : unreachable blocks. */
1469 80582 : set_all_edges_as_executable (fun);
1470 80582 : mark_dfs_back_edges (fun);
1471 80582 : int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
1472 80582 : int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
1473 80582 : int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
1474 1560615 : for (int i = 0; i < n; ++i)
1475 1480033 : bb_to_rpo[rpo[i]] = i;
1476 :
1477 : /* Re-do the plain uninitialized variable check, as optimization may have
1478 : straightened control flow. Do this first so that we don't accidentally
1479 : get a "may be" warning when we'd have seen an "is" warning later. */
1480 80582 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1481 :
1482 80582 : timevar_push (TV_TREE_UNINIT);
1483 :
1484 : /* Avoid quadratic behavior when looking up case labels for edges. */
1485 80582 : start_recording_case_labels ();
1486 :
1487 80582 : possibly_undefined_names = new hash_set<tree>;
1488 80582 : defined_args = new hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t>;
1489 :
1490 : /* Walk the CFG in RPO order so we visit PHIs with defs that are
1491 : possibly uninitialized from other PHIs after those. The uninit
1492 : predicate analysis will then expand the PHIs predicate with
1493 : the predicates of the edges from such PHI defs. */
1494 1560615 : for (int i = 0; i < n; ++i)
1495 1480033 : for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
1496 2142086 : !gsi_end_p (gsi); gsi_next (&gsi))
1497 : {
1498 662053 : gphi *phi = gsi.phi ();
1499 :
1500 : /* Don't look at virtual operands. */
1501 1324106 : if (virtual_operand_p (gimple_phi_result (phi)))
1502 215410 : continue;
1503 :
1504 446643 : unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1505 446643 : if (MASK_EMPTY (uninit_opnds))
1506 446275 : continue;
1507 :
1508 368 : warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
1509 : }
1510 :
1511 80582 : free (rpo);
1512 80582 : free (bb_to_rpo);
1513 161164 : delete possibly_undefined_names;
1514 80582 : possibly_undefined_names = NULL;
1515 161164 : delete defined_args;
1516 80582 : defined_args = NULL;
1517 80582 : end_recording_case_labels ();
1518 80582 : free_dominance_info (CDI_POST_DOMINATORS);
1519 80582 : timevar_pop (TV_TREE_UNINIT);
1520 80582 : }
1521 :
1522 : unsigned int
1523 80582 : pass_late_warn_uninitialized::execute (function *fun)
1524 : {
1525 80582 : execute_late_warn_uninitialized (fun);
1526 80582 : return 0;
1527 : }
1528 :
1529 : } // anon namespace
1530 :
1531 : gimple_opt_pass *
1532 292371 : make_pass_late_warn_uninitialized (gcc::context *ctxt)
1533 : {
1534 292371 : return new pass_late_warn_uninitialized (ctxt);
1535 : }
1536 :
1537 : static unsigned int
1538 167808 : execute_early_warn_uninitialized (struct function *fun)
1539 : {
1540 : /* Currently, this pass runs always but
1541 : execute_late_warn_uninitialized only runs with optimization. With
1542 : optimization we want to warn about possible uninitialized as late
1543 : as possible, thus don't do it here. However, without
1544 : optimization we need to warn here about "may be uninitialized". */
1545 167808 : calculate_dominance_info (CDI_DOMINATORS);
1546 167808 : calculate_dominance_info (CDI_POST_DOMINATORS);
1547 :
1548 : /* Use VN in its cheapest incarnation and without doing any
1549 : elimination to compute edge reachability. Don't bother when
1550 : we only warn for unconditionally executed code though. */
1551 167808 : if (!optimize)
1552 19592 : do_rpo_vn (fun, NULL, NULL, false, false, false, VN_NOWALK);
1553 : else
1554 148216 : set_all_edges_as_executable (fun);
1555 :
1556 167808 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1557 :
1558 : /* Post-dominator information cannot be reliably updated. Free it
1559 : after the use. */
1560 :
1561 167808 : free_dominance_info (CDI_POST_DOMINATORS);
1562 167808 : return 0;
1563 : }
1564 :
1565 : namespace {
1566 :
1567 : const pass_data pass_data_early_warn_uninitialized =
1568 : {
1569 : GIMPLE_PASS, /* type */
1570 : "early_uninit", /* name */
1571 : OPTGROUP_NONE, /* optinfo_flags */
1572 : TV_TREE_UNINIT, /* tv_id */
1573 : PROP_ssa, /* properties_required */
1574 : 0, /* properties_provided */
1575 : 0, /* properties_destroyed */
1576 : 0, /* todo_flags_start */
1577 : 0, /* todo_flags_finish */
1578 : };
1579 :
1580 : class pass_early_warn_uninitialized : public gimple_opt_pass
1581 : {
1582 : public:
1583 292371 : pass_early_warn_uninitialized (gcc::context *ctxt)
1584 584742 : : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1585 : {}
1586 :
1587 : /* opt_pass methods: */
1588 2985540 : bool gate (function *) final override { return gate_warn_uninitialized (); }
1589 167808 : unsigned int execute (function *fun) final override
1590 : {
1591 167808 : return execute_early_warn_uninitialized (fun);
1592 : }
1593 :
1594 : }; // class pass_early_warn_uninitialized
1595 :
1596 : } // anon namespace
1597 :
1598 : gimple_opt_pass *
1599 292371 : make_pass_early_warn_uninitialized (gcc::context *ctxt)
1600 : {
1601 292371 : return new pass_early_warn_uninitialized (ctxt);
1602 : }
|