aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa.c')
-rw-r--r--gcc/tree-ssa.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index fb692f8..eed15c6 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1411,6 +1411,10 @@ warn_uninit (tree t, const char *gmsgid, void *data)
if (TREE_NO_WARNING (var))
return;
+ /* Do not warn if it can be initialized outside this module. */
+ if (is_global_var (var))
+ return;
+
location = (context != NULL && gimple_has_location (context))
? gimple_location (context)
: DECL_SOURCE_LOCATION (var);
@@ -1443,8 +1447,46 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_)
struct walk_data *data = (struct walk_data *) wi->info;
tree t = *tp;
+ /* We do not care about LHS. */
+ if (wi->is_lhs)
+ return NULL_TREE;
+
switch (TREE_CODE (t))
{
+ case ADDR_EXPR:
+ /* Taking the address of an uninitialized variable does not
+ count as using it. */
+ *walk_subtrees = 0;
+ break;
+
+ case VAR_DECL:
+ {
+ /* A VAR_DECL in the RHS of a gimple statement may mean that
+ this variable is loaded from memory. */
+ use_operand_p vuse;
+ tree op;
+
+ /* If there is not gimple stmt,
+ or alias information has not been computed,
+ then we cannot check VUSE ops. */
+ if (data->stmt == NULL
+ || !gimple_aliases_computed_p (cfun))
+ return NULL_TREE;
+
+ vuse = SINGLE_SSA_USE_OPERAND (data->stmt, SSA_OP_VUSE);
+ if (vuse == NULL_USE_OPERAND_P)
+ return NULL_TREE;
+
+ op = USE_FROM_PTR (vuse);
+ if (t != SSA_NAME_VAR (op)
+ || !SSA_NAME_IS_DEFAULT_DEF (op))
+ return NULL_TREE;
+ /* If this is a VUSE of t and it is the default definition,
+ then warn about op. */
+ t = op;
+ /* Fall through into SSA_NAME. */
+ }
+
case SSA_NAME:
/* We only do data flow with SSA_NAMEs, so that's all we
can warn about. */