/* If REG was promoted from the actual mode of the argument expression,
indicates whether the promotion is sign- or zero-extended. */
int unsignedp;
- /* Number of registers to use. 0 means put the whole arg in registers.
- Also 0 if not passed in registers. */
+ /* Number of bytes to put in registers. 0 means put the whole arg
+ in registers. Also 0 if not passed in registers. */
int partial;
/* Nonzero if argument must be passed on stack.
Note that some arguments may be passed on the stack
For example, if the function might return more than one time (setjmp), then
set RETURNS_TWICE to a nonzero value.
- Similarly set LONGJMP for if the function is in the longjmp family.
+ Similarly set NORETURN if the function is in the longjmp family.
Set MAY_BE_ALLOCA for any memory allocation function that might allocate
space from the stack such as alloca. */
return flags;
}
-/* Return nonzero when tree represent call to longjmp. */
+/* Return nonzero when FNDECL represents a call to setjmp. */
int
setjmp_call_p (tree fndecl)
int nregs;
int size = 0;
rtx before_arg = get_last_insn ();
- /* Set to non-negative if must move a word at a time, even if just
- one word (e.g, partial == 1 && mode == DFmode). Set to -1 if
- we just use a normal move insn. This value can be zero if the
- argument is a zero size structure with no fields. */
+ /* Set non-negative if we must move a word at a time, even if
+ just one word (e.g, partial == 4 && mode == DFmode). Set
+ to -1 if we just use a normal move insn. This value can be
+ zero if the argument is a zero size structure. */
nregs = -1;
if (GET_CODE (reg) == PARALLEL)
;
/* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */
- if (warn_aggregate_return && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
- warning ("function call has aggregate value");
+ if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ warning (OPT_Waggregate_return, "function call has aggregate value");
/* If the result of a pure or const function call is ignored (or void),
and none of its arguments are volatile, we can avoid expanding the
the argument areas are shared. */
|| (fndecl && decl_function_context (fndecl) == current_function_decl)
/* If this function requires more stack slots than the current
- function, we cannot change it into a sibling call. */
- || args_size.constant > current_function_args_size
+ function, we cannot change it into a sibling call.
+ current_function_pretend_args_size is not part of the
+ stack allocated by our caller. */
+ || args_size.constant > (current_function_args_size
+ - current_function_pretend_args_size)
/* If the callee pops its own arguments, then it must pop exactly
the same number of arguments as the current function. */
|| (RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
Also, do all pending adjustments now if there is any chance
this might be a call to alloca or if we are expanding a sibling
call sequence or if we are calling a function that is to return
- with stack pointer depressed. */
+ with stack pointer depressed.
+ Also do the adjustments before a throwing call, otherwise
+ exception handling can fail; PR 19225. */
if (pending_stack_adjust >= 32
|| (pending_stack_adjust > 0
&& (flags & (ECF_MAY_BE_ALLOCA | ECF_SP_DEPRESSED)))
+ || (pending_stack_adjust > 0
+ && flag_exceptions && !(flags & ECF_NOTHROW))
|| pass == 0)
do_pending_stack_adjust ();