aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-uninit.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-07-22 12:26:16 +0200
committerRichard Biener <rguenther@suse.de>2021-07-27 10:46:22 +0200
commit66030d68a7edfc9504a50469598e0707b8f787ce (patch)
treea005e80a5eacf12378a75971b856ed6c0d9771a7 /gcc/tree-ssa-uninit.c
parentc8ce54c6e67295b70052d1b9f9a2f7ce9e2f8f0d (diff)
downloadgcc-66030d68a7edfc9504a50469598e0707b8f787ce.zip
gcc-66030d68a7edfc9504a50469598e0707b8f787ce.tar.gz
gcc-66030d68a7edfc9504a50469598e0707b8f787ce.tar.bz2
tree-optimization/101573 - improve uninit warning at -O0
We can improve uninit warnings from the early pass by looking at PHI arguments on fallthru edges that are uninitialized and have uses that are before a possible loop exit. This catches some cases earlier that we'd only warn in a more confusing way after early inlining as seen by testcase adjustments. It introduces FAIL: gcc.dg/uninit-23.c (test for excess errors) where we additionally warn gcc.dg/uninit-23.c:21:13: warning: 't4' is used uninitialized [-Wuninitialized] which I think is OK even if it's not obvious that the new warning is an improvement when you look at the obvious source. Somehow for all cases I never get the `'foo' was declared here` notes, I didn't dig why that happens but it's odd. 2021-07-22 Richard Biener <rguenther@suse.de> PR tree-optimization/101573 * tree-ssa-uninit.c (warn_uninit_phi_uses): New function looking at uninitialized PHI arg defs in some constrained cases. (warn_uninitialized_vars): Call it. (execute_early_warn_uninitialized): Calculate dominators. * gcc.dg/uninit-pr101573.c: New testcase. * gcc.dg/uninit-15-O0.c: Adjust. * gcc.dg/uninit-15.c: Likewise. * gcc.dg/uninit-23.c: Likewise. * c-c++-common/uninit-17.c: Likewise.
Diffstat (limited to 'gcc/tree-ssa-uninit.c')
-rw-r--r--gcc/tree-ssa-uninit.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 148f3c2..718b326 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -638,6 +638,76 @@ maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
wlims.always_executed = save_always_executed;
}
+/* Warn about an uninitialized PHI argument on the fallthru path to
+ an always executed block BB. */
+
+static void
+warn_uninit_phi_uses (basic_block bb)
+{
+ edge_iterator ei;
+ edge e, found = NULL, found_back = NULL;
+ /* Look for a fallthru and possibly a single backedge. */
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ /* Ignore backedges. */
+ if (dominated_by_p (CDI_DOMINATORS, e->src, bb))
+ {
+ if (found_back)
+ {
+ found = NULL;
+ break;
+ }
+ found_back = e;
+ continue;
+ }
+ if (found)
+ {
+ found = NULL;
+ break;
+ }
+ found = e;
+ }
+ if (!found)
+ return;
+
+ basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
+ gsi_next (&si))
+ {
+ gphi *phi = si.phi ();
+ tree def = PHI_ARG_DEF_FROM_EDGE (phi, found);
+ if (TREE_CODE (def) != SSA_NAME
+ || !SSA_NAME_IS_DEFAULT_DEF (def)
+ || virtual_operand_p (def))
+ continue;
+ /* If there's a default def on the fallthru edge PHI
+ value and there's a use that post-dominates entry
+ then that use is uninitialized and we can warn. */
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ gimple *use_stmt = NULL;
+ FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
+ {
+ use_stmt = USE_STMT (use_p);
+ if (gimple_location (use_stmt) != UNKNOWN_LOCATION
+ && dominated_by_p (CDI_POST_DOMINATORS, succ,
+ gimple_bb (use_stmt))
+ /* If we found a non-fallthru edge make sure the
+ use is inside the loop, otherwise the backedge
+ can serve as initialization. */
+ && (!found_back
+ || dominated_by_p (CDI_DOMINATORS, found_back->src,
+ gimple_bb (use_stmt))))
+ break;
+ use_stmt = NULL;
+ }
+ if (use_stmt)
+ warn_uninit (OPT_Wuninitialized, def, SSA_NAME_VAR (def),
+ SSA_NAME_VAR (def),
+ "%qD is used uninitialized", use_stmt,
+ UNKNOWN_LOCATION);
+ }
+}
static unsigned int
warn_uninitialized_vars (bool wmaybe_uninit)
@@ -652,6 +722,10 @@ warn_uninitialized_vars (bool wmaybe_uninit)
{
basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
wlims.always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
+
+ if (wlims.always_executed)
+ warn_uninit_phi_uses (bb);
+
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple *stmt = gsi_stmt (gsi);
@@ -3135,6 +3209,7 @@ execute_early_warn_uninitialized (void)
optimization we want to warn about possible uninitialized as late
as possible, thus don't do it here. However, without
optimization we need to warn here about "may be uninitialized". */
+ calculate_dominance_info (CDI_DOMINATORS);
calculate_dominance_info (CDI_POST_DOMINATORS);
warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);