Branch data Line data Source code
1 : : /* Predicate aware uninitialized variable warning.
2 : : Copyright (C) 2001-2025 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 : 129 : get_mask_first_set_bit (unsigned mask)
67 : : {
68 : 129 : int pos = 0;
69 : 0 : if (mask == 0)
70 : : return -1;
71 : :
72 : 157 : 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 : 6429245 : has_undefined_value_p (tree t)
82 : : {
83 : 6429245 : return (ssa_undefined_value_p (t)
84 : 6429245 : || (possibly_undefined_names
85 : 864065 : && possibly_undefined_names->contains (t)));
86 : : }
87 : :
88 : : /* Return true if EXPR should suppress either uninitialized warning. */
89 : :
90 : : static inline bool
91 : 3063799 : get_no_uninit_warning (tree expr)
92 : : {
93 : 1443309 : return warning_suppressed_p (expr, OPT_Wuninitialized);
94 : : }
95 : :
96 : : /* Suppress both uninitialized warnings for EXPR. */
97 : :
98 : : static inline void
99 : 376 : set_no_uninit_warning (tree expr)
100 : : {
101 : 376 : suppress_warning (expr, OPT_Wuninitialized);
102 : 376 : }
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 : 865684 : uninit_undefined_value_p (tree t)
109 : : {
110 : 865684 : if (!has_undefined_value_p (t))
111 : : return false;
112 : 2568 : if (!SSA_NAME_VAR (t))
113 : : return true;
114 : 2549 : 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 : 5563558 : 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 : 5563558 : if (!has_undefined_value_p (t))
144 : 5562997 : 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 : 4513 : if (is_gimple_assign (context)
150 : 4513 : && 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 : 4503 : if (is_gimple_assign (context)
178 : 4503 : && (gimple_assign_rhs_code (context) == REALPART_EXPR
179 : 3920 : || 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 : 4498 : const char *var_name_str = NULL;
202 : 4498 : gimple *var_def_stmt = NULL;
203 : :
204 : 4731 : if (!var && !SSA_NAME_VAR (t))
205 : : {
206 : 233 : var_def_stmt = SSA_NAME_DEF_STMT (t);
207 : :
208 : 233 : 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 : 233 : 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 : 226 : tree lhs_var = NULL_TREE;
243 : :
244 : : /* Get the variable name from the 3rd argument of call. */
245 : 226 : tree var_name = gimple_call_arg (var_def_stmt, 2);
246 : 226 : var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
247 : 226 : var_name_str = TREE_STRING_POINTER (var_name);
248 : :
249 : 226 : if (is_gimple_assign (context))
250 : : {
251 : 219 : 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 : 218 : if (lhs_var)
257 : : {
258 : : /* Get the name string for the LHS_VAR.
259 : : Refer to routine gimple_add_init_for_auto_var. */
260 : 218 : if (DECL_NAME (lhs_var)
261 : 218 : && (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 : 4281 : 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 : 4281 : if (((warning_suppressed_p (context, OPT_Wuninitialized)
282 : 4278 : || (gimple_assign_single_p (context)
283 : 3543 : && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
284 : 8368 : || (var && get_no_uninit_warning (var))
285 : 6347 : || (var_name_str
286 : 8 : && warning_suppressed_p (var_def_stmt, OPT_Wuninitialized)))
287 : 2216 : 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 : 2065 : location_t location = UNKNOWN_LOCATION;
293 : 2065 : if (gimple_has_location (context))
294 : 2046 : location = gimple_location (context);
295 : 19 : else if (phi_arg_loc != UNKNOWN_LOCATION)
296 : : location = phi_arg_loc;
297 : 12 : else if (var)
298 : 12 : location = DECL_SOURCE_LOCATION (var);
299 : 0 : else if (var_name_str)
300 : 0 : location = gimple_location (var_def_stmt);
301 : :
302 : 2626 : auto_diagnostic_group d;
303 : 2065 : gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized);
304 : 2065 : if (var)
305 : : {
306 : 2058 : if ((opt == OPT_Wuninitialized
307 : 1654 : && !warning_at (location, opt, "%qD is used uninitialized", var))
308 : 2480 : || (opt == OPT_Wmaybe_uninitialized
309 : 826 : && !warning_at (location, opt, "%qD may be used uninitialized",
310 : : var)))
311 : 1504 : 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 : 570 : if (var)
326 : 563 : 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 : 570 : location_t var_loc = var ? DECL_SOURCE_LOCATION (var)
333 : 570 : : gimple_location (var_def_stmt);
334 : 570 : if (location == var_loc)
335 : : return;
336 : :
337 : 561 : if (var)
338 : 554 : 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 : 2998665 : builtin_call_nomodifying_p (gimple *stmt)
355 : : {
356 : 2998665 : if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
357 : : return false;
358 : :
359 : 358048 : tree fndecl = gimple_call_fndecl (stmt);
360 : 358048 : if (!fndecl)
361 : : return false;
362 : :
363 : 358048 : tree fntype = TREE_TYPE (fndecl);
364 : 358048 : 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 : 358048 : unsigned argno = 0;
370 : 358048 : tree argtype;
371 : 358048 : function_args_iterator it;
372 : 633555 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
373 : : {
374 : 438035 : if (VOID_TYPE_P (argtype))
375 : : return true;
376 : :
377 : 395336 : ++argno;
378 : :
379 : 395336 : if (!POINTER_TYPE_P (argtype))
380 : 48515 : continue;
381 : :
382 : 346821 : if (TYPE_READONLY (TREE_TYPE (argtype)))
383 : 226992 : 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 : 195520 : unsigned nargs = gimple_call_num_args (stmt);
391 : 195520 : 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 : 201929 : for (; argno < nargs; ++argno)
398 : : {
399 : 196769 : tree arg = gimple_call_arg (stmt, argno);
400 : 196769 : argtype = TREE_TYPE (arg);
401 : 196769 : if (!POINTER_TYPE_P (argtype))
402 : 6007 : 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 : 173574 : maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
418 : : {
419 : 173574 : if (!fndecl)
420 : 0 : return;
421 : :
422 : 173574 : if (get_no_uninit_warning (arg))
423 : : return;
424 : :
425 : 173574 : tree fntype = TREE_TYPE (fndecl);
426 : 173574 : if (!fntype)
427 : : return;
428 : :
429 : : /* Initialize a map of attribute access specifications for arguments
430 : : to the function call. */
431 : 173574 : rdwr_map rdwr_idx;
432 : 173574 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
433 : :
434 : 173574 : unsigned argno = 0;
435 : 173574 : tree parms = DECL_ARGUMENTS (fndecl);
436 : 313186 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
437 : : {
438 : 312701 : if (parm != arg)
439 : 139612 : continue;
440 : :
441 : 173557 : const attr_access* access = rdwr_idx.get (argno);
442 : 173557 : if (!access)
443 : : break;
444 : :
445 : 482 : if (access->mode != access_none
446 : 480 : && access->mode != access_write_only)
447 : 468 : 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 : 173574 : }
468 : :
469 : : /* Callback for walk_aliased_vdefs. */
470 : :
471 : : static bool
472 : 3135906 : check_defs (ao_ref *ref, tree vdef, void *data_)
473 : : {
474 : 3135906 : check_defs_data *data = (check_defs_data *)data_;
475 : 3135906 : 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 : 3135906 : 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 : 3135660 : if (is_gimple_assign (def_stmt)
488 : 3135660 : && gimple_assign_rhs_code (def_stmt) == SSA_NAME)
489 : : {
490 : 1351043 : tree tmp_var = gimple_assign_rhs1 (def_stmt);
491 : 1351043 : 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 : 3135611 : if (is_gimple_call (def_stmt))
498 : : {
499 : : /* The ASAN_MARK intrinsic doesn't modify the variable. */
500 : 1392795 : if (gimple_call_internal_p (def_stmt)
501 : 1392795 : && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
502 : : return false;
503 : :
504 : 1391100 : 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 : 1219802 : if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
510 : : {
511 : 359351 : built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
512 : 359351 : if (fncode > BEGIN_SANITIZER_BUILTINS
513 : 359351 : && fncode < END_SANITIZER_BUILTINS)
514 : : return false;
515 : : }
516 : : }
517 : : }
518 : :
519 : : /* End of VLA scope is not a kill. */
520 : 3133793 : 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 : 3133717 : if (gimple_clobber_p (def_stmt))
525 : : {
526 : 135052 : if (stmt_kills_ref_p (def_stmt, ref))
527 : : return true;
528 : : return false;
529 : : }
530 : :
531 : 2998665 : if (builtin_call_nomodifying_p (def_stmt))
532 : : return false;
533 : :
534 : : /* Found a may-def on this path. */
535 : 2950806 : data->found_may_defs = true;
536 : 2950806 : 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 : 1439820 : maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
562 : : wlimits &wlims)
563 : : {
564 : 1439820 : bool has_bit_insert = false;
565 : 1439820 : use_operand_p luse_p;
566 : 1439820 : imm_use_iterator liter;
567 : :
568 : 1439820 : 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 : 1439135 : tree base = ao_ref_base (&ref);
574 : 1439135 : if ((VAR_P (base)
575 : 579080 : && DECL_HARD_REGISTER (base))
576 : 2878264 : || get_no_uninit_warning (base))
577 : 4135 : return NULL_TREE;
578 : :
579 : : /* Do not warn if the access is zero size or if it's fully outside
580 : : the object. */
581 : 1435000 : poly_int64 decl_size;
582 : 1435000 : if (known_size_p (ref.size)
583 : 1212150 : && known_eq (ref.max_size, ref.size)
584 : 2512911 : && (known_eq (ref.size, 0)
585 : 1077897 : || known_le (ref.offset + ref.size, 0)))
586 : : return NULL_TREE;
587 : :
588 : 1434936 : if (DECL_P (base)
589 : 594978 : && known_ge (ref.offset, 0)
590 : 594971 : && DECL_SIZE (base)
591 : 578196 : && poly_int_tree_p (DECL_SIZE (base), &decl_size)
592 : 2013131 : && 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 : 1434429 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
598 : 2927431 : FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
599 : : {
600 : 1727046 : 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 : 2565227 : if (gassign *ass = dyn_cast <gassign *> (use_stmt))
604 : : {
605 : 838181 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
606 : 838181 : && luse_p->use == gimple_assign_rhs1_ptr (ass))
607 : : {
608 : : has_bit_insert = true;
609 : : break;
610 : : }
611 : : }
612 : : }
613 : :
614 : 1200385 : 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 : 1434429 : if (wlims.oracle_cnt > 128 * 128
621 : 36676 : && wlims.oracle_cnt > wlims.vdef_cnt * 2)
622 : 36676 : wlims.limit = 32;
623 : :
624 : 1434429 : check_defs_data data;
625 : 1434429 : bool fentry_reached = false;
626 : 1434429 : data.found_may_defs = false;
627 : 2873572 : tree use = gimple_vuse (stmt);
628 : 1434429 : if (!use)
629 : : return NULL_TREE;
630 : 1434171 : int res = walk_aliased_vdefs (&ref, use,
631 : : check_defs, &data, NULL,
632 : : &fentry_reached, wlims.limit);
633 : 1434171 : if (res == -1)
634 : : {
635 : 33723 : wlims.oracle_cnt += wlims.limit;
636 : 33723 : return NULL_TREE;
637 : : }
638 : :
639 : 1400448 : wlims.oracle_cnt += res;
640 : 1400448 : if (data.found_may_defs)
641 : : return NULL_TREE;
642 : :
643 : 474377 : bool found_alloc = false;
644 : 474377 : bool found_clobber_deref_this = false;
645 : :
646 : 474377 : if (fentry_reached)
647 : : {
648 : 474346 : if (TREE_CODE (base) == MEM_REF)
649 : 207423 : 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 : 484300 : while (TREE_CODE (base) == SSA_NAME)
656 : : {
657 : 215653 : gimple *def_stmt = SSA_NAME_DEF_STMT (base);
658 : :
659 : 215653 : if (is_gimple_call (def_stmt)
660 : 215653 : && 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 : 215511 : if (SSA_NAME_IS_DEFAULT_DEF (base)
680 : 172842 : && POINTER_TYPE_P (TREE_TYPE (base))
681 : 172842 : && SSA_NAME_VAR (base)
682 : 172842 : && TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL
683 : 388352 : && lookup_attribute ("clobber *this",
684 : 172841 : DECL_ATTRIBUTES (SSA_NAME_VAR (base))))
685 : : {
686 : : found_clobber_deref_this = true;
687 : : break;
688 : : }
689 : :
690 : 215495 : if (!is_gimple_assign (def_stmt))
691 : : break;
692 : :
693 : 35870 : tree_code code = gimple_assign_rhs_code (def_stmt);
694 : 35870 : if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
695 : : break;
696 : :
697 : 9954 : base = gimple_assign_rhs1 (def_stmt);
698 : 9954 : if (TREE_CODE (base) == ADDR_EXPR)
699 : 1378 : base = TREE_OPERAND (base, 0);
700 : :
701 : 9954 : if (DECL_P (base)
702 : 8977 : || TREE_CODE (base) == COMPONENT_REF)
703 : 1141 : rhs = base;
704 : :
705 : 9954 : if (TREE_CODE (base) == MEM_REF)
706 : 15 : base = TREE_OPERAND (base, 0);
707 : :
708 : 9954 : if (tree ba = get_base_address (base))
709 : 9954 : 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 : 474346 : if (DECL_P (base)
716 : 136357 : && EXPR_P (rhs)
717 : 62348 : && TREE_CODE (rhs) != COMPONENT_REF)
718 : 474346 : 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 : 474377 : if ((!found_alloc && !found_clobber_deref_this) && fentry_reached)
725 : : {
726 : 474217 : if (TREE_CODE (base) == SSA_NAME)
727 : : {
728 : 205570 : tree var = SSA_NAME_VAR (base);
729 : 183957 : if (var && TREE_CODE (var) == PARM_DECL)
730 : : {
731 : 173574 : maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
732 : 173574 : return NULL_TREE;
733 : : }
734 : : }
735 : :
736 : 300643 : if (!VAR_P (base)
737 : 300643 : || 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 : 1004 : if (TREE_CODE (rhs) == ADDR_EXPR)
746 : 0 : rhs = TREE_OPERAND (rhs, 0);
747 : :
748 : : /* Check again since RHS may have changed above. */
749 : 1004 : 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 : 998 : tree rhstype = TREE_TYPE (rhs);
756 : 998 : if (POINTER_TYPE_P (rhstype))
757 : 149 : rhstype = TREE_TYPE (rhstype);
758 : 998 : if (is_empty_type (rhstype))
759 : : return NULL_TREE;
760 : :
761 : 705 : 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 : 705 : location_t location = gimple_location (stmt);
765 : 705 : if (wlims.always_executed)
766 : : {
767 : 554 : 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 : 554 : if (lhs)
775 : 376 : 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 : 1234133 : maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
793 : : {
794 : 1234133 : if (!wlims.wmaybe_uninit)
795 : 759302 : return;
796 : :
797 : 625825 : unsigned nargs = gimple_call_num_args (stmt);
798 : 625825 : if (!nargs)
799 : : return;
800 : :
801 : 570023 : tree fndecl = gimple_call_fndecl (stmt);
802 : 1251331 : tree fntype = gimple_call_fntype (stmt);
803 : 492029 : if (!fntype)
804 : : return;
805 : :
806 : : /* Const function do not read their arguments. */
807 : 492029 : if (gimple_call_flags (stmt) & ECF_CONST)
808 : : return;
809 : :
810 : 481194 : const built_in_function fncode
811 : 432408 : = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
812 : 600917 : ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
813 : :
814 : 119723 : 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 : 474831 : 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 : 474831 : rdwr_map rdwr_idx;
829 : 474831 : init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
830 : :
831 : 474831 : tree argtype;
832 : 474831 : unsigned argno = 0;
833 : 474831 : function_args_iterator it;
834 : :
835 : 1636739 : FOREACH_FUNCTION_ARGS (fntype, argtype, it)
836 : : {
837 : 1570811 : ++argno;
838 : :
839 : 1570811 : if (argno > nargs)
840 : : break;
841 : :
842 : 1161908 : if (!POINTER_TYPE_P (argtype))
843 : 1161668 : continue;
844 : :
845 : 572774 : tree access_size = NULL_TREE;
846 : 572774 : const attr_access* access = rdwr_idx.get (argno - 1);
847 : 572774 : if (access)
848 : : {
849 : 2956 : if (access->mode == access_none
850 : 2793 : || access->mode == access_write_only)
851 : 395 : continue;
852 : :
853 : 4402 : if (access->mode == access_deferred
854 : 2561 : && !TYPE_READONLY (TREE_TYPE (argtype)))
855 : 1841 : continue;
856 : :
857 : 720 : 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 : 484 : wlims.always_executed = false;
865 : :
866 : 720 : if (access->sizarg < nargs)
867 : 217 : access_size = gimple_call_arg (stmt, access->sizarg);
868 : : }
869 : 569818 : else if (!TYPE_READONLY (TREE_TYPE (argtype)))
870 : 344727 : continue;
871 : 225091 : else if (save_always_executed && fncode != BUILT_IN_LAST)
872 : : /* Const-qualified arguments to built-ins imply read access. */
873 : 20787 : wlims.always_executed = true;
874 : : else
875 : : /* Const-qualified arguments to ordinary functions imply a likely
876 : : (but not definitive) read access. */
877 : 204304 : wlims.always_executed = false;
878 : :
879 : : /* Ignore args we are not going to read from. */
880 : 225811 : if (gimple_call_arg_flags (stmt, argno - 1)
881 : 225811 : & (EAF_UNUSED | EAF_NO_DIRECT_READ))
882 : 881 : continue;
883 : :
884 : 224930 : tree arg = gimple_call_arg (stmt, argno - 1);
885 : 224930 : if (!POINTER_TYPE_P (TREE_TYPE (arg)))
886 : : /* Avoid actual arguments with invalid types. */
887 : 0 : continue;
888 : :
889 : 224930 : ao_ref ref;
890 : 224930 : ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
891 : 224930 : tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
892 : 224930 : if (!argbase)
893 : 224690 : 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 : 474831 : wlims.always_executed = save_always_executed;
948 : 474831 : }
949 : :
950 : : /* Warn about an uninitialized PHI argument on the fallthru path to
951 : : an always executed block BB. */
952 : :
953 : : static void
954 : 401144 : warn_uninit_phi_uses (basic_block bb)
955 : : {
956 : 401144 : edge_iterator ei;
957 : 401144 : edge e, found = NULL, found_back = NULL;
958 : : /* Look for a fallthru and possibly a single backedge. */
959 : 816937 : FOR_EACH_EDGE (e, ei, bb->preds)
960 : : {
961 : : /* Ignore backedges. */
962 : 521085 : if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
963 : : {
964 : 15143 : if (found_back)
965 : : {
966 : : found = NULL;
967 : : break;
968 : : }
969 : 14649 : found_back = e;
970 : 14649 : continue;
971 : : }
972 : 505942 : if (found)
973 : : {
974 : : found = NULL;
975 : : break;
976 : : }
977 : : found = e;
978 : : }
979 : 401144 : if (!found)
980 : 105292 : return;
981 : :
982 : 295852 : basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
983 : 327672 : for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
984 : 31820 : gsi_next (&si))
985 : : {
986 : 31820 : gphi *phi = si.phi ();
987 : 31820 : tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
988 : 61966 : if (TREE_CODE (def) != SSA_NAME
989 : 27326 : || !SSA_NAME_IS_DEFAULT_DEF (def)
990 : 37053 : || virtual_operand_p (def))
991 : 30146 : 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 : 1674 : imm_use_iterator iter;
996 : 1674 : use_operand_p use_p;
997 : 1674 : gimple *use_stmt = NULL;
998 : 5828 : FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
999 : : {
1000 : 5203 : use_stmt = USE_STMT (use_p);
1001 : 5203 : if (gimple_location (use_stmt) != UNKNOWN_LOCATION
1002 : 4310 : && dominated_by_p (CDI_POST_DOMINATORS, succ,
1003 : 4310 : 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 : 6433 : && (!found_back
1008 : 1230 : || dominated_by_p (CDI_DOMINATORS, found_back->src,
1009 : 1230 : gimple_bb (use_stmt))))
1010 : : break;
1011 : 4154 : use_stmt = NULL;
1012 : : }
1013 : 1674 : if (use_stmt)
1014 : 2098 : warn_uninit (OPT_Wuninitialized, def,
1015 : 1049 : 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 : 241934 : warn_uninitialized_vars (bool wmaybe_uninit)
1024 : : {
1025 : : /* Counters and limits controlling the depth of the warning. */
1026 : 241934 : wlimits wlims = { };
1027 : 241934 : wlims.wmaybe_uninit = wmaybe_uninit;
1028 : :
1029 : 241934 : 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 : 241934 : basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1034 : 401207 : while (!(bb->flags & ft_reachable))
1035 : : {
1036 : 401144 : bb->flags |= ft_reachable;
1037 : 401144 : edge e = find_fallthru_edge (bb->succs);
1038 : 401144 : if (e && e->flags & EDGE_EXECUTABLE)
1039 : : {
1040 : 43689 : bb = e->dest;
1041 : 43689 : continue;
1042 : : }
1043 : : /* Find a single executable edge. */
1044 : 357455 : edge_iterator ei;
1045 : 357455 : edge ee = NULL;
1046 : 713472 : FOR_EACH_EDGE (e, ei, bb->succs)
1047 : 502705 : if (e->flags & EDGE_EXECUTABLE)
1048 : : {
1049 : 502510 : if (!ee)
1050 : : ee = e;
1051 : : else
1052 : : {
1053 : : ee = NULL;
1054 : : break;
1055 : : }
1056 : : }
1057 : 357455 : if (ee)
1058 : 209134 : bb = ee->dest;
1059 : : else
1060 : 148321 : bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1061 : 357455 : if (!bb || bb->index == EXIT_BLOCK)
1062 : : break;
1063 : : }
1064 : :
1065 : 2778412 : FOR_EACH_BB_FN (bb, cfun)
1066 : : {
1067 : 2536478 : wlims.always_executed = (bb->flags & ft_reachable);
1068 : 2536478 : bb->flags &= ~ft_reachable;
1069 : :
1070 : 2536478 : edge_iterator ei;
1071 : 2536478 : edge e;
1072 : 2537256 : FOR_EACH_EDGE (e, ei, bb->preds)
1073 : 2536869 : 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 : 2536478 : if (!e)
1078 : 387 : continue;
1079 : :
1080 : 2536091 : if (wlims.always_executed)
1081 : 401144 : warn_uninit_phi_uses (bb);
1082 : :
1083 : 2536091 : gimple_stmt_iterator gsi;
1084 : 20475021 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1085 : : {
1086 : 15402839 : 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 : 15402839 : if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
1092 : 8560926 : continue;
1093 : :
1094 : 15400157 : if (is_gimple_debug (stmt))
1095 : 7343791 : continue;
1096 : :
1097 : : /* We only do data flow with SSA_NAMEs, so that's all we
1098 : : can warn about. */
1099 : 8056366 : use_operand_p use_p;
1100 : 8056366 : ssa_op_iter op_iter;
1101 : 16560794 : 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 : 8504428 : if (gassign *ass = dyn_cast <gassign *> (stmt))
1106 : : {
1107 : 5621005 : if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
1108 : 5621005 : && use_p->use == gimple_assign_rhs1_ptr (ass))
1109 : 19 : continue;
1110 : : }
1111 : 8504409 : tree use = USE_FROM_PTR (use_p);
1112 : 8504409 : if (wlims.always_executed)
1113 : 3463258 : warn_uninit (OPT_Wuninitialized, use,
1114 : 1731629 : SSA_NAME_VAR (use), stmt);
1115 : 6772780 : else if (wlims.wmaybe_uninit)
1116 : 7661536 : warn_uninit (OPT_Wmaybe_uninitialized, use,
1117 : 3830768 : SSA_NAME_VAR (use), stmt);
1118 : : }
1119 : :
1120 : : /* For limiting the alias walk below we count all
1121 : : vdefs in the function. */
1122 : 15019243 : if (gimple_vdef (stmt))
1123 : 2009874 : wlims.vdef_cnt++;
1124 : :
1125 : 8056366 : if (gcall *call = dyn_cast <gcall *> (stmt))
1126 : 1234133 : maybe_warn_pass_by_reference (call, wlims);
1127 : 6822233 : else if (gimple_assign_load_p (stmt)
1128 : 6822233 : && gimple_has_location (stmt))
1129 : : {
1130 : 1214890 : tree rhs = gimple_assign_rhs1 (stmt);
1131 : 1214890 : tree lhs = gimple_assign_lhs (stmt);
1132 : :
1133 : 1214890 : ao_ref ref;
1134 : 1214890 : ao_ref_init (&ref, rhs);
1135 : 1214890 : tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
1136 : 1214890 : if (!var)
1137 : 1214453 : continue;
1138 : :
1139 : 437 : if (DECL_P (var))
1140 : : {
1141 : 316 : location_t loc = DECL_SOURCE_LOCATION (var);
1142 : 316 : inform (loc, "%qD declared here", var);
1143 : : }
1144 : : }
1145 : : }
1146 : : }
1147 : 241934 : }
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 : 1636 : can_skip_redundant_opnd (tree opnd, gimple *phi)
1157 : : {
1158 : 1636 : tree phi_def = gimple_phi_result (phi);
1159 : 1636 : gimple *op_def = SSA_NAME_DEF_STMT (opnd);
1160 : 1636 : if (gimple_code (op_def) != GIMPLE_PHI)
1161 : : return false;
1162 : :
1163 : 685 : unsigned n = gimple_phi_num_args (op_def);
1164 : 838 : for (unsigned i = 0; i < n; ++i)
1165 : : {
1166 : 831 : tree op = gimple_phi_arg_def (op_def, i);
1167 : 831 : if (TREE_CODE (op) != SSA_NAME)
1168 : 0 : continue;
1169 : 831 : 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 : 446808 : compute_uninit_opnds_pos (gphi *phi)
1181 : : {
1182 : 446808 : unsigned uninit_opnds = 0;
1183 : :
1184 : 446808 : unsigned n = gimple_phi_num_args (phi);
1185 : : /* Bail out for phi with too many args. */
1186 : 446808 : if (n > uninit_analysis::func_t::max_phi_args)
1187 : : return 0;
1188 : :
1189 : 1491720 : for (unsigned i = 0; i < n; ++i)
1190 : : {
1191 : 1044985 : tree op = gimple_phi_arg_def (phi, i);
1192 : 1044985 : if (TREE_CODE (op) == SSA_NAME
1193 : 864906 : && uninit_undefined_value_p (op)
1194 : 1046621 : && !can_skip_redundant_opnd (op, phi))
1195 : : {
1196 : 1629 : 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 : 1566 : MASK_SET_BIT (uninit_opnds, i);
1204 : : }
1205 : : }
1206 : : /* If we have recorded guarded uses of may-uninit values mask those. */
1207 : 446735 : if (auto *def_mask = defined_args->get (phi))
1208 : 64 : 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 : 516 : uninit_undef_val_t::phi_arg_set (gphi *phi)
1224 : : {
1225 : 516 : return compute_uninit_opnds_pos (phi);
1226 : : }
1227 : :
1228 : : /* sort helper for find_uninit_use. */
1229 : :
1230 : : static int
1231 : 337 : cand_cmp (const void *a, const void *b, void *data)
1232 : : {
1233 : 337 : int *bb_to_rpo = (int *)data;
1234 : 337 : const gimple *sa = *(const gimple * const *)a;
1235 : 337 : const gimple *sb = *(const gimple * const *)b;
1236 : 337 : if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index])
1237 : : return -1;
1238 : 166 : else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index])
1239 : 127 : 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 : 378 : 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 : 378 : uninit_undef_val_t eval;
1256 : 378 : uninit_analysis def_preds (eval);
1257 : :
1258 : : /* First process PHIs and record other candidates. */
1259 : 378 : auto_vec<gimple *, 64> cands;
1260 : 378 : use_operand_p use_p;
1261 : 378 : imm_use_iterator iter;
1262 : 378 : tree phi_result = gimple_phi_result (phi);
1263 : 1184 : FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1264 : : {
1265 : 806 : gimple *use_stmt = USE_STMT (use_p);
1266 : 806 : if (is_gimple_debug (use_stmt))
1267 : 289 : 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 : 599 : use_operand_p use2_p;
1273 : 599 : gimple *use2_stmt;
1274 : 599 : if (gimple_assign_ssa_name_copy_p (use_stmt)
1275 : 599 : && 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 : 837 : if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1282 : : {
1283 : 361 : unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p);
1284 : 361 : 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 : 361 : if (e->flags & EDGE_DFS_BACK)
1289 : 82 : continue;
1290 : :
1291 : 330 : basic_block use_bb = e->src;
1292 : 330 : 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 : 51 : if (idx < uninit_analysis::func_t::max_phi_args)
1297 : : {
1298 : 51 : bool existed_p;
1299 : 51 : auto &def_mask
1300 : 51 : = defined_args->get_or_insert (use_phi, &existed_p);
1301 : 51 : if (!existed_p)
1302 : 51 : def_mask = 0;
1303 : 51 : MASK_SET_BIT (def_mask, idx);
1304 : : }
1305 : 51 : continue;
1306 : 51 : }
1307 : :
1308 : 279 : 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 : 279 : possibly_undefined_names->add (USE_FROM_PTR (use_p));
1317 : : }
1318 : : else
1319 : 238 : cands.safe_push (use_stmt);
1320 : : }
1321 : :
1322 : : /* Sort candidates after RPO. */
1323 : 378 : cands.stablesort (cand_cmp, bb_to_rpo);
1324 : 378 : basic_block use_bb = NULL;
1325 : 1226 : for (gimple *use_stmt : cands)
1326 : : {
1327 : : /* We only have to try diagnosing the first use in each block. */
1328 : 204 : if (gimple_bb (use_stmt) == use_bb)
1329 : 0 : 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 : 92 : continue;
1334 : :
1335 : 112 : 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 : 378 : }
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 : 378 : warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo)
1355 : : {
1356 : 378 : 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 : 378 : gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo);
1363 : :
1364 : : /* All uses are properly guarded. */
1365 : 378 : if (!uninit_use_stmt)
1366 : : return;
1367 : :
1368 : 112 : unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1369 : 112 : tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1370 : :
1371 : 112 : location_t loc = UNKNOWN_LOCATION;
1372 : 112 : if (gimple_phi_arg_has_location (phi, phiarg_index))
1373 : : loc = gimple_phi_arg_location (phi, phiarg_index);
1374 : : else
1375 : : {
1376 : 97 : tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1377 : 97 : if (TREE_CODE (arg_def) == SSA_NAME)
1378 : : {
1379 : 97 : gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1380 : 97 : if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1381 : : {
1382 : 17 : unsigned uop = compute_uninit_opnds_pos (arg_phi);
1383 : 17 : unsigned idx = MASK_FIRST_SET_BIT (uop);
1384 : 17 : if (idx < gimple_phi_num_args (arg_phi)
1385 : 17 : && gimple_phi_arg_has_location (arg_phi, idx))
1386 : : loc = gimple_phi_arg_location (arg_phi, idx);
1387 : : }
1388 : : }
1389 : : }
1390 : :
1391 : 224 : warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1392 : 112 : SSA_NAME_VAR (uninit_op),
1393 : : uninit_use_stmt, loc);
1394 : : }
1395 : :
1396 : : static bool
1397 : 3944067 : gate_warn_uninitialized (void)
1398 : : {
1399 : 3702545 : 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 : 578160 : pass_late_warn_uninitialized (gcc::context *ctxt)
1421 : 1156320 : : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1422 : : {}
1423 : :
1424 : : /* opt_pass methods: */
1425 : 289080 : opt_pass *clone () final override
1426 : : {
1427 : 289080 : return new pass_late_warn_uninitialized (m_ctxt);
1428 : : }
1429 : 1038547 : 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 : 79130 : execute_late_warn_uninitialized (function *fun)
1436 : : {
1437 : 79130 : calculate_dominance_info (CDI_DOMINATORS);
1438 : 79130 : calculate_dominance_info (CDI_POST_DOMINATORS);
1439 : :
1440 : : /* Mark all edges executable, warn_uninitialized_vars will skip
1441 : : unreachable blocks. */
1442 : 79130 : set_all_edges_as_executable (fun);
1443 : 79130 : mark_dfs_back_edges (fun);
1444 : 79130 : int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
1445 : 79130 : int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false);
1446 : 79130 : int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
1447 : 1552159 : for (int i = 0; i < n; ++i)
1448 : 1473029 : 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 : 79130 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1454 : :
1455 : 79130 : timevar_push (TV_TREE_UNINIT);
1456 : :
1457 : : /* Avoid quadratic beahvior when looking up case labels for edges. */
1458 : 79130 : start_recording_case_labels ();
1459 : :
1460 : 79130 : possibly_undefined_names = new hash_set<tree>;
1461 : 79130 : 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 : 1552159 : for (int i = 0; i < n; ++i)
1468 : 1473029 : for (auto gsi = gsi_start_phis (BASIC_BLOCK_FOR_FN (fun, rpo[i]));
1469 : 2157980 : !gsi_end_p (gsi); gsi_next (&gsi))
1470 : : {
1471 : 684951 : gphi *phi = gsi.phi ();
1472 : :
1473 : : /* Don't look at virtual operands. */
1474 : 1369902 : if (virtual_operand_p (gimple_phi_result (phi)))
1475 : 238676 : continue;
1476 : :
1477 : 446275 : unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1478 : 446275 : if (MASK_EMPTY (uninit_opnds))
1479 : 445897 : continue;
1480 : :
1481 : 378 : warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo);
1482 : : }
1483 : :
1484 : 79130 : free (rpo);
1485 : 79130 : free (bb_to_rpo);
1486 : 158260 : delete possibly_undefined_names;
1487 : 79130 : possibly_undefined_names = NULL;
1488 : 158260 : delete defined_args;
1489 : 79130 : defined_args = NULL;
1490 : 79130 : end_recording_case_labels ();
1491 : 79130 : free_dominance_info (CDI_POST_DOMINATORS);
1492 : 79130 : timevar_pop (TV_TREE_UNINIT);
1493 : 79130 : }
1494 : :
1495 : : unsigned int
1496 : 79130 : pass_late_warn_uninitialized::execute (function *fun)
1497 : : {
1498 : 79130 : execute_late_warn_uninitialized (fun);
1499 : 79130 : return 0;
1500 : : }
1501 : :
1502 : : } // anon namespace
1503 : :
1504 : : gimple_opt_pass *
1505 : 289080 : make_pass_late_warn_uninitialized (gcc::context *ctxt)
1506 : : {
1507 : 289080 : return new pass_late_warn_uninitialized (ctxt);
1508 : : }
1509 : :
1510 : : static unsigned int
1511 : 162804 : 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 : 162804 : calculate_dominance_info (CDI_DOMINATORS);
1519 : 162804 : 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 : 162804 : if (!optimize)
1525 : 19380 : do_rpo_vn (fun, NULL, NULL, false, false, false, VN_NOWALK);
1526 : : else
1527 : 143424 : set_all_edges_as_executable (fun);
1528 : :
1529 : 162804 : warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1530 : :
1531 : : /* Post-dominator information cannot be reliably updated. Free it
1532 : : after the use. */
1533 : :
1534 : 162804 : free_dominance_info (CDI_POST_DOMINATORS);
1535 : 162804 : 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 : 289080 : pass_early_warn_uninitialized (gcc::context *ctxt)
1557 : 578160 : : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1558 : : {}
1559 : :
1560 : : /* opt_pass methods: */
1561 : 2905520 : bool gate (function *) final override { return gate_warn_uninitialized (); }
1562 : 162804 : unsigned int execute (function *fun) final override
1563 : : {
1564 : 162804 : return execute_early_warn_uninitialized (fun);
1565 : : }
1566 : :
1567 : : }; // class pass_early_warn_uninitialized
1568 : :
1569 : : } // anon namespace
1570 : :
1571 : : gimple_opt_pass *
1572 : 289080 : make_pass_early_warn_uninitialized (gcc::context *ctxt)
1573 : : {
1574 : 289080 : return new pass_early_warn_uninitialized (ctxt);
1575 : : }
|