]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-ssa-uninit.c
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / tree-ssa-uninit.c
1 /* Predicate aware uninitialized variable warning.
2 Copyright (C) 2001-2021 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
42 #include "gimple-predicate-analysis.h"
43
44 /* This implements the pass that does predicate aware warning on uses of
45 possibly uninitialized variables. The pass first collects the set of
46 possibly uninitialized SSA names. For each such name, it walks through
47 all its immediate uses. For each immediate use, it rebuilds the condition
48 expression (the predicate) that guards the use. The predicate is then
49 examined to see if the variable is always defined under that same condition.
50 This is done either by pruning the unrealizable paths that lead to the
51 default definitions or by checking if the predicate set that guards the
52 defining paths is a superset of the use predicate. */
53
54 /* Pointer set of potentially undefined ssa names, i.e.,
55 ssa names that are defined by phi with operands that
56 are not defined or potentially undefined. */
57 static hash_set<tree> *possibly_undefined_names = 0;
58
59 /* Returns the first bit position (starting from LSB)
60 in mask that is non zero. Returns -1 if the mask is empty. */
61 static int
62 get_mask_first_set_bit (unsigned mask)
63 {
64 int pos = 0;
65 if (mask == 0)
66 return -1;
67
68 while ((mask & (1 << pos)) == 0)
69 pos++;
70
71 return pos;
72 }
73 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
74
75 /* Return true if T, an SSA_NAME, has an undefined value. */
76 static bool
77 has_undefined_value_p (tree t)
78 {
79 return (ssa_undefined_value_p (t)
80 || (possibly_undefined_names
81 && possibly_undefined_names->contains (t)));
82 }
83
84 /* Return true if EXPR should suppress either uninitialized warning. */
85
86 static inline bool
87 get_no_uninit_warning (tree expr)
88 {
89 return warning_suppressed_p (expr, OPT_Wuninitialized);
90 }
91
92 /* Suppress both uninitialized warnings for EXPR. */
93
94 static inline void
95 set_no_uninit_warning (tree expr)
96 {
97 suppress_warning (expr, OPT_Wuninitialized);
98 }
99
100 /* Like has_undefined_value_p, but don't return true if the no-warning
101 bit is set on SSA_NAME_VAR for either uninit warning. */
102
103 static inline bool
104 uninit_undefined_value_p (tree t)
105 {
106 if (!has_undefined_value_p (t))
107 return false;
108 if (!SSA_NAME_VAR (t))
109 return true;
110 return !get_no_uninit_warning (SSA_NAME_VAR (t));
111 }
112
113 /* Emit warnings for uninitialized variables. This is done in two passes.
114
115 The first pass notices real uses of SSA names with undefined values.
116 Such uses are unconditionally uninitialized, and we can be certain that
117 such a use is a mistake. This pass is run before most optimizations,
118 so that we catch as many as we can.
119
120 The second pass follows PHI nodes to find uses that are potentially
121 uninitialized. In this case we can't necessarily prove that the use
122 is really uninitialized. This pass is run after most optimizations,
123 so that we thread as many jumps and possible, and delete as much dead
124 code as possible, in order to reduce false positives. We also look
125 again for plain uninitialized variables, since optimization may have
126 changed conditionally uninitialized to unconditionally uninitialized. */
127
128 /* Emit warning OPT for variable VAR at the point in the program where
129 the SSA_NAME T is being used uninitialized. The warning text is in
130 MSGID and STMT is the statement that does the uninitialized read.
131 PHI_ARG_LOC is the location of the PHI argument if T and VAR are one,
132 or UNKNOWN_LOCATION otherwise. */
133
134 static void
135 warn_uninit (opt_code opt, tree t, tree var, const char *gmsgid,
136 gimple *context, location_t phi_arg_loc = UNKNOWN_LOCATION)
137 {
138 /* Bail if the value isn't provably uninitialized. */
139 if (!has_undefined_value_p (t))
140 return;
141
142 /* Ignore COMPLEX_EXPR as initializing only a part of a complex
143 turns in a COMPLEX_EXPR with the not initialized part being
144 set to its previous (undefined) value. */
145 if (is_gimple_assign (context)
146 && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
147 return;
148
149 /* Ignore REALPART_EXPR or IMAGPART_EXPR if its operand is a call to
150 .DEFERRED_INIT. This is for handling the following case correctly:
151
152 1 typedef _Complex float C;
153 2 C foo (int cond)
154 3 {
155 4 C f;
156 5 __imag__ f = 0;
157 6 if (cond)
158 7 {
159 8 __real__ f = 1;
160 9 return f;
161 10 }
162 11 return f;
163 12 }
164
165 with -ftrivial-auto-var-init, compiler will insert the following
166 artificial initialization at line 4:
167 f = .DEFERRED_INIT (f, 2);
168 _1 = REALPART_EXPR <f>;
169
170 without the following special handling, _1 = REALPART_EXPR <f> will
171 be treated as the uninitialized use point, which is incorrect. (the
172 real uninitialized use point is at line 11). */
173 if (is_gimple_assign (context)
174 && (gimple_assign_rhs_code (context) == REALPART_EXPR
175 || gimple_assign_rhs_code (context) == IMAGPART_EXPR))
176 {
177 tree v = gimple_assign_rhs1 (context);
178 if (TREE_CODE (TREE_OPERAND (v, 0)) == SSA_NAME
179 && gimple_call_internal_p (SSA_NAME_DEF_STMT (TREE_OPERAND (v, 0)),
180 IFN_DEFERRED_INIT))
181 return;
182 }
183
184 /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
185 can return true if the def stmt of an anonymous SSA_NAME is COMPLEX_EXPR
186 created for conversion from scalar to complex. Use the underlying var of
187 the COMPLEX_EXPRs real part in that case. See PR71581. */
188 if (!var && !SSA_NAME_VAR (t))
189 {
190 gimple *def_stmt = SSA_NAME_DEF_STMT (t);
191 if (is_gimple_assign (def_stmt)
192 && gimple_assign_rhs_code (def_stmt) == COMPLEX_EXPR)
193 {
194 tree v = gimple_assign_rhs1 (def_stmt);
195 if (TREE_CODE (v) == SSA_NAME
196 && has_undefined_value_p (v)
197 && zerop (gimple_assign_rhs2 (def_stmt)))
198 var = SSA_NAME_VAR (v);
199 }
200 }
201
202 if (var == NULL_TREE)
203 return;
204
205 /* Avoid warning if we've already done so or if the warning has been
206 suppressed. */
207 if (((warning_suppressed_p (context, OPT_Wuninitialized)
208 || (gimple_assign_single_p (context)
209 && get_no_uninit_warning (gimple_assign_rhs1 (context)))))
210 || get_no_uninit_warning (var))
211 return;
212
213 /* Use either the location of the read statement or that of the PHI
214 argument, or that of the uninitialized variable, in that order,
215 whichever is valid. */
216 location_t location;
217 if (gimple_has_location (context))
218 location = gimple_location (context);
219 else if (phi_arg_loc != UNKNOWN_LOCATION)
220 location = phi_arg_loc;
221 else
222 location = DECL_SOURCE_LOCATION (var);
223 location = linemap_resolve_location (line_table, location,
224 LRK_SPELLING_LOCATION, NULL);
225
226 auto_diagnostic_group d;
227 if (!warning_at (location, opt, gmsgid, var))
228 return;
229
230 /* Avoid subsequent warnings for reads of the same variable again. */
231 suppress_warning (var, opt);
232
233 /* Issue a note pointing to the read variable unless the warning
234 is at the same location. */
235 location_t var_loc = DECL_SOURCE_LOCATION (var);
236 if (location == var_loc)
237 return;
238
239 inform (var_loc, "%qD was declared here", var);
240 }
241
242 struct check_defs_data
243 {
244 /* If we found any may-defs besides must-def clobbers. */
245 bool found_may_defs;
246 };
247
248 /* Return true if STMT is a call to built-in function all of whose
249 by-reference arguments are const-qualified (i.e., the function can
250 be assumed not to modify them). */
251
252 static bool
253 builtin_call_nomodifying_p (gimple *stmt)
254 {
255 if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
256 return false;
257
258 tree fndecl = gimple_call_fndecl (stmt);
259 if (!fndecl)
260 return false;
261
262 tree fntype = TREE_TYPE (fndecl);
263 if (!fntype)
264 return false;
265
266 /* Check the called function's signature for non-constc pointers.
267 If one is found, return false. */
268 unsigned argno = 0;
269 tree argtype;
270 function_args_iterator it;
271 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
272 {
273 if (VOID_TYPE_P (argtype))
274 return true;
275
276 ++argno;
277
278 if (!POINTER_TYPE_P (argtype))
279 continue;
280
281 if (TYPE_READONLY (TREE_TYPE (argtype)))
282 continue;
283
284 return false;
285 }
286
287 /* If the number of actual arguments to the call is less than or
288 equal to the number of parameters, return false. */
289 unsigned nargs = gimple_call_num_args (stmt);
290 if (nargs <= argno)
291 return false;
292
293 /* Check arguments passed through the ellipsis in calls to variadic
294 functions for pointers. If one is found that's a non-constant
295 pointer, return false. */
296 for (; argno < nargs; ++argno)
297 {
298 tree arg = gimple_call_arg (stmt, argno);
299 argtype = TREE_TYPE (arg);
300 if (!POINTER_TYPE_P (argtype))
301 continue;
302
303 if (TYPE_READONLY (TREE_TYPE (argtype)))
304 continue;
305
306 return false;
307 }
308
309 return true;
310 }
311
312 /* If ARG is a FNDECL parameter declared with attribute access none or
313 write_only issue a warning for its read access via PTR. */
314
315 static void
316 maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr)
317 {
318 if (!fndecl)
319 return;
320
321 if (get_no_uninit_warning (arg))
322 return;
323
324 tree fntype = TREE_TYPE (fndecl);
325 if (!fntype)
326 return;
327
328 /* Initialize a map of attribute access specifications for arguments
329 to the function function call. */
330 rdwr_map rdwr_idx;
331 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
332
333 unsigned argno = 0;
334 tree parms = DECL_ARGUMENTS (fndecl);
335 for (tree parm = parms; parm; parm = TREE_CHAIN (parm), ++argno)
336 {
337 if (parm != arg)
338 continue;
339
340 const attr_access* access = rdwr_idx.get (argno);
341 if (!access)
342 break;
343
344 if (access->mode != access_none
345 && access->mode != access_write_only)
346 continue;
347
348 location_t stmtloc
349 = linemap_resolve_location (line_table, gimple_location (stmt),
350 LRK_SPELLING_LOCATION, NULL);
351
352 if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized,
353 "%qE may be used uninitialized", ptr))
354 break;
355
356 suppress_warning (arg, OPT_Wmaybe_uninitialized);
357
358 const char* const access_str =
359 TREE_STRING_POINTER (access->to_external_string ());
360
361 location_t parmloc = DECL_SOURCE_LOCATION (parm);
362 inform (parmloc, "accessing argument %u of a function declared with "
363 "attribute %<%s%>",
364 argno + 1, access_str);
365
366 break;
367 }
368 }
369
370 /* Callback for walk_aliased_vdefs. */
371
372 static bool
373 check_defs (ao_ref *ref, tree vdef, void *data_)
374 {
375 check_defs_data *data = (check_defs_data *)data_;
376 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
377
378 /* Ignore the vdef if the definition statement is a call
379 to .DEFERRED_INIT function. */
380 if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
381 return false;
382
383 /* The ASAN_MARK intrinsic doesn't modify the variable. */
384 if (is_gimple_call (def_stmt))
385 {
386 /* The ASAN_MARK intrinsic doesn't modify the variable. */
387 if (gimple_call_internal_p (def_stmt)
388 && gimple_call_internal_fn (def_stmt) == IFN_ASAN_MARK)
389 return false;
390
391 if (tree fndecl = gimple_call_fndecl (def_stmt))
392 {
393 /* Some sanitizer calls pass integer arguments to built-ins
394 that expect pointets. Avoid using gimple_call_builtin_p()
395 which fails for such calls. */
396 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
397 {
398 built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
399 if (fncode > BEGIN_SANITIZER_BUILTINS
400 && fncode < END_SANITIZER_BUILTINS)
401 return false;
402 }
403 }
404 }
405
406 /* End of VLA scope is not a kill. */
407 if (gimple_call_builtin_p (def_stmt, BUILT_IN_STACK_RESTORE))
408 return false;
409
410 /* If this is a clobber then if it is not a kill walk past it. */
411 if (gimple_clobber_p (def_stmt))
412 {
413 if (stmt_kills_ref_p (def_stmt, ref))
414 return true;
415 return false;
416 }
417
418 if (builtin_call_nomodifying_p (def_stmt))
419 return false;
420
421 /* Found a may-def on this path. */
422 data->found_may_defs = true;
423 return true;
424 }
425
426 /* Counters and limits controlling the the depth of analysis and
427 strictness of the warning. */
428 struct wlimits
429 {
430 /* Number of VDEFs encountered. */
431 unsigned int vdef_cnt;
432 /* Number of statements examined by walk_aliased_vdefs. */
433 unsigned int oracle_cnt;
434 /* Limit on the number of statements visited by walk_aliased_vdefs. */
435 unsigned limit;
436 /* Set when basic block with statement is executed unconditionally. */
437 bool always_executed;
438 /* Set to issue -Wmaybe-uninitialized. */
439 bool wmaybe_uninit;
440 };
441
442 /* Determine if REF references an uninitialized operand and diagnose
443 it if so. STMS is the referencing statement. LHS is the result
444 of the access and may be null. RHS is the variable referenced by
445 the access; it may not be null. */
446
447 static tree
448 maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
449 wlimits &wlims)
450 {
451 bool has_bit_insert = false;
452 use_operand_p luse_p;
453 imm_use_iterator liter;
454
455 if (get_no_uninit_warning (rhs))
456 return NULL_TREE;
457
458 /* Do not warn if the base was marked so or this is a
459 hard register var. */
460 tree base = ao_ref_base (&ref);
461 if ((VAR_P (base)
462 && DECL_HARD_REGISTER (base))
463 || get_no_uninit_warning (base))
464 return NULL_TREE;
465
466 /* Do not warn if the access is zero size or if it's fully outside
467 the object. */
468 poly_int64 decl_size;
469 if (known_size_p (ref.size)
470 && known_eq (ref.max_size, ref.size)
471 && (known_eq (ref.size, 0)
472 || known_le (ref.offset + ref.size, 0)))
473 return NULL_TREE;
474
475 if (DECL_P (base)
476 && known_ge (ref.offset, 0)
477 && DECL_SIZE (base)
478 && poly_int_tree_p (DECL_SIZE (base), &decl_size)
479 && known_le (decl_size, ref.offset))
480 return NULL_TREE;
481
482 /* Do not warn if the result of the access is then used for
483 a BIT_INSERT_EXPR. */
484 if (lhs && TREE_CODE (lhs) == SSA_NAME)
485 FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
486 {
487 gimple *use_stmt = USE_STMT (luse_p);
488 /* BIT_INSERT_EXPR first operand should not be considered
489 a use for the purpose of uninit warnings. */
490 if (gassign *ass = dyn_cast <gassign *> (use_stmt))
491 {
492 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
493 && luse_p->use == gimple_assign_rhs1_ptr (ass))
494 {
495 has_bit_insert = true;
496 break;
497 }
498 }
499 }
500
501 if (has_bit_insert)
502 return NULL_TREE;
503
504 /* Limit the walking to a constant number of stmts after
505 we overcommit quadratic behavior for small functions
506 and O(n) behavior. */
507 if (wlims.oracle_cnt > 128 * 128
508 && wlims.oracle_cnt > wlims.vdef_cnt * 2)
509 wlims.limit = 32;
510
511 check_defs_data data;
512 bool fentry_reached = false;
513 data.found_may_defs = false;
514 tree use = gimple_vuse (stmt);
515 if (!use)
516 return NULL_TREE;
517 int res = walk_aliased_vdefs (&ref, use,
518 check_defs, &data, NULL,
519 &fentry_reached, wlims.limit);
520 if (res == -1)
521 {
522 wlims.oracle_cnt += wlims.limit;
523 return NULL_TREE;
524 }
525
526 wlims.oracle_cnt += res;
527 if (data.found_may_defs)
528 return NULL_TREE;
529
530 bool found_alloc = false;
531
532 if (fentry_reached)
533 {
534 if (TREE_CODE (base) == MEM_REF)
535 base = TREE_OPERAND (base, 0);
536
537 /* Follow the chain of SSA_NAME assignments looking for an alloca
538 call (or VLA) or malloc/realloc, or for decls. If any is found
539 (and in the latter case, the operand is a local variable) issue
540 a warning. */
541 while (TREE_CODE (base) == SSA_NAME)
542 {
543 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
544
545 if (is_gimple_call (def_stmt)
546 && gimple_call_builtin_p (def_stmt))
547 {
548 /* Detect uses of uninitialized alloca/VLAs. */
549 tree fndecl = gimple_call_fndecl (def_stmt);
550 const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
551 if (fncode == BUILT_IN_ALLOCA
552 || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
553 || fncode == BUILT_IN_MALLOC)
554 found_alloc = true;
555 break;
556 }
557
558 if (!is_gimple_assign (def_stmt))
559 break;
560
561 tree_code code = gimple_assign_rhs_code (def_stmt);
562 if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
563 break;
564
565 base = gimple_assign_rhs1 (def_stmt);
566 if (TREE_CODE (base) == ADDR_EXPR)
567 base = TREE_OPERAND (base, 0);
568
569 if (DECL_P (base)
570 || TREE_CODE (base) == COMPONENT_REF)
571 rhs = base;
572
573 if (TREE_CODE (base) == MEM_REF)
574 base = TREE_OPERAND (base, 0);
575
576 if (tree ba = get_base_address (base))
577 base = ba;
578 }
579
580 /* Replace the RHS expression with BASE so that it
581 refers to it in the diagnostic (instead of to
582 '<unknown>'). */
583 if (DECL_P (base)
584 && EXPR_P (rhs)
585 && TREE_CODE (rhs) != COMPONENT_REF)
586 rhs = base;
587 }
588
589 /* Do not warn if it can be initialized outside this function.
590 If we did not reach function entry then we found killing
591 clobbers on all paths to entry. */
592 if (!found_alloc && fentry_reached)
593 {
594 if (TREE_CODE (base) == SSA_NAME)
595 {
596 tree var = SSA_NAME_VAR (base);
597 if (var && TREE_CODE (var) == PARM_DECL)
598 {
599 maybe_warn_read_write_only (cfun->decl, stmt, var, rhs);
600 return NULL_TREE;
601 }
602 }
603
604 if (!VAR_P (base)
605 || is_global_var (base))
606 /* ??? We'd like to use ref_may_alias_global_p but that
607 excludes global readonly memory and thus we get bogus
608 warnings from p = cond ? "a" : "b" for example. */
609 return NULL_TREE;
610 }
611
612 /* Strip the address-of expression from arrays passed to functions. */
613 if (TREE_CODE (rhs) == ADDR_EXPR)
614 rhs = TREE_OPERAND (rhs, 0);
615
616 /* Check again since RHS may have changed above. */
617 if (get_no_uninit_warning (rhs))
618 return NULL_TREE;
619
620 /* Avoid warning about empty types such as structs with no members.
621 The first_field() test is important for C++ where the predicate
622 alone isn't always sufficient. */
623 tree rhstype = TREE_TYPE (rhs);
624 if (POINTER_TYPE_P (rhstype))
625 rhstype = TREE_TYPE (rhstype);
626 if (is_empty_type (rhstype))
627 return NULL_TREE;
628
629 bool warned = false;
630 /* We didn't find any may-defs so on all paths either
631 reached function entry or a killing clobber. */
632 location_t location
633 = linemap_resolve_location (line_table, gimple_location (stmt),
634 LRK_SPELLING_LOCATION, NULL);
635 if (wlims.always_executed)
636 {
637 if (warning_at (location, OPT_Wuninitialized,
638 "%qE is used uninitialized", rhs))
639 {
640 /* ??? This is only effective for decls as in
641 gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
642 uses or accesses by functions as it may hide important
643 locations. */
644 if (lhs)
645 set_no_uninit_warning (rhs);
646 warned = true;
647 }
648 }
649 else if (wlims.wmaybe_uninit)
650 warned = warning_at (location, OPT_Wmaybe_uninitialized,
651 "%qE may be used uninitialized", rhs);
652
653 return warned ? base : NULL_TREE;
654 }
655
656
657 /* Diagnose passing addresses of uninitialized objects to either const
658 pointer arguments to functions, or to functions declared with attribute
659 access implying read access to those objects. */
660
661 static void
662 maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
663 {
664 if (!wlims.wmaybe_uninit)
665 return;
666
667 unsigned nargs = gimple_call_num_args (stmt);
668 if (!nargs)
669 return;
670
671 tree fndecl = gimple_call_fndecl (stmt);
672 tree fntype = gimple_call_fntype (stmt);
673 if (!fntype)
674 return;
675
676 /* Const function do not read their arguments. */
677 if (gimple_call_flags (stmt) & ECF_CONST)
678 return;
679
680 const built_in_function fncode
681 = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
682 ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
683
684 if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
685 /* Avoid diagnosing calls to raw memory functions (this is overly
686 permissive; consider tightening it up). */
687 return;
688
689 /* Save the current warning setting and replace it either a "maybe"
690 when passing addresses of uninitialized variables to const-qualified
691 pointers or arguments declared with attribute read_write, or with
692 a "certain" when passing them to arguments declared with attribute
693 read_only. */
694 const bool save_always_executed = wlims.always_executed;
695
696 /* Initialize a map of attribute access specifications for arguments
697 to the function function call. */
698 rdwr_map rdwr_idx;
699 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
700
701 tree argtype;
702 unsigned argno = 0;
703 function_args_iterator it;
704
705 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
706 {
707 ++argno;
708
709 if (!POINTER_TYPE_P (argtype))
710 continue;
711
712 tree access_size = NULL_TREE;
713 const attr_access* access = rdwr_idx.get (argno - 1);
714 if (access)
715 {
716 if (access->mode == access_none
717 || access->mode == access_write_only)
718 continue;
719
720 if (access->mode == access_deferred
721 && !TYPE_READONLY (TREE_TYPE (argtype)))
722 continue;
723
724 if (save_always_executed && access->mode == access_read_only)
725 /* Attribute read_only arguments imply read access. */
726 wlims.always_executed = true;
727 else
728 /* Attribute read_write arguments are documented as requiring
729 initialized objects but it's expected that aggregates may
730 be only partially initialized regardless. */
731 wlims.always_executed = false;
732
733 if (access->sizarg < nargs)
734 access_size = gimple_call_arg (stmt, access->sizarg);
735 }
736 else if (!TYPE_READONLY (TREE_TYPE (argtype)))
737 continue;
738 else if (save_always_executed && fncode != BUILT_IN_LAST)
739 /* Const-qualified arguments to built-ins imply read access. */
740 wlims.always_executed = true;
741 else
742 /* Const-qualified arguments to ordinary functions imply a likely
743 (but not definitive) read access. */
744 wlims.always_executed = false;
745
746 /* Ignore args we are not going to read from. */
747 if (gimple_call_arg_flags (stmt, argno - 1) & (EAF_UNUSED | EAF_NOREAD))
748 continue;
749
750 tree arg = gimple_call_arg (stmt, argno - 1);
751 if (!POINTER_TYPE_P (TREE_TYPE (arg)))
752 /* Avoid actual arguments with invalid types. */
753 continue;
754
755 ao_ref ref;
756 ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
757 tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
758 if (!argbase)
759 continue;
760
761 if (access && access->mode != access_deferred)
762 {
763 const char* const access_str =
764 TREE_STRING_POINTER (access->to_external_string ());
765
766 if (fndecl)
767 {
768 location_t loc = DECL_SOURCE_LOCATION (fndecl);
769 inform (loc, "in a call to %qD declared with "
770 "attribute %<%s%> here", fndecl, access_str);
771 }
772 else
773 {
774 /* Handle calls through function pointers. */
775 location_t loc = gimple_location (stmt);
776 inform (loc, "in a call to %qT declared with "
777 "attribute %<%s%>", fntype, access_str);
778 }
779 }
780 else
781 {
782 /* For a declaration with no relevant attribute access create
783 a dummy object and use the formatting function to avoid
784 having to complicate things here. */
785 attr_access ptr_access = { };
786 if (!access)
787 access = &ptr_access;
788 const std::string argtypestr = access->array_as_string (argtype);
789 if (fndecl)
790 {
791 location_t loc (DECL_SOURCE_LOCATION (fndecl));
792 inform (loc, "by argument %u of type %s to %qD "
793 "declared here",
794 argno, argtypestr.c_str (), fndecl);
795 }
796 else
797 {
798 /* Handle calls through function pointers. */
799 location_t loc (gimple_location (stmt));
800 inform (loc, "by argument %u of type %s to %qT",
801 argno, argtypestr.c_str (), fntype);
802 }
803 }
804
805 if (DECL_P (argbase))
806 {
807 location_t loc = DECL_SOURCE_LOCATION (argbase);
808 inform (loc, "%qD declared here", argbase);
809 }
810 }
811
812 wlims.always_executed = save_always_executed;
813 }
814
815 /* Warn about an uninitialized PHI argument on the fallthru path to
816 an always executed block BB. */
817
818 static void
819 warn_uninit_phi_uses (basic_block bb)
820 {
821 edge_iterator ei;
822 edge e, found = NULL, found_back = NULL;
823 /* Look for a fallthru and possibly a single backedge. */
824 FOR_EACH_EDGE (e, ei, bb->preds)
825 {
826 /* Ignore backedges. */
827 if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
828 {
829 if (found_back)
830 {
831 found = NULL;
832 break;
833 }
834 found_back = e;
835 continue;
836 }
837 if (found)
838 {
839 found = NULL;
840 break;
841 }
842 found = e;
843 }
844 if (!found)
845 return;
846
847 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
848 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
849 gsi_next (&si))
850 {
851 gphi *phi = si.phi ();
852 tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
853 if (TREE_CODE (def) != SSA_NAME
854 || !SSA_NAME_IS_DEFAULT_DEF (def)
855 || virtual_operand_p (def))
856 continue;
857 /* If there's a default def on the fallthru edge PHI
858 value and there's a use that post-dominates entry
859 then that use is uninitialized and we can warn. */
860 imm_use_iterator iter;
861 use_operand_p use_p;
862 gimple *use_stmt = NULL;
863 FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
864 {
865 use_stmt = USE_STMT (use_p);
866 if (gimple_location (use_stmt) != UNKNOWN_LOCATION
867 && dominated_by_p (CDI_POST_DOMINATORS, succ,
868 gimple_bb (use_stmt))
869 /* If we found a non-fallthru edge make sure the
870 use is inside the loop, otherwise the backedge
871 can serve as initialization. */
872 && (!found_back
873 || dominated_by_p (CDI_DOMINATORS, found_back->src,
874 gimple_bb (use_stmt))))
875 break;
876 use_stmt = NULL;
877 }
878 if (use_stmt)
879 warn_uninit (OPT_Wuninitialized, def, SSA_NAME_VAR (def),
880 "%qD is used uninitialized", use_stmt);
881 }
882 }
883
884 /* Issue warnings about reads of uninitialized variables. WMAYBE_UNINIT
885 is true to issue -Wmaybe-uninitialized, otherwise -Wuninitialized. */
886
887 static void
888 warn_uninitialized_vars (bool wmaybe_uninit)
889 {
890 /* Counters and limits controlling the the depth of the warning. */
891 wlimits wlims = { };
892 wlims.wmaybe_uninit = wmaybe_uninit;
893
894 gimple_stmt_iterator gsi;
895 basic_block bb;
896 FOR_EACH_BB_FN (bb, cfun)
897 {
898 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
899 wlims.always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
900
901 if (wlims.always_executed)
902 warn_uninit_phi_uses (bb);
903
904 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
905 {
906 gimple *stmt = gsi_stmt (gsi);
907
908 /* The call is an artificial use, will not provide meaningful
909 error message. If the result of the call is used somewhere
910 else, we warn there instead. */
911 if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
912 continue;
913
914 if (is_gimple_debug (stmt))
915 continue;
916
917 /* We only do data flow with SSA_NAMEs, so that's all we
918 can warn about. */
919 use_operand_p use_p;
920 ssa_op_iter op_iter;
921 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
922 {
923 /* BIT_INSERT_EXPR first operand should not be considered
924 a use for the purpose of uninit warnings. */
925 if (gassign *ass = dyn_cast <gassign *> (stmt))
926 {
927 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
928 && use_p->use == gimple_assign_rhs1_ptr (ass))
929 continue;
930 }
931 tree use = USE_FROM_PTR (use_p);
932 if (wlims.always_executed)
933 warn_uninit (OPT_Wuninitialized, use, SSA_NAME_VAR (use),
934 "%qD is used uninitialized", stmt);
935 else if (wmaybe_uninit)
936 warn_uninit (OPT_Wmaybe_uninitialized, use, SSA_NAME_VAR (use),
937 "%qD may be used uninitialized", stmt);
938 }
939
940 /* For limiting the alias walk below we count all
941 vdefs in the function. */
942 if (gimple_vdef (stmt))
943 wlims.vdef_cnt++;
944
945 if (gcall *call = dyn_cast <gcall *> (stmt))
946 maybe_warn_pass_by_reference (call, wlims);
947 else if (gimple_assign_load_p (stmt)
948 && gimple_has_location (stmt))
949 {
950 tree rhs = gimple_assign_rhs1 (stmt);
951 tree lhs = gimple_assign_lhs (stmt);
952
953 ao_ref ref;
954 ao_ref_init (&ref, rhs);
955 tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
956 if (!var)
957 continue;
958
959 if (DECL_P (var))
960 {
961 location_t loc = DECL_SOURCE_LOCATION (var);
962 inform (loc, "%qD declared here", var);
963 }
964 }
965 }
966 }
967 }
968
969 /* Checks if the operand OPND of PHI is defined by
970 another phi with one operand defined by this PHI,
971 but the rest operands are all defined. If yes,
972 returns true to skip this operand as being
973 redundant. Can be enhanced to be more general. */
974
975 static bool
976 can_skip_redundant_opnd (tree opnd, gimple *phi)
977 {
978 tree phi_def = gimple_phi_result (phi);
979 gimple *op_def = SSA_NAME_DEF_STMT (opnd);
980 if (gimple_code (op_def) != GIMPLE_PHI)
981 return false;
982
983 unsigned n = gimple_phi_num_args (op_def);
984 for (unsigned i = 0; i < n; ++i)
985 {
986 tree op = gimple_phi_arg_def (op_def, i);
987 if (TREE_CODE (op) != SSA_NAME)
988 continue;
989 if (op != phi_def && uninit_undefined_value_p (op))
990 return false;
991 }
992
993 return true;
994 }
995
996 /* Return a bitset holding the positions of arguments in PHI with empty
997 (or possibly empty) definitions. */
998
999 static unsigned
1000 compute_uninit_opnds_pos (gphi *phi)
1001 {
1002 unsigned uninit_opnds = 0;
1003
1004 unsigned n = gimple_phi_num_args (phi);
1005 /* Bail out for phi with too many args. */
1006 if (n > predicate::func_t::max_phi_args)
1007 return 0;
1008
1009 for (unsigned i = 0; i < n; ++i)
1010 {
1011 tree op = gimple_phi_arg_def (phi, i);
1012 if (TREE_CODE (op) == SSA_NAME
1013 && uninit_undefined_value_p (op)
1014 && !can_skip_redundant_opnd (op, phi))
1015 {
1016 if (cfun->has_nonlocal_label || cfun->calls_setjmp)
1017 {
1018 /* Ignore SSA_NAMEs that appear on abnormal edges
1019 somewhere. */
1020 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
1021 continue;
1022 }
1023 MASK_SET_BIT (uninit_opnds, i);
1024 }
1025 }
1026 return uninit_opnds;
1027 }
1028
1029 /* Function object type used to determine whether an expression
1030 is of interest to the predicate analyzer. */
1031
1032 struct uninit_undef_val_t: public predicate::func_t
1033 {
1034 virtual bool operator()(tree) override;
1035 virtual unsigned phi_arg_set (gphi *) override;
1036 };
1037
1038 /* Return true if the argument is an expression of interest. */
1039
1040 bool
1041 uninit_undef_val_t::operator()(tree val)
1042 {
1043 if (TREE_CODE (val) == SSA_NAME)
1044 return uninit_undefined_value_p (val);
1045
1046 return false;
1047 }
1048
1049 /* Return a bitset of PHI arguments of interest. */
1050
1051 unsigned
1052 uninit_undef_val_t::phi_arg_set (gphi *phi)
1053 {
1054 return compute_uninit_opnds_pos (phi);
1055 }
1056
1057 /* Searches through all uses of a potentially
1058 uninitialized variable defined by PHI and returns a use
1059 statement if the use is not properly guarded. It returns
1060 NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
1061 holding the position(s) of uninit PHI operands. WORKLIST
1062 is the vector of candidate phis that may be updated by this
1063 function. ADDED_TO_WORKLIST is the pointer set tracking
1064 if the new phi is already in the worklist. */
1065
1066 static gimple *
1067 find_uninit_use (gphi *phi, unsigned uninit_opnds,
1068 vec<gphi *> *worklist, hash_set<gphi *> *added_to_worklist)
1069 {
1070 /* The Boolean predicate guarding the PHI definition. Initialized
1071 lazily from PHI in the first call to is_use_guarded() and cached
1072 for subsequent iterations. */
1073 uninit_undef_val_t eval;
1074 predicate def_preds (eval);
1075
1076 use_operand_p use_p;
1077 imm_use_iterator iter;
1078 tree phi_result = gimple_phi_result (phi);
1079 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1080 {
1081 gimple *use_stmt = USE_STMT (use_p);
1082 if (is_gimple_debug (use_stmt))
1083 continue;
1084
1085 basic_block use_bb;
1086 if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
1087 use_bb = gimple_phi_arg_edge (use_phi,
1088 PHI_ARG_INDEX_FROM_USE (use_p))->src;
1089 else
1090 use_bb = gimple_bb (use_stmt);
1091
1092 if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds))
1093 continue;
1094
1095 if (dump_file && (dump_flags & TDF_DETAILS))
1096 {
1097 fprintf (dump_file, "Found unguarded use in bb %u: ",
1098 use_bb->index);
1099 print_gimple_stmt (dump_file, use_stmt, 0);
1100 }
1101 /* Found one real use, return. */
1102 if (gimple_code (use_stmt) != GIMPLE_PHI)
1103 return use_stmt;
1104
1105 /* Found a phi use that is not guarded,
1106 add the phi to the worklist. */
1107 if (!added_to_worklist->add (as_a<gphi *> (use_stmt)))
1108 {
1109 if (dump_file && (dump_flags & TDF_DETAILS))
1110 {
1111 fprintf (dump_file, "[WORKLIST]: Update worklist with phi: ");
1112 print_gimple_stmt (dump_file, use_stmt, 0);
1113 }
1114
1115 worklist->safe_push (as_a<gphi *> (use_stmt));
1116 possibly_undefined_names->add (phi_result);
1117 }
1118 }
1119
1120 return NULL;
1121 }
1122
1123 /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1124 and gives warning if there exists a runtime path from the entry to a
1125 use of the PHI def that does not contain a definition. In other words,
1126 the warning is on the real use. The more dead paths that can be pruned
1127 by the compiler, the fewer false positives the warning is. WORKLIST
1128 is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is
1129 a pointer set tracking if the new phi is added to the worklist or not. */
1130
1131 static void
1132 warn_uninitialized_phi (gphi *phi, vec<gphi *> *worklist,
1133 hash_set<gphi *> *added_to_worklist)
1134 {
1135 /* Don't look at virtual operands. */
1136 if (virtual_operand_p (gimple_phi_result (phi)))
1137 return;
1138
1139 unsigned uninit_opnds = compute_uninit_opnds_pos (phi);
1140 if (MASK_EMPTY (uninit_opnds))
1141 return;
1142
1143 if (dump_file && (dump_flags & TDF_DETAILS))
1144 {
1145 fprintf (dump_file, "Examining phi: ");
1146 print_gimple_stmt (dump_file, phi, 0);
1147 }
1148
1149 gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds,
1150 worklist, added_to_worklist);
1151
1152 /* All uses are properly guarded but a new PHI may have been added
1153 to WORKLIST. */
1154 if (!uninit_use_stmt)
1155 return;
1156
1157 unsigned phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
1158 tree uninit_op = gimple_phi_arg_def (phi, phiarg_index);
1159 if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
1160 return;
1161
1162 location_t loc = UNKNOWN_LOCATION;
1163 if (gimple_phi_arg_has_location (phi, phiarg_index))
1164 loc = gimple_phi_arg_location (phi, phiarg_index);
1165 else
1166 {
1167 tree arg_def = gimple_phi_arg_def (phi, phiarg_index);
1168 if (TREE_CODE (arg_def) == SSA_NAME)
1169 {
1170 gimple *def_stmt = SSA_NAME_DEF_STMT (arg_def);
1171 if (gphi *arg_phi = dyn_cast<gphi *> (def_stmt))
1172 {
1173 unsigned uop = compute_uninit_opnds_pos (arg_phi);
1174 unsigned idx = MASK_FIRST_SET_BIT (uop);
1175 if (idx < gimple_phi_num_args (arg_phi)
1176 && gimple_phi_arg_has_location (arg_phi, idx))
1177 loc = gimple_phi_arg_location (arg_phi, idx);
1178 }
1179 }
1180 }
1181
1182 warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1183 SSA_NAME_VAR (uninit_op),
1184 "%qD may be used uninitialized in this function",
1185 uninit_use_stmt, loc);
1186 }
1187
1188 static bool
1189 gate_warn_uninitialized (void)
1190 {
1191 return warn_uninitialized || warn_maybe_uninitialized;
1192 }
1193
1194 namespace {
1195
1196 const pass_data pass_data_late_warn_uninitialized =
1197 {
1198 GIMPLE_PASS, /* type */
1199 "uninit", /* name */
1200 OPTGROUP_NONE, /* optinfo_flags */
1201 TV_NONE, /* tv_id */
1202 PROP_ssa, /* properties_required */
1203 0, /* properties_provided */
1204 0, /* properties_destroyed */
1205 0, /* todo_flags_start */
1206 0, /* todo_flags_finish */
1207 };
1208
1209 class pass_late_warn_uninitialized : public gimple_opt_pass
1210 {
1211 public:
1212 pass_late_warn_uninitialized (gcc::context *ctxt)
1213 : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
1214 {}
1215
1216 /* opt_pass methods: */
1217 opt_pass *clone () { return new pass_late_warn_uninitialized (m_ctxt); }
1218 virtual bool gate (function *) { return gate_warn_uninitialized (); }
1219 virtual unsigned int execute (function *);
1220
1221 }; // class pass_late_warn_uninitialized
1222
1223 static void
1224 execute_late_warn_uninitialized (function *fun)
1225 {
1226 basic_block bb;
1227 gphi_iterator gsi;
1228 vec<gphi *> worklist = vNULL;
1229
1230 calculate_dominance_info (CDI_DOMINATORS);
1231 calculate_dominance_info (CDI_POST_DOMINATORS);
1232 /* Re-do the plain uninitialized variable check, as optimization may have
1233 straightened control flow. Do this first so that we don't accidentally
1234 get a "may be" warning when we'd have seen an "is" warning later. */
1235 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
1236
1237 timevar_push (TV_TREE_UNINIT);
1238
1239 possibly_undefined_names = new hash_set<tree>;
1240 hash_set<gphi *> added_to_worklist;
1241
1242 /* Initialize worklist */
1243 FOR_EACH_BB_FN (bb, fun)
1244 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1245 {
1246 gphi *phi = gsi.phi ();
1247
1248 /* Don't look at virtual operands. */
1249 if (virtual_operand_p (gimple_phi_result (phi)))
1250 continue;
1251
1252 unsigned n = gimple_phi_num_args (phi);
1253 for (unsigned i = 0; i < n; ++i)
1254 {
1255 tree op = gimple_phi_arg_def (phi, i);
1256 if (TREE_CODE (op) == SSA_NAME && uninit_undefined_value_p (op))
1257 {
1258 worklist.safe_push (phi);
1259 added_to_worklist.add (phi);
1260 if (dump_file && (dump_flags & TDF_DETAILS))
1261 {
1262 fprintf (dump_file, "[WORKLIST]: add to initial list "
1263 "for operand %u of: ", i);
1264 print_gimple_stmt (dump_file, phi, 0);
1265 }
1266 break;
1267 }
1268 }
1269 }
1270
1271 while (worklist.length () != 0)
1272 {
1273 gphi *cur_phi = 0;
1274 cur_phi = worklist.pop ();
1275 warn_uninitialized_phi (cur_phi, &worklist, &added_to_worklist);
1276 }
1277
1278 worklist.release ();
1279 delete possibly_undefined_names;
1280 possibly_undefined_names = NULL;
1281 free_dominance_info (CDI_POST_DOMINATORS);
1282 timevar_pop (TV_TREE_UNINIT);
1283 }
1284
1285 unsigned int
1286 pass_late_warn_uninitialized::execute (function *fun)
1287 {
1288 execute_late_warn_uninitialized (fun);
1289 return 0;
1290 }
1291
1292 } // anon namespace
1293
1294 gimple_opt_pass *
1295 make_pass_late_warn_uninitialized (gcc::context *ctxt)
1296 {
1297 return new pass_late_warn_uninitialized (ctxt);
1298 }
1299
1300 static unsigned int
1301 execute_early_warn_uninitialized (void)
1302 {
1303 /* Currently, this pass runs always but
1304 execute_late_warn_uninitialized only runs with optimization. With
1305 optimization we want to warn about possible uninitialized as late
1306 as possible, thus don't do it here. However, without
1307 optimization we need to warn here about "may be uninitialized". */
1308 calculate_dominance_info (CDI_DOMINATORS);
1309 calculate_dominance_info (CDI_POST_DOMINATORS);
1310
1311 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
1312
1313 /* Post-dominator information cannot be reliably updated. Free it
1314 after the use. */
1315
1316 free_dominance_info (CDI_POST_DOMINATORS);
1317 return 0;
1318 }
1319
1320 namespace {
1321
1322 const pass_data pass_data_early_warn_uninitialized =
1323 {
1324 GIMPLE_PASS, /* type */
1325 "*early_warn_uninitialized", /* name */
1326 OPTGROUP_NONE, /* optinfo_flags */
1327 TV_TREE_UNINIT, /* tv_id */
1328 PROP_ssa, /* properties_required */
1329 0, /* properties_provided */
1330 0, /* properties_destroyed */
1331 0, /* todo_flags_start */
1332 0, /* todo_flags_finish */
1333 };
1334
1335 class pass_early_warn_uninitialized : public gimple_opt_pass
1336 {
1337 public:
1338 pass_early_warn_uninitialized (gcc::context *ctxt)
1339 : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
1340 {}
1341
1342 /* opt_pass methods: */
1343 virtual bool gate (function *) { return gate_warn_uninitialized (); }
1344 virtual unsigned int execute (function *)
1345 {
1346 return execute_early_warn_uninitialized ();
1347 }
1348
1349 }; // class pass_early_warn_uninitialized
1350
1351 } // anon namespace
1352
1353 gimple_opt_pass *
1354 make_pass_early_warn_uninitialized (gcc::context *ctxt)
1355 {
1356 return new pass_early_warn_uninitialized (ctxt);
1357 }