OSDN Git Service

* gcj.texi (Input and output files): Mention non-class entries.
[pf3gnuchains/gcc-fork.git] / gcc / calls.c
index 8296b84..1c51e1a 100644 (file)
@@ -197,6 +197,7 @@ static int check_sibcall_argument_overlap   PARAMS ((rtx, struct arg_data *,
 
 static int combine_pending_stack_adjustment_and_call
                                                 PARAMS ((int, struct args_size *, int));
+static tree fix_unsafe_tree            PARAMS ((tree));
 
 #ifdef REG_PARM_STACK_SPACE
 static rtx save_fixed_argument_area    PARAMS ((int, rtx, int *, int *));
@@ -2068,6 +2069,35 @@ check_sibcall_argument_overlap (insn, arg, mark_stored_args_map)
   return insn != NULL_RTX;
 }
 
+static tree
+fix_unsafe_tree (t)
+     tree t;
+{
+  switch (unsafe_for_reeval (t))
+    {
+    case 0: /* Safe.  */
+      break;
+
+    case 1: /* Mildly unsafe.  */
+      t = unsave_expr (t);
+      break;
+
+    case 2: /* Wildly unsafe.  */
+      {
+       tree var = build_decl (VAR_DECL, NULL_TREE,
+                              TREE_TYPE (t));
+       SET_DECL_RTL (var,
+                     expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL));
+       t = var;
+      }
+      break;
+
+    default:
+      abort ();
+    }
+  return t;
+}
+
 /* Generate all the code for a function call
    and return an rtx for its value.
    Store the value in TARGET (specified as an rtx) if convenient.
@@ -2516,35 +2546,16 @@ expand_call (exp, target, ignore)
 
       for (; i != end; i += inc)
        {
-         switch (unsafe_for_reeval (args[i].tree_value))
-           {
-           case 0: /* Safe.  */
-             break;
-
-           case 1: /* Mildly unsafe.  */
-             args[i].tree_value = unsave_expr (args[i].tree_value);
-             break;
-
-           case 2: /* Wildly unsafe.  */
-             {
-               tree var = build_decl (VAR_DECL, NULL_TREE,
-                                      TREE_TYPE (args[i].tree_value));
-               SET_DECL_RTL (var,
-                             expand_expr (args[i].tree_value, NULL_RTX,
-                                          VOIDmode, EXPAND_NORMAL));
-               args[i].tree_value = var;
-             }
-             break;
-
-           default:
-             abort ();
-           }
+          args[i].tree_value = fix_unsafe_tree (args[i].tree_value);
          /* We need to build actparms for optimize_tail_recursion.  We can
             safely trash away TREE_PURPOSE, since it is unused by this
             function.  */
          if (try_tail_recursion)
            actparms = tree_cons (NULL_TREE, args[i].tree_value, actparms);
        }
+      /* Do the same for the function address if it is an expression. */
+      if (!fndecl)
+        TREE_OPERAND (exp, 0) = fix_unsafe_tree (TREE_OPERAND (exp, 0));
       /* Expanding one of those dangerous arguments could have added
         cleanups, but otherwise give it a whirl.  */
       if (any_pending_cleanups (1))