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 110 : get_mask_first_set_bit (unsigned mask)
67 : {
68 110 : int pos = 0;
69 0 : if (mask == 0)
70 : return -1;
71 :
72 139 : while ((mask & (1 << pos)) == 0)
73 29 : 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 6603265 : has_undefined_value_p (tree t)
82 : {
83 6603265 : return (ssa_undefined_value_p (t)
84 6603265 : || (possibly_undefined_names
85 911044 : && possibly_undefined_names->contains (t)));
86 : }
87 :
88 : /* Return true if EXPR should suppress either uninitialized warning. */
89 :
90 : static inline bool
91 3137809 : get_no_uninit_warning (tree expr)
92 : {
93 1477320 : 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 : }
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 912829 : uninit_undefined_value_p (tree t)
109 : {
110 912829 : if (!has_undefined_value_p (t))
111 : return false;
112 2766 : if (!SSA_NAME_VAR (t))
113 : return true;
114 2747 : 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 5690433 : 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 5690433 : if (!has_undefined_value_p (t))
144 5689875 : 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 4697 : if (is_gimple_assign (context)
150 4697 : && 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 4687 : if (is_gimple_assign (context)
178 4687 : && (gimple_assign_rhs_code (context) == REALPART_EXPR
179 4110 : || 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 4682 : const char *var_name_str = NULL;
202 4682 : gimple *var_def_stmt = NULL;
203 :
204 4932 : 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 4450 : 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 4450 : if (((warning_suppressed_p (context, OPT_Wuninitialized)
282 4443 : || (gimple_assign_single_p (context)
283 3713 : && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
284 8697 : || (var && get_no_uninit_warning (var))
285 6509 : || (var_name_str
286 9 : && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
287 : 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 2058 : location_t location = UNKNOWN_LOCATION;
293 2058 : if (gimple_has_location (context))
294 2045 : 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 2616 : auto_diagnostic_group d;
303 2058 : gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
304 2058 : if (var)
305 : {
306 2050 : if ((opt == OPT_Wuninitialized
307 1657 : && !warning_at (location, opt, "%qD is used uninitialized", var))
308 2475 : || (opt == OPT_Wmaybe_uninitialized
309 2050 : && !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 : return;
322 : }
323 :
324 : /* Avoid subsequent warnings for reads of the same variable again. */
325 563 : if (var)
326 555 : 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 563 : location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
333 563 : : gimple_location (var_def_stmt);
334 563 : if (location == var_loc)
335 : return;
336 :
337 558 : if (var)
338 550 : 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 3064497 : builtin_call_nomodifying_p (gimple *stmt)
355 : {
356 3064497 : if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
357 : return false;
358 :
359 363804 : tree fndecl = gimple_call_fndecl (stmt);
360 363804 : if (!fndecl)
361 : return false;
362 :
363 363804 : tree fntype = TREE_TYPE (fndecl);
364 363804 : 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 363804 : unsigned argno = 0;
370 363804 : tree argtype;
371 363804 : function_args_iterator it;
372 644281 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
373 : {
374 445665 : if (VOID_TYPE_P (argtype))
375 : return true;
376 :
377 401795 : ++argno;
378 :
379 401795 : if (!POINTER_TYPE_P (argtype))
380 49883 : continue;
381 :
382 351912 : if (TYPE_READONLY (TREE_TYPE (argtype)))
383 230594 : 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 198616 : unsigned nargs = gimple_call_num_args (stmt);
391 198616 : 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 212903 : for (; argno < nargs; ++argno)
398 : {
399 204783 : tree arg = gimple_call_arg (stmt, argno);
400 204783 : argtype = TREE_TYPE (arg);
401 204783 : if (!POINTER_TYPE_P (argtype))
402 13867 : continue;
403 :
404 190916 : 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 178921 : maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
418 : {
419 178921 : if (!fndecl)
420 0 : return;
421 :
422 178921 : if (get_no_uninit_warning (arg))
423 : return;
424 :
425 178921 : tree fntype = TREE_TYPE (fndecl);
426 178921 : if (!fntype)
427 : return;
428 :
429 : /* Initialize a map of attribute access specifications for arguments
430 : to the function call. */
431 178921 : rdwr_map rdwr_idx;
432 178921 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
433 :
434 178921 : unsigned argno = 0;
435 178921 : tree parms = DECL_ARGUMENTS (fndecl);
436 320343 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
437 : {
438 319853 : if (parm != arg)
439 141422 : continue;
440 :
441 178903 : const attr_access* access = rdwr_idx.get (argno);
442 178903 : 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 178921 : }
468 :
469 : /* Callback for walk_aliased_vdefs. */
470 :
471 : static bool
472 3202964 : check_defs (ao_ref *ref, tree vdef, void *data_)
473 : {
474 3202964 : check_defs_data *data = (check_defs_data *)data_;
475 3202964 : 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 3202964 : 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 3202467 : if (is_gimple_assign (def_stmt)
488 3202467 : && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
489 : {
490 1347534 : tree tmp_var = gimple_assign_rhs1 (def_stmt);
491 1347534 : 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 3202420 : if (is_gimple_call (def_stmt))
498 : {
499 : /* The ASAN_MARK intrinsic doesn't modify the variable. */
500 1455939 : if (gimple_call_internal_p (def_stmt)
501 1455939 : && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
502 : return false;
503 :
504 1454208 : 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 1255597 : if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
510 : {
511 365147 : built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
512 365147 : if (fncode > BEGIN_SANITIZER_BUILTINS
513 365147 : && fncode < END_SANITIZER_BUILTINS)
514 : return false;
515 : }
516 : }
517 : }
518 :
519 : /* End of VLA scope is not a kill. */
520 3200540 : 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 3200464 : if (gimple_clobber_p (def_stmt))
525 : {
526 135967 : if (stmt_kills_ref_p (def_stmt, ref))
527 : return true;
528 : return false;
529 : }
530 :
531 3064497 : if (builtin_call_nomodifying_p (def_stmt))
532 : return false;
533 :
534 : /* Found a may-def on this path. */
535 3012507 : data->found_may_defs = true;
536 3012507 : 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 1473956 : maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
562 : wlimits &wlims)
563 : {
564 1473956 : bool has_bit_insert = false;
565 1473956 : use_operand_p luse_p;
566 1473956 : imm_use_iterator liter;
567 :
568 1473956 : 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 1472982 : tree base = ao_ref_base (&ref);
574 1472982 : if ((VAR_P (base)
575 590071 : && DECL_HARD_REGISTER (base))
576 2945958 : || get_no_uninit_warning (base))
577 : return NULL_TREE;
578 :
579 : /* Do not warn if the access is zero size or if it's fully outside
580 : the object. */
581 1468163 : poly_int64 decl_size;
582 1468163 : if (known_size_p (ref.size)
583 1238944 : && known_eq (ref.max_size, ref.size)
584 2572962 : && (known_eq (ref.size, 0)
585 1104785 : || known_le (ref.offset + ref.size, 0)))
586 : return NULL_TREE;
587 :
588 1468093 : if (DECL_P (base)
589 603863 : && known_ge (ref.offset, 0)
590 603856 : && DECL_SIZE (base)
591 587081 : && poly_int_tree_p (DECL_SIZE (base), &decl_size)
592 2055173 : && 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 1467581 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
598 2994228 : FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
599 : {
600 1767918 : 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 2622604 : if (gassign *ass = dyn_cast <gassign *> (use_stmt))
604 : {
605 854688 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
606 854688 : && luse_p->use == gimple_assign_rhs1_ptr (ass))
607 : {
608 : has_bit_insert = true;
609 : break;
610 : }
611 : }
612 1226312 : }
613 :
614 1226312 : 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 1467579 : if (wlims.oracle_cnt > 128 * 128
621 36553 : && wlims.oracle_cnt > wlims.vdef_cnt * 2)
622 36553 : wlims.limit = 32;
623 :
624 1467579 : check_defs_data data;
625 1467579 : bool fentry_reached = false;
626 1467579 : data.found_may_defs = false;
627 1467579 : tree use = gimple_vuse (stmt);
628 1467579 : if (!use)
629 : return NULL_TREE;
630 1467321 : int res = walk_aliased_vdefs (&ref, use,
631 : check_defs, &data, NULL,
632 : &fentry_reached, wlims.limit);
633 1467321 : if (res == -1)
634 : {
635 33517 : wlims.oracle_cnt += wlims.limit;
636 33517 : return NULL_TREE;
637 : }
638 :
639 1433804 : wlims.oracle_cnt += res;
640 1433804 : if (data.found_may_defs)
641 : return NULL_TREE;
642 :
643 492271 : bool found_alloc = false;
644 492271 : bool found_clobber_deref_this = false;
645 :
646 492271 : if (fentry_reached)
647 : {
648 492240 : if (TREE_CODE (base) == MEM_REF)
649 214434 : 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 502597 : while (TREE_CODE (base) == SSA_NAME)
656 : {
657 223025 : gimple *def_stmt = SSA_NAME_DEF_STMT (base);
658 :
659 223025 : if (is_gimple_call (def_stmt)
660 223025 : && 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 222869 : if (SSA_NAME_IS_DEFAULT_DEF (base)
680 178158 : && POINTER_TYPE_P (TREE_TYPE (base))
681 178158 : && SSA_NAME_VAR (base)
682 178158 : && TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL
683 401026 : && lookup_attribute ("clobber *this",
684 178157 : DECL_ATTRIBUTES (SSA_NAME_VAR (base))))
685 : {
686 : found_clobber_deref_this = true;
687 : break;
688 : }
689 :
690 222852 : if (!is_gimple_assign (def_stmt))
691 : break;
692 :
693 37649 : tree_code code = gimple_assign_rhs_code (def_stmt);
694 37649 : if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
695 : break;
696 :
697 10357 : base = gimple_assign_rhs1 (def_stmt);
698 10357 : if (TREE_CODE (base) == ADDR_EXPR)
699 1436 : base = TREE_OPERAND (base, 0);
700 :
701 10357 : if (DECL_P (base)
702 9329 : || TREE_CODE (base) == COMPONENT_REF)
703 1198 : rhs = base;
704 :
705 10357 : if (TREE_CODE (base) == MEM_REF)
706 15 : base = TREE_OPERAND (base, 0);
707 :
708 10357 : if (tree ba = get_base_address (base))
709 10357 : 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 492240 : if (DECL_P (base)
716 138546 : && EXPR_P (rhs)
717 64173 : && TREE_CODE (rhs) != COMPONENT_REF)
718 492240 : 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 492271 : if ((!found_alloc && !found_clobber_deref_this) && fentry_reached)
725 : {
726 492110 : if (TREE_CODE (base) == SSA_NAME)
727 : {
728 212538 : tree var = SSA_NAME_VAR (base);
729 189605 : if (var && TREE_CODE (var) == PARM_DECL)
730 : {
731 178921 : maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
732 178921 : return NULL_TREE;
733 : }
734 : }
735 :
736 313189 : if (!VAR_P (base)
737 313189 : || 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 1152 : if (TREE_CODE (rhs) == ADDR_EXPR)
746 0 : rhs = TREE_OPERAND (rhs, 0);
747 :
748 : /* Check again since RHS may have changed above. */
749 1152 : 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 1146 : tree rhstype = TREE_TYPE (rhs);
756 1146 : if (POINTER_TYPE_P (rhstype))
757 149 : rhstype = TREE_TYPE (rhstype);
758 1146 : 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 737 : gimple *use_stmt;
766 737 : if (gimple_assign_load_p (stmt)
767 485 : && TREE_CODE (lhs) == SSA_NAME
768 1200 : && single_imm_use (lhs, &luse_p, &use_stmt))
769 : {
770 405 : gassign *use_ass = dyn_cast <gassign *> (use_stmt);
771 409 : for (int i = 0; i < 4; ++i)
772 409 : 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 413 : && 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 405 : if (use_ass
782 254 : && gimple_vdef (use_ass)
783 434 : && operand_equal_p (gimple_assign_rhs1 (stmt),
784 29 : gimple_assign_lhs (use_ass)))
785 : return NULL_TREE;
786 : }
787 :
788 733 : 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 733 : location_t location = gimple_location (stmt);
792 733 : 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 150 : else if (wlims.wmaybe_uninit)
807 139 : warned = warning_at (location, OPT_Wmaybe_uninitialized,
808 : "%qE may be used uninitialized", rhs);
809 :
810 544 : 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 1271731 : maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
820 : {
821 1271731 : if (!wlims.wmaybe_uninit)
822 784227 : return;
823 :
824 642228 : unsigned nargs = gimple_call_num_args (stmt);
825 642228 : if (!nargs)
826 : return;
827 :
828 583540 : tree fndecl = gimple_call_fndecl (stmt);
829 1290163 : tree fntype = gimple_call_fntype (stmt);
830 505936 : if (!fntype)
831 : return;
832 :
833 : /* Const function do not read their arguments. */
834 505936 : if (gimple_call_flags (stmt) & ECF_CONST)
835 : return;
836 :
837 494378 : const built_in_function fncode
838 444658 : = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
839 618911 : ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
840 :
841 124533 : 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 487504 : 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 487504 : rdwr_map rdwr_idx;
856 487504 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
857 :
858 487504 : tree argtype;
859 487504 : unsigned argno = 0;
860 487504 : function_args_iterator it;
861 :
862 1655735 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
863 : {
864 1586698 : ++argno;
865 :
866 1586698 : if (argno > nargs)
867 : break;
868 :
869 1168231 : if (!POINTER_TYPE_P (argtype))
870 1167991 : continue;
871 :
872 590015 : tree access_size = NULL_TREE;
873 590015 : const attr_access* access = rdwr_idx.get (argno - 1);
874 590015 : 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 586994 : else if (!TYPE_READONLY (TREE_TYPE (argtype)))
897 354401 : continue;
898 232593 : else if (save_always_executed && fncode != BUILT_IN_LAST)
899 : /* Const-qualified arguments to built-ins imply read access. */
900 20893 : wlims.always_executed = true;
901 : else
902 : /* Const-qualified arguments to ordinary functions imply a likely
903 : (but not definitive) read access. */
904 211700 : wlims.always_executed = false;
905 :
906 : /* Ignore args we are not going to read from. */
907 233325 : if (gimple_call_arg_flags (stmt, argno - 1)
908 233325 : & (EAF_UNUSED | EAF_NO_DIRECT_READ))
909 1995 : continue;
910 :
911 231330 : tree arg = gimple_call_arg (stmt, argno - 1);
912 231330 : if (!POINTER_TYPE_P (TREE_TYPE (arg)))
913 : /* Avoid actual arguments with invalid types. */
914 0 : continue;
915 :
916 231330 : ao_ref ref;
917 231330 : ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
918 231330 : tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
919 231330 : if (!argbase)
920 231090 : 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 487504 : wlims.always_executed = save_always_executed;
975 487504 : }
976 :
977 : /* Warn about an uninitialized PHI argument on the fallthru path to
978 : an always executed block BB. */
979 :
980 : static void
981 411734 : warn_uninit_phi_uses (basic_block bb)
982 : {
983 411734 : edge_iterator ei;
984 411734 : edge e, found = NULL, found_back = NULL;
985 : /* Look for a fallthru and possibly a single backedge. */
986 838609 : FOR_EACH_EDGE (e, ei, bb->preds)
987 : {
988 : /* Ignore backedges. */
989 534298 : if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
990 : {
991 15633 : if (found_back)
992 : {
993 : found = NULL;
994 : break;
995 : }
996 15141 : found_back = e;
997 15141 : continue;
998 : }
999 518665 : if (found)
1000 : {
1001 : found = NULL;
1002 : break;
1003 : }
1004 : found = e;
1005 : }
1006 411734 : if (!found)
1007 107423 : return;
1008 :
1009 304311 : basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1010 338197 : for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
1011 33886 : gsi_next (&si))
1012 : {
1013 33886 : gphi *phi = si.phi ();
1014 33886 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
1015 66052 : if (TREE_CODE (def) != SSA_NAME
1016 29522 : || !SSA_NAME_IS_DEFAULT_DEF (def)
1017 39222 : || virtual_operand_p (def))
1018 32166 : 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 6083 : FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
1026 : {
1027 5467 : use_stmt = USE_STMT (use_p);
1028 5467 : 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 6761 : && (!found_back
1035 1294 : || dominated_by_p (CDI_DOMINATORS, found_back->src,
1036 1294 : gimple_bb (use_stmt))))
1037 : break;
1038 4363 : use_stmt = NULL;
1039 1720 : }
1040 1720 : if (use_stmt)
1041 2208 : warn_uninit (OPT_Wuninitialized, def,
1042 1104 : 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 248888 : warn_uninitialized_vars (bool wmaybe_uninit)
1051 : {
1052 : /* Counters and limits controlling the depth of the warning. */
1053 248888 : wlimits wlims = { };
1054 248888 : wlims.wmaybe_uninit = wmaybe_uninit;
1055 :
1056 248888 : 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 248888 : basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1061 411796 : while (!(bb->flags & ft_reachable))
1062 : {
1063 411734 : bb->flags |= ft_reachable;
1064 411734 : edge e = find_fallthru_edge (bb->succs);
1065 411734 : if (e && e->flags & EDGE_EXECUTABLE)
1066 : {
1067 44841 : bb = e->dest;
1068 44841 : continue;
1069 : }
1070 : /* Find a single executable edge. */
1071 366893 : edge_iterator ei;
1072 366893 : edge ee = NULL;
1073 732144 : FOR_EACH_EDGE (e, ei, bb->succs)
1074 515902 : if (e->flags & EDGE_EXECUTABLE)
1075 : {
1076 515702 : if (!ee)
1077 : ee = e;
1078 : else
1079 : {
1080 : ee = NULL;
1081 : break;
1082 : }
1083 : }
1084 366893 : if (ee)
1085 214400 : bb = ee->dest;
1086 : else
1087 152493 : bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1088 366893 : if (!bb || bb->index == EXIT_BLOCK)
1089 : break;
1090 : }
1091 :
1092 2828813 : FOR_EACH_BB_FN (bb, cfun)
1093 : {
1094 2579925 : wlims.always_executed = (bb->flags & ft_reachable);
1095 2579925 : bb->flags &= ~ft_reachable;
1096 :
1097 2579925 : edge_iterator ei;
1098 2579925 : edge e;
1099 2580720 : FOR_EACH_EDGE (e, ei, bb->preds)
1100 2580331 : 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 2579925 : if (!e)
1105 389 : continue;
1106 :
1107 2579536 : if (wlims.always_executed)
1108 411734 : warn_uninit_phi_uses (bb);
1109 :
1110 2579536 : gimple_stmt_iterator gsi;
1111 21025585 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1112 : {
1113 15866513 : 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 15866513 : if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
1119 8871796 : continue;
1120 :
1121 15862776 : if (is_gimple_debug (stmt))
1122 7625899 : continue;
1123 :
1124 : /* We only do data flow with SSA_NAMEs, so that's all we
1125 : can warn about. */
1126 8236877 : use_operand_p use_p;
1127 8236877 : ssa_op_iter op_iter;
1128 16919031 : 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 8682154 : if (gassign *ass = dyn_cast <gassign *> (stmt))
1133 : {
1134 5725602 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
1135 5725602 : && use_p->use == gimple_assign_rhs1_ptr (ass))
1136 21 : continue;
1137 : }
1138 8682133 : tree use = USE_FROM_PTR (use_p);
1139 8682133 : if (wlims.always_executed)
1140 3543576 : warn_uninit (OPT_Wuninitialized, use,
1141 1771788 : SSA_NAME_VAR (use), stmt);
1142 6910345 : else if (wlims.wmaybe_uninit)
1143 7834886 : warn_uninit (OPT_Wmaybe_uninitialized, use,
1144 3917443 : SSA_NAME_VAR (use), stmt);
1145 : }
1146 :
1147 : /* For limiting the alias walk below we count all
1148 : vdefs in the function. */
1149 15342225 : if (gimple_vdef (stmt))
1150 2074501 : wlims.vdef_cnt++;
1151 :
1152 8236877 : if (gcall *call = dyn_cast <gcall *> (stmt))
1153 1271731 : maybe_warn_pass_by_reference (call, wlims);
1154 6965146 : else if (gimple_assign_load_p (stmt)
1155 6965146 : && gimple_has_location (stmt))
1156 : {
1157 1242626 : tree rhs = gimple_assign_rhs1 (stmt);
1158 1242626 : tree lhs = gimple_assign_lhs (stmt);
1159 :
1160 1242626 : ao_ref ref;
1161 1242626 : ao_ref_init (&ref, rhs);
1162 1242626 : tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
1163 1242626 : if (!var)
1164 1242160 : 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 248888 : }
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 1779 : can_skip_redundant_opnd (tree opnd, gimple *phi)
1184 : {
1185 1779 : tree phi_def = gimple_phi_result (phi);
1186 1779 : gimple *op_def = SSA_NAME_DEF_STMT (opnd);
1187 1779 : 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 448014 : compute_uninit_opnds_pos (gphi *phi)
1208 : {
1209 448014 : unsigned uninit_opnds = 0;
1210 :
1211 448014 : unsigned n = gimple_phi_num_args (phi);
1212 : /* Bail out for phi with too many args. */
1213 448014 : if (n > uninit_analysis::func_t::max_phi_args)
1214 : return 0;
1215 :
1216 1561711 : for (unsigned i = 0; i < n; ++i)
1217 : {
1218 1113866 : tree op = gimple_phi_arg_def (phi, i);
1219 1113866 : if (TREE_CODE (op) == SSA_NAME
1220 912009 : && uninit_undefined_value_p (op)
1221 1115645 : && !can_skip_redundant_opnd (op, phi))
1222 : {
1223 1778 : 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 1715 : MASK_SET_BIT (uninit_opnds, i);
1231 : }
1232 : }
1233 : /* If we have recorded guarded uses of may-uninit values mask those. */
1234 447845 : 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 165 : cand_cmp (const void *a, const void *b, void *data)
1259 : {
1260 165 : int *bb_to_rpo = (int *)data;
1261 165 : const gimple *sa = *(const gimple * const *)a;
1262 165 : const gimple *sb = *(const gimple * const *)b;
1263 165 : if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
1264 : return -1;
1265 84 : else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
1266 45 : 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 366 : 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 366 : uninit_undef_val_t eval;
1283 366 : uninit_analysis def_preds (eval);
1284 :
1285 : /* First process PHIs and record other candidates. */
1286 366 : auto_vec<gimple *, 64> cands;
1287 366 : use_operand_p use_p;
1288 366 : imm_use_iterator iter;
1289 366 : tree phi_result = gimple_phi_result (phi);
1290 1147 : FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1291 : {
1292 781 : gimple *use_stmt = USE_STMT (use_p);
1293 781 : if (is_gimple_debug (use_stmt))
1294 271 : 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 590 : use_operand_p use2_p;
1300 590 : gimple *use2_stmt;
1301 590 : if (gimple_assign_ssa_name_copy_p (use_stmt)
1302 590 : && 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 809 : 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 219 : cands.safe_push (use_stmt);
1347 366 : }
1348 :
1349 : /* Sort candidates after RPO. */
1350 366 : cands.stablesort (cand_cmp, bb_to_rpo);
1351 366 : basic_block use_bb = NULL;
1352 1205 : for (gimple *use_stmt : cands)
1353 : {
1354 : /* We only have to try diagnosing the first use in each block. */
1355 205 : if (gimple_bb (use_stmt) == use_bb)
1356 0 : continue;
1357 :
1358 205 : use_bb = gimple_bb (use_stmt);
1359 205 : if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1360 107 : continue;
1361 :
1362 98 : 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 366 : }
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 366 : warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1382 : {
1383 366 : 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 366 : gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);
1390 :
1391 : /* All uses are properly guarded. */
1392 366 : if (!uninit_use_stmt)
1393 : return;
1394 :
1395 98 : unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1396 98 : tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1397 :
1398 98 : location_t loc = UNKNOWN_LOCATION;
1399 98 : if (gimple_phi_arg_has_location (phi, phiarg_index))
1400 : loc = gimple_phi_arg_location (phi, phiarg_index);
1401 : else
1402 : {
1403 83 : tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1404 83 : if (TREE_CODE (arg_def) == SSA_NAME)
1405 : {
1406 83 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1407 83 : 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 196 : warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1419 98 : SSA_NAME_VAR (uninit_op),
1420 : uninit_use_stmt, loc);
1421 : }
1422 :
1423 : static bool
1424 4066825 : gate_warn_uninitialized (void)
1425 : {
1426 3818490 : 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 588392 : pass_late_warn_uninitialized (gcc::context *ctxt)
1448 1176784 : : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1449 : {}
1450 :
1451 : /* opt_pass methods: */
1452 294196 : opt_pass *clone () final override
1453 : {
1454 294196 : return new pass_late_warn_uninitialized (m_ctxt);
1455 : }
1456 1062796 : 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 80790 : execute_late_warn_uninitialized (function *fun)
1463 : {
1464 80790 : calculate_dominance_info (CDI_DOMINATORS);
1465 80790 : calculate_dominance_info (CDI_POST_DOMINATORS);
1466 :
1467 : /* Mark all edges executable, warn_uninitialized_vars will skip
1468 : unreachable blocks. */
1469 80790 : set_all_edges_as_executable (fun);
1470 80790 : mark_dfs_back_edges (fun);
1471 80790 : int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
1472 80790 : int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
1473 80790 : int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
1474 1643368 : for (int i = 0; i < n; ++i)
1475 1481788 : 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 80790 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1481 :
1482 80790 : timevar_push (TV_TREE_UNINIT);
1483 :
1484 : /* Avoid quadratic behavior when looking up case labels for edges. */
1485 80790 : start_recording_case_labels ();
1486 :
1487 80790 : possibly_undefined_names = new hash_set<tree>;
1488 80790 : 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 1562578 : for (int i = 0; i < n; ++i)
1495 1481788 : for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
1496 2145081 : !gsi_end_p (gsi); gsi_next (&gsi))
1497 : {
1498 663293 : gphi *phi = gsi.phi ();
1499 :
1500 : /* Don't look at virtual operands. */
1501 1326586 : if (virtual_operand_p (gimple_phi_result (phi)))
1502 215810 : continue;
1503 :
1504 447483 : unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1505 447483 : if (MASK_EMPTY (uninit_opnds))
1506 447117 : continue;
1507 :
1508 366 : warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
1509 : }
1510 :
1511 80790 : free (rpo);
1512 80790 : free (bb_to_rpo);
1513 161580 : delete possibly_undefined_names;
1514 80790 : possibly_undefined_names = NULL;
1515 161580 : delete defined_args;
1516 80790 : defined_args = NULL;
1517 80790 : end_recording_case_labels ();
1518 80790 : free_dominance_info (CDI_POST_DOMINATORS);
1519 80790 : timevar_pop (TV_TREE_UNINIT);
1520 80790 : }
1521 :
1522 : unsigned int
1523 80790 : pass_late_warn_uninitialized::execute (function *fun)
1524 : {
1525 80790 : execute_late_warn_uninitialized (fun);
1526 80790 : return 0;
1527 : }
1528 :
1529 : } // anon namespace
1530 :
1531 : gimple_opt_pass *
1532 294196 : make_pass_late_warn_uninitialized (gcc::context *ctxt)
1533 : {
1534 294196 : return new pass_late_warn_uninitialized (ctxt);
1535 : }
1536 :
1537 : static unsigned int
1538 168098 : 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 168098 : calculate_dominance_info (CDI_DOMINATORS);
1546 168098 : 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 168098 : if (!optimize)
1552 19603 : do_rpo_vn (fun, NULL, NULL, false, false, false, VN_NOWALK);
1553 : else
1554 148495 : set_all_edges_as_executable (fun);
1555 :
1556 168098 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1557 :
1558 : /* Post-dominator information cannot be reliably updated. Free it
1559 : after the use. */
1560 :
1561 168098 : free_dominance_info (CDI_POST_DOMINATORS);
1562 168098 : 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 294196 : pass_early_warn_uninitialized (gcc::context *ctxt)
1584 588392 : : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1585 : {}
1586 :
1587 : /* opt_pass methods: */
1588 3004029 : bool gate (function *) final override { return gate_warn_uninitialized (); }
1589 168098 : unsigned int execute (function *fun) final override
1590 : {
1591 168098 : return execute_early_warn_uninitialized (fun);
1592 : }
1593 :
1594 : }; // class pass_early_warn_uninitialized
1595 :
1596 : } // anon namespace
1597 :
1598 : gimple_opt_pass *
1599 294196 : make_pass_early_warn_uninitialized (gcc::context *ctxt)
1600 : {
1601 294196 : return new pass_early_warn_uninitialized (ctxt);
1602 : }
|