===================================================================
@@ -260,7 +260,7 @@ Objective-C and Objective-C++ Dialects}.
-Wredundant-decls @gol
-Wreturn-type -Wsequence-point -Wshadow @gol
-Wsign-compare -Wsign-conversion -Wstack-protector @gol
--Wstrict-aliasing -Wstrict-aliasing=n @gol
+-Wstack-usage=@var{len} -Wstrict-aliasing -Wstrict-aliasing=n @gol
-Wstrict-overflow -Wstrict-overflow=@var{n} @gol
-Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{]} @gol
-Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol
@@ -3922,6 +3922,14 @@ via @code{alloca}, variable-length array
is not included by the compiler when determining
whether or not to issue a warning.
+@item -Wstack-usage=@var{len}
+@opindex Wstack-usage
+Warn if the stack usage of a function might be larger than @var{len} bytes.
+The computation done to determine the stack usage is conservative.
+Any space allocated via @code{alloca}, variable-length arrays, or related
+constructs is included by the compiler when determining whether or not to
+issue a warning.
+
@item -Wunsafe-loop-optimizations
@opindex Wunsafe-loop-optimizations
@opindex Wno-unsafe-loop-optimizations
===================================================================
@@ -1048,14 +1048,12 @@ output_stack_usage (void)
};
HOST_WIDE_INT stack_usage = current_function_static_stack_size;
enum stack_usage_kind_type stack_usage_kind;
- expanded_location loc;
- const char *raw_id, *id;
if (stack_usage < 0)
{
if (!warning_issued)
{
- warning (0, "-fstack-usage not supported for this target");
+ warning (0, "stack usage computation not supported for this target");
warning_issued = true;
}
return;
@@ -1082,24 +1080,44 @@ output_stack_usage (void)
stack_usage += current_function_dynamic_stack_size;
}
- loc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
+ if (flag_stack_usage)
+ {
+ expanded_location loc
+ = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
+ const char *raw_id, *id;
+
+ /* Strip the scope prefix if any. */
+ raw_id = lang_hooks.decl_printable_name (current_function_decl, 2);
+ id = strrchr (raw_id, '.');
+ if (id)
+ id++;
+ else
+ id = raw_id;
+
+ fprintf (stack_usage_file,
+ "%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n",
+ lbasename (loc.file),
+ loc.line,
+ loc.column,
+ id,
+ stack_usage,
+ stack_usage_kind_str[stack_usage_kind]);
+ }
- /* Strip the scope prefix if any. */
- raw_id = lang_hooks.decl_printable_name (current_function_decl, 2);
- id = strrchr (raw_id, '.');
- if (id)
- id++;
- else
- id = raw_id;
-
- fprintf (stack_usage_file,
- "%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n",
- lbasename (loc.file),
- loc.line,
- loc.column,
- id,
- stack_usage,
- stack_usage_kind_str[stack_usage_kind]);
+ if (warn_stack_usage >= 0)
+ {
+ if (stack_usage_kind == DYNAMIC)
+ warning (OPT_Wstack_usage_, "stack usage might be unbounded");
+ else if (stack_usage > warn_stack_usage)
+ {
+ if (stack_usage_kind == DYNAMIC_BOUNDED)
+ warning (OPT_Wstack_usage_, "stack usage might be %wd bytes",
+ stack_usage);
+ else
+ warning (OPT_Wstack_usage_, "stack usage is %wd bytes",
+ stack_usage);
+ }
+ }
}
/* Open an auxiliary output file. */
===================================================================
@@ -1410,6 +1410,11 @@ common_handle_option (struct gcc_options
opts->x_warn_frame_larger_than = value != -1;
break;
+ case OPT_Wstack_usage_:
+ opts->x_warn_stack_usage = value;
+ opts->x_flag_stack_usage_info = value != -1;
+ break;
+
case OPT_Wstrict_aliasing:
set_Wstrict_aliasing (opts, value);
break;
@@ -1631,6 +1636,11 @@ common_handle_option (struct gcc_options
/* Deferred. */
break;
+ case OPT_fstack_usage:
+ opts->x_flag_stack_usage = value;
+ opts->x_flag_stack_usage_info = value != 0;
+ break;
+
case OPT_ftree_vectorizer_verbose_:
vect_set_verbosity_level (opts, value);
break;
===================================================================
@@ -1940,7 +1940,7 @@ instantiate_virtual_regs (void)
/* See allocate_dynamic_stack_space for the rationale. */
#ifdef SETJMP_VIA_SAVE_AREA
- if (flag_stack_usage && cfun->calls_setjmp)
+ if (flag_stack_usage_info && cfun->calls_setjmp)
{
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
dynamic_offset = (dynamic_offset + align - 1) / align * align;
@@ -4437,7 +4437,7 @@ prepare_function_start (void)
init_expr ();
default_rtl_profile ();
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
{
cfun->su = ggc_alloc_cleared_stack_usage ();
cfun->su->static_stack_size = -1;
@@ -5881,7 +5881,7 @@ rest_of_handle_thread_prologue_and_epilo
thread_prologue_and_epilogue_insns ();
/* The stack usage info is finalized during prologue expansion. */
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
output_stack_usage ();
return 0;
===================================================================
@@ -2505,7 +2505,7 @@ expand_call (tree exp, rtx target, int i
stack_arg_under_construction = 0;
}
argblock = push_block (ARGS_SIZE_RTX (adjusted_args_size), 0, 0);
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_has_unbounded_dynamic_stack_size = 1;
}
else
@@ -2714,7 +2714,7 @@ expand_call (tree exp, rtx target, int i
/* Record the maximum pushed stack space size. We need to delay
doing it this far to take into account the optimization done
by combine_pending_stack_adjustment_and_call. */
- if (flag_stack_usage
+ if (flag_stack_usage_info
&& !ACCUMULATE_OUTGOING_ARGS
&& pass
&& adjusted_args_size.var == 0)
@@ -3579,7 +3579,7 @@ emit_library_call_value_1 (int retval, r
if (args_size.constant > crtl->outgoing_args_size)
crtl->outgoing_args_size = args_size.constant;
- if (flag_stack_usage && !ACCUMULATE_OUTGOING_ARGS)
+ if (flag_stack_usage_info && !ACCUMULATE_OUTGOING_ARGS)
{
int pushed = args_size.constant + pending_stack_adjust;
if (pushed > current_function_pushed_stack_size)
===================================================================
@@ -1128,7 +1128,7 @@ allocate_dynamic_stack_space (rtx size,
/* If stack usage info is requested, look into the size we are passed.
We need to do so this early to avoid the obfuscation that may be
introduced later by the various alignment operations. */
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
{
if (CONST_INT_P (size))
stack_usage_size = INTVAL (size);
@@ -1220,7 +1220,7 @@ allocate_dynamic_stack_space (rtx size,
size = plus_constant (size, extra);
size = force_operand (size, NULL_RTX);
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
stack_usage_size += extra;
if (extra && size_align > extra_align)
@@ -1251,7 +1251,7 @@ allocate_dynamic_stack_space (rtx size,
/* The above dynamic offset cannot be computed statically at this
point, but it will be possible to do so after RTL expansion is
done. Record how many times we will need to add it. */
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_dynamic_alloc_count++;
/* ??? Can we infer a minimum of STACK_BOUNDARY here? */
@@ -1276,7 +1276,7 @@ allocate_dynamic_stack_space (rtx size,
{
size = round_push (size);
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
{
int align = crtl->preferred_stack_boundary / BITS_PER_UNIT;
stack_usage_size = (stack_usage_size + align - 1) / align * align;
@@ -1287,7 +1287,7 @@ allocate_dynamic_stack_space (rtx size,
/* The size is supposed to be fully adjusted at this point so record it
if stack usage info is requested. */
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
{
current_function_dynamic_stack_size += stack_usage_size;
===================================================================
@@ -138,6 +138,10 @@ enum vect_verbosity_levels user_vect_ver
Variable
enum stack_check_type flag_stack_check = NO_STACK_CHECK
+; True if stack usage information needs to be computed.
+Variable
+bool flag_stack_usage_info = false
+
; -dA causes debug commentary information to be produced in
; the generated assembly code (to make it more readable). This option
; is generally only of use to those who actually need to read the
@@ -566,6 +570,10 @@ Wstack-protector
Common Var(warn_stack_protect) Warning
Warn when not issuing stack smashing protection for some reason
+Wstack-usage=
+Common Joined RejectNegative UInteger Var(warn_stack_usage) Init(-1) Warning
+Warn if stack usage might be larger than specified amount
+
Wstrict-aliasing
Common Warning
Warn about code which might break strict aliasing rules
===================================================================
@@ -7531,7 +7531,7 @@ alpha_expand_prologue (void)
sa_size = alpha_sa_size ();
frame_size = compute_frame_size (get_frame_size (), sa_size);
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = frame_size;
if (TARGET_ABI_OPEN_VMS)
===================================================================
@@ -8097,7 +8097,7 @@ s390_emit_prologue (void)
if (!TARGET_PACKED_STACK)
next_fpr = cfun_save_high_fprs_p ? 31 : 0;
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = cfun_frame_layout.frame_size;
/* Decrement stack pointer. */
===================================================================
@@ -2093,7 +2093,7 @@ spu_expand_prologue (void)
}
}
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = total_size;
}
===================================================================
@@ -4562,7 +4562,7 @@ sparc_expand_prologue (void)
/* Advertise that the data calculated just above are now valid. */
sparc_prologue_data_valid_p = true;
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = actual_fsize;
if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && actual_fsize)
===================================================================
@@ -10540,7 +10540,7 @@ ix86_expand_prologue (void)
allocate = frame.stack_pointer_offset - m->fs.sp_offset;
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
{
/* We start to count from ARG_POINTER. */
HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
===================================================================
@@ -7345,7 +7345,7 @@ sh_expand_prologue (void)
emit_insn (gen_shcompact_incoming_args ());
}
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = stack_usage;
}
===================================================================
@@ -869,7 +869,7 @@ expand_prologue (void)
}
}
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = cfun->machine->stack_usage;
}
===================================================================
@@ -3184,7 +3184,7 @@ ia64_expand_prologue (void)
ia64_compute_frame_size (get_frame_size ());
last_scratch_gr_reg = 15;
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = current_frame_info.total_size;
if (dump_file)
===================================================================
@@ -20451,7 +20451,7 @@ rs6000_emit_prologue (void)
&& call_used_regs[STATIC_CHAIN_REGNUM]);
HOST_WIDE_INT sp_offset = 0;
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = info->total_size;
if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
===================================================================
@@ -15972,7 +15972,7 @@ arm_expand_prologue (void)
}
}
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size
= offsets->outgoing_args - offsets->saved_args;
@@ -20788,7 +20788,7 @@ thumb1_expand_prologue (void)
emit_move_insn (gen_rtx_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM),
stack_pointer_rtx);
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size
= offsets->outgoing_args - offsets->saved_args;
===================================================================
@@ -3845,7 +3845,7 @@ hppa_expand_prologue (void)
local_fsize += STARTING_FRAME_OFFSET;
actual_fsize = compute_frame_size (size, &save_fregs);
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = actual_fsize;
/* Compute a few things we will use often. */
===================================================================
@@ -10080,7 +10080,7 @@ mips_expand_prologue (void)
frame = &cfun->machine->frame;
size = frame->total_size;
- if (flag_stack_usage)
+ if (flag_stack_usage_info)
current_function_static_stack_size = size;
/* Save the registers. Allocate up to MIPS_MAX_FIRST_STACK_STEP