OSDN Git Service

2009-12-11 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
[pf3gnuchains/gcc-fork.git] / gcc / gimplify.c
index b20c8ac..a3c6834 100644 (file)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "splay-tree.h"
 #include "vec.h"
 #include "gimple.h"
+#include "tree-pass.h"
 
 
 enum gimplify_omp_var_data
@@ -776,23 +777,6 @@ should_carry_location_p (gimple gs)
   return true;
 }
 
-/* Same, but for a tree.  */
-
-static bool
-tree_should_carry_location_p (const_tree stmt)
-{
-  /* Don't emit a line note for a label.  We particularly don't want to
-     emit one for the break label, since it doesn't actually correspond
-     to the beginning of the loop/switch.  */
-  if (TREE_CODE (stmt) == LABEL_EXPR)
-    return false;
-
-  /* Do not annotate empty statements, since it confuses gcov.  */
-  if (!TREE_SIDE_EFFECTS (stmt))
-    return false;
-
-  return true;
-}
 
 /* Return true if a location should not be emitted for this statement
    by annotate_one_with_location.  */
@@ -819,22 +803,12 @@ gimple_set_do_not_emit_location (gimple g)
 static void
 annotate_one_with_location (gimple gs, location_t location)
 {
-  if (!gimple_has_location (gs) 
+  if (!gimple_has_location (gs)
       && !gimple_do_not_emit_location_p (gs)
       && should_carry_location_p (gs))
     gimple_set_location (gs, location);
 }
 
-/* Same, but for tree T.  */
-
-static void
-tree_annotate_one_with_location (tree t, location_t location)
-{
-  if (CAN_HAVE_LOCATION_P (t)
-      && ! EXPR_HAS_LOCATION (t) && tree_should_carry_location_p (t))
-    SET_EXPR_LOCATION (t, location);
-}
-
 
 /* Set LOCATION for all the statements after iterator GSI in sequence
    SEQ.  If GSI is pointing to the end of the sequence, start with the
@@ -871,29 +845,6 @@ annotate_all_with_location (gimple_seq stmt_p, location_t location)
     }
 }
 
-/* Same, but for statement or statement list in *STMT_P.  */
-
-void
-tree_annotate_all_with_location (tree *stmt_p, location_t location)
-{
-  tree_stmt_iterator i;
-
-  if (!*stmt_p)
-    return;
-
-  for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i))
-    {
-      tree t = tsi_stmt (i);
-
-      /* Assuming we've already been gimplified, we shouldn't
-         see nested chaining constructs anymore.  */
-      gcc_assert (TREE_CODE (t) != STATEMENT_LIST
-                 && TREE_CODE (t) != COMPOUND_EXPR);
-
-      tree_annotate_one_with_location (t, location);
-    }
-}
-
 
 /* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes.
    These nodes model computations that should only be done once.  If we
@@ -1494,12 +1445,12 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
       tree default_case = NULL_TREE;
       size_t i, len;
       gimple gimple_switch;
-      
+
       /* If someone can be bothered to fill in the labels, they can
         be bothered to null out the body too.  */
       gcc_assert (!SWITCH_LABELS (switch_expr));
 
-      /* save old labels, get new ones from body, then restore the old 
+      /* save old labels, get new ones from body, then restore the old
          labels.  Save all the things from the switch body to append after.  */
       saved_labels = gimplify_ctxp->case_labels;
       gimplify_ctxp->case_labels = VEC_alloc (tree, heap, 8);
@@ -1507,7 +1458,7 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
       gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
       labels = gimplify_ctxp->case_labels;
       gimplify_ctxp->case_labels = saved_labels;
+
       i = 0;
       while (i < VEC_length (tree, labels))
        {
@@ -1596,7 +1547,7 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
            }
        }
 
-      gimple_switch = gimple_build_switch_vec (SWITCH_COND (switch_expr), 
+      gimple_switch = gimple_build_switch_vec (SWITCH_COND (switch_expr),
                                                default_case, labels);
       gimplify_seq_add_stmt (pre_p, gimple_switch);
       gimplify_seq_add_seq (pre_p, switch_body_seq);
@@ -1762,7 +1713,8 @@ canonicalize_addr_expr (tree *expr_p)
      the expression pointer type.  */
   ddatype = TREE_TYPE (datype);
   pddatype = build_pointer_type (ddatype);
-  if (!useless_type_conversion_p (pddatype, ddatype))
+  if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
+                                 pddatype))
     return;
 
   /* The lower bound and element sizes must be constant.  */
@@ -1777,6 +1729,10 @@ canonicalize_addr_expr (tree *expr_p)
                    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
                    NULL_TREE, NULL_TREE);
   *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
+
+  /* We can have stripped a required restrict qualifier above.  */
+  if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
+    *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
 }
 
 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
@@ -1786,6 +1742,7 @@ static enum gimplify_status
 gimplify_conversion (tree *expr_p)
 {
   tree tem;
+  location_t loc = EXPR_LOCATION (*expr_p);
   gcc_assert (CONVERT_EXPR_P (*expr_p));
 
   /* Then strip away all but the outermost conversion.  */
@@ -1826,9 +1783,9 @@ gimplify_conversion (tree *expr_p)
 
   /* If we have a conversion to a non-register type force the
      use of a VIEW_CONVERT_EXPR instead.  */
-  if (!is_gimple_reg_type (TREE_TYPE (*expr_p)))
-    *expr_p = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
-                          TREE_OPERAND (*expr_p, 0));
+  if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
+    *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
+                              TREE_OPERAND (*expr_p, 0));
 
   return GS_OK;
 }
@@ -1836,7 +1793,7 @@ gimplify_conversion (tree *expr_p)
 /* Nonlocal VLAs seen in the current function.  */
 static struct pointer_set_t *nonlocal_vlas;
 
-/* Gimplify a VAR_DECL or PARM_DECL.  Returns GS_OK if we expanded a 
+/* Gimplify a VAR_DECL or PARM_DECL.  Returns GS_OK if we expanded a
    DECL_VALUE_EXPR, and it's worth re-examining things.  */
 
 static enum gimplify_status
@@ -1933,6 +1890,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   VEC(tree,heap) *stack;
   enum gimplify_status ret = GS_OK, tret;
   int i;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   /* Create a stack of the subexpressions so later we can walk them in
      order from inner to outer.  */
@@ -1944,7 +1902,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
     restart:
       /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
       if (TREE_CODE (*p) == INDIRECT_REF)
-       *p = fold_indirect_ref (*p);
+       *p = fold_indirect_ref_loc (loc, *p);
 
       if (handled_component_p (*p))
        ;
@@ -1955,7 +1913,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
        goto restart;
       else
        break;
-              
+
       VEC_safe_push (tree, heap, stack, *p);
     }
 
@@ -2003,7 +1961,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 
              /* Divide the element size by the alignment of the element
                 type (above).  */
-             elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor);
+             elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
 
              if (!is_gimple_min_invariant (elmt_size))
                {
@@ -2026,7 +1984,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
 
              /* Divide the offset by its alignment.  */
-             offset = size_binop (EXACT_DIV_EXPR, offset, factor);
+             offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
 
              if (!is_gimple_min_invariant (offset))
                {
@@ -2116,6 +2074,7 @@ gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   bool postfix;
   enum tree_code arith_code;
   enum gimplify_status ret;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   code = TREE_CODE (*expr_p);
 
@@ -2159,9 +2118,9 @@ gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
       if (!is_gimple_min_lval (lvalue))
        {
          mark_addressable (lvalue);
-         lvalue = build_fold_addr_expr (lvalue);
+         lvalue = build_fold_addr_expr_loc (input_location, lvalue);
          gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue);
-         lvalue = build_fold_indirect_ref (lvalue);
+         lvalue = build_fold_indirect_ref_loc (input_location, lvalue);
        }
       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
       if (ret == GS_ERROR)
@@ -2171,9 +2130,9 @@ gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
   if (POINTER_TYPE_P (TREE_TYPE (lhs)))
     {
-      rhs = fold_convert (sizetype, rhs);
+      rhs = fold_convert_loc (loc, sizetype, rhs);
       if (arith_code == MINUS_EXPR)
-       rhs = fold_build1 (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
+       rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
       arith_code = POINTER_PLUS_EXPR;
     }
 
@@ -2268,6 +2227,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
   int i, nargs;
   gimple call;
   bool builtin_va_start_p = FALSE;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
 
@@ -2291,7 +2251,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
   fndecl = get_callee_fndecl (*expr_p);
   if (fndecl && DECL_BUILT_IN (fndecl))
     {
-      tree new_tree = fold_call_expr (*expr_p, !want_value);
+      tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
 
       if (new_tree && new_tree != *expr_p)
        {
@@ -2312,7 +2272,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
              *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
              return GS_OK;
            }
-         
+
          if (fold_builtin_next_arg (*expr_p, true))
            {
              *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
@@ -2364,8 +2324,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
          tree call = *expr_p;
 
          --nargs;
-         *expr_p = build_call_array (TREE_TYPE (call), CALL_EXPR_FN (call),
-                                     nargs, CALL_EXPR_ARGP (call));
+         *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
+                                         CALL_EXPR_FN (call),
+                                         nargs, CALL_EXPR_ARGP (call));
 
          /* Copy all CALL_EXPR flags, location and block, except
             CALL_EXPR_VA_ARG_PACK flag.  */
@@ -2405,10 +2366,18 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
         }
     }
 
+  /* Verify the function result.  */
+  if (want_value && fndecl
+      && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
+    {
+      error_at (loc, "using result of function returning %<void%>");
+      ret = GS_ERROR;
+    }
+
   /* Try this again in case gimplification exposed something.  */
   if (ret != GS_ERROR)
     {
-      tree new_tree = fold_call_expr (*expr_p, !want_value);
+      tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
 
       if (new_tree && new_tree != *expr_p)
        {
@@ -2749,6 +2718,7 @@ tree
 gimple_boolify (tree expr)
 {
   tree type = TREE_TYPE (expr);
+  location_t loc = EXPR_LOCATION (expr);
 
   if (TREE_CODE (type) == BOOLEAN_TYPE)
     return expr;
@@ -2777,7 +2747,7 @@ gimple_boolify (tree expr)
     default:
       /* Other expressions that get here must have boolean values, but
         might need to be converted to the appropriate mode.  */
-      return fold_convert (boolean_type_node, expr);
+      return fold_convert_loc (loc, boolean_type_node, expr);
     }
 }
 
@@ -2860,6 +2830,7 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
   gimple gimple_cond;
   enum tree_code pred_code;
   gimple_seq seq = NULL;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   type = TREE_TYPE (expr);
 
@@ -2893,18 +2864,18 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
 
          if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
            TREE_OPERAND (expr, 1) =
-             build_fold_addr_expr (TREE_OPERAND (expr, 1));
+             build_fold_addr_expr_loc (loc, TREE_OPERAND (expr, 1));
 
          if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
            TREE_OPERAND (expr, 2) =
-             build_fold_addr_expr (TREE_OPERAND (expr, 2));
+             build_fold_addr_expr_loc (loc, TREE_OPERAND (expr, 2));
 
          tmp = create_tmp_var (type, "iftmp");
 
          expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0),
                         TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2));
 
-         result = build_fold_indirect_ref (tmp);
+         result = build_fold_indirect_ref_loc (loc, tmp);
        }
 
       /* Build the then clause, 't1 = a;'.  But don't build an assignment
@@ -3074,6 +3045,25 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
   return ret;
 }
 
+/* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
+   to be marked addressable.
+
+   We cannot rely on such an expression being directly markable if a temporary
+   has been created by the gimplification.  In this case, we create another
+   temporary and initialize it with a copy, which will become a store after we
+   mark it addressable.  This can happen if the front-end passed us something
+   that it could not mark addressable yet, like a Fortran pass-by-reference
+   parameter (int) floatvar.  */
+
+static void
+prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
+{
+  while (handled_component_p (*expr_p))
+    expr_p = &TREE_OPERAND (*expr_p, 0);
+  if (is_gimple_reg (*expr_p))
+    *expr_p = get_initialized_tmp_var (*expr_p, seq_p, NULL);
+}
+
 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
    a call to __builtin_memcpy.  */
 
@@ -3083,17 +3073,22 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
 {
   tree t, to, to_ptr, from, from_ptr;
   gimple gs;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   to = TREE_OPERAND (*expr_p, 0);
   from = TREE_OPERAND (*expr_p, 1);
 
+  /* Mark the RHS addressable.  Beware that it may not be possible to do so
+     directly if a temporary has been created by the gimplification.  */
+  prepare_gimple_addressable (&from, seq_p);
+
   mark_addressable (from);
-  from_ptr = build_fold_addr_expr (from);
-  gimplify_arg (&from_ptr, seq_p, EXPR_LOCATION (*expr_p));
+  from_ptr = build_fold_addr_expr_loc (loc, from);
+  gimplify_arg (&from_ptr, seq_p, loc);
 
   mark_addressable (to);
-  to_ptr = build_fold_addr_expr (to);
-  gimplify_arg (&to_ptr, seq_p, EXPR_LOCATION (*expr_p));
+  to_ptr = build_fold_addr_expr_loc (loc, to);
+  gimplify_arg (&to_ptr, seq_p, loc);
 
   t = implicit_built_in_decls[BUILT_IN_MEMCPY];
 
@@ -3125,11 +3120,12 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
 {
   tree t, from, to, to_ptr;
   gimple gs;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   /* Assert our assumptions, to abort instead of producing wrong code
      silently if they are not met.  Beware that the RHS CONSTRUCTOR might
      not be immediately exposed.  */
-  from = TREE_OPERAND (*expr_p, 1);  
+  from = TREE_OPERAND (*expr_p, 1);
   if (TREE_CODE (from) == WITH_SIZE_EXPR)
     from = TREE_OPERAND (from, 0);
 
@@ -3139,8 +3135,8 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
   /* Now proceed.  */
   to = TREE_OPERAND (*expr_p, 0);
 
-  to_ptr = build_fold_addr_expr (to);
-  gimplify_arg (&to_ptr, seq_p, EXPR_LOCATION (*expr_p));
+  to_ptr = build_fold_addr_expr_loc (loc, to);
+  gimplify_arg (&to_ptr, seq_p, loc);
   t = implicit_built_in_decls[BUILT_IN_MEMSET];
 
   gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
@@ -3362,18 +3358,18 @@ gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
 }
 
 /* Return true if FDECL is accessing a field that is zero sized.  */
-   
+
 static bool
 zero_sized_field_decl (const_tree fdecl)
 {
-  if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl) 
+  if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
       && integer_zerop (DECL_SIZE (fdecl)))
     return true;
   return false;
 }
 
 /* Return true if TYPE is zero sized.  */
-   
+
 static bool
 zero_sized_type (const_tree type)
 {
@@ -3620,7 +3616,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
              return GS_OK;
            break;
          }
+
        /* Fetch information about the constructor to direct later processing.
           We might want to make static versions of it in various cases, and
           can only do so if it known to be a valid constant initializer.  */
@@ -4029,7 +4025,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
        break;
       case INDIRECT_REF:
        {
-         /* If we have code like 
+         /* If we have code like
 
                *(const A*)(A*)&x
 
@@ -4200,7 +4196,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
            *expr_p = wrap;
          return GS_OK;
        }
-       
+
       case COMPOUND_LITERAL_EXPR:
        {
          tree complit = TREE_OPERAND (*expr_p, 1);
@@ -4296,6 +4292,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   tree *to_p = &TREE_OPERAND (*expr_p, 0);
   enum gimplify_status ret = GS_UNHANDLED;
   gimple assign;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
              || TREE_CODE (*expr_p) == INIT_EXPR);
@@ -4303,12 +4300,11 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   /* Insert pointer conversions required by the middle-end that are not
      required by the frontend.  This fixes middle-end type checking for
      for example gcc.dg/redecl-6.c.  */
-  if (POINTER_TYPE_P (TREE_TYPE (*to_p))
-      && lang_hooks.types_compatible_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
+  if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
     {
       STRIP_USELESS_TYPE_CONVERSION (*from_p);
       if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
-       *from_p = fold_convert (TREE_TYPE (*to_p), *from_p);
+       *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
     }
 
   /* See if any simplifications can be done based on what the RHS is.  */
@@ -4450,14 +4446,15 @@ gimplify_variable_sized_compare (tree *expr_p)
   tree op0 = TREE_OPERAND (*expr_p, 0);
   tree op1 = TREE_OPERAND (*expr_p, 1);
   tree t, arg, dest, src;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
   arg = unshare_expr (arg);
   arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
-  src = build_fold_addr_expr (op1);
-  dest = build_fold_addr_expr (op0);
+  src = build_fold_addr_expr_loc (loc, op1);
+  dest = build_fold_addr_expr_loc (loc, op0);
   t = implicit_built_in_decls[BUILT_IN_MEMCMP];
-  t = build_call_expr (t, 3, dest, src, arg);
+  t = build_call_expr_loc (loc, t, 3, dest, src, arg);
   *expr_p
     = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
 
@@ -4470,17 +4467,18 @@ gimplify_variable_sized_compare (tree *expr_p)
 static enum gimplify_status
 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
 {
+  location_t loc = EXPR_LOCATION (*expr_p);
   tree op0 = TREE_OPERAND (*expr_p, 0);
   tree op1 = TREE_OPERAND (*expr_p, 1);
 
   tree type = TREE_TYPE (op0);
   tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
 
-  op0 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op0);
-  op1 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op1);
+  op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
+  op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
 
   *expr_p
-    = fold_build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
+    = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
 
   return GS_OK;
 }
@@ -4502,8 +4500,8 @@ gimplify_boolean_expr (tree *expr_p, location_t locus)
   tree type = TREE_TYPE (*expr_p);
 
   *expr_p = build3 (COND_EXPR, type, *expr_p,
-                   fold_convert (type, boolean_true_node),
-                   fold_convert (type, boolean_false_node));
+                   fold_convert_loc (locus, type, boolean_true_node),
+                   fold_convert_loc (locus, type, boolean_false_node));
 
   SET_EXPR_LOCATION (*expr_p, locus);
 
@@ -4607,6 +4605,7 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   tree expr = *expr_p;
   tree op0 = TREE_OPERAND (expr, 0);
   enum gimplify_status ret;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
   switch (TREE_CODE (op0))
     {
@@ -4628,7 +4627,7 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
        tree t_op00 = TREE_TYPE (op00);
 
         if (!useless_type_conversion_p (t_expr, t_op00))
-         op00 = fold_convert (TREE_TYPE (expr), op00);
+         op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
         *expr_p = op00;
         ret = GS_OK;
       }
@@ -4647,8 +4646,9 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
        op0 = TREE_OPERAND (op0, 0);
 
-      *expr_p = fold_convert (TREE_TYPE (expr),
-                             build_fold_addr_expr (TREE_OPERAND (op0, 0)));
+      *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
+                                 build_fold_addr_expr_loc (loc,
+                                                       TREE_OPERAND (op0, 0)));
       ret = GS_OK;
       break;
 
@@ -4658,22 +4658,15 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
         gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
         the implied temporary explicit.  */
 
-      /* Mark the RHS addressable.  */
+      /* Make the operand addressable.  */
       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
                           is_gimple_addressable, fb_either);
       if (ret == GS_ERROR)
        break;
 
-      /* We cannot rely on making the RHS addressable if it is
-        a temporary created by gimplification.  In this case create a
-        new temporary that is initialized by a copy (which will
-        become a store after we mark it addressable).
-        This mostly happens if the frontend passed us something that
-        it could not mark addressable yet, like a fortran
-        pass-by-reference parameter (int) floatvar.  */
-      if (is_gimple_reg (TREE_OPERAND (expr, 0)))
-       TREE_OPERAND (expr, 0)
-         = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
+      /* Then mark it.  Beware that it may not be possible to do so directly
+        if a temporary has been created by the gimplification.  */
+      prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
 
       op0 = TREE_OPERAND (expr, 0);
 
@@ -4682,10 +4675,22 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (TREE_CODE (op0) == INDIRECT_REF)
        goto do_indirect_ref;
 
+      mark_addressable (TREE_OPERAND (expr, 0));
+
+      /* The FEs may end up building ADDR_EXPRs early on a decl with
+        an incomplete type.  Re-build ADDR_EXPRs in canonical form
+        here.  */
+      if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
+       *expr_p = build_fold_addr_expr (op0);
+
       /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
-      recompute_tree_invariant_for_addr_expr (expr);
+      recompute_tree_invariant_for_addr_expr (*expr_p);
+
+      /* If we re-built the ADDR_EXPR add a conversion to the original type
+         if required.  */
+      if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
+       *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
 
-      mark_addressable (TREE_OPERAND (expr, 0));
       break;
     }
 
@@ -4710,13 +4715,14 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   VEC(tree, gc) *inputs;
   VEC(tree, gc) *outputs;
   VEC(tree, gc) *clobbers;
+  VEC(tree, gc) *labels;
   tree link_next;
-  
+
   expr = *expr_p;
   noutputs = list_length (ASM_OUTPUTS (expr));
   oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
 
-  inputs = outputs = clobbers = NULL;
+  inputs = outputs = clobbers = labels = NULL;
 
   ret = GS_ALL_DONE;
   link_next = NULL_TREE;
@@ -4896,17 +4902,24 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       TREE_CHAIN (link) = NULL_TREE;
       VEC_safe_push (tree, gc, inputs, link);
     }
-  
+
   for (link = ASM_CLOBBERS (expr); link; ++i, link = TREE_CHAIN (link))
-      VEC_safe_push (tree, gc, clobbers, link);
-    
-  stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
-                               inputs, outputs, clobbers);
+    VEC_safe_push (tree, gc, clobbers, link);
 
-  gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr));
-  gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
+  for (link = ASM_LABELS (expr); link; ++i, link = TREE_CHAIN (link))
+    VEC_safe_push (tree, gc, labels, link);
 
-  gimplify_seq_add_stmt (pre_p, stmt);
+  /* Do not add ASMs with errors to the gimple IL stream.  */
+  if (ret != GS_ERROR)
+    {
+      stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
+                                  inputs, outputs, clobbers, labels);
+
+      gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr));
+      gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
+
+      gimplify_seq_add_stmt (pre_p, stmt);
+    }
 
   return ret;
 }
@@ -5264,7 +5277,7 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
     }
 
   /* When adding a variable-sized variable, we have to handle all sorts
-     of additional bits of data: the pointer replacement variable, and 
+     of additional bits of data: the pointer replacement variable, and
      the parameters of the type.  */
   if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
     {
@@ -5296,7 +5309,7 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
        flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
                | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
 
-      /* We're going to make use of the TYPE_SIZE_UNIT at least in the 
+      /* We're going to make use of the TYPE_SIZE_UNIT at least in the
         alloca statement we generate for the variable, so make sure it
         is available.  This isn't automatically needed for the SHARED
         case, since we won't be allocating local storage then.
@@ -5615,7 +5628,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
              push_gimplify_context (&gctx);
              gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
                                &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
-             pop_gimplify_context 
+             pop_gimplify_context
                (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
              OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
              OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
@@ -5812,7 +5825,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
          OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
            = (n->value & GOVD_FIRSTPRIVATE) != 0;
          break;
-         
+
        case OMP_CLAUSE_REDUCTION:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
@@ -5838,7 +5851,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
 
   /* Add in any implicit data sharing.  */
   splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, list_p);
-  
+
   gimplify_omp_ctxp = ctx->outer_context;
   delete_omp_context (ctx);
 }
@@ -5962,7 +5975,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
        {
          var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
          TREE_OPERAND (t, 0) = var;
-                              
+
          gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
 
          omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
@@ -6112,21 +6125,16 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
 }
 
 /* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
-   stabilized the lhs of the atomic operation as *ADDR.  Return true if 
+   stabilized the lhs of the atomic operation as *ADDR.  Return true if
    EXPR is this stabilized form.  */
 
 static bool
 goa_lhs_expr_p (tree expr, tree addr)
 {
   /* Also include casts to other type variants.  The C front end is fond
-     of adding these for e.g. volatile variables.  This is like 
+     of adding these for e.g. volatile variables.  This is like
      STRIP_TYPE_NOPS but includes the main variant lookup.  */
-  while ((CONVERT_EXPR_P (expr)
-          || TREE_CODE (expr) == NON_LVALUE_EXPR)
-         && TREE_OPERAND (expr, 0) != error_mark_node
-         && (TYPE_MAIN_VARIANT (TREE_TYPE (expr))
-             == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (expr, 0)))))
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_USELESS_TYPE_CONVERSION (expr);
 
   if (TREE_CODE (expr) == INDIRECT_REF)
     {
@@ -6135,8 +6143,7 @@ goa_lhs_expr_p (tree expr, tree addr)
             && (CONVERT_EXPR_P (expr)
                 || TREE_CODE (expr) == NON_LVALUE_EXPR)
             && TREE_CODE (expr) == TREE_CODE (addr)
-            && TYPE_MAIN_VARIANT (TREE_TYPE (expr))
-               == TYPE_MAIN_VARIANT (TREE_TYPE (addr)))
+            && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
        {
          expr = TREE_OPERAND (expr, 0);
          addr = TREE_OPERAND (addr, 0);
@@ -6171,7 +6178,7 @@ goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
     }
   if (is_gimple_val (expr))
     return 0;
+
   saw_lhs = 0;
   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
     {
@@ -6224,6 +6231,8 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
   tree tmp_load;
 
    tmp_load = create_tmp_var (type, NULL);
+   if (TREE_CODE (type) == COMPLEX_TYPE || TREE_CODE (type) == VECTOR_TYPE)
+     DECL_GIMPLE_REG_P (tmp_load) = 1;
    if (goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
      return GS_ERROR;
 
@@ -6556,7 +6565,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
          break;
 
        case INDIRECT_REF:
-         *expr_p = fold_indirect_ref (*expr_p);
+         *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
          if (*expr_p != save_expr)
            break;
          /* else fall through.  */
@@ -6592,11 +6601,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
          ret = gimplify_decl_expr (expr_p, pre_p);
          break;
 
-       case EXC_PTR_EXPR:
-         /* FIXME make this a decl.  */
-         ret = GS_ALL_DONE;
-         break;
-
        case BIND_EXPR:
          ret = gimplify_bind_expr (expr_p, pre_p);
          break;
@@ -6788,8 +6792,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
            gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
            ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
            gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
-           gimple_eh_filter_set_must_not_throw
-             (ehf, EH_FILTER_MUST_NOT_THROW (*expr_p));
            gimplify_seq_add_stmt (pre_p, ehf);
            ret = GS_ALL_DONE;
            break;
@@ -7125,7 +7127,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                  && code != GOTO_EXPR
                  && code != LABEL_EXPR
                  && code != LOOP_EXPR
-                 && code != RESX_EXPR
                  && code != SWITCH_EXPR
                  && code != TRY_FINALLY_EXPR
                  && code != OMP_CRITICAL
@@ -7161,7 +7162,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
       /* An lvalue will do.  Take the address of the expression, store it
         in a temporary, and replace the expression with an INDIRECT_REF of
         that temporary.  */
-      tmp = build_fold_addr_expr (*expr_p);
+      tmp = build_fold_addr_expr_loc (input_location, *expr_p);
       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
       *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
     }
@@ -7457,7 +7458,7 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
 
 /* Entry point to the gimplification pass.  FNDECL is the FUNCTION_DECL
    node for the function we want to gimplify.
-   
+
    Returns the sequence of GIMPLE statements corresponding to the body
    of FNDECL.  */
 
@@ -7468,6 +7469,8 @@ gimplify_function_tree (tree fndecl)
   gimple_seq seq;
   gimple bind;
 
+  gcc_assert (!gimple_body (fndecl));
+
   oldfn = current_function_decl;
   current_function_decl = fndecl;
   if (DECL_STRUCT_FUNCTION (fndecl))
@@ -7534,6 +7537,7 @@ gimplify_function_tree (tree fndecl)
     }
 
   DECL_SAVED_TREE (fndecl) = NULL_TREE;
+  cfun->curr_properties = PROP_gimple_any;
 
   current_function_decl = oldfn;
   pop_cfun ();