OSDN Git Service

2010-08-27 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-uninit.c
index 4f23962..4398db7 100644 (file)
@@ -1,5 +1,5 @@
 /* Predicate aware uninitialized variable warning.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2010 Free Software
    Foundation, Inc.
    Contributed by Xinliang David Li <davidxl@google.com>
 
@@ -25,26 +25,22 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "flags.h"
-#include "rtl.h"
 #include "tm_p.h"
-#include "ggc.h"
 #include "langhooks.h"
-#include "hard-reg-set.h"
 #include "basic-block.h"
 #include "output.h"
-#include "expr.h"
 #include "function.h"
-#include "diagnostic.h"
+#include "gimple-pretty-print.h"
 #include "bitmap.h"
 #include "pointer-set.h"
 #include "tree-flow.h"
 #include "gimple.h"
 #include "tree-inline.h"
-#include "varray.h"
 #include "timevar.h"
 #include "hashtab.h"
 #include "tree-dump.h"
 #include "tree-pass.h"
+#include "diagnostic-core.h"
 #include "toplev.h"
 #include "timevar.h"
 
@@ -97,6 +93,12 @@ ssa_undefined_value_p (tree t)
   if (TREE_CODE (var) == PARM_DECL)
     return false;
 
+  /* When returning by reference the return address is actually a hidden
+     parameter.  */
+  if (TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL
+      && DECL_BY_REFERENCE (SSA_NAME_VAR (t)))
+    return false;
+
   /* Hard register variables get their initial value from the ether.  */
   if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
     return false;
@@ -488,17 +490,33 @@ collect_phi_def_edges (gimple phi, basic_block cd_root,
       opnd_edge = gimple_phi_arg_edge (phi, i);
       opnd = gimple_phi_arg_def (phi, i);
 
-      if (TREE_CODE (opnd) != SSA_NAME
-          || !ssa_undefined_value_p (opnd))
-        VEC_safe_push (edge, heap, *edges, opnd_edge);
+      if (TREE_CODE (opnd) != SSA_NAME)
+        {
+          if (dump_file && (dump_flags & TDF_DETAILS))
+            {
+              fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i);
+              print_gimple_stmt (dump_file, phi, 0, 0);
+            }
+          VEC_safe_push (edge, heap, *edges, opnd_edge);
+        }
       else
         {
           gimple def = SSA_NAME_DEF_STMT (opnd);
+
           if (gimple_code (def) == GIMPLE_PHI
               && dominated_by_p (CDI_DOMINATORS,
                                  gimple_bb (def), cd_root))
             collect_phi_def_edges (def, cd_root, edges,
                                    visited_phis);
+          else if (!ssa_undefined_value_p (opnd))
+            {
+              if (dump_file && (dump_flags & TDF_DETAILS))
+                {
+                  fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i);
+                  print_gimple_stmt (dump_file, phi, 0, 0);
+                }
+              VEC_safe_push (edge, heap, *edges, opnd_edge);
+            }
         }
     }
 }
@@ -1528,7 +1546,7 @@ is_use_properly_guarded (gimple use_stmt,
 
   if (dump_file)
     dump_predicates (use_stmt, num_preds, preds,
-                     "Use in stmt ");
+                     "\nUse in stmt ");
 
   has_valid_preds = find_def_preds (&def_preds,
                                     &num_def_preds, phi);
@@ -1580,27 +1598,17 @@ find_uninit_use (gimple phi, unsigned uninit_opnds,
       struct pointer_set_t *visited_phis;
       basic_block use_bb;
 
-      use_stmt = use_p->loc.stmt;
+      use_stmt = USE_STMT (use_p);
+      if (is_gimple_debug (use_stmt))
+       continue;
 
       visited_phis = pointer_set_create ();
 
-      use_bb = gimple_bb (use_stmt);
       if (gimple_code (use_stmt) == GIMPLE_PHI)
-        {
-         unsigned i, n;
-          n = gimple_phi_num_args (use_stmt);
-
-          /* Find the matching phi argument of the use.  */
-          for (i = 0; i < n; ++i)
-            {
-               if (gimple_phi_arg_def_ptr (use_stmt, i) == use_p->use)
-                {
-                   edge e = gimple_phi_arg_edge (use_stmt, i);
-                   use_bb = e->src;
-                    break;
-                }
-           }
-       }
+       use_bb = gimple_phi_arg_edge (use_stmt,
+                                     PHI_ARG_INDEX_FROM_USE (use_p))->src;
+      else
+       use_bb = gimple_bb (use_stmt);
 
       if (is_use_properly_guarded (use_stmt,
                                    use_bb, 
@@ -1613,15 +1621,26 @@ find_uninit_use (gimple phi, unsigned uninit_opnds,
         }
       pointer_set_destroy (visited_phis);
 
+      if (dump_file && (dump_flags & TDF_DETAILS))
+        {
+          fprintf (dump_file, "[CHECK]: Found unguarded use: ");
+          print_gimple_stmt (dump_file, use_stmt, 0, 0);
+        }
       /* Found one real use, return.  */
       if (gimple_code (use_stmt) != GIMPLE_PHI)
-         return use_stmt;
+        return use_stmt;
 
       /* Found a phi use that is not guarded,
          add the phi to the worklist.  */
       if (!pointer_set_insert (added_to_worklist,
                                use_stmt))
         {
+          if (dump_file && (dump_flags & TDF_DETAILS))
+            {
+              fprintf (dump_file, "[WORKLIST]: Update worklist with phi: ");
+              print_gimple_stmt (dump_file, use_stmt, 0, 0);
+            }
+
           VEC_safe_push (gimple, heap, *worklist, use_stmt);
           pointer_set_insert (possibly_undefined_names,
                              phi_result);
@@ -1656,6 +1675,12 @@ warn_uninitialized_phi (gimple phi, VEC(gimple, heap) **worklist,
   if  (MASK_EMPTY (uninit_opnds))
     return;
 
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "[CHECK]: examining phi: ");
+      print_gimple_stmt (dump_file, phi, 0, 0);
+    }
+
   /* Now check if we have any use of the value without proper guard.  */
   uninit_use_stmt = find_uninit_use (phi, uninit_opnds,
                                      worklist, added_to_worklist);
@@ -1715,6 +1740,11 @@ execute_late_warn_uninitialized (void)
               {
                 VEC_safe_push (gimple, heap, worklist, phi);
                pointer_set_insert (added_to_worklist, phi);
+                if (dump_file && (dump_flags & TDF_DETAILS))
+                  {
+                    fprintf (dump_file, "[WORKLIST]: add to initial list: ");
+                    print_gimple_stmt (dump_file, phi, 0, 0);
+                  }
                 break;
               }
           }
@@ -1726,7 +1756,7 @@ execute_late_warn_uninitialized (void)
       cur_phi = VEC_pop (gimple, worklist);
       warn_uninitialized_phi (cur_phi, &worklist, added_to_worklist);
     }
-  
+
   VEC_free (gimple, heap, worklist);
   pointer_set_destroy (added_to_worklist);
   pointer_set_destroy (possibly_undefined_names);