aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-02-21 10:53:56 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-02-21 10:53:56 +0100
commit92261ce01d53d2b0ba31eb180e95fdc58427e0b1 (patch)
treefd719ad6495d65560c713ce1fb75c59e15ca32e8 /gcc
parentaa6ef874510f64ed0c9d2e6a0812cf0731a49899 (diff)
downloadgcc-92261ce01d53d2b0ba31eb180e95fdc58427e0b1.zip
gcc-92261ce01d53d2b0ba31eb180e95fdc58427e0b1.tar.gz
gcc-92261ce01d53d2b0ba31eb180e95fdc58427e0b1.tar.bz2
re PR tree-optimization/56490 (-Wall triggering infinite loop)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/params.def6
-rw-r--r--gcc/tree-ssa-uninit.c63
3 files changed, 44 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cc9031b..29ed8c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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]
diff --git a/gcc/params.def b/gcc/params.def
index abfda73..ad63a37 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -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:
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 71a564c..d9b33b1 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -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;
}