mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-28 22:34:03 +08:00
re PR middle-end/64614 (bogus used initialized warning (in gcc 4.9.2); switch statement versus &)
2015-01-16 Richard Biener <rguenther@suse.de> PR middle-end/64614 * tree-ssa-uninit.c: Include tree-cfg.h. (MAX_SWITCH_CASES): New define. (convert_control_dep_chain_into_preds): Handle switch statements. (is_pred_expr_subset_of): Handle x == CST vs. (x & CST) != 0. (normalize_one_pred_1): Do not split bit-manipulations. Record (x & CST). * gcc.dg/uninit-18.c: New testcase. From-SVN: r219739
This commit is contained in:
parent
6220fdff17
commit
666e8e0603
@ -1,3 +1,13 @@
|
||||
2015-01-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/64614
|
||||
* tree-ssa-uninit.c: Include tree-cfg.h.
|
||||
(MAX_SWITCH_CASES): New define.
|
||||
(convert_control_dep_chain_into_preds): Handle switch statements.
|
||||
(is_pred_expr_subset_of): Handle x == CST vs. (x & CST) != 0.
|
||||
(normalize_one_pred_1): Do not split bit-manipulations.
|
||||
Record (x & CST).
|
||||
|
||||
2015-01-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/64568
|
||||
|
@ -1,3 +1,8 @@
|
||||
2015-01-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/64614
|
||||
* gcc.dg/uninit-18.c: New testcase.
|
||||
|
||||
2015-01-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/64568
|
||||
|
24
gcc/testsuite/gcc.dg/uninit-18.c
Normal file
24
gcc/testsuite/gcc.dg/uninit-18.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -Wuninitialized" } */
|
||||
|
||||
char *foo(int bar, char *baz)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (bar & 3)
|
||||
tmp = baz;
|
||||
|
||||
switch (bar) {
|
||||
case 1:
|
||||
tmp[5] = 7; /* { dg-bogus "may be used uninitialized" } */
|
||||
break;
|
||||
case 2:
|
||||
tmp[11] = 15; /* { dg-bogus "may be used uninitialized" } */
|
||||
break;
|
||||
default:
|
||||
tmp = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return tmp; /* { dg-bogus "may be used uninitialized" } */
|
||||
}
|
@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "tree-pass.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "params.h"
|
||||
#include "tree-cfg.h"
|
||||
|
||||
/* This implements the pass that does predicate aware warning on uses of
|
||||
possibly uninitialized variables. The pass first collects the set of
|
||||
@ -411,6 +412,7 @@ find_control_equiv_block (basic_block bb)
|
||||
#define MAX_NUM_CHAINS 8
|
||||
#define MAX_CHAIN_LEN 5
|
||||
#define MAX_POSTDOM_CHECK 8
|
||||
#define MAX_SWITCH_CASES 40
|
||||
|
||||
/* Computes the control dependence chains (paths of edges)
|
||||
for DEP_BB up to the dominating basic block BB (the head node of a
|
||||
@ -592,17 +594,63 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
|
||||
if (skip)
|
||||
continue;
|
||||
}
|
||||
if (gimple_code (cond_stmt) != GIMPLE_COND)
|
||||
if (gimple_code (cond_stmt) == GIMPLE_COND)
|
||||
{
|
||||
one_pred.pred_lhs = gimple_cond_lhs (cond_stmt);
|
||||
one_pred.pred_rhs = gimple_cond_rhs (cond_stmt);
|
||||
one_pred.cond_code = gimple_cond_code (cond_stmt);
|
||||
one_pred.invert = !!(e->flags & EDGE_FALSE_VALUE);
|
||||
t_chain.safe_push (one_pred);
|
||||
has_valid_pred = true;
|
||||
}
|
||||
else if (gswitch *gs = dyn_cast <gswitch *> (cond_stmt))
|
||||
{
|
||||
/* Avoid quadratic behavior. */
|
||||
if (gimple_switch_num_labels (gs) > MAX_SWITCH_CASES)
|
||||
{
|
||||
has_valid_pred = false;
|
||||
break;
|
||||
}
|
||||
/* Find the case label. */
|
||||
tree l = NULL_TREE;
|
||||
unsigned idx;
|
||||
for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx)
|
||||
{
|
||||
tree tl = gimple_switch_label (gs, idx);
|
||||
if (e->dest == label_to_block (CASE_LABEL (tl)))
|
||||
{
|
||||
if (!l)
|
||||
l = tl;
|
||||
else
|
||||
{
|
||||
l = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If more than one label reaches this block or the case
|
||||
label doesn't have a single value (like the default one)
|
||||
fail. */
|
||||
if (!l
|
||||
|| !CASE_LOW (l)
|
||||
|| (CASE_HIGH (l) && !operand_equal_p (CASE_LOW (l),
|
||||
CASE_HIGH (l), 0)))
|
||||
{
|
||||
has_valid_pred = false;
|
||||
break;
|
||||
}
|
||||
one_pred.pred_lhs = gimple_switch_index (gs);
|
||||
one_pred.pred_rhs = CASE_LOW (l);
|
||||
one_pred.cond_code = EQ_EXPR;
|
||||
one_pred.invert = false;
|
||||
t_chain.safe_push (one_pred);
|
||||
has_valid_pred = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
has_valid_pred = false;
|
||||
break;
|
||||
}
|
||||
one_pred.pred_lhs = gimple_cond_lhs (cond_stmt);
|
||||
one_pred.pred_rhs = gimple_cond_rhs (cond_stmt);
|
||||
one_pred.cond_code = gimple_cond_code (cond_stmt);
|
||||
one_pred.invert = !!(e->flags & EDGE_FALSE_VALUE);
|
||||
t_chain.safe_push (one_pred);
|
||||
has_valid_pred = true;
|
||||
}
|
||||
|
||||
if (!has_valid_pred)
|
||||
@ -1329,6 +1377,10 @@ is_pred_expr_subset_of (pred_info expr1, pred_info expr2)
|
||||
if (expr2.invert)
|
||||
code2 = invert_tree_comparison (code2, false);
|
||||
|
||||
if (code1 == EQ_EXPR && code2 == BIT_AND_EXPR)
|
||||
return wi::eq_p (expr1.pred_rhs,
|
||||
wi::bit_and (expr1.pred_rhs, expr2.pred_rhs));
|
||||
|
||||
if (code1 != code2 && code2 != NE_EXPR)
|
||||
return false;
|
||||
|
||||
@ -1970,8 +2022,25 @@ normalize_one_pred_1 (pred_chain_union *norm_preds,
|
||||
}
|
||||
else if (gimple_assign_rhs_code (def_stmt) == and_or_code)
|
||||
{
|
||||
push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
|
||||
push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
|
||||
/* Avoid splitting up bit manipulations like x & 3 or y | 1. */
|
||||
if (is_gimple_min_invariant (gimple_assign_rhs2 (def_stmt)))
|
||||
{
|
||||
/* But treat x & 3 as condition. */
|
||||
if (and_or_code == BIT_AND_EXPR)
|
||||
{
|
||||
pred_info n_pred;
|
||||
n_pred.pred_lhs = gimple_assign_rhs1 (def_stmt);
|
||||
n_pred.pred_rhs = gimple_assign_rhs2 (def_stmt);
|
||||
n_pred.cond_code = and_or_code;
|
||||
n_pred.invert = false;
|
||||
norm_chain->safe_push (n_pred);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
|
||||
push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
|
||||
== tcc_comparison)
|
||||
|
Loading…
Reference in New Issue
Block a user