@@ -244,21 +244,18 @@ find_matching_predicate_in_rest_chains (const pred_info &pred,
of that's the form "FLAG_VAR CMP FLAG_VAR" with value range info.
PHI is the phi node whose incoming (interesting) paths need to be
examined. On success, return the comparison code, set defintion
- gimple of FLAG_DEF and BOUNDARY_CST. Otherwise return ERROR_MARK. */
+ gimple of FLAG_DEF and BOUNDARY_CST. Otherwise return ERROR_MARK.
+ I is the running iterator so the function can be called repeatedly
+ to gather all candidates. */
static tree_code
find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def,
- tree *boundary_cst)
+ tree *boundary_cst, unsigned &i)
{
- tree_code vrinfo_code = ERROR_MARK;
- gimple *vrinfo_def = NULL;
- tree vrinfo_cst = NULL;
-
gcc_assert (preds.length () > 0);
pred_chain chain = preds[0];
- for (unsigned i = 0; i < chain.length (); i++)
+ for (; i < chain.length (); i++)
{
- bool use_vrinfo_p = false;
const pred_info &pred = chain[i];
tree cond_lhs = pred.pred_lhs;
tree cond_rhs = pred.pred_rhs;
@@ -282,8 +279,7 @@ find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def,
}
/* Check if we can take advantage of FLAG_VAR COMP FLAG_VAR predicate
with value range info. Note only first of such case is handled. */
- else if (vrinfo_code == ERROR_MARK
- && TREE_CODE (cond_lhs) == SSA_NAME
+ else if (TREE_CODE (cond_lhs) == SSA_NAME
&& TREE_CODE (cond_rhs) == SSA_NAME)
{
gimple* lhs_def = SSA_NAME_DEF_STMT (cond_lhs);
@@ -331,8 +327,6 @@ find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def,
cond_rhs = wide_int_to_tree (type, min);
else
continue;
-
- use_vrinfo_p = true;
}
else
continue;
@@ -345,27 +339,13 @@ find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def,
|| !find_matching_predicate_in_rest_chains (pred, preds))
continue;
- /* Return if any "flag_var comp const" predicate is found. */
- if (!use_vrinfo_p)
- {
- *boundary_cst = cond_rhs;
- return code;
- }
- /* Record if any "flag_var comp flag_var[vinfo]" predicate is found. */
- else if (vrinfo_code == ERROR_MARK)
- {
- vrinfo_code = code;
- vrinfo_def = *flag_def;
- vrinfo_cst = cond_rhs;
- }
- }
- /* Return the "flag_var cmp flag_var[vinfo]" predicate we found. */
- if (vrinfo_code != ERROR_MARK)
- {
- *flag_def = vrinfo_def;
- *boundary_cst = vrinfo_cst;
+ /* Return predicate found. */
+ *boundary_cst = cond_rhs;
+ ++i;
+ return code;
}
- return vrinfo_code;
+
+ return ERROR_MARK;
}
/* Return true if all interesting opnds are pruned, false otherwise.
@@ -641,27 +621,29 @@ uninit_analysis::overlap (gphi *phi, unsigned opnds, hash_set<gphi *> *visited,
{
gimple *flag_def = NULL;
tree boundary_cst = NULL_TREE;
- bitmap visited_flag_phis = NULL;
/* Find within the common prefix of multiple predicate chains
a predicate that is a comparison of a flag variable against
a constant. */
- tree_code cmp_code = find_var_cmp_const (use_preds.chain (), phi, &flag_def,
- &boundary_cst);
- if (cmp_code == ERROR_MARK)
- return true;
-
- /* Now check all the uninit incoming edges have a constant flag
- value that is in conflict with the use guard/predicate. */
- gphi *phi_def = as_a<gphi *> (flag_def);
- bool all_pruned = prune_phi_opnds (phi, opnds, phi_def, boundary_cst,
- cmp_code, visited,
- &visited_flag_phis);
-
- if (visited_flag_phis)
- BITMAP_FREE (visited_flag_phis);
+ unsigned i = 0;
+ tree_code cmp_code;
+ while ((cmp_code = find_var_cmp_const (use_preds.chain (), phi, &flag_def,
+ &boundary_cst, i)) != ERROR_MARK)
+ {
+ /* Now check all the uninit incoming edges have a constant flag
+ value that is in conflict with the use guard/predicate. */
+ bitmap visited_flag_phis = NULL;
+ gphi *phi_def = as_a<gphi *> (flag_def);
+ bool all_pruned = prune_phi_opnds (phi, opnds, phi_def, boundary_cst,
+ cmp_code, visited,
+ &visited_flag_phis);
+ if (visited_flag_phis)
+ BITMAP_FREE (visited_flag_phis);
+ if (all_pruned)
+ return false;
+ }
- return !all_pruned;
+ return true;
}
/* Return true if two predicates PRED1 and X2 are equivalent. Assume
new file mode 100644
@@ -0,0 +1,17 @@
+// { dg-do compile }
+// { dg-additional-options "-Wuninitialized" }
+
+void* operator new[](__SIZE_TYPE__, void* __p) ;
+
+class Result
+{
+public:
+ Result();
+ ~Result();
+};
+
+void *foo(long nElements, void *p)
+{
+ return p ? new((int*)p) Result[nElements] : new Result[nElements]; // { dg-bogus "uninitialized" }
+}
+