tree-flow.h (ssa_undefined_value_p): Remove prototype.
authorAndrew MacLeod <amacleod@redhat.com>
Tue, 17 Sep 2013 17:22:05 +0000 (17:22 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Tue, 17 Sep 2013 17:22:05 +0000 (17:22 +0000)
2013-09-17  Andrew MacLeod <amacleod@redhat.com>

* tree-flow.h (ssa_undefined_value_p): Remove prototype.
* tree-ssa.c (ssa_undefined_value_p): Move pass independent parts here.
(warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized,
make_pass_early_warn_uninitialized): Move to tree-ssa-uninit.c.
* tree-ssa-uninit.c (ssa_undefined_value_p): Move to tree-ssa.c
(has_undefined_value_p): New.  Pass dependant parts of
ssa_undefined_value_p.
(uninit_undefined_value_p): Use has_undefined_value_p.
(warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized,
make_pass_early_warn_uninitialized): Move from tree-ssa.c
* tree-ssa.h: Adjust prototypes

From-SVN: r202659

gcc/ChangeLog
gcc/tree-flow.h
gcc/tree-ssa-uninit.c
gcc/tree-ssa.c
gcc/tree-ssa.h

index 3f3a1bc3d7cce59169a1f1f5f96a86f74fc830d9..eb162f4a2b2125e86da17e9c04a232681fea1306 100644 (file)
@@ -1,3 +1,17 @@
+2013-09-17  Andrew MacLeod <amacleod@redhat.com>
+
+       * tree-flow.h (ssa_undefined_value_p): Remove prototype.
+       * tree-ssa.c (ssa_undefined_value_p): Move pass independent parts here.
+       (warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized,
+       make_pass_early_warn_uninitialized): Move to tree-ssa-uninit.c.
+       * tree-ssa-uninit.c (ssa_undefined_value_p): Move to tree-ssa.c
+       (has_undefined_value_p): New.  Pass dependant parts of 
+       ssa_undefined_value_p.
+       (uninit_undefined_value_p): Use has_undefined_value_p.
+       (warn_uninit, warn_uninitialized_vars, execute_early_warn_uninitialized,
+       make_pass_early_warn_uninitialized): Move from tree-ssa.c
+       * tree-ssa.h: Adjust prototypes
+
 2013-09-17  Jan Hubicka  <jh@suse.cz>
 
        PR middle-end/58329
index 9c5d979872d0ac40f3ca4e23f8125f12b931d4e5..2f64abc2bbde7a52e984fb2a4b782d0defed0f88 100644 (file)
@@ -421,9 +421,6 @@ extern bool gimple_seq_may_fallthru (gimple_seq);
 extern bool gimple_stmt_may_fallthru (gimple);
 extern bool gimple_check_call_matching_types (gimple, tree, bool);
 
-/* In tree-ssa-uninit.c  */
-extern bool ssa_undefined_value_p (tree);
-
 /* In tree-into-ssa.c  */
 void update_ssa (unsigned);
 void delete_update_ssa (void);
index ae30e244a1ca4319fb892c59ee5b17b2db4e1abd..bd46ddfb18ee08df6cef31f485854fb1e4f53344 100644 (file)
@@ -74,46 +74,173 @@ get_mask_first_set_bit (unsigned mask)
 }
 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
 
-
 /* Return true if T, an SSA_NAME, has an undefined value.  */
-
-bool
-ssa_undefined_value_p (tree t)
+static bool
+has_undefined_value_p (tree t)
 {
-  tree var = SSA_NAME_VAR (t);
-
-  if (!var)
-    ;
-  /* Parameters get their initial value from the function entry.  */
-  else if (TREE_CODE (var) == PARM_DECL)
-    return false;
-  /* When returning by reference the return address is actually a hidden
-     parameter.  */
-  else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var))
-    return false;
-  /* Hard register variables get their initial value from the ether.  */
-  else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
-    return false;
-
-  /* The value is undefined iff its definition statement is empty.  */
-  return (gimple_nop_p (SSA_NAME_DEF_STMT (t))
+  return (ssa_undefined_value_p (t)
           || (possibly_undefined_names
               && pointer_set_contains (possibly_undefined_names, t)));
 }
 
-/* Like ssa_undefined_value_p, but don't return true if TREE_NO_WARNING
+
+
+/* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING
    is set on SSA_NAME_VAR.  */
 
 static inline bool
-uninit_undefined_value_p (tree t)
-{
-  if (!ssa_undefined_value_p (t))
+uninit_undefined_value_p (tree t) {
+  if (!has_undefined_value_p (t))
     return false;
   if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t)))
     return false;
   return true;
 }
 
+/* Emit warnings for uninitialized variables.  This is done in two passes.
+
+   The first pass notices real uses of SSA names with undefined values.
+   Such uses are unconditionally uninitialized, and we can be certain that
+   such a use is a mistake.  This pass is run before most optimizations,
+   so that we catch as many as we can.
+
+   The second pass follows PHI nodes to find uses that are potentially
+   uninitialized.  In this case we can't necessarily prove that the use
+   is really uninitialized.  This pass is run after most optimizations,
+   so that we thread as many jumps and possible, and delete as much dead
+   code as possible, in order to reduce false positives.  We also look
+   again for plain uninitialized variables, since optimization may have
+   changed conditionally uninitialized to unconditionally uninitialized.  */
+
+/* Emit a warning for EXPR based on variable VAR at the point in the
+   program T, an SSA_NAME, is used being uninitialized.  The exact
+   warning text is in MSGID and LOCUS may contain a location or be null.
+   WC is the warning code.  */
+
+static void
+warn_uninit (enum opt_code wc, tree t,
+            tree expr, tree var, const char *gmsgid, void *data)
+{
+  gimple context = (gimple) data;
+  location_t location, cfun_loc;
+  expanded_location xloc, floc;
+
+  if (!has_undefined_value_p (t))
+    return;
+
+  /* TREE_NO_WARNING either means we already warned, or the front end
+     wishes to suppress the warning.  */
+  if ((context
+       && (gimple_no_warning_p (context)
+          || (gimple_assign_single_p (context)
+              && TREE_NO_WARNING (gimple_assign_rhs1 (context)))))
+      || TREE_NO_WARNING (expr))
+    return;
+
+  location = (context != NULL && gimple_has_location (context))
+            ? gimple_location (context)
+            : DECL_SOURCE_LOCATION (var);
+  location = linemap_resolve_location (line_table, location,
+                                      LRK_SPELLING_LOCATION,
+                                      NULL);
+  cfun_loc = DECL_SOURCE_LOCATION (cfun->decl);
+  xloc = expand_location (location);
+  floc = expand_location (cfun_loc);
+  if (warning_at (location, wc, gmsgid, expr))
+    {
+      TREE_NO_WARNING (expr) = 1;
+
+      if (location == DECL_SOURCE_LOCATION (var))
+       return;
+      if (xloc.file != floc.file
+         || linemap_location_before_p (line_table,
+                                       location, cfun_loc)
+         || linemap_location_before_p (line_table,
+                                       cfun->function_end_locus,
+                                       location))
+       inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
+    }
+}
+
+static unsigned int
+warn_uninitialized_vars (bool warn_possibly_uninitialized)
+{
+  gimple_stmt_iterator gsi;
+  basic_block bb;
+
+  FOR_EACH_BB (bb)
+    {
+      bool always_executed = dominated_by_p (CDI_POST_DOMINATORS,
+                                            single_succ (ENTRY_BLOCK_PTR), bb);
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       {
+         gimple stmt = gsi_stmt (gsi);
+         use_operand_p use_p;
+         ssa_op_iter op_iter;
+         tree use;
+
+         if (is_gimple_debug (stmt))
+           continue;
+
+         /* We only do data flow with SSA_NAMEs, so that's all we
+            can warn about.  */
+         FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
+           {
+             use = USE_FROM_PTR (use_p);
+             if (always_executed)
+               warn_uninit (OPT_Wuninitialized, use,
+                            SSA_NAME_VAR (use), SSA_NAME_VAR (use),
+                            "%qD is used uninitialized in this function",
+                            stmt);
+             else if (warn_possibly_uninitialized)
+               warn_uninit (OPT_Wmaybe_uninitialized, use,
+                            SSA_NAME_VAR (use), SSA_NAME_VAR (use),
+                            "%qD may be used uninitialized in this function",
+                            stmt);
+           }
+
+         /* For memory the only cheap thing we can do is see if we
+            have a use of the default def of the virtual operand.
+            ???  Note that at -O0 we do not have virtual operands.
+            ???  Not so cheap would be to use the alias oracle via
+            walk_aliased_vdefs, if we don't find any aliasing vdef
+            warn as is-used-uninitialized, if we don't find an aliasing
+            vdef that kills our use (stmt_kills_ref_p), warn as
+            may-be-used-uninitialized.  But this walk is quadratic and
+            so must be limited which means we would miss warning
+            opportunities.  */
+         use = gimple_vuse (stmt);
+         if (use
+             && gimple_assign_single_p (stmt)
+             && !gimple_vdef (stmt)
+             && SSA_NAME_IS_DEFAULT_DEF (use))
+           {
+             tree rhs = gimple_assign_rhs1 (stmt);
+             tree base = get_base_address (rhs);
+
+             /* Do not warn if it can be initialized outside this function.  */
+             if (TREE_CODE (base) != VAR_DECL
+                 || DECL_HARD_REGISTER (base)
+                 || is_global_var (base))
+               continue;
+
+             if (always_executed)
+               warn_uninit (OPT_Wuninitialized, use, 
+                            gimple_assign_rhs1 (stmt), base,
+                            "%qE is used uninitialized in this function",
+                            stmt);
+             else if (warn_possibly_uninitialized)
+               warn_uninit (OPT_Wmaybe_uninitialized, use,
+                            gimple_assign_rhs1 (stmt), base,
+                            "%qE may be used uninitialized in this function",
+                            stmt);
+           }
+       }
+    }
+
+  return 0;
+}
+
 /* Checks if the operand OPND of PHI is defined by 
    another phi with one operand defined by this PHI, 
    but the rest operands are all defined. If yes, 
@@ -2084,3 +2211,65 @@ make_pass_late_warn_uninitialized (gcc::context *ctxt)
 {
   return new pass_late_warn_uninitialized (ctxt);
 }
+
+
+static unsigned int
+execute_early_warn_uninitialized (void)
+{
+  /* Currently, this pass runs always but
+     execute_late_warn_uninitialized only runs with optimization. With
+     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_POST_DOMINATORS);
+
+  warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
+
+  /* Post-dominator information can not be reliably updated. Free it
+     after the use.  */
+
+  free_dominance_info (CDI_POST_DOMINATORS);
+  return 0;
+}
+
+
+namespace {
+
+const pass_data pass_data_early_warn_uninitialized =
+{
+  GIMPLE_PASS, /* type */
+  "*early_warn_uninitialized", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  true, /* has_gate */
+  true, /* has_execute */
+  TV_TREE_UNINIT, /* tv_id */
+  PROP_ssa, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_early_warn_uninitialized : public gimple_opt_pass
+{
+public:
+  pass_early_warn_uninitialized(gcc::context *ctxt)
+    : gimple_opt_pass(pass_data_early_warn_uninitialized, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  bool gate () { return gate_warn_uninitialized (); }
+  unsigned int execute () { return execute_early_warn_uninitialized (); }
+
+}; // class pass_early_warn_uninitialized
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_early_warn_uninitialized (gcc::context *ctxt)
+{
+  return new pass_early_warn_uninitialized (ctxt);
+}
+
+
index 461bb52e821de5b427dfca112a3d31b9247ebfc8..8146e1fed1d46ed1ba1bb01c612ecb86c3de597c 100644 (file)
@@ -1193,6 +1193,31 @@ tree_ssa_strip_useless_type_conversions (tree exp)
 }
 
 
+/* Return true if T, an SSA_NAME, has an undefined value.  */
+
+bool
+ssa_undefined_value_p (tree t)
+{
+  tree var = SSA_NAME_VAR (t);
+
+  if (!var)
+    ;
+  /* Parameters get their initial value from the function entry.  */
+  else if (TREE_CODE (var) == PARM_DECL)
+    return false;
+  /* When returning by reference the return address is actually a hidden
+     parameter.  */
+  else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var))
+    return false;
+  /* Hard register variables get their initial value from the ether.  */
+  else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
+    return false;
+
+  /* The value is undefined iff its definition statement is empty.  */
+  return gimple_nop_p (SSA_NAME_DEF_STMT (t));
+}
+
+
 /* Internal helper for walk_use_def_chains.  VAR, FN and DATA are as
    described in walk_use_def_chains.
 
@@ -1301,215 +1326,6 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
     }
 }
 
-\f
-/* Emit warnings for uninitialized variables.  This is done in two passes.
-
-   The first pass notices real uses of SSA names with undefined values.
-   Such uses are unconditionally uninitialized, and we can be certain that
-   such a use is a mistake.  This pass is run before most optimizations,
-   so that we catch as many as we can.
-
-   The second pass follows PHI nodes to find uses that are potentially
-   uninitialized.  In this case we can't necessarily prove that the use
-   is really uninitialized.  This pass is run after most optimizations,
-   so that we thread as many jumps and possible, and delete as much dead
-   code as possible, in order to reduce false positives.  We also look
-   again for plain uninitialized variables, since optimization may have
-   changed conditionally uninitialized to unconditionally uninitialized.  */
-
-/* Emit a warning for EXPR based on variable VAR at the point in the
-   program T, an SSA_NAME, is used being uninitialized.  The exact
-   warning text is in MSGID and LOCUS may contain a location or be null.
-   WC is the warning code.  */
-
-void
-warn_uninit (enum opt_code wc, tree t,
-            tree expr, tree var, const char *gmsgid, void *data)
-{
-  gimple context = (gimple) data;
-  location_t location, cfun_loc;
-  expanded_location xloc, floc;
-
-  if (!ssa_undefined_value_p (t))
-    return;
-
-  /* TREE_NO_WARNING either means we already warned, or the front end
-     wishes to suppress the warning.  */
-  if ((context
-       && (gimple_no_warning_p (context)
-          || (gimple_assign_single_p (context)
-              && TREE_NO_WARNING (gimple_assign_rhs1 (context)))))
-      || TREE_NO_WARNING (expr))
-    return;
-
-  location = (context != NULL && gimple_has_location (context))
-            ? gimple_location (context)
-            : DECL_SOURCE_LOCATION (var);
-  location = linemap_resolve_location (line_table, location,
-                                      LRK_SPELLING_LOCATION,
-                                      NULL);
-  cfun_loc = DECL_SOURCE_LOCATION (cfun->decl);
-  xloc = expand_location (location);
-  floc = expand_location (cfun_loc);
-  if (warning_at (location, wc, gmsgid, expr))
-    {
-      TREE_NO_WARNING (expr) = 1;
-
-      if (location == DECL_SOURCE_LOCATION (var))
-       return;
-      if (xloc.file != floc.file
-         || linemap_location_before_p (line_table,
-                                       location, cfun_loc)
-         || linemap_location_before_p (line_table,
-                                       cfun->function_end_locus,
-                                       location))
-       inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
-    }
-}
-
-unsigned int
-warn_uninitialized_vars (bool warn_possibly_uninitialized)
-{
-  gimple_stmt_iterator gsi;
-  basic_block bb;
-
-  FOR_EACH_BB (bb)
-    {
-      bool always_executed = dominated_by_p (CDI_POST_DOMINATORS,
-                                            single_succ (ENTRY_BLOCK_PTR), bb);
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-       {
-         gimple stmt = gsi_stmt (gsi);
-         use_operand_p use_p;
-         ssa_op_iter op_iter;
-         tree use;
-
-         if (is_gimple_debug (stmt))
-           continue;
-
-         /* We only do data flow with SSA_NAMEs, so that's all we
-            can warn about.  */
-         FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
-           {
-             use = USE_FROM_PTR (use_p);
-             if (always_executed)
-               warn_uninit (OPT_Wuninitialized, use,
-                            SSA_NAME_VAR (use), SSA_NAME_VAR (use),
-                            "%qD is used uninitialized in this function",
-                            stmt);
-             else if (warn_possibly_uninitialized)
-               warn_uninit (OPT_Wmaybe_uninitialized, use,
-                            SSA_NAME_VAR (use), SSA_NAME_VAR (use),
-                            "%qD may be used uninitialized in this function",
-                            stmt);
-           }
-
-         /* For memory the only cheap thing we can do is see if we
-            have a use of the default def of the virtual operand.
-            ???  Note that at -O0 we do not have virtual operands.
-            ???  Not so cheap would be to use the alias oracle via
-            walk_aliased_vdefs, if we don't find any aliasing vdef
-            warn as is-used-uninitialized, if we don't find an aliasing
-            vdef that kills our use (stmt_kills_ref_p), warn as
-            may-be-used-uninitialized.  But this walk is quadratic and
-            so must be limited which means we would miss warning
-            opportunities.  */
-         use = gimple_vuse (stmt);
-         if (use
-             && gimple_assign_single_p (stmt)
-             && !gimple_vdef (stmt)
-             && SSA_NAME_IS_DEFAULT_DEF (use))
-           {
-             tree rhs = gimple_assign_rhs1 (stmt);
-             tree base = get_base_address (rhs);
-
-             /* Do not warn if it can be initialized outside this function.  */
-             if (TREE_CODE (base) != VAR_DECL
-                 || DECL_HARD_REGISTER (base)
-                 || is_global_var (base))
-               continue;
-
-             if (always_executed)
-               warn_uninit (OPT_Wuninitialized, use, 
-                            gimple_assign_rhs1 (stmt), base,
-                            "%qE is used uninitialized in this function",
-                            stmt);
-             else if (warn_possibly_uninitialized)
-               warn_uninit (OPT_Wmaybe_uninitialized, use,
-                            gimple_assign_rhs1 (stmt), base,
-                            "%qE may be used uninitialized in this function",
-                            stmt);
-           }
-       }
-    }
-
-  return 0;
-}
-
-static unsigned int
-execute_early_warn_uninitialized (void)
-{
-  /* Currently, this pass runs always but
-     execute_late_warn_uninitialized only runs with optimization. With
-     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_POST_DOMINATORS);
-
-  warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
-
-  /* Post-dominator information can not be reliably updated. Free it
-     after the use.  */
-
-  free_dominance_info (CDI_POST_DOMINATORS);
-  return 0;
-}
-
-static bool
-gate_warn_uninitialized (void)
-{
-  return warn_uninitialized != 0;
-}
-
-namespace {
-
-const pass_data pass_data_early_warn_uninitialized =
-{
-  GIMPLE_PASS, /* type */
-  "*early_warn_uninitialized", /* name */
-  OPTGROUP_NONE, /* optinfo_flags */
-  true, /* has_gate */
-  true, /* has_execute */
-  TV_TREE_UNINIT, /* tv_id */
-  PROP_ssa, /* properties_required */
-  0, /* properties_provided */
-  0, /* properties_destroyed */
-  0, /* todo_flags_start */
-  0, /* todo_flags_finish */
-};
-
-class pass_early_warn_uninitialized : public gimple_opt_pass
-{
-public:
-  pass_early_warn_uninitialized(gcc::context *ctxt)
-    : gimple_opt_pass(pass_data_early_warn_uninitialized, ctxt)
-  {}
-
-  /* opt_pass methods: */
-  bool gate () { return gate_warn_uninitialized (); }
-  unsigned int execute () { return execute_early_warn_uninitialized (); }
-
-}; // class pass_early_warn_uninitialized
-
-} // anon namespace
-
-gimple_opt_pass *
-make_pass_early_warn_uninitialized (gcc::context *ctxt)
-{
-  return new pass_early_warn_uninitialized (ctxt);
-}
-
 
 /* If necessary, rewrite the base of the reference tree *TP from
    a MEM_REF to a plain or converted symbol.  */
index 457fd6bf5e7bde0bee9a7a57ad3506a351dc20d1..1808b1c447a5affbebd4d7bc6a7b9f00a4935312 100644 (file)
@@ -58,8 +58,7 @@ extern tree tree_ssa_strip_useless_type_conversions (tree);
 typedef bool (*walk_use_def_chains_fn) (tree, gimple, void *);
 extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
 
-extern void warn_uninit (enum opt_code, tree, tree, tree, const char *, void *);
-extern unsigned int warn_uninitialized_vars (bool);
+extern bool ssa_undefined_value_p (tree);
 extern void execute_update_addresses_taken (void);
 
 /* Given an edge_var_map V, return the PHI arg definition.  */