Commit e1ec47c4 by Thomas Preud'homme Committed by Joey Ye

re PR middle-end/39246 (FAIL: gcc.dg/uninit-13.c)

2014-05-07  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        PR middle-end/39246
        * tree-complex.c (expand_complex_move): Keep line info when expanding
        complex move.
        * tree-ssa-uninit.c (warn_uninit): New argument. Ignore assignment 
        of complex expression. Use new argument to display correct location 
        for values coming from phi statement.
        (warn_uninitialized_vars): Adapt to new signature of warn_uninit.
        (warn_uninitialized_phi): Pass location of phi argument to 
        warn_uninit.
        * tree-ssa.c (ssa_undefined_value_p): For SSA_NAME initialized by a
        COMPLEX_EXPR, recurse on each part of the COMPLEX_EXPR.

testsuite:

        * gcc.dg/uninit-13.c: Move warning on the actual source line where
        the uninitialized complex is used.
        * gcc.dg/uninit-17.c: New test to check partial initialization of
        complex with branches.
        * gcc.dg/uninit-17-O0.c: Likewise.

From-SVN: r210199
parent 10e08855
...@@ -5,6 +5,6 @@ typedef _Complex float C; ...@@ -5,6 +5,6 @@ typedef _Complex float C;
C foo() C foo()
{ {
C f; C f;
__imag__ f = 0; /* { dg-warning "is used" "unconditional" } */ __imag__ f = 0;
return f; return f; /* { dg-warning "is used" "unconditional" } */
} }
...@@ -831,12 +831,15 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type) ...@@ -831,12 +831,15 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type)
{ {
tree x; tree x;
gimple t; gimple t;
location_t loc;
loc = gimple_location (stmt);
r = extract_component (gsi, rhs, 0, false); r = extract_component (gsi, rhs, 0, false);
i = extract_component (gsi, rhs, 1, false); i = extract_component (gsi, rhs, 1, false);
x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs)); x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
t = gimple_build_assign (x, r); t = gimple_build_assign (x, r);
gimple_set_location (t, loc);
gsi_insert_before (gsi, t, GSI_SAME_STMT); gsi_insert_before (gsi, t, GSI_SAME_STMT);
if (stmt == gsi_stmt (*gsi)) if (stmt == gsi_stmt (*gsi))
...@@ -849,6 +852,7 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type) ...@@ -849,6 +852,7 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type)
{ {
x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs)); x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
t = gimple_build_assign (x, i); t = gimple_build_assign (x, i);
gimple_set_location (t, loc);
gsi_insert_before (gsi, t, GSI_SAME_STMT); gsi_insert_before (gsi, t, GSI_SAME_STMT);
stmt = gsi_stmt (*gsi); stmt = gsi_stmt (*gsi);
......
...@@ -123,17 +123,25 @@ uninit_undefined_value_p (tree t) { ...@@ -123,17 +123,25 @@ uninit_undefined_value_p (tree t) {
/* Emit a warning for EXPR based on variable VAR at the point in the /* Emit a warning for EXPR based on variable VAR at the point in the
program T, an SSA_NAME, is used being uninitialized. The exact program T, an SSA_NAME, is used being uninitialized. The exact
warning text is in MSGID and LOCUS may contain a location or be null. warning text is in MSGID and DATA is the gimple stmt with info about
WC is the warning code. */ the location in source code. When DATA is a GIMPLE_PHI, PHIARG_IDX
gives which argument of the phi node to take the location from. WC
is the warning code. */
static void static void
warn_uninit (enum opt_code wc, tree t, warn_uninit (enum opt_code wc, tree t, tree expr, tree var,
tree expr, tree var, const char *gmsgid, void *data) const char *gmsgid, void *data, location_t phiarg_loc)
{ {
gimple context = (gimple) data; gimple context = (gimple) data;
location_t location, cfun_loc; location_t location, cfun_loc;
expanded_location xloc, floc; expanded_location xloc, floc;
/* Ignore COMPLEX_EXPR as initializing only a part of a complex
turns in a COMPLEX_EXPR with the not initialized part being
set to its previous (undefined) value. */
if (is_gimple_assign (context)
&& gimple_assign_rhs_code (context) == COMPLEX_EXPR)
return;
if (!has_undefined_value_p (t)) if (!has_undefined_value_p (t))
return; return;
...@@ -146,9 +154,12 @@ warn_uninit (enum opt_code wc, tree t, ...@@ -146,9 +154,12 @@ warn_uninit (enum opt_code wc, tree t,
|| TREE_NO_WARNING (expr)) || TREE_NO_WARNING (expr))
return; return;
location = (context != NULL && gimple_has_location (context)) if (context != NULL && gimple_has_location (context))
? gimple_location (context) location = gimple_location (context);
: DECL_SOURCE_LOCATION (var); else if (phiarg_loc != UNKNOWN_LOCATION)
location = phiarg_loc;
else
location = DECL_SOURCE_LOCATION (var);
location = linemap_resolve_location (line_table, location, location = linemap_resolve_location (line_table, location,
LRK_SPELLING_LOCATION, LRK_SPELLING_LOCATION,
NULL); NULL);
...@@ -200,12 +211,12 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) ...@@ -200,12 +211,12 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
warn_uninit (OPT_Wuninitialized, use, warn_uninit (OPT_Wuninitialized, use,
SSA_NAME_VAR (use), SSA_NAME_VAR (use), SSA_NAME_VAR (use), SSA_NAME_VAR (use),
"%qD is used uninitialized in this function", "%qD is used uninitialized in this function",
stmt); stmt, UNKNOWN_LOCATION);
else if (warn_possibly_uninitialized) else if (warn_possibly_uninitialized)
warn_uninit (OPT_Wmaybe_uninitialized, use, warn_uninit (OPT_Wmaybe_uninitialized, use,
SSA_NAME_VAR (use), SSA_NAME_VAR (use), SSA_NAME_VAR (use), SSA_NAME_VAR (use),
"%qD may be used uninitialized in this function", "%qD may be used uninitialized in this function",
stmt); stmt, UNKNOWN_LOCATION);
} }
/* For memory the only cheap thing we can do is see if we /* For memory the only cheap thing we can do is see if we
...@@ -236,12 +247,12 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) ...@@ -236,12 +247,12 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
warn_uninit (OPT_Wuninitialized, use, warn_uninit (OPT_Wuninitialized, use,
gimple_assign_rhs1 (stmt), base, gimple_assign_rhs1 (stmt), base,
"%qE is used uninitialized in this function", "%qE is used uninitialized in this function",
stmt); stmt, UNKNOWN_LOCATION);
else if (warn_possibly_uninitialized) else if (warn_possibly_uninitialized)
warn_uninit (OPT_Wmaybe_uninitialized, use, warn_uninit (OPT_Wmaybe_uninitialized, use,
gimple_assign_rhs1 (stmt), base, gimple_assign_rhs1 (stmt), base,
"%qE may be used uninitialized in this function", "%qE may be used uninitialized in this function",
stmt); stmt, UNKNOWN_LOCATION);
} }
} }
} }
...@@ -2246,6 +2257,8 @@ warn_uninitialized_phi (gimple phi, vec<gimple> *worklist, ...@@ -2246,6 +2257,8 @@ warn_uninitialized_phi (gimple phi, vec<gimple> *worklist,
unsigned uninit_opnds; unsigned uninit_opnds;
gimple uninit_use_stmt = 0; gimple uninit_use_stmt = 0;
tree uninit_op; tree uninit_op;
int phiarg_index;
location_t loc;
/* Don't look at virtual operands. */ /* Don't look at virtual operands. */
if (virtual_operand_p (gimple_phi_result (phi))) if (virtual_operand_p (gimple_phi_result (phi)))
...@@ -2270,13 +2283,18 @@ warn_uninitialized_phi (gimple phi, vec<gimple> *worklist, ...@@ -2270,13 +2283,18 @@ warn_uninitialized_phi (gimple phi, vec<gimple> *worklist,
if (!uninit_use_stmt) if (!uninit_use_stmt)
return; return;
uninit_op = gimple_phi_arg_def (phi, MASK_FIRST_SET_BIT (uninit_opnds)); phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
uninit_op = gimple_phi_arg_def (phi, phiarg_index);
if (SSA_NAME_VAR (uninit_op) == NULL_TREE) if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
return; return;
if (gimple_phi_arg_has_location (phi, phiarg_index))
loc = gimple_phi_arg_location (phi, phiarg_index);
else
loc = UNKNOWN_LOCATION;
warn_uninit (OPT_Wmaybe_uninitialized, uninit_op, SSA_NAME_VAR (uninit_op), warn_uninit (OPT_Wmaybe_uninitialized, uninit_op, SSA_NAME_VAR (uninit_op),
SSA_NAME_VAR (uninit_op), SSA_NAME_VAR (uninit_op),
"%qD may be used uninitialized in this function", "%qD may be used uninitialized in this function",
uninit_use_stmt); uninit_use_stmt, loc);
} }
......
...@@ -1246,6 +1246,7 @@ tree_ssa_strip_useless_type_conversions (tree exp) ...@@ -1246,6 +1246,7 @@ tree_ssa_strip_useless_type_conversions (tree exp)
bool bool
ssa_undefined_value_p (tree t) ssa_undefined_value_p (tree t)
{ {
gimple def_stmt;
tree var = SSA_NAME_VAR (t); tree var = SSA_NAME_VAR (t);
if (!var) if (!var)
...@@ -1262,7 +1263,22 @@ ssa_undefined_value_p (tree t) ...@@ -1262,7 +1263,22 @@ ssa_undefined_value_p (tree t)
return false; return false;
/* The value is undefined iff its definition statement is empty. */ /* The value is undefined iff its definition statement is empty. */
return gimple_nop_p (SSA_NAME_DEF_STMT (t)); def_stmt = SSA_NAME_DEF_STMT (t);
if (gimple_nop_p (def_stmt))
return true;
/* Check if the complex was not only partially defined. */
if (is_gimple_assign (def_stmt)
&& gimple_assign_rhs_code (def_stmt) == COMPLEX_EXPR)
{
tree rhs1, rhs2;
rhs1 = gimple_assign_rhs1 (def_stmt);
rhs2 = gimple_assign_rhs2 (def_stmt);
return (TREE_CODE (rhs1) == SSA_NAME && ssa_undefined_value_p (rhs1))
|| (TREE_CODE (rhs2) == SSA_NAME && ssa_undefined_value_p (rhs2));
}
return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment