OSDN Git Service

PR libgcj/27271:
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.c
index a6ee6ed..4749be5 100644 (file)
@@ -590,6 +590,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
          if (n)
            {
              tree new;
+             tree old;
              /* If we happen to get an ADDR_EXPR in n->value, strip
                 it manually here as we'll eventually get ADDR_EXPRs
                 which lie about their types pointed to.  In this case
@@ -598,13 +599,17 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
                 does other useful transformations, try that first, though.  */
              tree type = TREE_TYPE (TREE_TYPE ((tree)n->value));
              new = unshare_expr ((tree)n->value);
+             old = *tp;
              *tp = fold_indirect_ref_1 (type, new);
              if (! *tp)
                {
                  if (TREE_CODE (new) == ADDR_EXPR)
                    *tp = TREE_OPERAND (new, 0);
                  else
-                   *tp = build1 (INDIRECT_REF, type, new);
+                   {
+                     *tp = build1 (INDIRECT_REF, type, new);
+                     TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+                   }
                }
              *walk_subtrees = 0;
              return NULL;
@@ -654,7 +659,12 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
       else if (TREE_CODE (*tp) == ADDR_EXPR)
        {
          walk_tree (&TREE_OPERAND (*tp, 0), copy_body_r, id, NULL);
-         recompute_tree_invariant_for_addr_expr (*tp);
+         /* Handle the case where we substituted an INDIRECT_REF
+            into the operand of the ADDR_EXPR.  */
+         if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
+           *tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
+         else
+           recompute_tree_invariant_for_addr_expr (*tp);
          *walk_subtrees = 0;
        }
     }
@@ -1071,6 +1081,8 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
 
       if (rhs == error_mark_node)
        return;
+       
+      STRIP_USELESS_TYPE_CONVERSION (rhs);
 
       /* We want to use MODIFY_EXPR, not INIT_EXPR here so that we
         keep our trees in gimple form.  */
@@ -1257,6 +1269,8 @@ declare_return_variable (copy_body_data *id, tree return_slot_addr,
   use = var;
   if (!lang_hooks.types_compatible_p (TREE_TYPE (var), caller_type))
     use = fold_convert (caller_type, var);
+    
+  STRIP_USELESS_TYPE_CONVERSION (use);
 
  done:
   /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
@@ -1603,7 +1617,8 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
     case PHI_NODE:
     case WITH_SIZE_EXPR:
     case OMP_CLAUSE:
-    case OMP_RETURN_EXPR:
+    case OMP_RETURN:
+    case OMP_CONTINUE:
       break;
 
     /* We don't account constants for now.  Assume that the cost is amortized
@@ -2072,6 +2087,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
       if (CALL_EXPR_RETURN_SLOT_OPT (t))
        {
          return_slot_addr = build_fold_addr_expr (modify_dest);
+         STRIP_USELESS_TYPE_CONVERSION (return_slot_addr);
          modify_dest = NULL;
        }
     }