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