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 117 : get_mask_first_set_bit (unsigned mask)
67 : {
68 117 : int pos = 0;
69 0 : if (mask == 0)
70 : return -1;
71 :
72 144 : while ((mask & (1 << pos)) == 0)
73 27 : pos++;
74 :
75 : return pos;
76 : }
77 : #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
78 :
79 : /* Return true if T, an SSA_NAME, has an undefined value. */
80 : static bool
81 6494209 : has_undefined_value_p (tree t)
82 : {
83 6494209 : return (ssa_undefined_value_p (t)
84 6494209 : || (possibly_undefined_names
85 885412 : && possibly_undefined_names->contains (t)));
86 : }
87 :
88 : /* Return true if EXPR should suppress either uninitialized warning. */
89 :
90 : static inline bool
91 3076431 : get_no_uninit_warning (tree expr)
92 : {
93 1449250 : return warning_suppressed_p (expr, OPT_Wuninitialized);
94 : }
95 :
96 : /* Suppress both uninitialized warnings for EXPR. */
97 :
98 : static inline void
99 402 : set_no_uninit_warning (tree expr)
100 : {
101 402 : suppress_warning (expr, OPT_Wuninitialized);
102 402 : }
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 887178 : uninit_undefined_value_p (tree t)
109 : {
110 887178 : if (!has_undefined_value_p (t))
111 : return false;
112 2753 : if (!SSA_NAME_VAR (t))
113 : return true;
114 2734 : 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 5607028 : 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 5607028 : if (!has_undefined_value_p (t))
144 5606471 : 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 4512 : if (is_gimple_assign (context)
150 4512 : && 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 4502 : if (is_gimple_assign (context)
178 4502 : && (gimple_assign_rhs_code (context) == REALPART_EXPR
179 3923 : || 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 optimziation, 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 4497 : const char *var_name_str = NULL;
202 4497 : gimple *var_def_stmt = NULL;
203 :
204 4726 : if (!var && !SSA_NAME_VAR (t))
205 : {
206 229 : var_def_stmt = SSA_NAME_DEF_STMT (t);
207 :
208 229 : 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 229 : 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 222 : tree lhs_var = NULL_TREE;
243 :
244 : /* Get the variable name from the 3rd argument of call. */
245 222 : tree var_name = gimple_call_arg (var_def_stmt, 2);
246 222 : var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
247 222 : var_name_str = TREE_STRING_POINTER (var_name);
248 :
249 222 : if (is_gimple_assign (context))
250 : {
251 215 : if (VAR_P (gimple_assign_lhs (context)))
252 : lhs_var = gimple_assign_lhs (context);
253 14 : else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME)
254 14 : lhs_var = SSA_NAME_VAR (gimple_assign_lhs (context));
255 : }
256 214 : if (lhs_var)
257 : {
258 : /* Get the name string for the LHS_VAR.
259 : Refer to routine gimple_add_init_for_auto_var. */
260 214 : if (DECL_NAME (lhs_var)
261 214 : && (strcmp (IDENTIFIER_POINTER (DECL_NAME (lhs_var)),
262 : var_name_str) == 0))
263 : return;
264 7 : 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 4284 : 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 4284 : if (((warning_suppressed_p (context, OPT_Wuninitialized)
282 4281 : || (gimple_assign_single_p (context)
283 3552 : && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
284 8374 : || (var && get_no_uninit_warning (var))
285 6342 : || (var_name_str
286 8 : && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
287 2227 : return;
288 :
289 : /* Use either the location of the read statement or that of the PHI
290 : argument, or that of the uninitialized variable, in that order,
291 : whichever is valid. */
292 2057 : location_t location = UNKNOWN_LOCATION;
293 2057 : if (gimple_has_location (context))
294 2044 : location = gimple_location (context);
295 13 : else if (phi_arg_loc != UNKNOWN_LOCATION)
296 : location = phi_arg_loc;
297 8 : else if (var)
298 8 : location = DECL_SOURCE_LOCATION (var);
299 0 : else if (var_name_str)
300 0 : location = gimple_location (var_def_stmt);
301 :
302 2614 : auto_diagnostic_group d;
303 2057 : gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
304 2057 : if (var)
305 : {
306 2050 : if ((opt == OPT_Wuninitialized
307 1655 : && !warning_at (location, opt, "%qD is used uninitialized", var))
308 2473 : || (opt == OPT_Wmaybe_uninitialized
309 818 : && !warning_at (location, opt, "%qD may be used uninitialized",
310 : var)))
311 1500 : return;
312 : }
313 7 : else if (var_name_str)
314 : {
315 7 : if ((opt == OPT_Wuninitialized
316 2 : && !warning_at (location, opt, "%qs is used uninitialized",
317 : var_name_str))
318 9 : || (opt == OPT_Wmaybe_uninitialized
319 7 : && !warning_at (location, opt, "%qs may be used uninitialized",
320 : var_name_str)))
321 0 : return;
322 : }
323 :
324 : /* Avoid subsequent warnings for reads of the same variable again. */
325 562 : if (var)
326 555 : suppress_warning (var, opt);
327 7 : else if (var_name_str)
328 7 : suppress_warning (var_def_stmt, opt);
329 :
330 : /* Issue a note pointing to the read variable unless the warning
331 : is at the same location. */
332 562 : location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
333 562 : : gimple_location (var_def_stmt);
334 562 : if (location == var_loc)
335 : return;
336 :
337 557 : if (var)
338 550 : inform (var_loc, "%qD was declared here", var);
339 7 : else if (var_name_str)
340 7 : 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 3022943 : builtin_call_nomodifying_p (gimple *stmt)
355 : {
356 3022943 : if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
357 : return false;
358 :
359 358914 : tree fndecl = gimple_call_fndecl (stmt);
360 358914 : if (!fndecl)
361 : return false;
362 :
363 358914 : tree fntype = TREE_TYPE (fndecl);
364 358914 : 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 358914 : unsigned argno = 0;
370 358914 : tree argtype;
371 358914 : function_args_iterator it;
372 635650 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
373 : {
374 440069 : if (VOID_TYPE_P (argtype))
375 : return true;
376 :
377 396783 : ++argno;
378 :
379 396783 : if (!POINTER_TYPE_P (argtype))
380 49092 : continue;
381 :
382 347691 : if (TYPE_READONLY (TREE_TYPE (argtype)))
383 227644 : 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 195581 : unsigned nargs = gimple_call_num_args (stmt);
391 195581 : 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 202051 : for (; argno < nargs; ++argno)
398 : {
399 196830 : tree arg = gimple_call_arg (stmt, argno);
400 196830 : argtype = TREE_TYPE (arg);
401 196830 : if (!POINTER_TYPE_P (argtype))
402 6068 : continue;
403 :
404 190762 : if (TYPE_READONLY (TREE_TYPE (argtype)))
405 402 : 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 174100 : maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
418 : {
419 174100 : if (!fndecl)
420 0 : return;
421 :
422 174100 : if (get_no_uninit_warning (arg))
423 : return;
424 :
425 174100 : tree fntype = TREE_TYPE (fndecl);
426 174100 : if (!fntype)
427 : return;
428 :
429 : /* Initialize a map of attribute access specifications for arguments
430 : to the function call. */
431 174100 : rdwr_map rdwr_idx;
432 174100 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
433 :
434 174100 : unsigned argno = 0;
435 174100 : tree parms = DECL_ARGUMENTS (fndecl);
436 314116 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
437 : {
438 313626 : if (parm != arg)
439 140016 : continue;
440 :
441 174082 : const attr_access* access = rdwr_idx.get (argno);
442 174082 : 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 174100 : }
468 :
469 : /* Callback for walk_aliased_vdefs. */
470 :
471 : static bool
472 3160361 : check_defs (ao_ref *ref, tree vdef, void *data_)
473 : {
474 3160361 : check_defs_data *data = (check_defs_data *)data_;
475 3160361 : 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 3160361 : 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 3160121 : if (is_gimple_assign (def_stmt)
488 3160121 : && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
489 : {
490 1366100 : tree tmp_var = gimple_assign_rhs1 (def_stmt);
491 1366100 : 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 3160074 : if (is_gimple_call (def_stmt))
498 : {
499 : /* The ASAN_MARK intrinsic doesn't modify the variable. */
500 1401797 : if (gimple_call_internal_p (def_stmt)
501 1401797 : && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
502 : return false;
503 :
504 1400051 : 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 1228150 : if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
510 : {
511 360208 : built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
512 360208 : if (fncode > BEGIN_SANITIZER_BUILTINS
513 360208 : && fncode < END_SANITIZER_BUILTINS)
514 : return false;
515 : }
516 : }
517 : }
518 :
519 : /* End of VLA scope is not a kill. */
520 3158214 : 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 3158138 : if (gimple_clobber_p (def_stmt))
525 : {
526 135195 : if (stmt_kills_ref_p (def_stmt, ref))
527 : return true;
528 : return false;
529 : }
530 :
531 3022943 : if (builtin_call_nomodifying_p (def_stmt))
532 : return false;
533 :
534 : /* Found a may-def on this path. */
535 2974436 : data->found_may_defs = true;
536 2974436 : 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 1445763 : maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
562 : wlimits &wlims)
563 : {
564 1445763 : bool has_bit_insert = false;
565 1445763 : use_operand_p luse_p;
566 1445763 : imm_use_iterator liter;
567 :
568 1445763 : 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 1445073 : tree base = ao_ref_base (&ref);
574 1445073 : if ((VAR_P (base)
575 580213 : && DECL_HARD_REGISTER (base))
576 2890140 : || get_no_uninit_warning (base))
577 4076 : return NULL_TREE;
578 :
579 : /* Do not warn if the access is zero size or if it's fully outside
580 : the object. */
581 1440997 : poly_int64 decl_size;
582 1440997 : if (known_size_p (ref.size)
583 1216050 : && known_eq (ref.max_size, ref.size)
584 2522906 : && (known_eq (ref.size, 0)
585 1081895 : || known_le (ref.offset + ref.size, 0)))
586 : return NULL_TREE;
587 :
588 1440933 : if (DECL_P (base)
589 596241 : && known_ge (ref.offset, 0)
590 596234 : && DECL_SIZE (base)
591 579505 : && poly_int_tree_p (DECL_SIZE (base), &decl_size)
592 2020437 : && 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 1440426 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
598 4143324 : FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
599 : {
600 1734902 : 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 2573916 : if (gassign *ass = dyn_cast <gassign *> (use_stmt))
604 : {
605 839016 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
606 839016 : && luse_p->use == gimple_assign_rhs1_ptr (ass))
607 : {
608 : has_bit_insert = true;
609 : break;
610 : }
611 : }
612 1204212 : }
613 :
614 1204212 : 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 1440424 : if (wlims.oracle_cnt > 128 * 128
621 36673 : && wlims.oracle_cnt > wlims.vdef_cnt * 2)
622 36673 : wlims.limit = 32;
623 :
624 1440424 : check_defs_data data;
625 1440424 : bool fentry_reached = false;
626 1440424 : data.found_may_defs = false;
627 2885484 : tree use = gimple_vuse (stmt);
628 1440424 : if (!use)
629 : return NULL_TREE;
630 1440166 : int res = walk_aliased_vdefs (&ref, use,
631 : check_defs, &data, NULL,
632 : &fentry_reached, wlims.limit);
633 1440166 : if (res == -1)
634 : {
635 33587 : wlims.oracle_cnt += wlims.limit;
636 33587 : return NULL_TREE;
637 : }
638 :
639 1406579 : wlims.oracle_cnt += res;
640 1406579 : if (data.found_may_defs)
641 : return NULL_TREE;
642 :
643 477035 : bool found_alloc = false;
644 477035 : bool found_clobber_deref_this = false;
645 :
646 477035 : if (fentry_reached)
647 : {
648 477004 : if (TREE_CODE (base) == MEM_REF)
649 208415 : 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 486972 : while (TREE_CODE (base) == SSA_NAME)
656 : {
657 216640 : gimple *def_stmt = SSA_NAME_DEF_STMT (base);
658 :
659 216640 : if (is_gimple_call (def_stmt)
660 216640 : && gimple_call_builtin_p (def_stmt))
661 : {
662 : /* Detect uses of uninitialized alloca/VLAs. */
663 142 : tree fndecl = gimple_call_fndecl (def_stmt);
664 142 : const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
665 142 : if (fncode == BUILT_IN_ALLOCA
666 142 : || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
667 69 : || 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 216498 : if (SSA_NAME_IS_DEFAULT_DEF (base)
680 173351 : && POINTER_TYPE_P (TREE_TYPE (base))
681 173351 : && SSA_NAME_VAR (base)
682 173351 : && TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL
683 389848 : && lookup_attribute ("clobber *this",
684 173350 : DECL_ATTRIBUTES (SSA_NAME_VAR (base))))
685 : {
686 : found_clobber_deref_this = true;
687 : break;
688 : }
689 :
690 216481 : if (!is_gimple_assign (def_stmt))
691 : break;
692 :
693 36241 : tree_code code = gimple_assign_rhs_code (def_stmt);
694 36241 : if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
695 : break;
696 :
697 9968 : base = gimple_assign_rhs1 (def_stmt);
698 9968 : if (TREE_CODE (base) == ADDR_EXPR)
699 1397 : base = TREE_OPERAND (base, 0);
700 :
701 9968 : if (DECL_P (base)
702 8972 : || TREE_CODE (base) == COMPONENT_REF)
703 1160 : rhs = base;
704 :
705 9968 : if (TREE_CODE (base) == MEM_REF)
706 15 : base = TREE_OPERAND (base, 0);
707 :
708 9968 : if (tree ba = get_base_address (base))
709 9968 : 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 477004 : if (DECL_P (base)
716 136736 : && EXPR_P (rhs)
717 62449 : && TREE_CODE (rhs) != COMPONENT_REF)
718 477004 : 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 477035 : if ((!found_alloc && !found_clobber_deref_this) && fentry_reached)
725 : {
726 476874 : if (TREE_CODE (base) == SSA_NAME)
727 : {
728 206542 : tree var = SSA_NAME_VAR (base);
729 184626 : if (var && TREE_CODE (var) == PARM_DECL)
730 : {
731 174100 : maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
732 174100 : return NULL_TREE;
733 : }
734 : }
735 :
736 302774 : if (!VAR_P (base)
737 302774 : || 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 1032 : if (TREE_CODE (rhs) == ADDR_EXPR)
746 0 : rhs = TREE_OPERAND (rhs, 0);
747 :
748 : /* Check again since RHS may have changed above. */
749 1032 : 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 1026 : tree rhstype = TREE_TYPE (rhs);
756 1026 : if (POINTER_TYPE_P (rhstype))
757 149 : rhstype = TREE_TYPE (rhstype);
758 1026 : if (is_empty_type (rhstype))
759 : return NULL_TREE;
760 :
761 731 : bool warned = false;
762 : /* We didn't find any may-defs so on all paths either
763 : reached function entry or a killing clobber. */
764 731 : location_t location = gimple_location (stmt);
765 731 : if (wlims.always_executed)
766 : {
767 580 : if (warning_at (location, OPT_Wuninitialized,
768 : "%qE is used uninitialized", rhs))
769 : {
770 : /* ??? This is only effective for decls as in
771 : gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
772 : uses or accesses by functions as it may hide important
773 : locations. */
774 580 : if (lhs)
775 402 : set_no_uninit_warning (rhs);
776 : warned = true;
777 : }
778 : }
779 151 : else if (wlims.wmaybe_uninit)
780 139 : warned = warning_at (location, OPT_Wmaybe_uninitialized,
781 : "%qE may be used uninitialized", rhs);
782 :
783 139 : return warned ? base : NULL_TREE;
784 : }
785 :
786 :
787 : /* Diagnose passing addresses of uninitialized objects to either const
788 : pointer arguments to functions, or to functions declared with attribute
789 : access implying read access to those objects. */
790 :
791 : static void
792 1244399 : maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
793 : {
794 1244399 : if (!wlims.wmaybe_uninit)
795 765485 : return;
796 :
797 630766 : unsigned nargs = gimple_call_num_args (stmt);
798 630766 : if (!nargs)
799 : return;
800 :
801 574215 : tree fndecl = gimple_call_fndecl (stmt);
802 1261689 : tree fntype = gimple_call_fntype (stmt);
803 496204 : if (!fntype)
804 : return;
805 :
806 : /* Const function do not read their arguments. */
807 496204 : if (gimple_call_flags (stmt) & ECF_CONST)
808 : return;
809 :
810 485350 : const built_in_function fncode
811 436194 : = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
812 606045 : ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
813 :
814 120695 : if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
815 : /* Avoid diagnosing calls to raw memory functions (this is overly
816 : permissive; consider tightening it up). */
817 : return;
818 :
819 : /* Save the current warning setting and replace it either a "maybe"
820 : when passing addresses of uninitialized variables to const-qualified
821 : pointers or arguments declared with attribute read_write, or with
822 : a "certain" when passing them to arguments declared with attribute
823 : read_only. */
824 478914 : const bool save_always_executed = wlims.always_executed;
825 :
826 : /* Initialize a map of attribute access specifications for arguments
827 : to the function call. */
828 478914 : rdwr_map rdwr_idx;
829 478914 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
830 :
831 478914 : tree argtype;
832 478914 : unsigned argno = 0;
833 478914 : function_args_iterator it;
834 :
835 1629188 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
836 : {
837 1562831 : ++argno;
838 :
839 1562831 : if (argno > nargs)
840 : break;
841 :
842 1150274 : if (!POINTER_TYPE_P (argtype))
843 1150034 : continue;
844 :
845 578613 : tree access_size = NULL_TREE;
846 578613 : const attr_access* access = rdwr_idx.get (argno - 1);
847 578613 : if (access)
848 : {
849 2991 : if (access->mode == access_none
850 2828 : || access->mode == access_write_only)
851 395 : continue;
852 :
853 4468 : if (access->mode == access_deferred
854 2596 : && !TYPE_READONLY (TREE_TYPE (argtype)))
855 1872 : continue;
856 :
857 724 : if (save_always_executed && access->mode == access_read_only)
858 : /* Attribute read_only arguments imply read access. */
859 236 : wlims.always_executed = true;
860 : else
861 : /* Attribute read_write arguments are documented as requiring
862 : initialized objects but it's expected that aggregates may
863 : be only partially initialized regardless. */
864 488 : wlims.always_executed = false;
865 :
866 724 : if (access->sizarg < nargs)
867 217 : access_size = gimple_call_arg (stmt, access->sizarg);
868 : }
869 575622 : else if (!TYPE_READONLY (TREE_TYPE (argtype)))
870 348455 : continue;
871 227167 : else if (save_always_executed && fncode != BUILT_IN_LAST)
872 : /* Const-qualified arguments to built-ins imply read access. */
873 20902 : wlims.always_executed = true;
874 : else
875 : /* Const-qualified arguments to ordinary functions imply a likely
876 : (but not definitive) read access. */
877 206265 : wlims.always_executed = false;
878 :
879 : /* Ignore args we are not going to read from. */
880 227891 : if (gimple_call_arg_flags (stmt, argno - 1)
881 227891 : & (EAF_UNUSED | EAF_NO_DIRECT_READ))
882 867 : continue;
883 :
884 227024 : tree arg = gimple_call_arg (stmt, argno - 1);
885 227024 : if (!POINTER_TYPE_P (TREE_TYPE (arg)))
886 : /* Avoid actual arguments with invalid types. */
887 0 : continue;
888 :
889 227024 : ao_ref ref;
890 227024 : ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
891 227024 : tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
892 227024 : if (!argbase)
893 226784 : continue;
894 :
895 240 : if (access && access->mode != access_deferred)
896 : {
897 48 : const char* const access_str =
898 48 : TREE_STRING_POINTER (access->to_external_string ());
899 :
900 48 : auto_urlify_attributes sentinel;
901 48 : if (fndecl)
902 : {
903 48 : location_t loc = DECL_SOURCE_LOCATION (fndecl);
904 48 : inform (loc, "in a call to %qD declared with "
905 : "attribute %qs here", fndecl, access_str);
906 : }
907 : else
908 : {
909 : /* Handle calls through function pointers. */
910 0 : location_t loc = gimple_location (stmt);
911 0 : inform (loc, "in a call to %qT declared with "
912 : "attribute %qs", fntype, access_str);
913 : }
914 48 : }
915 : else
916 : {
917 : /* For a declaration with no relevant attribute access create
918 : a dummy object and use the formatting function to avoid
919 : having to complicate things here. */
920 192 : attr_access ptr_access = { };
921 192 : if (!access)
922 173 : access = &ptr_access;
923 192 : const std::string argtypestr = access->array_as_string (argtype);
924 192 : if (fndecl)
925 : {
926 192 : location_t loc (DECL_SOURCE_LOCATION (fndecl));
927 192 : inform (loc, "by argument %u of type %s to %qD "
928 : "declared here",
929 : argno, argtypestr.c_str (), fndecl);
930 : }
931 : else
932 : {
933 : /* Handle calls through function pointers. */
934 0 : location_t loc (gimple_location (stmt));
935 0 : inform (loc, "by argument %u of type %s to %qT",
936 : argno, argtypestr.c_str (), fntype);
937 : }
938 192 : }
939 :
940 240 : if (DECL_P (argbase))
941 : {
942 219 : location_t loc = DECL_SOURCE_LOCATION (argbase);
943 219 : inform (loc, "%qD declared here", argbase);
944 : }
945 : }
946 :
947 478914 : wlims.always_executed = save_always_executed;
948 478914 : }
949 :
950 : /* Warn about an uninitialized PHI argument on the fallthru path to
951 : an always executed block BB. */
952 :
953 : static void
954 403534 : warn_uninit_phi_uses (basic_block bb)
955 : {
956 403534 : edge_iterator ei;
957 403534 : edge e, found = NULL, found_back = NULL;
958 : /* Look for a fallthru and possibly a single backedge. */
959 821739 : FOR_EACH_EDGE (e, ei, bb->preds)
960 : {
961 : /* Ignore backedges. */
962 524444 : if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
963 : {
964 15153 : if (found_back)
965 : {
966 : found = NULL;
967 : break;
968 : }
969 14671 : found_back = e;
970 14671 : continue;
971 : }
972 509291 : if (found)
973 : {
974 : found = NULL;
975 : break;
976 : }
977 : found = e;
978 : }
979 403534 : if (!found)
980 106239 : return;
981 :
982 297295 : basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
983 329659 : for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
984 32364 : gsi_next (&si))
985 : {
986 32364 : gphi *phi = si.phi ();
987 32364 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
988 63110 : if (TREE_CODE (def) != SSA_NAME
989 28095 : || !SSA_NAME_IS_DEFAULT_DEF (def)
990 37518 : || virtual_operand_p (def))
991 30746 : continue;
992 : /* If there's a default def on the fallthru edge PHI
993 : value and there's a use that post-dominates entry
994 : then that use is uninitialized and we can warn. */
995 1618 : imm_use_iterator iter;
996 1618 : use_operand_p use_p;
997 1618 : gimple *use_stmt = NULL;
998 7278 : FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
999 : {
1000 5102 : use_stmt = USE_STMT (use_p);
1001 5102 : if (gimple_location (use_stmt) != UNKNOWN_LOCATION
1002 4257 : && dominated_by_p (CDI_POST_DOMINATORS, succ,
1003 4257 : gimple_bb (use_stmt))
1004 : /* If we found a non-fallthru edge make sure the
1005 : use is inside the loop, otherwise the backedge
1006 : can serve as initialization. */
1007 6330 : && (!found_back
1008 1228 : || dominated_by_p (CDI_DOMINATORS, found_back->src,
1009 1228 : gimple_bb (use_stmt))))
1010 : break;
1011 4042 : use_stmt = NULL;
1012 1618 : }
1013 1618 : if (use_stmt)
1014 2120 : warn_uninit (OPT_Wuninitialized, def,
1015 1060 : SSA_NAME_VAR (def), use_stmt);
1016 : }
1017 : }
1018 :
1019 : /* Issue warnings about reads of uninitialized variables. WMAYBE_UNINIT
1020 : is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized. */
1021 :
1022 : static void
1023 243306 : warn_uninitialized_vars (bool wmaybe_uninit)
1024 : {
1025 : /* Counters and limits controlling the depth of the warning. */
1026 243306 : wlimits wlims = { };
1027 243306 : wlims.wmaybe_uninit = wmaybe_uninit;
1028 :
1029 243306 : auto_bb_flag ft_reachable (cfun);
1030 :
1031 : /* Mark blocks that are always executed when we ignore provably
1032 : not executed and EH and abnormal edges. */
1033 243306 : basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1034 403597 : while (!(bb->flags & ft_reachable))
1035 : {
1036 403534 : bb->flags |= ft_reachable;
1037 403534 : edge e = find_fallthru_edge (bb->succs);
1038 403534 : if (e && e->flags & EDGE_EXECUTABLE)
1039 : {
1040 43676 : bb = e->dest;
1041 43676 : continue;
1042 : }
1043 : /* Find a single executable edge. */
1044 359858 : edge_iterator ei;
1045 359858 : edge ee = NULL;
1046 718196 : FOR_EACH_EDGE (e, ei, bb->succs)
1047 506303 : if (e->flags & EDGE_EXECUTABLE)
1048 : {
1049 506100 : if (!ee)
1050 : ee = e;
1051 : else
1052 : {
1053 : ee = NULL;
1054 : break;
1055 : }
1056 : }
1057 359858 : if (ee)
1058 210170 : bb = ee->dest;
1059 : else
1060 149688 : bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1061 359858 : if (!bb || bb->index == EXIT_BLOCK)
1062 : break;
1063 : }
1064 :
1065 2767928 : FOR_EACH_BB_FN (bb, cfun)
1066 : {
1067 2524622 : wlims.always_executed = (bb->flags & ft_reachable);
1068 2524622 : bb->flags &= ~ft_reachable;
1069 :
1070 2524622 : edge_iterator ei;
1071 2524622 : edge e;
1072 2525429 : FOR_EACH_EDGE (e, ei, bb->preds)
1073 2525034 : if (e->flags & EDGE_EXECUTABLE)
1074 : break;
1075 : /* Skip unreachable blocks. For early analysis we use VN to
1076 : determine edge executability when wmaybe_uninit. */
1077 2524622 : if (!e)
1078 395 : continue;
1079 :
1080 2524227 : if (wlims.always_executed)
1081 403534 : warn_uninit_phi_uses (bb);
1082 :
1083 2524227 : gimple_stmt_iterator gsi;
1084 20579691 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1085 : {
1086 15531237 : gimple *stmt = gsi_stmt (gsi);
1087 :
1088 : /* The call is an artificial use, will not provide meaningful
1089 : error message. If the result of the call is used somewhere
1090 : else, we warn there instead. */
1091 15531237 : if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
1092 8641702 : continue;
1093 :
1094 15528569 : if (is_gimple_debug (stmt))
1095 7420758 : continue;
1096 :
1097 : /* We only do data flow with SSA_NAMEs, so that's all we
1098 : can warn about. */
1099 8107811 : use_operand_p use_p;
1100 8107811 : ssa_op_iter op_iter;
1101 16668845 : FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
1102 : {
1103 : /* BIT_INSERT_EXPR first operand should not be considered
1104 : a use for the purpose of uninit warnings. */
1105 8561034 : if (gassign *ass = dyn_cast <gassign *> (stmt))
1106 : {
1107 5651706 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
1108 5651706 : && use_p->use == gimple_assign_rhs1_ptr (ass))
1109 21 : continue;
1110 : }
1111 8561013 : tree use = USE_FROM_PTR (use_p);
1112 8561013 : if (wlims.always_executed)
1113 3483032 : warn_uninit (OPT_Wuninitialized, use,
1114 1741516 : SSA_NAME_VAR (use), stmt);
1115 6819497 : else if (wlims.wmaybe_uninit)
1116 7728700 : warn_uninit (OPT_Wmaybe_uninitialized, use,
1117 3864350 : SSA_NAME_VAR (use), stmt);
1118 : }
1119 :
1120 : /* For limiting the alias walk below we count all
1121 : vdefs in the function. */
1122 15112195 : if (gimple_vdef (stmt))
1123 2026533 : wlims.vdef_cnt++;
1124 :
1125 8107811 : if (gcall *call = dyn_cast <gcall *> (stmt))
1126 1244399 : maybe_warn_pass_by_reference (call, wlims);
1127 6863412 : else if (gimple_assign_load_p (stmt)
1128 6863412 : && gimple_has_location (stmt))
1129 : {
1130 1218739 : tree rhs = gimple_assign_rhs1 (stmt);
1131 1218739 : tree lhs = gimple_assign_lhs (stmt);
1132 :
1133 1218739 : ao_ref ref;
1134 1218739 : ao_ref_init (&ref, rhs);
1135 1218739 : tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
1136 1218739 : if (!var)
1137 1218276 : continue;
1138 :
1139 463 : if (DECL_P (var))
1140 : {
1141 341 : location_t loc = DECL_SOURCE_LOCATION (var);
1142 341 : inform (loc, "%qD declared here", var);
1143 : }
1144 : }
1145 : }
1146 : }
1147 243306 : }
1148 :
1149 : /* Checks if the operand OPND of PHI is defined by
1150 : another phi with one operand defined by this PHI,
1151 : but the rest operands are all defined. If yes,
1152 : returns true to skip this operand as being
1153 : redundant. Can be enhanced to be more general. */
1154 :
1155 : static bool
1156 1775 : can_skip_redundant_opnd (tree opnd, gimple *phi)
1157 : {
1158 1775 : tree phi_def = gimple_phi_result (phi);
1159 1775 : gimple *op_def = SSA_NAME_DEF_STMT (opnd);
1160 1775 : if (gimple_code (op_def) != GIMPLE_PHI)
1161 : return false;
1162 :
1163 717 : unsigned n = gimple_phi_num_args (op_def);
1164 899 : for (unsigned i = 0; i < n; ++i)
1165 : {
1166 898 : tree op = gimple_phi_arg_def (op_def, i);
1167 898 : if (TREE_CODE (op) != SSA_NAME)
1168 0 : continue;
1169 898 : if (op != phi_def && uninit_undefined_value_p (op))
1170 : return false;
1171 : }
1172 :
1173 : return true;
1174 : }
1175 :
1176 : /* Return a bitset holding the positions of arguments in PHI with empty
1177 : (or possibly empty) definitions. */
1178 :
1179 : static unsigned
1180 438161 : compute_uninit_opnds_pos (gphi *phi)
1181 : {
1182 438161 : unsigned uninit_opnds = 0;
1183 :
1184 438161 : unsigned n = gimple_phi_num_args (phi);
1185 : /* Bail out for phi with too many args. */
1186 438161 : if (n > uninit_analysis::func_t::max_phi_args)
1187 : return 0;
1188 :
1189 1520010 : for (unsigned i = 0; i < n; ++i)
1190 : {
1191 1082030 : tree op = gimple_phi_arg_def (phi, i);
1192 1082030 : if (TREE_CODE (op) == SSA_NAME
1193 886355 : && uninit_undefined_value_p (op)
1194 1083805 : && !can_skip_redundant_opnd (op, phi))
1195 : {
1196 1774 : if (cfun->has_nonlocal_label || cfun->calls_setjmp)
1197 : {
1198 : /* Ignore SSA_NAMEs that appear on abnormal edges
1199 : somewhere. */
1200 91 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
1201 63 : continue;
1202 : }
1203 1711 : MASK_SET_BIT (uninit_opnds, i);
1204 : }
1205 : }
1206 : /* If we have recorded guarded uses of may-uninit values mask those. */
1207 437980 : if (auto *def_mask = defined_args->get (phi))
1208 63 : uninit_opnds &= ~*def_mask;
1209 : return uninit_opnds;
1210 : }
1211 :
1212 : /* Function object type used to determine whether an expression
1213 : is of interest to the predicate analyzer. */
1214 :
1215 : struct uninit_undef_val_t: public uninit_analysis::func_t
1216 : {
1217 : virtual unsigned phi_arg_set (gphi *) override;
1218 : };
1219 :
1220 : /* Return a bitset of PHI arguments of interest. */
1221 :
1222 : unsigned
1223 517 : uninit_undef_val_t::phi_arg_set (gphi *phi)
1224 : {
1225 517 : return compute_uninit_opnds_pos (phi);
1226 : }
1227 :
1228 : /* sort helper for find_uninit_use. */
1229 :
1230 : static int
1231 183 : cand_cmp (const void *a, const void *b, void *data)
1232 : {
1233 183 : int *bb_to_rpo = (int *)data;
1234 183 : const gimple *sa = *(const gimple * const *)a;
1235 183 : const gimple *sb = *(const gimple * const *)b;
1236 183 : if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
1237 : return -1;
1238 92 : else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
1239 50 : return 1;
1240 : return 0;
1241 : }
1242 :
1243 : /* Searches through all uses of a potentially
1244 : uninitialized variable defined by PHI and returns a use
1245 : statement if the use is not properly guarded. It returns
1246 : NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
1247 : holding the position(s) of uninit PHI operands. */
1248 :
1249 : static gimple *
1250 368 : find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1251 : {
1252 : /* The Boolean predicate guarding the PHI definition. Initialized
1253 : lazily from PHI in the first call to is_use_guarded() and cached
1254 : for subsequent iterations. */
1255 368 : uninit_undef_val_t eval;
1256 368 : uninit_analysis def_preds (eval);
1257 :
1258 : /* First process PHIs and record other candidates. */
1259 368 : auto_vec<gimple *, 64> cands;
1260 368 : use_operand_p use_p;
1261 368 : imm_use_iterator iter;
1262 368 : tree phi_result = gimple_phi_result (phi);
1263 1524 : FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1264 : {
1265 788 : gimple *use_stmt = USE_STMT (use_p);
1266 788 : if (is_gimple_debug (use_stmt))
1267 273 : continue;
1268 :
1269 : /* Look through a single level of SSA name copies. This is
1270 : important for copies involving abnormals which we can't always
1271 : proapgate out but which result in spurious unguarded uses. */
1272 595 : use_operand_p use2_p;
1273 595 : gimple *use2_stmt;
1274 595 : if (gimple_assign_ssa_name_copy_p (use_stmt)
1275 595 : && single_imm_use (gimple_assign_lhs (use_stmt), &use2_p, &use2_stmt))
1276 : {
1277 8 : use_p = use2_p;
1278 8 : use_stmt = use2_stmt;
1279 : }
1280 :
1281 816 : if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1282 : {
1283 374 : unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p);
1284 374 : edge e = gimple_phi_arg_edge (use_phi, idx);
1285 : /* Do not look for uses in the next iteration of a loop, predicate
1286 : analysis will not use the appropriate predicates to prove
1287 : reachability. */
1288 374 : if (e->flags & EDGE_DFS_BACK)
1289 80 : continue;
1290 :
1291 344 : basic_block use_bb = e->src;
1292 344 : if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1293 : {
1294 : /* For a guarded use in a PHI record the PHI argument as
1295 : initialized. */
1296 50 : if (idx < uninit_analysis::func_t::max_phi_args)
1297 : {
1298 50 : bool existed_p;
1299 50 : auto &def_mask
1300 50 : = defined_args->get_or_insert (use_phi, &existed_p);
1301 50 : if (!existed_p)
1302 50 : def_mask = 0;
1303 50 : MASK_SET_BIT (def_mask, idx);
1304 : }
1305 50 : continue;
1306 50 : }
1307 :
1308 294 : if (dump_file && (dump_flags & TDF_DETAILS))
1309 : {
1310 0 : fprintf (dump_file, "Found unguarded use on edge %u -> %u: ",
1311 0 : e->src->index, e->dest->index);
1312 0 : print_gimple_stmt (dump_file, use_stmt, 0);
1313 : }
1314 : /* Found a phi use that is not guarded, mark the use as
1315 : possibly undefined. */
1316 294 : possibly_undefined_names->add (USE_FROM_PTR (use_p));
1317 : }
1318 : else
1319 221 : cands.safe_push (use_stmt);
1320 368 : }
1321 :
1322 : /* Sort candidates after RPO. */
1323 368 : cands.stablesort (cand_cmp, bb_to_rpo);
1324 368 : basic_block use_bb = NULL;
1325 1211 : for (gimple *use_stmt : cands)
1326 : {
1327 : /* We only have to try diagnosing the first use in each block. */
1328 209 : if (gimple_bb (use_stmt) == use_bb)
1329 5 : continue;
1330 :
1331 204 : use_bb = gimple_bb (use_stmt);
1332 204 : if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1333 102 : continue;
1334 :
1335 102 : if (dump_file && (dump_flags & TDF_DETAILS))
1336 : {
1337 0 : fprintf (dump_file, "Found unguarded use in bb %u: ",
1338 : use_bb->index);
1339 0 : print_gimple_stmt (dump_file, use_stmt, 0);
1340 : }
1341 : return use_stmt;
1342 : }
1343 :
1344 : return NULL;
1345 368 : }
1346 :
1347 : /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1348 : and gives warning if there exists a runtime path from the entry to a
1349 : use of the PHI def that does not contain a definition. In other words,
1350 : the warning is on the real use. The more dead paths that can be pruned
1351 : by the compiler, the fewer false positives the warning is. */
1352 :
1353 : static void
1354 368 : warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1355 : {
1356 368 : if (dump_file && (dump_flags & TDF_DETAILS))
1357 : {
1358 0 : fprintf (dump_file, "Examining phi: ");
1359 0 : print_gimple_stmt (dump_file, phi, 0);
1360 : }
1361 :
1362 368 : gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);
1363 :
1364 : /* All uses are properly guarded. */
1365 368 : if (!uninit_use_stmt)
1366 : return;
1367 :
1368 102 : unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1369 102 : tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1370 :
1371 102 : location_t loc = UNKNOWN_LOCATION;
1372 102 : if (gimple_phi_arg_has_location (phi, phiarg_index))
1373 : loc = gimple_phi_arg_location (phi, phiarg_index);
1374 : else
1375 : {
1376 87 : tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1377 87 : if (TREE_CODE (arg_def) == SSA_NAME)
1378 : {
1379 87 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1380 87 : if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1381 : {
1382 15 : unsigned uop = compute_uninit_opnds_pos (arg_phi);
1383 15 : unsigned idx = MASK_FIRST_SET_BIT (uop);
1384 15 : if (idx < gimple_phi_num_args (arg_phi)
1385 15 : && gimple_phi_arg_has_location (arg_phi, idx))
1386 : loc = gimple_phi_arg_location (arg_phi, idx);
1387 : }
1388 : }
1389 : }
1390 :
1391 204 : warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1392 102 : SSA_NAME_VAR (uninit_op),
1393 : uninit_use_stmt, loc);
1394 : }
1395 :
1396 : static bool
1397 3892803 : gate_warn_uninitialized (void)
1398 : {
1399 3650050 : return warn_uninitialized || warn_maybe_uninitialized;
1400 : }
1401 :
1402 : namespace {
1403 :
1404 : const pass_data pass_data_late_warn_uninitialized =
1405 : {
1406 : GIMPLE_PASS, /* type */
1407 : "uninit", /* name */
1408 : OPTGROUP_NONE, /* optinfo_flags */
1409 : TV_NONE, /* tv_id */
1410 : PROP_ssa, /* properties_required */
1411 : 0, /* properties_provided */
1412 : 0, /* properties_destroyed */
1413 : 0, /* todo_flags_start */
1414 : 0, /* todo_flags_finish */
1415 : };
1416 :
1417 : class pass_late_warn_uninitialized : public gimple_opt_pass
1418 : {
1419 : public:
1420 571444 : pass_late_warn_uninitialized (gcc::context *ctxt)
1421 1142888 : : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1422 : {}
1423 :
1424 : /* opt_pass methods: */
1425 285722 : opt_pass *clone () final override
1426 : {
1427 285722 : return new pass_late_warn_uninitialized (m_ctxt);
1428 : }
1429 1044139 : bool gate (function *) final override { return gate_warn_uninitialized (); }
1430 : unsigned int execute (function *) final override;
1431 :
1432 : }; // class pass_late_warn_uninitialized
1433 :
1434 : static void
1435 79696 : execute_late_warn_uninitialized (function *fun)
1436 : {
1437 79696 : calculate_dominance_info (CDI_DOMINATORS);
1438 79696 : calculate_dominance_info (CDI_POST_DOMINATORS);
1439 :
1440 : /* Mark all edges executable, warn_uninitialized_vars will skip
1441 : unreachable blocks. */
1442 79696 : set_all_edges_as_executable (fun);
1443 79696 : mark_dfs_back_edges (fun);
1444 79696 : int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
1445 79696 : int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
1446 79696 : int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
1447 1534151 : for (int i = 0; i < n; ++i)
1448 1454455 : bb_to_rpo[rpo[i]] = i;
1449 :
1450 : /* Re-do the plain uninitialized variable check, as optimization may have
1451 : straightened control flow. Do this first so that we don't accidentally
1452 : get a "may be" warning when we'd have seen an "is" warning later. */
1453 79696 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1454 :
1455 79696 : timevar_push (TV_TREE_UNINIT);
1456 :
1457 : /* Avoid quadratic beahvior when looking up case labels for edges. */
1458 79696 : start_recording_case_labels ();
1459 :
1460 79696 : possibly_undefined_names = new hash_set<tree>;
1461 79696 : defined_args = new hash_map<gphi *, uninit_analysis::func_t::phi_arg_set_t>;
1462 :
1463 : /* Walk the CFG in RPO order so we visit PHIs with defs that are
1464 : possibly uninitialized from other PHIs after those. The uninit
1465 : predicate analysis will then expand the PHIs predicate with
1466 : the predicates of the edges from such PHI defs. */
1467 1534151 : for (int i = 0; i < n; ++i)
1468 1454455 : for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
1469 2103679 : !gsi_end_p (gsi); gsi_next (&gsi))
1470 : {
1471 649224 : gphi *phi = gsi.phi ();
1472 :
1473 : /* Don't look at virtual operands. */
1474 1298448 : if (virtual_operand_p (gimple_phi_result (phi)))
1475 211595 : continue;
1476 :
1477 437629 : unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1478 437629 : if (MASK_EMPTY (uninit_opnds))
1479 437261 : continue;
1480 :
1481 368 : warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
1482 : }
1483 :
1484 79696 : free (rpo);
1485 79696 : free (bb_to_rpo);
1486 159392 : delete possibly_undefined_names;
1487 79696 : possibly_undefined_names = NULL;
1488 159392 : delete defined_args;
1489 79696 : defined_args = NULL;
1490 79696 : end_recording_case_labels ();
1491 79696 : free_dominance_info (CDI_POST_DOMINATORS);
1492 79696 : timevar_pop (TV_TREE_UNINIT);
1493 79696 : }
1494 :
1495 : unsigned int
1496 79696 : pass_late_warn_uninitialized::execute (function *fun)
1497 : {
1498 79696 : execute_late_warn_uninitialized (fun);
1499 79696 : return 0;
1500 : }
1501 :
1502 : } // anon namespace
1503 :
1504 : gimple_opt_pass *
1505 285722 : make_pass_late_warn_uninitialized (gcc::context *ctxt)
1506 : {
1507 285722 : return new pass_late_warn_uninitialized (ctxt);
1508 : }
1509 :
1510 : static unsigned int
1511 163610 : execute_early_warn_uninitialized (struct function *fun)
1512 : {
1513 : /* Currently, this pass runs always but
1514 : execute_late_warn_uninitialized only runs with optimization. With
1515 : optimization we want to warn about possible uninitialized as late
1516 : as possible, thus don't do it here. However, without
1517 : optimization we need to warn here about "may be uninitialized". */
1518 163610 : calculate_dominance_info (CDI_DOMINATORS);
1519 163610 : calculate_dominance_info (CDI_POST_DOMINATORS);
1520 :
1521 : /* Use VN in its cheapest incarnation and without doing any
1522 : elimination to compute edge reachability. Don't bother when
1523 : we only warn for unconditionally executed code though. */
1524 163610 : if (!optimize)
1525 19419 : do_rpo_vn (fun, NULL, NULL, false, false, false, VN_NOWALK);
1526 : else
1527 144191 : set_all_edges_as_executable (fun);
1528 :
1529 163610 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1530 :
1531 : /* Post-dominator information cannot be reliably updated. Free it
1532 : after the use. */
1533 :
1534 163610 : free_dominance_info (CDI_POST_DOMINATORS);
1535 163610 : return 0;
1536 : }
1537 :
1538 : namespace {
1539 :
1540 : const pass_data pass_data_early_warn_uninitialized =
1541 : {
1542 : GIMPLE_PASS, /* type */
1543 : "early_uninit", /* name */
1544 : OPTGROUP_NONE, /* optinfo_flags */
1545 : TV_TREE_UNINIT, /* tv_id */
1546 : PROP_ssa, /* properties_required */
1547 : 0, /* properties_provided */
1548 : 0, /* properties_destroyed */
1549 : 0, /* todo_flags_start */
1550 : 0, /* todo_flags_finish */
1551 : };
1552 :
1553 : class pass_early_warn_uninitialized : public gimple_opt_pass
1554 : {
1555 : public:
1556 285722 : pass_early_warn_uninitialized (gcc::context *ctxt)
1557 571444 : : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1558 : {}
1559 :
1560 : /* opt_pass methods: */
1561 2848664 : bool gate (function *) final override { return gate_warn_uninitialized (); }
1562 163610 : unsigned int execute (function *fun) final override
1563 : {
1564 163610 : return execute_early_warn_uninitialized (fun);
1565 : }
1566 :
1567 : }; // class pass_early_warn_uninitialized
1568 :
1569 : } // anon namespace
1570 :
1571 : gimple_opt_pass *
1572 285722 : make_pass_early_warn_uninitialized (gcc::context *ctxt)
1573 : {
1574 285722 : return new pass_early_warn_uninitialized (ctxt);
1575 : }
|