diff mbox

--enable-checking=fold fixes followup (PR bootstrap/45700)

Message ID 20101126085404.GJ29412@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 26, 2010, 8:54 a.m. UTC
Hi!

As I've mentioned in the PR as well as in comments for Uros' patch,
this patch implements the rest of fold checking fixes and cleanups
I had in mind.  Particularly, moves over buildN_loc from fortran
to tree.h, On Diego/Richard's request adds CAN_HAVE_LOCATION_P guards
into it and converts fold-const.c to use it instead of buildN followed
by protected_set_expr_location or SET_EXPR_LOCATION.  In one place where
it is still needed adds the unsharing version of setting location if it is

	Jakub

Comments

Richard Biener Nov. 26, 2010, 9:14 a.m. UTC | #1
On Fri, Nov 26, 2010 at 9:54 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As I've mentioned in the PR as well as in comments for Uros' patch,
> this patch implements the rest of fold checking fixes and cleanups
> I had in mind.  Particularly, moves over buildN_loc from fortran
> to tree.h, On Diego/Richard's request adds CAN_HAVE_LOCATION_P guards
> into it and converts fold-const.c to use it instead of buildN followed
> by protected_set_expr_location or SET_EXPR_LOCATION.  In one place where
> it is still needed adds the unsharing version of setting location if it is
> different instead.
> The patch also fixes a bug introduced during fold-const.c loc-iziation,
> in associate_trees.
>
> Bootstrapped/regtested with --enable-checking=yes,rtl,fold on x86_64-linux
> and i686-linux, with no regressions compared to yes,rtl
> build (without this patch).
>
> Ok for trunk?

Ok.

Thanks,
Richard.

> 2010-11-26  Jakub Jelinek  <jakub@redhat.com>
>
>        PR bootstrap/45700
>        * tree.h (build1_stat_loc, build2_stat_loc, build3_stat_loc,
>        build4_stat_loc, build5_stat_loc, build6_stat_loc): New inlines.
>        (build1_loc, build2_loc, build3_loc, build4_loc, build5_loc,
>        build6_loc): Define.
>        * fold-const.c (protected_set_expr_location_unshare): New inline.
>        (fold_convert_loc, pedantic_non_lvalue_loc): Use it.
>        (negate_expr, associate_trees, non_lvalue_loc, omit_one_operand_loc,
>        pedantic_omit_one_operand_loc, omit_two_operands_loc,
>        fold_truth_not_expr, invert_truthvalue_loc, make_bit_field_ref,
>        optimize_bit_field_compare, make_range, fold_range_test, fold_truthop,
>        build_fold_addr_expr_with_type_loc, fold_unary_loc, fold_binary_loc,
>        fold_indirect_ref_1, build_fold_indirect_ref_loc): Use builN_loc
>        instead of buildN followed by SET_EXPR_LOCATION or
>        protected_set_expr_location.
>        (fold_build1_stat_loc, fold_build2_stat_loc, fold_build3_stat_loc):
>        Use buildN_stat_loc instead of buildN_stat followed by
>        SET_EXPR_LOCATION.
>
>        * trans.h (build1_stat_loc, build2_stat_loc, build3_stat_loc,
>        build4_stat_loc): Removed.
>        (build1_loc, build2_loc, build3_loc, build4_loc): Removed.
>
> --- gcc/tree.h.jj       2010-11-24 18:10:55.000000000 +0100
> +++ gcc/tree.h  2010-11-24 18:22:57.000000000 +0100
> @@ -4034,6 +4034,81 @@ extern tree build6_stat (enum tree_code,
>  #define build6(c,t1,t2,t3,t4,t5,t6,t7) \
>   build6_stat (c,t1,t2,t3,t4,t5,t6,t7 MEM_STAT_INFO)
>
> +/* _loc versions of build[1-6].  */
> +
> +static inline tree
> +build1_stat_loc (location_t loc, enum tree_code code, tree type,
> +                tree arg1 MEM_STAT_DECL)
> +{
> +  tree t = build1_stat (code, type, arg1 PASS_MEM_STAT);
> +  if (CAN_HAVE_LOCATION_P (t))
> +    SET_EXPR_LOCATION (t, loc);
> +  return t;
> +}
> +#define build1_loc(l,c,t1,t2) build1_stat_loc (l,c,t1,t2 MEM_STAT_INFO)
> +
> +static inline tree
> +build2_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> +                tree arg1 MEM_STAT_DECL)
> +{
> +  tree t = build2_stat (code, type, arg0, arg1 PASS_MEM_STAT);
> +  if (CAN_HAVE_LOCATION_P (t))
> +    SET_EXPR_LOCATION (t, loc);
> +  return t;
> +}
> +#define build2_loc(l,c,t1,t2,t3) build2_stat_loc (l,c,t1,t2,t3 MEM_STAT_INFO)
> +
> +static inline tree
> +build3_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> +                tree arg1, tree arg2 MEM_STAT_DECL)
> +{
> +  tree t = build3_stat (code, type, arg0, arg1, arg2 PASS_MEM_STAT);
> +  if (CAN_HAVE_LOCATION_P (t))
> +    SET_EXPR_LOCATION (t, loc);
> +  return t;
> +}
> +#define build3_loc(l,c,t1,t2,t3,t4) \
> +  build3_stat_loc (l,c,t1,t2,t3,t4 MEM_STAT_INFO)
> +
> +static inline tree
> +build4_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> +                tree arg1, tree arg2, tree arg3 MEM_STAT_DECL)
> +{
> +  tree t = build4_stat (code, type, arg0, arg1, arg2, arg3 PASS_MEM_STAT);
> +  if (CAN_HAVE_LOCATION_P (t))
> +    SET_EXPR_LOCATION (t, loc);
> +  return t;
> +}
> +#define build4_loc(l,c,t1,t2,t3,t4,t5) \
> +  build4_stat_loc (l,c,t1,t2,t3,t4,t5 MEM_STAT_INFO)
> +
> +static inline tree
> +build5_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> +                tree arg1, tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
> +{
> +  tree t = build5_stat (code, type, arg0, arg1, arg2, arg3,
> +                       arg4 PASS_MEM_STAT);
> +  if (CAN_HAVE_LOCATION_P (t))
> +    SET_EXPR_LOCATION (t, loc);
> +  return t;
> +}
> +#define build5_loc(l,c,t1,t2,t3,t4,t5,t6) \
> +  build5_stat_loc (l,c,t1,t2,t3,t4,t5,t6 MEM_STAT_INFO)
> +
> +static inline tree
> +build6_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> +                tree arg1, tree arg2, tree arg3, tree arg4,
> +                tree arg5 MEM_STAT_DECL)
> +{
> +  tree t = build6_stat (code, type, arg0, arg1, arg2, arg3, arg4,
> +                       arg5 PASS_MEM_STAT);
> +  if (CAN_HAVE_LOCATION_P (t))
> +    SET_EXPR_LOCATION (t, loc);
> +  return t;
> +}
> +#define build6_loc(l,c,t1,t2,t3,t4,t5,t6,t7) \
> +  build6_stat_loc (l,c,t1,t2,t3,t4,t5,t6,t7 MEM_STAT_INFO)
> +
>  extern tree build_var_debug_value_stat (tree, tree MEM_STAT_DECL);
>  #define build_var_debug_value(t1,t2) \
>   build_var_debug_value_stat (t1,t2 MEM_STAT_INFO)
> --- gcc/fold-const.c.jj 2010-11-24 18:10:55.000000000 +0100
> +++ gcc/fold-const.c    2010-11-25 21:04:35.000000000 +0100
> @@ -143,6 +143,25 @@ static tree fold_relational_const (enum
>  static tree fold_convert_const (enum tree_code, tree, tree);
>
>
> +/* Similar to protected_set_expr_location, but never modify x in place,
> +   if location can and needs to be set, unshare it.  */
> +
> +static inline tree
> +protected_set_expr_location_unshare (tree x, location_t loc)
> +{
> +  if (CAN_HAVE_LOCATION_P (x)
> +      && EXPR_LOCATION (x) != loc
> +      && !(TREE_CODE (x) == SAVE_EXPR
> +          || TREE_CODE (x) == TARGET_EXPR
> +          || TREE_CODE (x) == BIND_EXPR))
> +    {
> +      x = copy_node (x);
> +      SET_EXPR_LOCATION (x, loc);
> +    }
> +  return x;
> +}
> +
> +
>  /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
>    overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
>    and SUM1.  Then this yields nonzero if overflow occurred during the
> @@ -727,10 +746,7 @@ negate_expr (tree t)
>
>   tem = fold_negate_expr (loc, t);
>   if (!tem)
> -    {
> -      tem = build1 (NEGATE_EXPR, TREE_TYPE (t), t);
> -      SET_EXPR_LOCATION (tem, loc);
> -    }
> +    tem = build1_loc (loc, NEGATE_EXPR, TREE_TYPE (t), t);
>   return fold_convert_loc (loc, type, tem);
>  }
>
> @@ -841,8 +857,6 @@ split_tree (tree in, enum tree_code code
>  static tree
>  associate_trees (location_t loc, tree t1, tree t2, enum tree_code code, tree type)
>  {
> -  tree tem;
> -
>   if (t1 == 0)
>     return t2;
>   else if (t2 == 0)
> @@ -857,11 +871,15 @@ associate_trees (location_t loc, tree t1
>       if (code == PLUS_EXPR)
>        {
>          if (TREE_CODE (t1) == NEGATE_EXPR)
> -           tem = build2 (MINUS_EXPR, type, fold_convert_loc (loc, type, t2),
> -                         fold_convert_loc (loc, type, TREE_OPERAND (t1, 0)));
> +           return build2_loc (loc, MINUS_EXPR, type,
> +                              fold_convert_loc (loc, type, t2),
> +                              fold_convert_loc (loc, type,
> +                                                TREE_OPERAND (t1, 0)));
>          else if (TREE_CODE (t2) == NEGATE_EXPR)
> -           tem = build2 (MINUS_EXPR, type, fold_convert_loc (loc, type, t1),
> -                         fold_convert_loc (loc, type, TREE_OPERAND (t2, 0)));
> +           return build2_loc (loc, MINUS_EXPR, type,
> +                              fold_convert_loc (loc, type, t1),
> +                              fold_convert_loc (loc, type,
> +                                                TREE_OPERAND (t2, 0)));
>          else if (integer_zerop (t2))
>            return fold_convert_loc (loc, type, t1);
>        }
> @@ -871,16 +889,12 @@ associate_trees (location_t loc, tree t1
>            return fold_convert_loc (loc, type, t1);
>        }
>
> -      tem = build2 (code, type, fold_convert_loc (loc, type, t1),
> -                   fold_convert_loc (loc, type, t2));
> -      goto associate_trees_exit;
> +      return build2_loc (loc, code, type, fold_convert_loc (loc, type, t1),
> +                        fold_convert_loc (loc, type, t2));
>     }
>
>   return fold_build2_loc (loc, code, type, fold_convert_loc (loc, type, t1),
> -                     fold_convert_loc (loc, type, t2));
> - associate_trees_exit:
> -  protected_set_expr_location (tem, loc);
> -  return tem;
> +                         fold_convert_loc (loc, type, t2));
>  }
>
>  /* Check whether TYPE1 and TYPE2 are equivalent integer types, suitable
> @@ -2015,7 +2029,7 @@ fold_convert_loc (location_t loc, tree t
>       gcc_unreachable ();
>     }
>  fold_convert_exit:
> -  protected_set_expr_location (tem, loc);
> +  protected_set_expr_location_unshare (tem, loc);
>   return tem;
>  }
>
> @@ -2079,9 +2093,7 @@ non_lvalue_loc (location_t loc, tree x)
>
>   if (! maybe_lvalue_p (x))
>     return x;
> -  x = build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
> -  SET_EXPR_LOCATION (x, loc);
> -  return x;
> +  return build1_loc (loc, NON_LVALUE_EXPR, TREE_TYPE (x), x);
>  }
>
>  /* Nonzero means lvalues are limited to those valid in pedantic ANSI C.
> @@ -2098,16 +2110,7 @@ pedantic_non_lvalue_loc (location_t loc,
>   if (pedantic_lvalues)
>     return non_lvalue_loc (loc, x);
>
> -  if (CAN_HAVE_LOCATION_P (x)
> -      && EXPR_LOCATION (x) != loc
> -      && !(TREE_CODE (x) == SAVE_EXPR
> -          || TREE_CODE (x) == TARGET_EXPR
> -          || TREE_CODE (x) == BIND_EXPR))
> -    {
> -      x = copy_node (x);
> -      SET_EXPR_LOCATION (x, loc);
> -    }
> -  return x;
> +  return protected_set_expr_location_unshare (x, loc);
>  }
>
>  /* Given a tree comparison code, return the code that is the logical inverse
> @@ -2981,22 +2984,14 @@ omit_one_operand_loc (location_t loc, tr
>   /* If the resulting operand is an empty statement, just return the omitted
>      statement casted to void. */
>   if (IS_EMPTY_STMT (t) && TREE_SIDE_EFFECTS (omitted))
> -    {
> -      t = build1 (NOP_EXPR, void_type_node, fold_ignored_result (omitted));
> -      goto omit_one_operand_exit;
> -    }
> +    return build1_loc (loc, NOP_EXPR, void_type_node,
> +                      fold_ignored_result (omitted));
>
>   if (TREE_SIDE_EFFECTS (omitted))
> -    {
> -      t = build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
> -      goto omit_one_operand_exit;
> -    }
> +    return build2_loc (loc, COMPOUND_EXPR, type,
> +                      fold_ignored_result (omitted), t);
>
>   return non_lvalue_loc (loc, t);
> -
> - omit_one_operand_exit:
> -  protected_set_expr_location (t, loc);
> -  return t;
>  }
>
>  /* Similar, but call pedantic_non_lvalue instead of non_lvalue.  */
> @@ -3010,22 +3005,14 @@ pedantic_omit_one_operand_loc (location_
>   /* If the resulting operand is an empty statement, just return the omitted
>      statement casted to void. */
>   if (IS_EMPTY_STMT (t) && TREE_SIDE_EFFECTS (omitted))
> -    {
> -      t = build1 (NOP_EXPR, void_type_node, fold_ignored_result (omitted));
> -      goto pedantic_omit_one_operand_exit;
> -    }
> +    return build1_loc (loc, NOP_EXPR, void_type_node,
> +                      fold_ignored_result (omitted));
>
>   if (TREE_SIDE_EFFECTS (omitted))
> -    {
> -      t = build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
> -      goto pedantic_omit_one_operand_exit;
> -    }
> +    return build2_loc (loc, COMPOUND_EXPR, type,
> +                      fold_ignored_result (omitted), t);
>
>   return pedantic_non_lvalue_loc (loc, t);
> -
> - pedantic_omit_one_operand_exit:
> -  protected_set_expr_location (t, loc);
> -  return t;
>  }
>
>  /* Return a tree for the case when the result of an expression is RESULT
> @@ -3039,20 +3026,14 @@ pedantic_omit_one_operand_loc (location_
>
>  tree
>  omit_two_operands_loc (location_t loc, tree type, tree result,
> -                  tree omitted1, tree omitted2)
> +                      tree omitted1, tree omitted2)
>  {
>   tree t = fold_convert_loc (loc, type, result);
>
>   if (TREE_SIDE_EFFECTS (omitted2))
> -    {
> -      t = build2 (COMPOUND_EXPR, type, omitted2, t);
> -      SET_EXPR_LOCATION (t, loc);
> -    }
> +    t = build2_loc (loc, COMPOUND_EXPR, type, omitted2, t);
>   if (TREE_SIDE_EFFECTS (omitted1))
> -    {
> -      t = build2 (COMPOUND_EXPR, type, omitted1, t);
> -      SET_EXPR_LOCATION (t, loc);
> -    }
> +    t = build2_loc (loc, COMPOUND_EXPR, type, omitted1, t);
>
>   return TREE_CODE (t) != COMPOUND_EXPR ? non_lvalue_loc (loc, t) : t;
>  }
> @@ -3068,7 +3049,7 @@ omit_two_operands_loc (location_t loc, t
>  tree
>  fold_truth_not_expr (location_t loc, tree arg)
>  {
> -  tree t, type = TREE_TYPE (arg);
> +  tree type = TREE_TYPE (arg);
>   enum tree_code code = TREE_CODE (arg);
>   location_t loc1, loc2;
>
> @@ -3089,9 +3070,8 @@ fold_truth_not_expr (location_t loc, tre
>       if (code == ERROR_MARK)
>        return NULL_TREE;
>
> -      t = build2 (code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
> -      SET_EXPR_LOCATION (t, loc);
> -      return t;
> +      return build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
> +                        TREE_OPERAND (arg, 1));
>     }
>
>   switch (code)
> @@ -3106,10 +3086,9 @@ fold_truth_not_expr (location_t loc, tre
>        loc1 = loc;
>       if (loc2 == UNKNOWN_LOCATION)
>        loc2 = loc;
> -      t = build2 (TRUTH_OR_EXPR, type,
> -                 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> -                 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
> -      break;
> +      return build2_loc (loc, TRUTH_OR_EXPR, type,
> +                        invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> +                        invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
>
>     case TRUTH_OR_EXPR:
>       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
> @@ -3118,10 +3097,9 @@ fold_truth_not_expr (location_t loc, tre
>        loc1 = loc;
>       if (loc2 == UNKNOWN_LOCATION)
>        loc2 = loc;
> -      t = build2 (TRUTH_AND_EXPR, type,
> -                 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> -                 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
> -      break;
> +      return build2_loc (loc, TRUTH_AND_EXPR, type,
> +                        invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> +                        invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
>
>     case TRUTH_XOR_EXPR:
>       /* Here we can invert either operand.  We invert the first operand
> @@ -3130,13 +3108,12 @@ fold_truth_not_expr (location_t loc, tre
>         negation of the second operand.  */
>
>       if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
> -       t = build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
> -                   TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
> +       return build2_loc (loc, TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
> +                          TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
>       else
> -       t = build2 (TRUTH_XOR_EXPR, type,
> -                   invert_truthvalue_loc (loc, TREE_OPERAND (arg, 0)),
> -                   TREE_OPERAND (arg, 1));
> -      break;
> +       return build2_loc (loc, TRUTH_XOR_EXPR, type,
> +                          invert_truthvalue_loc (loc, TREE_OPERAND (arg, 0)),
> +                          TREE_OPERAND (arg, 1));
>
>     case TRUTH_ANDIF_EXPR:
>       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
> @@ -3145,10 +3122,9 @@ fold_truth_not_expr (location_t loc, tre
>        loc1 = loc;
>       if (loc2 == UNKNOWN_LOCATION)
>        loc2 = loc;
> -      t = build2 (TRUTH_ORIF_EXPR, type,
> -                 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> -                 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
> -      break;
> +      return build2_loc (loc, TRUTH_ORIF_EXPR, type,
> +                        invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> +                        invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
>
>     case TRUTH_ORIF_EXPR:
>       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
> @@ -3157,10 +3133,9 @@ fold_truth_not_expr (location_t loc, tre
>        loc1 = loc;
>       if (loc2 == UNKNOWN_LOCATION)
>        loc2 = loc;
> -      t = build2 (TRUTH_ANDIF_EXPR, type,
> -                 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> -                 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
> -      break;
> +      return build2_loc (loc, TRUTH_ANDIF_EXPR, type,
> +                        invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
> +                        invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
>
>     case TRUTH_NOT_EXPR:
>       return TREE_OPERAND (arg, 0);
> @@ -3180,22 +3155,20 @@ fold_truth_not_expr (location_t loc, tre
>        /* A COND_EXPR may have a throw as one operand, which
>           then has void type.  Just leave void operands
>           as they are.  */
> -       t = build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
> -                   VOID_TYPE_P (TREE_TYPE (arg1))
> -                   ? arg1 : invert_truthvalue_loc (loc1, arg1),
> -                   VOID_TYPE_P (TREE_TYPE (arg2))
> -                   ? arg2 : invert_truthvalue_loc (loc2, arg2));
> -       break;
> +       return build3_loc (loc, COND_EXPR, type, TREE_OPERAND (arg, 0),
> +                          VOID_TYPE_P (TREE_TYPE (arg1))
> +                          ? arg1 : invert_truthvalue_loc (loc1, arg1),
> +                          VOID_TYPE_P (TREE_TYPE (arg2))
> +                          ? arg2 : invert_truthvalue_loc (loc2, arg2));
>       }
>
>     case COMPOUND_EXPR:
>       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
>       if (loc1 == UNKNOWN_LOCATION)
>        loc1 = loc;
> -      t = build2 (COMPOUND_EXPR, type,
> -                 TREE_OPERAND (arg, 0),
> -                 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 1)));
> -      break;
> +      return build2_loc (loc, COMPOUND_EXPR, type,
> +                        TREE_OPERAND (arg, 0),
> +                        invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 1)));
>
>     case NON_LVALUE_EXPR:
>       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
> @@ -3205,10 +3178,7 @@ fold_truth_not_expr (location_t loc, tre
>
>     CASE_CONVERT:
>       if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
> -       {
> -         t = build1 (TRUTH_NOT_EXPR, type, arg);
> -         break;
> -       }
> +       return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);
>
>       /* ... fall through ...  */
>
> @@ -3216,37 +3186,27 @@ fold_truth_not_expr (location_t loc, tre
>       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
>       if (loc1 == UNKNOWN_LOCATION)
>        loc1 = loc;
> -      t = build1 (TREE_CODE (arg), type,
> -                 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
> -      break;
> +      return build1_loc (loc, TREE_CODE (arg), type,
> +                        invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
>
>     case BIT_AND_EXPR:
>       if (!integer_onep (TREE_OPERAND (arg, 1)))
>        return NULL_TREE;
> -      t = build2 (EQ_EXPR, type, arg, build_int_cst (type, 0));
> -      break;
> +      return build2_loc (loc, EQ_EXPR, type, arg, build_int_cst (type, 0));
>
>     case SAVE_EXPR:
> -      t = build1 (TRUTH_NOT_EXPR, type, arg);
> -      break;
> +      return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);
>
>     case CLEANUP_POINT_EXPR:
>       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
>       if (loc1 == UNKNOWN_LOCATION)
>        loc1 = loc;
> -      t = build1 (CLEANUP_POINT_EXPR, type,
> -                 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
> -      break;
> +      return build1_loc (loc, CLEANUP_POINT_EXPR, type,
> +                        invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
>
>     default:
> -      t = NULL_TREE;
> -      break;
> +      return NULL_TREE;
>     }
> -
> -  if (t)
> -    SET_EXPR_LOCATION (t, loc);
> -
> -  return t;
>  }
>
>  /* Return a simplified tree node for the truth-negation of ARG.  This
> @@ -3266,10 +3226,7 @@ invert_truthvalue_loc (location_t loc, t
>
>   tem = fold_truth_not_expr (loc, arg);
>   if (!tem)
> -    {
> -      tem = build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg), arg);
> -      SET_EXPR_LOCATION (tem, loc);
> -    }
> +    tem = build1_loc (loc, TRUTH_NOT_EXPR, TREE_TYPE (arg), arg);
>
>   return tem;
>  }
> @@ -3395,9 +3352,8 @@ make_bit_field_ref (location_t loc, tree
>       || TYPE_UNSIGNED (bftype) == !unsignedp)
>     bftype = build_nonstandard_integer_type (bitsize, 0);
>
> -  result = build3 (BIT_FIELD_REF, bftype, inner,
> -                  size_int (bitsize), bitsize_int (bitpos));
> -  SET_EXPR_LOCATION (result, loc);
> +  result = build3_loc (loc, BIT_FIELD_REF, bftype, inner,
> +                      size_int (bitsize), bitsize_int (bitpos));
>
>   if (bftype != type)
>     result = fold_convert_loc (loc, type, result);
> @@ -3576,10 +3532,8 @@ optimize_bit_field_compare (location_t l
>                                  size_int (lbitpos)),
>                     mask);
>
> -  lhs = build2 (code, compare_type,
> -               build2 (BIT_AND_EXPR, unsigned_type, lhs, mask),
> -               rhs);
> -  SET_EXPR_LOCATION (lhs, loc);
> +  lhs = build2_loc (loc, code, compare_type,
> +                   build2 (BIT_AND_EXPR, unsigned_type, lhs, mask), rhs);
>   return lhs;
>  }
>
> @@ -4005,9 +3959,8 @@ make_range (tree exp, int *pin_p, tree *
>
>        case BIT_NOT_EXPR:
>          /* ~ X -> -X - 1  */
> -         exp = build2 (MINUS_EXPR, exp_type, negate_expr (arg0),
> -                       build_int_cst (exp_type, 1));
> -         SET_EXPR_LOCATION (exp, loc);
> +         exp = build2_loc (loc, MINUS_EXPR, exp_type, negate_expr (arg0),
> +                           build_int_cst (exp_type, 1));
>          continue;
>
>        case PLUS_EXPR:  case MINUS_EXPR:
> @@ -4925,13 +4878,9 @@ fold_range_test (location_t loc, enum tr
>         unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
>         which cases we can't do this.  */
>       if (simple_operand_p (lhs))
> -       {
> -         tem = build2 (code == TRUTH_ANDIF_EXPR
> -                       ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
> -                       type, op0, op1);
> -         SET_EXPR_LOCATION (tem, loc);
> -         return tem;
> -       }
> +       return build2_loc (loc, code == TRUTH_ANDIF_EXPR
> +                          ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
> +                          type, op0, op1);
>
>       else if (lang_hooks.decls.global_bindings_p () == 0
>               && ! CONTAINS_PLACEHOLDER_P (lhs))
> @@ -4948,11 +4897,9 @@ fold_range_test (location_t loc, enum tr
>              if (strict_overflow_p)
>                fold_overflow_warning (warnmsg,
>                                       WARN_STRICT_OVERFLOW_COMPARISON);
> -             tem = build2 (code == TRUTH_ANDIF_EXPR
> -                           ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
> -                           type, lhs, rhs);
> -             SET_EXPR_LOCATION (tem, loc);
> -             return tem;
> +             return build2_loc (loc, code == TRUTH_ANDIF_EXPR
> +                                ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
> +                                type, lhs, rhs);
>            }
>        }
>     }
> @@ -5166,7 +5113,6 @@ fold_truthop (location_t loc, enum tree_
>   if (simple_operand_p (ll_arg)
>       && simple_operand_p (lr_arg))
>     {
> -      tree result;
>       if (operand_equal_p (ll_arg, rl_arg, 0)
>           && operand_equal_p (lr_arg, rr_arg, 0))
>        {
> @@ -5207,13 +5153,10 @@ fold_truthop (location_t loc, enum tree_
>          && rcode == NE_EXPR && integer_zerop (rr_arg)
>          && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg)
>          && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)))
> -       {
> -         result = build2 (NE_EXPR, truth_type,
> +       return build2_loc (loc, NE_EXPR, truth_type,
>                           build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
>                                   ll_arg, rl_arg),
>                           build_int_cst (TREE_TYPE (ll_arg), 0));
> -         goto fold_truthop_exit;
> -       }
>
>       /* Convert (a == 0) && (b == 0) into (a | b) == 0.  */
>       if (code == TRUTH_AND_EXPR
> @@ -5221,21 +5164,15 @@ fold_truthop (location_t loc, enum tree_
>          && rcode == EQ_EXPR && integer_zerop (rr_arg)
>          && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg)
>          && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)))
> -       {
> -         result = build2 (EQ_EXPR, truth_type,
> +       return build2_loc (loc, EQ_EXPR, truth_type,
>                           build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
>                                   ll_arg, rl_arg),
>                           build_int_cst (TREE_TYPE (ll_arg), 0));
> -         goto fold_truthop_exit;
> -       }
>
>       if (LOGICAL_OP_NON_SHORT_CIRCUIT)
>        {
>          if (code != orig_code || lhs != orig_lhs || rhs != orig_rhs)
> -           {
> -             result = build2 (code, truth_type, lhs, rhs);
> -             goto fold_truthop_exit;
> -           }
> +           return build2_loc (loc, code, truth_type, lhs, rhs);
>          return NULL_TREE;
>        }
>     }
> @@ -5426,8 +5363,7 @@ fold_truthop (location_t loc, enum tree_
>          if (! all_ones_mask_p (lr_mask, rnbitsize))
>            rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
>
> -         result = build2 (wanted_code, truth_type, lhs, rhs);
> -         goto fold_truthop_exit;
> +         return build2_loc (loc, wanted_code, truth_type, lhs, rhs);
>        }
>
>       /* There is still another way we can do something:  If both pairs of
> @@ -5480,8 +5416,7 @@ fold_truthop (location_t loc, enum tree_
>          if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
>            rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask);
>
> -         result = build2 (wanted_code, truth_type, lhs, rhs);
> -         goto fold_truthop_exit;
> +         return build2_loc (loc, wanted_code, truth_type, lhs, rhs);
>        }
>
>       return 0;
> @@ -5517,17 +5452,10 @@ fold_truthop (location_t loc, enum tree_
>
>   ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask);
>   if (! all_ones_mask_p (ll_mask, lnbitsize))
> -    {
> -      result = build2 (BIT_AND_EXPR, lntype, result, ll_mask);
> -      SET_EXPR_LOCATION (result, loc);
> -    }
> +    result = build2_loc (loc, BIT_AND_EXPR, lntype, result, ll_mask);
>
> -  result = build2 (wanted_code, truth_type, result,
> -                  const_binop (BIT_IOR_EXPR, l_const, r_const));
> -
> - fold_truthop_exit:
> -  SET_EXPR_LOCATION (result, loc);
> -  return result;
> +  return build2_loc (loc, wanted_code, truth_type, result,
> +                    const_binop (BIT_IOR_EXPR, l_const, r_const));
>  }
>
>  /* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a
> @@ -7616,10 +7544,7 @@ build_fold_addr_expr_with_type_loc (loca
>       t = TREE_OPERAND (t, 0);
>
>       if (TREE_TYPE (t) != ptrtype)
> -       {
> -         t = build1 (NOP_EXPR, ptrtype, t);
> -         SET_EXPR_LOCATION (t, loc);
> -       }
> +       t = build1_loc (loc, NOP_EXPR, ptrtype, t);
>     }
>   else if (TREE_CODE (t) == MEM_REF
>       && integer_zerop (TREE_OPERAND (t, 1)))
> @@ -7632,10 +7557,7 @@ build_fold_addr_expr_with_type_loc (loca
>        t = fold_convert_loc (loc, ptrtype, t);
>     }
>   else
> -    {
> -      t = build1 (ADDR_EXPR, ptrtype, t);
> -      SET_EXPR_LOCATION (t, loc);
> -    }
> +    t = build1_loc (loc, ADDR_EXPR, ptrtype, t);
>
>   return t;
>  }
> @@ -7736,16 +7658,14 @@ fold_unary_loc (location_t loc, enum tre
>                         (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
>                     && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD)
>                  || flag_syntax_only))
> -           {
> -             tem = build1 (code, type,
> -                           build3 (COND_EXPR,
> -                                   TREE_TYPE (TREE_OPERAND
> -                                              (TREE_OPERAND (tem, 1), 0)),
> -                                   TREE_OPERAND (tem, 0),
> -                                   TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
> -                                   TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
> -             SET_EXPR_LOCATION (tem, loc);
> -           }
> +           tem = build1_loc (loc, code, type,
> +                             build3 (COND_EXPR,
> +                                     TREE_TYPE (TREE_OPERAND
> +                                                (TREE_OPERAND (tem, 1), 0)),
> +                                     TREE_OPERAND (tem, 0),
> +                                     TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
> +                                     TREE_OPERAND (TREE_OPERAND (tem, 2),
> +                                                   0)));
>          return tem;
>        }
>       else if (COMPARISON_CLASS_P (arg0))
> @@ -7908,10 +7828,9 @@ fold_unary_loc (location_t loc, enum tre
>             unless assigning a bitfield.  */
>          tem = fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 1));
>          /* First do the assignment, then return converted constant.  */
> -         tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
> +         tem = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
>          TREE_NO_WARNING (tem) = 1;
>          TREE_USED (tem) = 1;
> -         SET_EXPR_LOCATION (tem, loc);
>          return tem;
>        }
>
> @@ -9533,8 +9452,8 @@ fold_binary_loc (location_t loc,
>          tem = fold_build2_loc (loc, code, type,
>                             fold_convert_loc (loc, TREE_TYPE (op0),
>                                               TREE_OPERAND (arg0, 1)), op1);
> -         tem = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0), tem);
> -         goto fold_binary_exit;
> +         return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
> +                            tem);
>        }
>       if (TREE_CODE (arg1) == COMPOUND_EXPR
>          && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
> @@ -9542,8 +9461,8 @@ fold_binary_loc (location_t loc,
>          tem = fold_build2_loc (loc, code, type, op0,
>                             fold_convert_loc (loc, TREE_TYPE (op1),
>                                               TREE_OPERAND (arg1, 1)));
> -         tem = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0), tem);
> -         goto fold_binary_exit;
> +         return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
> +                            tem);
>        }
>
>       if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0))
> @@ -9942,12 +9861,10 @@ fold_binary_loc (location_t loc,
>                && ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
>                    == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
>              {
> -               tem = build2 (LROTATE_EXPR,
> -                             TREE_TYPE (TREE_OPERAND (arg0, 0)),
> -                             TREE_OPERAND (arg0, 0),
> -                             code0 == LSHIFT_EXPR
> -                             ? tree01 : tree11);
> -               SET_EXPR_LOCATION (tem, loc);
> +               tem = build2_loc (loc, LROTATE_EXPR,
> +                                 TREE_TYPE (TREE_OPERAND (arg0, 0)),
> +                                 TREE_OPERAND (arg0, 0),
> +                                 code0 == LSHIFT_EXPR ? tree01 : tree11);
>                return fold_convert_loc (loc, type, tem);
>              }
>            else if (code11 == MINUS_EXPR)
> @@ -13142,13 +13059,10 @@ fold_binary_loc (location_t loc,
>          && TYPE_UNSIGNED (TREE_TYPE (arg0))
>          && TREE_CODE (arg1) == LSHIFT_EXPR
>          && integer_onep (TREE_OPERAND (arg1, 0)))
> -       {
> -         tem = build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
> -                       build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
> -                               TREE_OPERAND (arg1, 1)),
> -                       build_int_cst (TREE_TYPE (arg0), 0));
> -         goto fold_binary_exit;
> -       }
> +       return build2_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
> +                          build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
> +                                  TREE_OPERAND (arg1, 1)),
> +                          build_int_cst (TREE_TYPE (arg0), 0));
>
>       if ((code == LT_EXPR || code == GE_EXPR)
>          && TYPE_UNSIGNED (TREE_TYPE (arg0))
> @@ -13156,14 +13070,11 @@ fold_binary_loc (location_t loc,
>          && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
>          && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
>        {
> -         tem = build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
> -                       fold_convert_loc (loc, TREE_TYPE (arg0),
> -                                         build2 (RSHIFT_EXPR,
> -                                                 TREE_TYPE (arg0), arg0,
> -                                                 TREE_OPERAND (TREE_OPERAND (arg1, 0),
> -                                                               1))),
> -                       build_int_cst (TREE_TYPE (arg0), 0));
> -         goto fold_binary_exit;
> +         tem = build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
> +                       TREE_OPERAND (TREE_OPERAND (arg1, 0), 1));
> +         return build2_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
> +                            fold_convert_loc (loc, TREE_TYPE (arg0), tem),
> +                            build_int_cst (TREE_TYPE (arg0), 0));
>        }
>
>       return NULL_TREE;
> @@ -13257,9 +13168,6 @@ fold_binary_loc (location_t loc,
>     default:
>       return NULL_TREE;
>     } /* switch (code) */
> - fold_binary_exit:
> -  protected_set_expr_location (tem, loc);
> -  return tem;
>  }
>
>  /* Callback for walk_tree, looking for LABEL_EXPR.  Return *TP if it is
> @@ -14026,10 +13934,7 @@ fold_build1_stat_loc (location_t loc,
>
>   tem = fold_unary_loc (loc, code, type, op0);
>   if (!tem)
> -    {
> -      tem = build1_stat (code, type, op0 PASS_MEM_STAT);
> -      SET_EXPR_LOCATION (tem, loc);
> -    }
> +    tem = build1_stat_loc (loc, code, type, op0 PASS_MEM_STAT);
>
>  #ifdef ENABLE_FOLD_CHECKING
>   md5_init_ctx (&ctx);
> @@ -14077,10 +13982,7 @@ fold_build2_stat_loc (location_t loc,
>
>   tem = fold_binary_loc (loc, code, type, op0, op1);
>   if (!tem)
> -    {
> -      tem = build2_stat (code, type, op0, op1 PASS_MEM_STAT);
> -      SET_EXPR_LOCATION (tem, loc);
> -    }
> +    tem = build2_stat_loc (loc, code, type, op0, op1 PASS_MEM_STAT);
>
>  #ifdef ENABLE_FOLD_CHECKING
>   md5_init_ctx (&ctx);
> @@ -14142,10 +14044,7 @@ fold_build3_stat_loc (location_t loc, en
>   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
>   tem = fold_ternary_loc (loc, code, type, op0, op1, op2);
>   if (!tem)
> -    {
> -      tem =  build3_stat (code, type, op0, op1, op2 PASS_MEM_STAT);
> -      SET_EXPR_LOCATION (tem, loc);
> -    }
> +    tem = build3_stat_loc (loc, code, type, op0, op1, op2 PASS_MEM_STAT);
>
>  #ifdef ENABLE_FOLD_CHECKING
>   md5_init_ctx (&ctx);
> @@ -15661,9 +15560,8 @@ fold_indirect_ref_1 (location_t loc, tre
>          tree min_val = size_zero_node;
>          if (type_domain && TYPE_MIN_VALUE (type_domain))
>            min_val = TYPE_MIN_VALUE (type_domain);
> -         op0 = build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
> -         SET_EXPR_LOCATION (op0, loc);
> -         return op0;
> +         return build4_loc (loc, ARRAY_REF, type, op, min_val,
> +                            NULL_TREE, NULL_TREE);
>        }
>       /* *(foo *)&complexfoo => __real__ complexfoo */
>       else if (TREE_CODE (optype) == COMPLEX_TYPE
> @@ -15727,10 +15625,8 @@ fold_indirect_ref_1 (location_t loc, tre
>              op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01,
>                                     TYPE_SIZE_UNIT (type));
>              op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val);
> -             op0 = build4 (ARRAY_REF, type, op00, op01,
> -                           NULL_TREE, NULL_TREE);
> -             SET_EXPR_LOCATION (op0, loc);
> -             return op0;
> +             return build4_loc (loc, ARRAY_REF, type, op00, op01,
> +                                NULL_TREE, NULL_TREE);
>            }
>        }
>     }
> @@ -15745,9 +15641,8 @@ fold_indirect_ref_1 (location_t loc, tre
>       type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
>       if (type_domain && TYPE_MIN_VALUE (type_domain))
>        min_val = TYPE_MIN_VALUE (type_domain);
> -      op0 = build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
> -      SET_EXPR_LOCATION (op0, loc);
> -      return op0;
> +      return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
> +                        NULL_TREE);
>     }
>
>   return NULL_TREE;
> @@ -15765,9 +15660,7 @@ build_fold_indirect_ref_loc (location_t
>   if (sub)
>     return sub;
>
> -  t = build1 (INDIRECT_REF, type, t);
> -  SET_EXPR_LOCATION (t, loc);
> -  return t;
> +  return build1_loc (loc, INDIRECT_REF, type, t);
>  }
>
>  /* Given an INDIRECT_REF T, return either T or a simplified version.  */
> --- gcc/fortran/trans.h.jj      2010-11-01 09:07:18.000000000 +0100
> +++ gcc/fortran/trans.h 2010-11-24 18:16:07.000000000 +0100
> @@ -756,51 +756,6 @@ struct GTY((variable_size)) lang_decl {
>   (TYPE_LANG_SPECIFIC(node)->base_decl[(internal)])
>
>
> -/* Create _loc version of build[0-9].  */
> -
> -static inline tree
> -build1_stat_loc (location_t loc, enum tree_code code, tree type,
> -                tree op MEM_STAT_DECL)
> -{
> -  tree t = build1_stat (code, type, op PASS_MEM_STAT);
> -  SET_EXPR_LOCATION (t, loc);
> -  return t;
> -}
> -#define build1_loc(l,c,t1,t2) build1_stat_loc (l,c,t1,t2 MEM_STAT_INFO)
> -
> -static inline tree
> -build2_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> -                tree op MEM_STAT_DECL)
> -{
> -  tree t = build2_stat (code, type, arg0, op PASS_MEM_STAT);
> -  SET_EXPR_LOCATION (t, loc);
> -  return t;
> -}
> -#define build2_loc(l,c,t1,t2,t3) build2_stat_loc (l,c,t1,t2,t3 MEM_STAT_INFO)
> -
> -static inline tree
> -build3_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> -                tree arg1, tree op MEM_STAT_DECL)
> -{
> -  tree t = build3_stat (code, type, arg0, arg1, op PASS_MEM_STAT);
> -  SET_EXPR_LOCATION (t, loc);
> -  return t;
> -}
> -#define build3_loc(l,c,t1,t2,t3,t4) \
> -  build3_stat_loc (l,c,t1,t2,t3,t4 MEM_STAT_INFO)
> -
> -static inline tree
> -build4_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
> -                tree arg1, tree arg2, tree op MEM_STAT_DECL)
> -{
> -  tree t = build4_stat (code, type, arg0, arg1, arg2, op PASS_MEM_STAT);
> -  SET_EXPR_LOCATION (t, loc);
> -  return t;
> -}
> -#define build4_loc(l,c,t1,t2,t3,t4,t5) \
> -  build4_stat_loc (l,c,t1,t2,t3,t4,t5 MEM_STAT_INFO)
> -
> -
>  /* Build an expression with void type.  */
>  #define build1_v(code, arg) \
>        fold_build1_loc (input_location, code, void_type_node, arg)
>
>        Jakub
>
diff mbox

Patch

different instead.
The patch also fixes a bug introduced during fold-const.c loc-iziation,
in associate_trees.

Bootstrapped/regtested with --enable-checking=yes,rtl,fold on x86_64-linux
and i686-linux, with no regressions compared to yes,rtl
build (without this patch).

Ok for trunk?

2010-11-26  Jakub Jelinek  <jakub@redhat.com>

	PR bootstrap/45700
	* tree.h (build1_stat_loc, build2_stat_loc, build3_stat_loc,
	build4_stat_loc, build5_stat_loc, build6_stat_loc): New inlines.
	(build1_loc, build2_loc, build3_loc, build4_loc, build5_loc,
	build6_loc): Define.
	* fold-const.c (protected_set_expr_location_unshare): New inline.
	(fold_convert_loc, pedantic_non_lvalue_loc): Use it.
	(negate_expr, associate_trees, non_lvalue_loc, omit_one_operand_loc,
	pedantic_omit_one_operand_loc, omit_two_operands_loc,
	fold_truth_not_expr, invert_truthvalue_loc, make_bit_field_ref,
	optimize_bit_field_compare, make_range, fold_range_test, fold_truthop,
	build_fold_addr_expr_with_type_loc, fold_unary_loc, fold_binary_loc,
	fold_indirect_ref_1, build_fold_indirect_ref_loc): Use builN_loc
	instead of buildN followed by SET_EXPR_LOCATION or
	protected_set_expr_location.
	(fold_build1_stat_loc, fold_build2_stat_loc, fold_build3_stat_loc):
	Use buildN_stat_loc instead of buildN_stat followed by
	SET_EXPR_LOCATION.

	* trans.h (build1_stat_loc, build2_stat_loc, build3_stat_loc,
	build4_stat_loc): Removed.
	(build1_loc, build2_loc, build3_loc, build4_loc): Removed.

--- gcc/tree.h.jj	2010-11-24 18:10:55.000000000 +0100
+++ gcc/tree.h	2010-11-24 18:22:57.000000000 +0100
@@ -4034,6 +4034,81 @@  extern tree build6_stat (enum tree_code,
 #define build6(c,t1,t2,t3,t4,t5,t6,t7) \
   build6_stat (c,t1,t2,t3,t4,t5,t6,t7 MEM_STAT_INFO)
 
+/* _loc versions of build[1-6].  */
+
+static inline tree
+build1_stat_loc (location_t loc, enum tree_code code, tree type,
+		 tree arg1 MEM_STAT_DECL)
+{
+  tree t = build1_stat (code, type, arg1 PASS_MEM_STAT);
+  if (CAN_HAVE_LOCATION_P (t))
+    SET_EXPR_LOCATION (t, loc);
+  return t;
+}
+#define build1_loc(l,c,t1,t2) build1_stat_loc (l,c,t1,t2 MEM_STAT_INFO)
+
+static inline tree
+build2_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+		 tree arg1 MEM_STAT_DECL)
+{
+  tree t = build2_stat (code, type, arg0, arg1 PASS_MEM_STAT);
+  if (CAN_HAVE_LOCATION_P (t))
+    SET_EXPR_LOCATION (t, loc);
+  return t;
+}
+#define build2_loc(l,c,t1,t2,t3) build2_stat_loc (l,c,t1,t2,t3 MEM_STAT_INFO)
+
+static inline tree
+build3_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+		 tree arg1, tree arg2 MEM_STAT_DECL)
+{
+  tree t = build3_stat (code, type, arg0, arg1, arg2 PASS_MEM_STAT);
+  if (CAN_HAVE_LOCATION_P (t))
+    SET_EXPR_LOCATION (t, loc);
+  return t;
+}
+#define build3_loc(l,c,t1,t2,t3,t4) \
+  build3_stat_loc (l,c,t1,t2,t3,t4 MEM_STAT_INFO)
+
+static inline tree
+build4_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+		 tree arg1, tree arg2, tree arg3 MEM_STAT_DECL)
+{
+  tree t = build4_stat (code, type, arg0, arg1, arg2, arg3 PASS_MEM_STAT);
+  if (CAN_HAVE_LOCATION_P (t))
+    SET_EXPR_LOCATION (t, loc);
+  return t;
+}
+#define build4_loc(l,c,t1,t2,t3,t4,t5) \
+  build4_stat_loc (l,c,t1,t2,t3,t4,t5 MEM_STAT_INFO)
+
+static inline tree
+build5_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+		 tree arg1, tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
+{
+  tree t = build5_stat (code, type, arg0, arg1, arg2, arg3,
+			arg4 PASS_MEM_STAT);
+  if (CAN_HAVE_LOCATION_P (t))
+    SET_EXPR_LOCATION (t, loc);
+  return t;
+}
+#define build5_loc(l,c,t1,t2,t3,t4,t5,t6) \
+  build5_stat_loc (l,c,t1,t2,t3,t4,t5,t6 MEM_STAT_INFO)
+
+static inline tree
+build6_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+		 tree arg1, tree arg2, tree arg3, tree arg4,
+		 tree arg5 MEM_STAT_DECL)
+{
+  tree t = build6_stat (code, type, arg0, arg1, arg2, arg3, arg4,
+			arg5 PASS_MEM_STAT);
+  if (CAN_HAVE_LOCATION_P (t))
+    SET_EXPR_LOCATION (t, loc);
+  return t;
+}
+#define build6_loc(l,c,t1,t2,t3,t4,t5,t6,t7) \
+  build6_stat_loc (l,c,t1,t2,t3,t4,t5,t6,t7 MEM_STAT_INFO)
+
 extern tree build_var_debug_value_stat (tree, tree MEM_STAT_DECL);
 #define build_var_debug_value(t1,t2) \
   build_var_debug_value_stat (t1,t2 MEM_STAT_INFO)
--- gcc/fold-const.c.jj	2010-11-24 18:10:55.000000000 +0100
+++ gcc/fold-const.c	2010-11-25 21:04:35.000000000 +0100
@@ -143,6 +143,25 @@  static tree fold_relational_const (enum 
 static tree fold_convert_const (enum tree_code, tree, tree);
 
 
+/* Similar to protected_set_expr_location, but never modify x in place,
+   if location can and needs to be set, unshare it.  */
+
+static inline tree
+protected_set_expr_location_unshare (tree x, location_t loc)
+{
+  if (CAN_HAVE_LOCATION_P (x)
+      && EXPR_LOCATION (x) != loc
+      && !(TREE_CODE (x) == SAVE_EXPR
+	   || TREE_CODE (x) == TARGET_EXPR
+	   || TREE_CODE (x) == BIND_EXPR))
+    {
+      x = copy_node (x);
+      SET_EXPR_LOCATION (x, loc);
+    }
+  return x;
+}
+
+
 /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
    overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
    and SUM1.  Then this yields nonzero if overflow occurred during the
@@ -727,10 +746,7 @@  negate_expr (tree t)
 
   tem = fold_negate_expr (loc, t);
   if (!tem)
-    {
-      tem = build1 (NEGATE_EXPR, TREE_TYPE (t), t);
-      SET_EXPR_LOCATION (tem, loc);
-    }
+    tem = build1_loc (loc, NEGATE_EXPR, TREE_TYPE (t), t);
   return fold_convert_loc (loc, type, tem);
 }
 
@@ -841,8 +857,6 @@  split_tree (tree in, enum tree_code code
 static tree
 associate_trees (location_t loc, tree t1, tree t2, enum tree_code code, tree type)
 {
-  tree tem;
-
   if (t1 == 0)
     return t2;
   else if (t2 == 0)
@@ -857,11 +871,15 @@  associate_trees (location_t loc, tree t1
       if (code == PLUS_EXPR)
 	{
 	  if (TREE_CODE (t1) == NEGATE_EXPR)
-	    tem = build2 (MINUS_EXPR, type, fold_convert_loc (loc, type, t2),
-			  fold_convert_loc (loc, type, TREE_OPERAND (t1, 0)));
+	    return build2_loc (loc, MINUS_EXPR, type,
+			       fold_convert_loc (loc, type, t2),
+			       fold_convert_loc (loc, type,
+						 TREE_OPERAND (t1, 0)));
 	  else if (TREE_CODE (t2) == NEGATE_EXPR)
-	    tem = build2 (MINUS_EXPR, type, fold_convert_loc (loc, type, t1),
-			  fold_convert_loc (loc, type, TREE_OPERAND (t2, 0)));
+	    return build2_loc (loc, MINUS_EXPR, type,
+			       fold_convert_loc (loc, type, t1),
+			       fold_convert_loc (loc, type,
+						 TREE_OPERAND (t2, 0)));
 	  else if (integer_zerop (t2))
 	    return fold_convert_loc (loc, type, t1);
 	}
@@ -871,16 +889,12 @@  associate_trees (location_t loc, tree t1
 	    return fold_convert_loc (loc, type, t1);
 	}
 
-      tem = build2 (code, type, fold_convert_loc (loc, type, t1),
-		    fold_convert_loc (loc, type, t2));
-      goto associate_trees_exit;
+      return build2_loc (loc, code, type, fold_convert_loc (loc, type, t1),
+			 fold_convert_loc (loc, type, t2));
     }
 
   return fold_build2_loc (loc, code, type, fold_convert_loc (loc, type, t1),
-		      fold_convert_loc (loc, type, t2));
- associate_trees_exit:
-  protected_set_expr_location (tem, loc);
-  return tem;
+			  fold_convert_loc (loc, type, t2));
 }
 
 /* Check whether TYPE1 and TYPE2 are equivalent integer types, suitable
@@ -2015,7 +2029,7 @@  fold_convert_loc (location_t loc, tree t
       gcc_unreachable ();
     }
  fold_convert_exit:
-  protected_set_expr_location (tem, loc);
+  protected_set_expr_location_unshare (tem, loc);
   return tem;
 }
 
@@ -2079,9 +2093,7 @@  non_lvalue_loc (location_t loc, tree x)
 
   if (! maybe_lvalue_p (x))
     return x;
-  x = build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
-  SET_EXPR_LOCATION (x, loc);
-  return x;
+  return build1_loc (loc, NON_LVALUE_EXPR, TREE_TYPE (x), x);
 }
 
 /* Nonzero means lvalues are limited to those valid in pedantic ANSI C.
@@ -2098,16 +2110,7 @@  pedantic_non_lvalue_loc (location_t loc,
   if (pedantic_lvalues)
     return non_lvalue_loc (loc, x);
 
-  if (CAN_HAVE_LOCATION_P (x)
-      && EXPR_LOCATION (x) != loc
-      && !(TREE_CODE (x) == SAVE_EXPR
-	   || TREE_CODE (x) == TARGET_EXPR
-	   || TREE_CODE (x) == BIND_EXPR))
-    {
-      x = copy_node (x);
-      SET_EXPR_LOCATION (x, loc);
-    }
-  return x;
+  return protected_set_expr_location_unshare (x, loc);
 }
 
 /* Given a tree comparison code, return the code that is the logical inverse
@@ -2981,22 +2984,14 @@  omit_one_operand_loc (location_t loc, tr
   /* If the resulting operand is an empty statement, just return the omitted
      statement casted to void. */
   if (IS_EMPTY_STMT (t) && TREE_SIDE_EFFECTS (omitted))
-    {
-      t = build1 (NOP_EXPR, void_type_node, fold_ignored_result (omitted));
-      goto omit_one_operand_exit;
-    }
+    return build1_loc (loc, NOP_EXPR, void_type_node,
+		       fold_ignored_result (omitted));
 
   if (TREE_SIDE_EFFECTS (omitted))
-    {
-      t = build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
-      goto omit_one_operand_exit;
-    }
+    return build2_loc (loc, COMPOUND_EXPR, type,
+		       fold_ignored_result (omitted), t);
 
   return non_lvalue_loc (loc, t);
-
- omit_one_operand_exit:
-  protected_set_expr_location (t, loc);
-  return t;
 }
 
 /* Similar, but call pedantic_non_lvalue instead of non_lvalue.  */
@@ -3010,22 +3005,14 @@  pedantic_omit_one_operand_loc (location_
   /* If the resulting operand is an empty statement, just return the omitted
      statement casted to void. */
   if (IS_EMPTY_STMT (t) && TREE_SIDE_EFFECTS (omitted))
-    {
-      t = build1 (NOP_EXPR, void_type_node, fold_ignored_result (omitted));
-      goto pedantic_omit_one_operand_exit;
-    }
+    return build1_loc (loc, NOP_EXPR, void_type_node,
+		       fold_ignored_result (omitted));
 
   if (TREE_SIDE_EFFECTS (omitted))
-    {
-      t = build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
-      goto pedantic_omit_one_operand_exit;
-    }
+    return build2_loc (loc, COMPOUND_EXPR, type,
+		       fold_ignored_result (omitted), t);
 
   return pedantic_non_lvalue_loc (loc, t);
-
- pedantic_omit_one_operand_exit:
-  protected_set_expr_location (t, loc);
-  return t;
 }
 
 /* Return a tree for the case when the result of an expression is RESULT
@@ -3039,20 +3026,14 @@  pedantic_omit_one_operand_loc (location_
 
 tree
 omit_two_operands_loc (location_t loc, tree type, tree result,
-		   tree omitted1, tree omitted2)
+		       tree omitted1, tree omitted2)
 {
   tree t = fold_convert_loc (loc, type, result);
 
   if (TREE_SIDE_EFFECTS (omitted2))
-    {
-      t = build2 (COMPOUND_EXPR, type, omitted2, t);
-      SET_EXPR_LOCATION (t, loc);
-    }
+    t = build2_loc (loc, COMPOUND_EXPR, type, omitted2, t);
   if (TREE_SIDE_EFFECTS (omitted1))
-    {
-      t = build2 (COMPOUND_EXPR, type, omitted1, t);
-      SET_EXPR_LOCATION (t, loc);
-    }
+    t = build2_loc (loc, COMPOUND_EXPR, type, omitted1, t);
 
   return TREE_CODE (t) != COMPOUND_EXPR ? non_lvalue_loc (loc, t) : t;
 }
@@ -3068,7 +3049,7 @@  omit_two_operands_loc (location_t loc, t
 tree
 fold_truth_not_expr (location_t loc, tree arg)
 {
-  tree t, type = TREE_TYPE (arg);
+  tree type = TREE_TYPE (arg);
   enum tree_code code = TREE_CODE (arg);
   location_t loc1, loc2;
 
@@ -3089,9 +3070,8 @@  fold_truth_not_expr (location_t loc, tre
       if (code == ERROR_MARK)
 	return NULL_TREE;
 
-      t = build2 (code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
-      SET_EXPR_LOCATION (t, loc);
-      return t;
+      return build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
+			 TREE_OPERAND (arg, 1));
     }
 
   switch (code)
@@ -3106,10 +3086,9 @@  fold_truth_not_expr (location_t loc, tre
 	loc1 = loc;
       if (loc2 == UNKNOWN_LOCATION)
 	loc2 = loc;
-      t = build2 (TRUTH_OR_EXPR, type,
-		  invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
-		  invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
-      break;
+      return build2_loc (loc, TRUTH_OR_EXPR, type,
+			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
+			 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
 
     case TRUTH_OR_EXPR:
       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
@@ -3118,10 +3097,9 @@  fold_truth_not_expr (location_t loc, tre
 	loc1 = loc;
       if (loc2 == UNKNOWN_LOCATION)
 	loc2 = loc;
-      t = build2 (TRUTH_AND_EXPR, type,
-		  invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
-		  invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
-      break;
+      return build2_loc (loc, TRUTH_AND_EXPR, type,
+			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
+			 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
 
     case TRUTH_XOR_EXPR:
       /* Here we can invert either operand.  We invert the first operand
@@ -3130,13 +3108,12 @@  fold_truth_not_expr (location_t loc, tre
 	 negation of the second operand.  */
 
       if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
-	t = build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
-		    TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
+	return build2_loc (loc, TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
+			   TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
       else
-	t = build2 (TRUTH_XOR_EXPR, type,
-		    invert_truthvalue_loc (loc, TREE_OPERAND (arg, 0)),
-		    TREE_OPERAND (arg, 1));
-      break;
+	return build2_loc (loc, TRUTH_XOR_EXPR, type,
+			   invert_truthvalue_loc (loc, TREE_OPERAND (arg, 0)),
+			   TREE_OPERAND (arg, 1));
 
     case TRUTH_ANDIF_EXPR:
       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
@@ -3145,10 +3122,9 @@  fold_truth_not_expr (location_t loc, tre
 	loc1 = loc;
       if (loc2 == UNKNOWN_LOCATION)
 	loc2 = loc;
-      t = build2 (TRUTH_ORIF_EXPR, type,
-		  invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
-		  invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
-      break;
+      return build2_loc (loc, TRUTH_ORIF_EXPR, type,
+			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
+			 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
 
     case TRUTH_ORIF_EXPR:
       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
@@ -3157,10 +3133,9 @@  fold_truth_not_expr (location_t loc, tre
 	loc1 = loc;
       if (loc2 == UNKNOWN_LOCATION)
 	loc2 = loc;
-      t = build2 (TRUTH_ANDIF_EXPR, type,
-		  invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
-		  invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
-      break;
+      return build2_loc (loc, TRUTH_ANDIF_EXPR, type,
+			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
+			 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));
 
     case TRUTH_NOT_EXPR:
       return TREE_OPERAND (arg, 0);
@@ -3180,22 +3155,20 @@  fold_truth_not_expr (location_t loc, tre
 	/* A COND_EXPR may have a throw as one operand, which
 	   then has void type.  Just leave void operands
 	   as they are.  */
-	t = build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
-		    VOID_TYPE_P (TREE_TYPE (arg1))
-		    ? arg1 : invert_truthvalue_loc (loc1, arg1),
-		    VOID_TYPE_P (TREE_TYPE (arg2))
-		    ? arg2 : invert_truthvalue_loc (loc2, arg2));
-	break;
+	return build3_loc (loc, COND_EXPR, type, TREE_OPERAND (arg, 0),
+			   VOID_TYPE_P (TREE_TYPE (arg1))
+			   ? arg1 : invert_truthvalue_loc (loc1, arg1),
+			   VOID_TYPE_P (TREE_TYPE (arg2))
+			   ? arg2 : invert_truthvalue_loc (loc2, arg2));
       }
 
     case COMPOUND_EXPR:
       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 1));
       if (loc1 == UNKNOWN_LOCATION)
 	loc1 = loc;
-      t = build2 (COMPOUND_EXPR, type,
-		  TREE_OPERAND (arg, 0),
-		  invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 1)));
-      break;
+      return build2_loc (loc, COMPOUND_EXPR, type,
+			 TREE_OPERAND (arg, 0),
+			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 1)));
 
     case NON_LVALUE_EXPR:
       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
@@ -3205,10 +3178,7 @@  fold_truth_not_expr (location_t loc, tre
 
     CASE_CONVERT:
       if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
-	{
-	  t = build1 (TRUTH_NOT_EXPR, type, arg);
-	  break;
-	}
+	return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);
 
       /* ... fall through ...  */
 
@@ -3216,37 +3186,27 @@  fold_truth_not_expr (location_t loc, tre
       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
       if (loc1 == UNKNOWN_LOCATION)
 	loc1 = loc;
-      t = build1 (TREE_CODE (arg), type,
-		  invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
-      break;
+      return build1_loc (loc, TREE_CODE (arg), type,
+			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
 
     case BIT_AND_EXPR:
       if (!integer_onep (TREE_OPERAND (arg, 1)))
 	return NULL_TREE;
-      t = build2 (EQ_EXPR, type, arg, build_int_cst (type, 0));
-      break;
+      return build2_loc (loc, EQ_EXPR, type, arg, build_int_cst (type, 0));
 
     case SAVE_EXPR:
-      t = build1 (TRUTH_NOT_EXPR, type, arg);
-      break;
+      return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);
 
     case CLEANUP_POINT_EXPR:
       loc1 = EXPR_LOCATION (TREE_OPERAND (arg, 0));
       if (loc1 == UNKNOWN_LOCATION)
 	loc1 = loc;
-      t = build1 (CLEANUP_POINT_EXPR, type,
-		  invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
-      break;
+      return build1_loc (loc, CLEANUP_POINT_EXPR, type,
+			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));
 
     default:
-      t = NULL_TREE;
-      break;
+      return NULL_TREE;
     }
-
-  if (t)
-    SET_EXPR_LOCATION (t, loc);
-
-  return t;
 }
 
 /* Return a simplified tree node for the truth-negation of ARG.  This
@@ -3266,10 +3226,7 @@  invert_truthvalue_loc (location_t loc, t
 
   tem = fold_truth_not_expr (loc, arg);
   if (!tem)
-    {
-      tem = build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg), arg);
-      SET_EXPR_LOCATION (tem, loc);
-    }
+    tem = build1_loc (loc, TRUTH_NOT_EXPR, TREE_TYPE (arg), arg);
 
   return tem;
 }
@@ -3395,9 +3352,8 @@  make_bit_field_ref (location_t loc, tree
       || TYPE_UNSIGNED (bftype) == !unsignedp)
     bftype = build_nonstandard_integer_type (bitsize, 0);
 
-  result = build3 (BIT_FIELD_REF, bftype, inner,
-		   size_int (bitsize), bitsize_int (bitpos));
-  SET_EXPR_LOCATION (result, loc);
+  result = build3_loc (loc, BIT_FIELD_REF, bftype, inner,
+		       size_int (bitsize), bitsize_int (bitpos));
 
   if (bftype != type)
     result = fold_convert_loc (loc, type, result);
@@ -3576,10 +3532,8 @@  optimize_bit_field_compare (location_t l
 				  size_int (lbitpos)),
 		     mask);
 
-  lhs = build2 (code, compare_type,
-		build2 (BIT_AND_EXPR, unsigned_type, lhs, mask),
-		rhs);
-  SET_EXPR_LOCATION (lhs, loc);
+  lhs = build2_loc (loc, code, compare_type,
+		    build2 (BIT_AND_EXPR, unsigned_type, lhs, mask), rhs);
   return lhs;
 }
 
@@ -4005,9 +3959,8 @@  make_range (tree exp, int *pin_p, tree *
 
 	case BIT_NOT_EXPR:
 	  /* ~ X -> -X - 1  */
-	  exp = build2 (MINUS_EXPR, exp_type, negate_expr (arg0),
-			build_int_cst (exp_type, 1));
-	  SET_EXPR_LOCATION (exp, loc);
+	  exp = build2_loc (loc, MINUS_EXPR, exp_type, negate_expr (arg0),
+			    build_int_cst (exp_type, 1));
 	  continue;
 
 	case PLUS_EXPR:  case MINUS_EXPR:
@@ -4925,13 +4878,9 @@  fold_range_test (location_t loc, enum tr
 	 unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
 	 which cases we can't do this.  */
       if (simple_operand_p (lhs))
-	{
-	  tem = build2 (code == TRUTH_ANDIF_EXPR
-			? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
-			type, op0, op1);
-	  SET_EXPR_LOCATION (tem, loc);
-	  return tem;
-	}
+	return build2_loc (loc, code == TRUTH_ANDIF_EXPR
+			   ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
+			   type, op0, op1);
 
       else if (lang_hooks.decls.global_bindings_p () == 0
 	       && ! CONTAINS_PLACEHOLDER_P (lhs))
@@ -4948,11 +4897,9 @@  fold_range_test (location_t loc, enum tr
 	      if (strict_overflow_p)
 		fold_overflow_warning (warnmsg,
 				       WARN_STRICT_OVERFLOW_COMPARISON);
-	      tem = build2 (code == TRUTH_ANDIF_EXPR
-			    ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
-			    type, lhs, rhs);
-	      SET_EXPR_LOCATION (tem, loc);
-	      return tem;
+	      return build2_loc (loc, code == TRUTH_ANDIF_EXPR
+				 ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
+				 type, lhs, rhs);
 	    }
 	}
     }
@@ -5166,7 +5113,6 @@  fold_truthop (location_t loc, enum tree_
   if (simple_operand_p (ll_arg)
       && simple_operand_p (lr_arg))
     {
-      tree result;
       if (operand_equal_p (ll_arg, rl_arg, 0)
           && operand_equal_p (lr_arg, rr_arg, 0))
 	{
@@ -5207,13 +5153,10 @@  fold_truthop (location_t loc, enum tree_
 	  && rcode == NE_EXPR && integer_zerop (rr_arg)
 	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg)
 	  && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)))
-	{
-	  result = build2 (NE_EXPR, truth_type,
+	return build2_loc (loc, NE_EXPR, truth_type,
 			   build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
 				   ll_arg, rl_arg),
 			   build_int_cst (TREE_TYPE (ll_arg), 0));
-	  goto fold_truthop_exit;
-	}
 
       /* Convert (a == 0) && (b == 0) into (a | b) == 0.  */
       if (code == TRUTH_AND_EXPR
@@ -5221,21 +5164,15 @@  fold_truthop (location_t loc, enum tree_
 	  && rcode == EQ_EXPR && integer_zerop (rr_arg)
 	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg)
 	  && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)))
-	{
-	  result = build2 (EQ_EXPR, truth_type,
+	return build2_loc (loc, EQ_EXPR, truth_type,
 			   build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
 				   ll_arg, rl_arg),
 			   build_int_cst (TREE_TYPE (ll_arg), 0));
-	  goto fold_truthop_exit;
-	}
 
       if (LOGICAL_OP_NON_SHORT_CIRCUIT)
 	{
 	  if (code != orig_code || lhs != orig_lhs || rhs != orig_rhs)
-	    {
-	      result = build2 (code, truth_type, lhs, rhs);
-	      goto fold_truthop_exit;
-	    }
+	    return build2_loc (loc, code, truth_type, lhs, rhs);
 	  return NULL_TREE;
 	}
     }
@@ -5426,8 +5363,7 @@  fold_truthop (location_t loc, enum tree_
 	  if (! all_ones_mask_p (lr_mask, rnbitsize))
 	    rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
 
-	  result = build2 (wanted_code, truth_type, lhs, rhs);
-	  goto fold_truthop_exit;
+	  return build2_loc (loc, wanted_code, truth_type, lhs, rhs);
 	}
 
       /* There is still another way we can do something:  If both pairs of
@@ -5480,8 +5416,7 @@  fold_truthop (location_t loc, enum tree_
 	  if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
 	    rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask);
 
-	  result = build2 (wanted_code, truth_type, lhs, rhs);
-	  goto fold_truthop_exit;
+	  return build2_loc (loc, wanted_code, truth_type, lhs, rhs);
 	}
 
       return 0;
@@ -5517,17 +5452,10 @@  fold_truthop (location_t loc, enum tree_
 
   ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask);
   if (! all_ones_mask_p (ll_mask, lnbitsize))
-    {
-      result = build2 (BIT_AND_EXPR, lntype, result, ll_mask);
-      SET_EXPR_LOCATION (result, loc);
-    }
+    result = build2_loc (loc, BIT_AND_EXPR, lntype, result, ll_mask);
 
-  result = build2 (wanted_code, truth_type, result,
-		   const_binop (BIT_IOR_EXPR, l_const, r_const));
-
- fold_truthop_exit:
-  SET_EXPR_LOCATION (result, loc);
-  return result;
+  return build2_loc (loc, wanted_code, truth_type, result,
+		     const_binop (BIT_IOR_EXPR, l_const, r_const));
 }
 
 /* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a
@@ -7616,10 +7544,7 @@  build_fold_addr_expr_with_type_loc (loca
       t = TREE_OPERAND (t, 0);
 
       if (TREE_TYPE (t) != ptrtype)
-	{
-	  t = build1 (NOP_EXPR, ptrtype, t);
-	  SET_EXPR_LOCATION (t, loc);
-	}
+	t = build1_loc (loc, NOP_EXPR, ptrtype, t);
     }
   else if (TREE_CODE (t) == MEM_REF
       && integer_zerop (TREE_OPERAND (t, 1)))
@@ -7632,10 +7557,7 @@  build_fold_addr_expr_with_type_loc (loca
 	t = fold_convert_loc (loc, ptrtype, t);
     }
   else
-    {
-      t = build1 (ADDR_EXPR, ptrtype, t);
-      SET_EXPR_LOCATION (t, loc);
-    }
+    t = build1_loc (loc, ADDR_EXPR, ptrtype, t);
 
   return t;
 }
@@ -7736,16 +7658,14 @@  fold_unary_loc (location_t loc, enum tre
 			 (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
 		     && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD)
 		  || flag_syntax_only))
-	    {
-	      tem = build1 (code, type,
-			    build3 (COND_EXPR,
-				    TREE_TYPE (TREE_OPERAND
-					       (TREE_OPERAND (tem, 1), 0)),
-				    TREE_OPERAND (tem, 0),
-				    TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
-				    TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
-	      SET_EXPR_LOCATION (tem, loc);
-	    }
+	    tem = build1_loc (loc, code, type,
+			      build3 (COND_EXPR,
+				      TREE_TYPE (TREE_OPERAND
+						 (TREE_OPERAND (tem, 1), 0)),
+				      TREE_OPERAND (tem, 0),
+				      TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
+				      TREE_OPERAND (TREE_OPERAND (tem, 2),
+						    0)));
 	  return tem;
 	}
       else if (COMPARISON_CLASS_P (arg0))
@@ -7908,10 +7828,9 @@  fold_unary_loc (location_t loc, enum tre
 	     unless assigning a bitfield.  */
 	  tem = fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 1));
 	  /* First do the assignment, then return converted constant.  */
-	  tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
+	  tem = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
 	  TREE_NO_WARNING (tem) = 1;
 	  TREE_USED (tem) = 1;
-	  SET_EXPR_LOCATION (tem, loc);
 	  return tem;
 	}
 
@@ -9533,8 +9452,8 @@  fold_binary_loc (location_t loc,
 	  tem = fold_build2_loc (loc, code, type,
 			     fold_convert_loc (loc, TREE_TYPE (op0),
 					       TREE_OPERAND (arg0, 1)), op1);
-	  tem = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0), tem);
-	  goto fold_binary_exit;
+	  return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
+			     tem);
 	}
       if (TREE_CODE (arg1) == COMPOUND_EXPR
 	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
@@ -9542,8 +9461,8 @@  fold_binary_loc (location_t loc,
 	  tem = fold_build2_loc (loc, code, type, op0,
 			     fold_convert_loc (loc, TREE_TYPE (op1),
 					       TREE_OPERAND (arg1, 1)));
-	  tem = build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0), tem);
-	  goto fold_binary_exit;
+	  return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
+			     tem);
 	}
 
       if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0))
@@ -9942,12 +9861,10 @@  fold_binary_loc (location_t loc,
 		&& ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
 		    == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
 	      {
-		tem = build2 (LROTATE_EXPR,
-			      TREE_TYPE (TREE_OPERAND (arg0, 0)),
-			      TREE_OPERAND (arg0, 0),
-			      code0 == LSHIFT_EXPR
-			      ? tree01 : tree11);
-		SET_EXPR_LOCATION (tem, loc);
+		tem = build2_loc (loc, LROTATE_EXPR,
+				  TREE_TYPE (TREE_OPERAND (arg0, 0)),
+				  TREE_OPERAND (arg0, 0),
+				  code0 == LSHIFT_EXPR ? tree01 : tree11);
 		return fold_convert_loc (loc, type, tem);
 	      }
 	    else if (code11 == MINUS_EXPR)
@@ -13142,13 +13059,10 @@  fold_binary_loc (location_t loc,
 	  && TYPE_UNSIGNED (TREE_TYPE (arg0))
 	  && TREE_CODE (arg1) == LSHIFT_EXPR
 	  && integer_onep (TREE_OPERAND (arg1, 0)))
-	{
-	  tem = build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
-			build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
-				TREE_OPERAND (arg1, 1)),
-			build_int_cst (TREE_TYPE (arg0), 0));
-	  goto fold_binary_exit;
-	}
+	return build2_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
+			   build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
+				   TREE_OPERAND (arg1, 1)),
+			   build_int_cst (TREE_TYPE (arg0), 0));
 
       if ((code == LT_EXPR || code == GE_EXPR)
 	  && TYPE_UNSIGNED (TREE_TYPE (arg0))
@@ -13156,14 +13070,11 @@  fold_binary_loc (location_t loc,
 	  && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
 	  && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
 	{
-	  tem = build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
-			fold_convert_loc (loc, TREE_TYPE (arg0),
-					  build2 (RSHIFT_EXPR,
-						  TREE_TYPE (arg0), arg0,
-						  TREE_OPERAND (TREE_OPERAND (arg1, 0),
-								1))),
-			build_int_cst (TREE_TYPE (arg0), 0));
-	  goto fold_binary_exit;
+	  tem = build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
+			TREE_OPERAND (TREE_OPERAND (arg1, 0), 1));
+	  return build2_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
+			     fold_convert_loc (loc, TREE_TYPE (arg0), tem),
+			     build_int_cst (TREE_TYPE (arg0), 0));
 	}
 
       return NULL_TREE;
@@ -13257,9 +13168,6 @@  fold_binary_loc (location_t loc,
     default:
       return NULL_TREE;
     } /* switch (code) */
- fold_binary_exit:
-  protected_set_expr_location (tem, loc);
-  return tem;
 }
 
 /* Callback for walk_tree, looking for LABEL_EXPR.  Return *TP if it is
@@ -14026,10 +13934,7 @@  fold_build1_stat_loc (location_t loc,
 
   tem = fold_unary_loc (loc, code, type, op0);
   if (!tem)
-    {
-      tem = build1_stat (code, type, op0 PASS_MEM_STAT);
-      SET_EXPR_LOCATION (tem, loc);
-    }
+    tem = build1_stat_loc (loc, code, type, op0 PASS_MEM_STAT);
 
 #ifdef ENABLE_FOLD_CHECKING
   md5_init_ctx (&ctx);
@@ -14077,10 +13982,7 @@  fold_build2_stat_loc (location_t loc,
 
   tem = fold_binary_loc (loc, code, type, op0, op1);
   if (!tem)
-    {
-      tem = build2_stat (code, type, op0, op1 PASS_MEM_STAT);
-      SET_EXPR_LOCATION (tem, loc);
-    }
+    tem = build2_stat_loc (loc, code, type, op0, op1 PASS_MEM_STAT);
 
 #ifdef ENABLE_FOLD_CHECKING
   md5_init_ctx (&ctx);
@@ -14142,10 +14044,7 @@  fold_build3_stat_loc (location_t loc, en
   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
   tem = fold_ternary_loc (loc, code, type, op0, op1, op2);
   if (!tem)
-    {
-      tem =  build3_stat (code, type, op0, op1, op2 PASS_MEM_STAT);
-      SET_EXPR_LOCATION (tem, loc);
-    }
+    tem = build3_stat_loc (loc, code, type, op0, op1, op2 PASS_MEM_STAT);
 
 #ifdef ENABLE_FOLD_CHECKING
   md5_init_ctx (&ctx);
@@ -15661,9 +15560,8 @@  fold_indirect_ref_1 (location_t loc, tre
 	  tree min_val = size_zero_node;
 	  if (type_domain && TYPE_MIN_VALUE (type_domain))
 	    min_val = TYPE_MIN_VALUE (type_domain);
-	  op0 = build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
-	  SET_EXPR_LOCATION (op0, loc);
-	  return op0;
+	  return build4_loc (loc, ARRAY_REF, type, op, min_val,
+			     NULL_TREE, NULL_TREE);
 	}
       /* *(foo *)&complexfoo => __real__ complexfoo */
       else if (TREE_CODE (optype) == COMPLEX_TYPE
@@ -15727,10 +15625,8 @@  fold_indirect_ref_1 (location_t loc, tre
 	      op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01,
 				     TYPE_SIZE_UNIT (type));
 	      op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val);
-	      op0 = build4 (ARRAY_REF, type, op00, op01,
-			    NULL_TREE, NULL_TREE);
-	      SET_EXPR_LOCATION (op0, loc);
-	      return op0;
+	      return build4_loc (loc, ARRAY_REF, type, op00, op01,
+				 NULL_TREE, NULL_TREE);
 	    }
 	}
     }
@@ -15745,9 +15641,8 @@  fold_indirect_ref_1 (location_t loc, tre
       type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
       if (type_domain && TYPE_MIN_VALUE (type_domain))
 	min_val = TYPE_MIN_VALUE (type_domain);
-      op0 = build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
-      SET_EXPR_LOCATION (op0, loc);
-      return op0;
+      return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
+			 NULL_TREE);
     }
 
   return NULL_TREE;
@@ -15765,9 +15660,7 @@  build_fold_indirect_ref_loc (location_t 
   if (sub)
     return sub;
 
-  t = build1 (INDIRECT_REF, type, t);
-  SET_EXPR_LOCATION (t, loc);
-  return t;
+  return build1_loc (loc, INDIRECT_REF, type, t);
 }
 
 /* Given an INDIRECT_REF T, return either T or a simplified version.  */
--- gcc/fortran/trans.h.jj	2010-11-01 09:07:18.000000000 +0100
+++ gcc/fortran/trans.h	2010-11-24 18:16:07.000000000 +0100
@@ -756,51 +756,6 @@  struct GTY((variable_size)) lang_decl {
   (TYPE_LANG_SPECIFIC(node)->base_decl[(internal)])
 
 
-/* Create _loc version of build[0-9].  */
-
-static inline tree
-build1_stat_loc (location_t loc, enum tree_code code, tree type,
-		 tree op MEM_STAT_DECL)
-{
-  tree t = build1_stat (code, type, op PASS_MEM_STAT);
-  SET_EXPR_LOCATION (t, loc);
-  return t;
-}
-#define build1_loc(l,c,t1,t2) build1_stat_loc (l,c,t1,t2 MEM_STAT_INFO)
-
-static inline tree
-build2_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
-		 tree op MEM_STAT_DECL)
-{
-  tree t = build2_stat (code, type, arg0, op PASS_MEM_STAT);
-  SET_EXPR_LOCATION (t, loc);
-  return t;
-}
-#define build2_loc(l,c,t1,t2,t3) build2_stat_loc (l,c,t1,t2,t3 MEM_STAT_INFO)
-
-static inline tree
-build3_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
-		 tree arg1, tree op MEM_STAT_DECL)
-{
-  tree t = build3_stat (code, type, arg0, arg1, op PASS_MEM_STAT);
-  SET_EXPR_LOCATION (t, loc);
-  return t;
-}
-#define build3_loc(l,c,t1,t2,t3,t4) \
-  build3_stat_loc (l,c,t1,t2,t3,t4 MEM_STAT_INFO)
-
-static inline tree
-build4_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
-		 tree arg1, tree arg2, tree op MEM_STAT_DECL)
-{
-  tree t = build4_stat (code, type, arg0, arg1, arg2, op PASS_MEM_STAT);
-  SET_EXPR_LOCATION (t, loc);
-  return t;
-}
-#define build4_loc(l,c,t1,t2,t3,t4,t5) \
-  build4_stat_loc (l,c,t1,t2,t3,t4,t5 MEM_STAT_INFO)
-
-
 /* Build an expression with void type.  */
 #define build1_v(code, arg) \
 	fold_build1_loc (input_location, code, void_type_node, arg)