OSDN Git Service

* gcc.dg/lower-subreg-1.c: Fix and simplify target selector.
[pf3gnuchains/gcc-fork.git] / gcc / calls.c
index 95369b7..19b2bfa 100644 (file)
@@ -1,7 +1,7 @@
 /* Convert function calls to rtl insns, for GNU C compiler.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   2011, 2012 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -445,6 +445,11 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
       if (SUPPORTS_STACK_ALIGNMENT)
         crtl->need_drap = true;
     }
+  /* For noreturn calls when not accumulating outgoing args force
+     REG_ARGS_SIZE note to prevent crossjumping of calls with different
+     args sizes.  */
+  else if (!ACCUMULATE_OUTGOING_ARGS && (ecf_flags & ECF_NORETURN) != 0)
+    add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
 
   if (!ACCUMULATE_OUTGOING_ARGS)
     {
@@ -711,7 +716,7 @@ flags_from_decl_or_type (const_tree exp)
        {
          if (is_tm_builtin (exp))
            flags |= ECF_TM_BUILTIN;
-         else if ((flags & ECF_CONST) != 0
+         else if ((flags & (ECF_CONST|ECF_NOVOPS)) != 0
                   || lookup_attribute ("transaction_pure",
                                        TYPE_ATTRIBUTES (TREE_TYPE (exp))))
            flags |= ECF_TM_PURE;
@@ -1157,7 +1162,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
                             type, argpos < n_named_args))
        {
          bool callee_copies;
-         tree base;
+         tree base = NULL_TREE;
 
          callee_copies
            = reference_callee_copied (args_so_far_pnt, TYPE_MODE (type),
@@ -1705,9 +1710,11 @@ internal_arg_pointer_based_exp_scan (void)
            val = internal_arg_pointer_based_exp (SET_SRC (set), false);
          if (val != NULL_RTX)
            {
-             VEC_safe_grow_cleared (rtx, heap,
-                                    internal_arg_pointer_exp_state.cache,
-                                    idx + 1);
+             if (idx
+                 >= VEC_length (rtx, internal_arg_pointer_exp_state.cache))
+               VEC_safe_grow_cleared (rtx, heap,
+                                      internal_arg_pointer_exp_state.cache,
+                                      idx + 1);
              VEC_replace (rtx, internal_arg_pointer_exp_state.cache,
                           idx, val);
            }
@@ -1801,6 +1808,11 @@ mem_overlaps_already_clobbered_arg_p (rtx addr, unsigned HOST_WIDE_INT size)
     return true;
   else
     i = INTVAL (val);
+#ifdef STACK_GROWS_DOWNWARD
+  i -= crtl->args.pretend_args_size;
+#else
+  i += crtl->args.pretend_args_size;
+#endif
 
 #ifdef ARGS_GROW_DOWNWARD
   i = -i - size;