re PR tree-optimization/56490 (-Wall triggering infinite loop)
authorJakub Jelinek <jakub@redhat.com>
Fri, 21 Feb 2014 09:53:56 +0000 (10:53 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 21 Feb 2014 09:53:56 +0000 (10:53 +0100)
PR tree-optimization/56490
* params.def (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS): New param.
* tree-ssa-uninit.c: Include params.h.
(compute_control_dep_chain): Add num_calls argument, return false
if it exceed PARAM_UNINIT_CONTROL_DEP_ATTEMPTS param, pass
num_calls to recursive call.
(find_predicates): Change dep_chain into normal array,
cur_chain into auto_vec<edge, MAX_CHAIN_LEN + 1>, add num_calls
variable and adjust compute_control_dep_chain caller.
(find_def_preds): Likewise.

From-SVN: r207988

gcc/ChangeLog
gcc/params.def
gcc/tree-ssa-uninit.c

index cc9031bc18465d5e78b6e80e5bd6c97327974bef..29ed8c833c4c0e8203df890b176bf26e08577906 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/56490
+       * params.def (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS): New param.
+       * tree-ssa-uninit.c: Include params.h.
+       (compute_control_dep_chain): Add num_calls argument, return false
+       if it exceed PARAM_UNINIT_CONTROL_DEP_ATTEMPTS param, pass
+       num_calls to recursive call.
+       (find_predicates): Change dep_chain into normal array,
+       cur_chain into auto_vec<edge, MAX_CHAIN_LEN + 1>, add num_calls
+       variable and adjust compute_control_dep_chain caller.
+       (find_def_preds): Likewise.
+
 2014-02-21  Thomas Schwinge  <thomas@codesourcery.com>
 
        * gimple-pretty-print.c (dump_gimple_omp_for) [flags & TDF_RAW]
index abfda73ca8740a37ddaa85ce6e855bd6a62dc342..ad63a37a76ff491c7d20427dca6fb1473e30d18f 100644 (file)
@@ -1078,6 +1078,12 @@ DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
          "asan-use-after-return",
          "Enable asan builtin functions protection",
          1, 0, 1)
+
+DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
+         "uninit-control-dep-attempts",
+         "Maximum number of nested calls to search for control dependencies "
+         "during uninitialized variable analysis",
+         1000, 1, 0)
 /*
 
 Local variables:
index 71a564c9944e89e7fbfeb1691971f92144a6de7c..d9b33b13e9b8ca52d142ab59104433be02ee34ba 100644 (file)
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hashtab.h"
 #include "tree-pass.h"
 #include "diagnostic-core.h"
+#include "params.h"
 
 /* This implements the pass that does predicate aware warning on uses of
    possibly uninitialized variables. The pass first collects the set of
@@ -390,8 +391,8 @@ find_control_equiv_block (basic_block bb)
 
 /* Computes the control dependence chains (paths of edges)
    for DEP_BB up to the dominating basic block BB (the head node of a
-   chain should be dominated by it).  CD_CHAINS is pointer to a
-   dynamic array holding the result chains. CUR_CD_CHAIN is the current
+   chain should be dominated by it).  CD_CHAINS is pointer to an
+   array holding the result chains.  CUR_CD_CHAIN is the current
    chain being computed.  *NUM_CHAINS is total number of chains.  The
    function returns true if the information is successfully computed,
    return false if there is no control dependence or not computed.  */
@@ -400,7 +401,8 @@ static bool
 compute_control_dep_chain (basic_block bb, basic_block dep_bb,
                            vec<edge> *cd_chains,
                            size_t *num_chains,
-                           vec<edge> *cur_cd_chain)
+                          vec<edge> *cur_cd_chain,
+                          int *num_calls)
 {
   edge_iterator ei;
   edge e;
@@ -411,6 +413,10 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
   if (EDGE_COUNT (bb->succs) < 2)
     return false;
 
+  if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS))
+    return false;
+  ++*num_calls;
+
   /* Could use a set instead.  */
   cur_chain_len = cur_cd_chain->length ();
   if (cur_chain_len > MAX_CHAIN_LEN)
@@ -450,7 +456,7 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
 
           /* Now check if DEP_BB is indirectly control dependent on BB.  */
           if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains,
-                                         num_chains, cur_cd_chain))
+                                        num_chains, cur_cd_chain, num_calls))
             {
               found_cd_chain = true;
               break;
@@ -595,14 +601,12 @@ find_predicates (pred_chain_union *preds,
                  basic_block use_bb)
 {
   size_t num_chains = 0, i;
-  vec<edge> *dep_chains = 0;
-  vec<edge> cur_chain = vNULL;
+  int num_calls = 0;
+  vec<edge> dep_chains[MAX_NUM_CHAINS];
+  auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
   bool has_valid_pred = false;
   basic_block cd_root = 0;
 
-  typedef vec<edge> vec_edge_heap;
-  dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
-
   /* First find the closest bb that is control equivalent to PHI_BB
      that also dominates USE_BB.  */
   cd_root = phi_bb;
@@ -615,19 +619,13 @@ find_predicates (pred_chain_union *preds,
         break;
     }
 
-  compute_control_dep_chain (cd_root, use_bb,
-                             dep_chains, &num_chains,
-                             &cur_chain);
+  compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains,
+                            &cur_chain, &num_calls);
 
   has_valid_pred
-      = convert_control_dep_chain_into_preds (dep_chains,
-                                              num_chains,
-                                              preds);
-  /* Free individual chain  */
-  cur_chain.release ();
+    = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
   for (i = 0; i < num_chains; i++)
     dep_chains[i].release ();
-  free (dep_chains);
   return has_valid_pred;
 }
 
@@ -694,16 +692,13 @@ static bool
 find_def_preds (pred_chain_union *preds, gimple phi)
 {
   size_t num_chains = 0, i, n;
-  vec<edge> *dep_chains = 0;
-  vec<edge> cur_chain = vNULL;
+  vec<edge> dep_chains[MAX_NUM_CHAINS];
+  auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
   vec<edge> def_edges = vNULL;
   bool has_valid_pred = false;
   basic_block phi_bb, cd_root = 0;
   pointer_set_t *visited_phis;
 
-  typedef vec<edge> vec_edge_heap;
-  dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
-
   phi_bb = gimple_bb (phi);
   /* First find the closest dominating bb to be
      the control dependence root  */
@@ -722,37 +717,29 @@ find_def_preds (pred_chain_union *preds, gimple phi)
   for (i = 0; i < n; i++)
     {
       size_t prev_nc, j;
+      int num_calls = 0;
       edge opnd_edge;
 
       opnd_edge = def_edges[i];
       prev_nc = num_chains;
-      compute_control_dep_chain (cd_root, opnd_edge->src,
-                                 dep_chains, &num_chains,
-                                 &cur_chain);
-      /* Free individual chain  */
-      cur_chain.release ();
+      compute_control_dep_chain (cd_root, opnd_edge->src, dep_chains,
+                                &num_chains, &cur_chain, &num_calls);
 
       /* Now update the newly added chains with
          the phi operand edge:  */
       if (EDGE_COUNT (opnd_edge->src->succs) > 1)
         {
-          if (prev_nc == num_chains
-              && num_chains < MAX_NUM_CHAINS)
-            num_chains++;
+         if (prev_nc == num_chains && num_chains < MAX_NUM_CHAINS)
+           dep_chains[num_chains++] = vNULL;
           for (j = prev_nc; j < num_chains; j++)
-            {
-              dep_chains[j].safe_push (opnd_edge);
-            }
+           dep_chains[j].safe_push (opnd_edge);
         }
     }
 
   has_valid_pred
-      = convert_control_dep_chain_into_preds (dep_chains,
-                                              num_chains,
-                                              preds);
+    = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
   for (i = 0; i < num_chains; i++)
     dep_chains[i].release ();
-  free (dep_chains);
   return has_valid_pred;
 }