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