On Sun, May 4, 2014 at 10:32 AM, Thomas Preud'homme
<thomas.preudho...@arm.com> wrote:
> Warning for use of a partially initialized complex is displayed on the wrong 
> line (the one where the partial initialization is done) and is not consistent 
> between target (or even within a given target, for instance between hardfloat 
> and softfloat on arm-none-eabi target). This patch correctly retains the line 
> location when expanding a complex move, stop warning when a COMPLEX_EXPR is 
> constructed but instead warn when it is used, and for cases where a branch is 
> involved, get the line location from the phi argument involved as a fallback. 
> This fixes PR39246.
>
> The ChangeLog are as follows:
>
> *** gcc/ChangeLog ***
>
> 2014-05-04  Thomas Preud'homme  <thomas.preudho...@arm.com>
>
>         PR middle-end/39246
>         * tree-complex.c (expand_complex_move): Keep line info when expanding
>         complex move.

This part and the corresponding testcase adjustment is ok.  You can
commit it separately.

>         * 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.

This change will also affect PRE in a bogus way.  It also affects
tree-complex.c lowering process, eventually in a similar pessimizing way.

So please do the change local to tree-ssa-uninit.c.

Thanks,
Richard.

>
> *** gcc/testsuite/ChangeLog ***
>
> 2014-05-04  Thomas Preud'homme  <thomas.preudho...@arm.com>
>
>         * 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.
>
> Bootstrapped on x86_64-linux-gnu with no regression in the testsuite. Also 
> tested a cross-build of gcc for arm-none-eabi target and run the regression 
> testsuite in qemu for cortex-m3 without any regression and the uninit-13.c 
> test fixed.
>
> Ok for stage1? Patch with proper formatting in attachment.
>
> diff --git a/gcc/testsuite/gcc.dg/uninit-13.c 
> b/gcc/testsuite/gcc.dg/uninit-13.c
> index 631e8de..5e88a8a 100644
> --- a/gcc/testsuite/gcc.dg/uninit-13.c
> +++ b/gcc/testsuite/gcc.dg/uninit-13.c
> @@ -5,6 +5,6 @@ typedef _Complex float C;
>  C foo()
>  {
>    C f;
> -  __imag__ f = 0;      /* { dg-warning "is used" "unconditional" } */
> -  return f;
> +  __imag__ f = 0;
> +  return f;    /* { dg-warning "is used" "unconditional" } */
>  }
> diff --git a/gcc/testsuite/gcc.dg/uninit-17-O0.c 
> b/gcc/testsuite/gcc.dg/uninit-17-O0.c
> new file mode 100644
> index 0000000..0eaef05
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/uninit-17-O0.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Wuninitialized" } */
> +
> +typedef _Complex float C;
> +C foo(int cond)
> +{
> +  C f;
> +  __imag__ f = 0;
> +  if (cond)
> +    {
> +      __real__ f = 1;
> +      return f;
> +    }
> +  return f;
> +}
> diff --git a/gcc/testsuite/gcc.dg/uninit-17.c 
> b/gcc/testsuite/gcc.dg/uninit-17.c
> new file mode 100644
> index 0000000..8a95f15
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/uninit-17.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -Wuninitialized" } */
> +
> +typedef _Complex float C;
> +C foo(int cond)
> +{
> +  C f;
> +  __imag__ f = 0;
> +  if (cond)
> +    {
> +      __real__ f = 1;
> +      return f;
> +    }
> +  return f;    /* { dg-warning "may be used" "unconditional" } */
> +}
> diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
> index a97aaf9..2286e2e 100644
> --- a/gcc/tree-complex.c
> +++ b/gcc/tree-complex.c
> @@ -831,12 +831,15 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree 
> type)
>      {
>        tree x;
>        gimple t;
> +      location_t loc;
>
> +      loc = gimple_location (stmt);
>        r = extract_component (gsi, rhs, 0, false);
>        i = extract_component (gsi, rhs, 1, false);
>
>        x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
>        t = gimple_build_assign (x, r);
> +      gimple_set_location (t, loc);
>        gsi_insert_before (gsi, t, GSI_SAME_STMT);
>
>        if (stmt == gsi_stmt (*gsi))
> @@ -849,6 +852,7 @@ expand_complex_move (gimple_stmt_iterator *gsi, tree type)
>         {
>           x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
>           t = gimple_build_assign (x, i);
> +         gimple_set_location (t, loc);
>           gsi_insert_before (gsi, t, GSI_SAME_STMT);
>
>           stmt = gsi_stmt (*gsi);
> diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
> index ae251cc..4310e7e 100644
> --- a/gcc/tree-ssa-uninit.c
> +++ b/gcc/tree-ssa-uninit.c
> @@ -123,17 +123,25 @@ uninit_undefined_value_p (tree t) {
>
>  /* 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
> -   warning text is in MSGID and LOCUS may contain a location or be null.
> -   WC is the warning code.  */
> +   warning text is in MSGID and DATA is the gimple stmt with info about
> +   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
> -warn_uninit (enum opt_code wc, tree t,
> -            tree expr, tree var, const char *gmsgid, void *data)
> +warn_uninit (enum opt_code wc, tree t, tree expr, tree var,
> +            const char *gmsgid, void *data, location_t phiarg_loc)
>  {
>    gimple context = (gimple) data;
>    location_t location, cfun_loc;
>    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))
>      return;
>
> @@ -146,9 +154,12 @@ warn_uninit (enum opt_code wc, tree t,
>        || TREE_NO_WARNING (expr))
>      return;
>
> -  location = (context != NULL && gimple_has_location (context))
> -            ? gimple_location (context)
> -            : DECL_SOURCE_LOCATION (var);
> +  if (context != NULL && gimple_has_location (context))
> +    location = gimple_location (context);
> +  else if (phiarg_loc != UNKNOWN_LOCATION)
> +    location = phiarg_loc;
> +  else
> +    location = DECL_SOURCE_LOCATION (var);
>    location = linemap_resolve_location (line_table, location,
>                                        LRK_SPELLING_LOCATION,
>                                        NULL);
> @@ -200,12 +211,12 @@ warn_uninitialized_vars (bool 
> warn_possibly_uninitialized)
>                 warn_uninit (OPT_Wuninitialized, use,
>                              SSA_NAME_VAR (use), SSA_NAME_VAR (use),
>                              "%qD is used uninitialized in this function",
> -                            stmt);
> +                            stmt, UNKNOWN_LOCATION);
>               else if (warn_possibly_uninitialized)
>                 warn_uninit (OPT_Wmaybe_uninitialized, use,
>                              SSA_NAME_VAR (use), SSA_NAME_VAR (use),
>                              "%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
> @@ -236,12 +247,12 @@ warn_uninitialized_vars (bool 
> warn_possibly_uninitialized)
>                 warn_uninit (OPT_Wuninitialized, use,
>                              gimple_assign_rhs1 (stmt), base,
>                              "%qE is used uninitialized in this function",
> -                            stmt);
> +                            stmt, UNKNOWN_LOCATION);
>               else if (warn_possibly_uninitialized)
>                 warn_uninit (OPT_Wmaybe_uninitialized, use,
>                              gimple_assign_rhs1 (stmt), base,
>                              "%qE may be used uninitialized in this function",
> -                            stmt);
> +                            stmt, UNKNOWN_LOCATION);
>             }
>         }
>      }
> @@ -2247,6 +2258,8 @@ warn_uninitialized_phi (gimple phi, vec<gimple> 
> *worklist,
>    unsigned uninit_opnds;
>    gimple uninit_use_stmt = 0;
>    tree uninit_op;
> +  int phiarg_index;
> +  location_t loc;
>
>    /* Don't look at virtual operands.  */
>    if (virtual_operand_p (gimple_phi_result (phi)))
> @@ -2271,13 +2284,18 @@ warn_uninitialized_phi (gimple phi, vec<gimple> 
> *worklist,
>    if (!uninit_use_stmt)
>      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)
>      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),
>                SSA_NAME_VAR (uninit_op),
>                 "%qD may be used uninitialized in this function",
> -               uninit_use_stmt);
> +               uninit_use_stmt, loc);
>
>  }
>
> diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
> index 1ea639d..499bd06 100644
> --- a/gcc/tree-ssa.c
> +++ b/gcc/tree-ssa.c
> @@ -1246,6 +1246,7 @@ tree_ssa_strip_useless_type_conversions (tree exp)
>  bool
>  ssa_undefined_value_p (tree t)
>  {
> +  gimple def_stmt;
>    tree var = SSA_NAME_VAR (t);
>
>    if (!var)
> @@ -1262,7 +1263,22 @@ ssa_undefined_value_p (tree t)
>      return false;
>
>    /* 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;
>  }
>

Reply via email to