diff options
author | 2006-07-20 21:05:18 +0000 | |
---|---|---|
committer | 2006-07-20 21:05:18 +0000 | |
commit | 302f939fd2ba276575e227b3149e98d702143b17 (patch) | |
tree | e536c6ea420d19d1f00b8b69836a9e2f4e151f20 | |
parent | Enable bus master; X probably needs it to do accelerated graphics. (diff) | |
download | wireguard-openbsd-302f939fd2ba276575e227b3149e98d702143b17.tar.xz wireguard-openbsd-302f939fd2ba276575e227b3149e98d702143b17.zip |
Introduce a new compiler warning, -Wstack-larger-than-N, to report
functions which are too greedy in stack variables.
This is intended to be used for kernel compiles, where this warning will
be enabled for a reasonable size (after a few weeks grace period so that
people can upgrade their compiler).
Please note that this warning relies upon md code, and as such is only
available on platforms OpenBSD runs on; also, the stack size being warned
on is only the local variables size, regardless of the ABI stack usage
requirements and the callee-saved registers; which means a function may
be warning-clean yet need more stack space than meets the eye; the
actual size being checked on may change to include these extras in the
future.
-rw-r--r-- | gnu/egcs/gcc/config/alpha/alpha.c | 3 | ||||
-rw-r--r-- | gnu/egcs/gcc/config/m68k/m68k.c | 2 | ||||
-rw-r--r-- | gnu/egcs/gcc/config/m88k/m88k.c | 3 | ||||
-rw-r--r-- | gnu/egcs/gcc/config/sparc/sparc.c | 4 | ||||
-rw-r--r-- | gnu/egcs/gcc/config/vax/vax.h | 9 | ||||
-rw-r--r-- | gnu/egcs/gcc/flags.h | 6 | ||||
-rw-r--r-- | gnu/egcs/gcc/toplev.c | 17 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/arm/arm.c | 9 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/i386/i386.c | 6 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/mips/mips.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/pa/pa.c | 3 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/rs6000/rs6000.c | 3 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/sparc/sparc.c | 4 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/flags.h | 6 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/toplev.c | 12 | ||||
-rw-r--r-- | share/man/man1/gcc-local.1 | 13 |
16 files changed, 98 insertions, 6 deletions
diff --git a/gnu/egcs/gcc/config/alpha/alpha.c b/gnu/egcs/gcc/config/alpha/alpha.c index 2d62693d76b..861d58d644f 100644 --- a/gnu/egcs/gcc/config/alpha/alpha.c +++ b/gnu/egcs/gcc/config/alpha/alpha.c @@ -3460,6 +3460,9 @@ alpha_expand_prologue () + ALPHA_ROUND (frame_size + current_function_pretend_args_size)); + if (warn_stack_larger_than && frame_size > stack_larger_than_size) + warning ("stack usage is %d bytes", frame_size); + if (TARGET_OPEN_VMS) reg_offset = 8; else diff --git a/gnu/egcs/gcc/config/m68k/m68k.c b/gnu/egcs/gcc/config/m68k/m68k.c index e751326c85b..72d305c073a 100644 --- a/gnu/egcs/gcc/config/m68k/m68k.c +++ b/gnu/egcs/gcc/config/m68k/m68k.c @@ -151,6 +151,8 @@ output_function_prologue (stream, size) int fsize = (size + 3) & -4; int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset; + if (warn_stack_larger_than && fsize > stack_larger_than_size) + warning ("stack usage is %d bytes", fsize); if (frame_pointer_needed) { diff --git a/gnu/egcs/gcc/config/m88k/m88k.c b/gnu/egcs/gcc/config/m88k/m88k.c index 6c46ff1d544..8c9eaed2678 100644 --- a/gnu/egcs/gcc/config/m88k/m88k.c +++ b/gnu/egcs/gcc/config/m88k/m88k.c @@ -1920,6 +1920,9 @@ m88k_expand_prologue () { m88k_layout_frame (); + if (warn_stack_larger_than && m88k_stack_size > stack_larger_than_size) + warning ("stack usage is %d bytes", m88k_stack_size); + if (m88k_stack_size) emit_add (stack_pointer_rtx, stack_pointer_rtx, -m88k_stack_size); diff --git a/gnu/egcs/gcc/config/sparc/sparc.c b/gnu/egcs/gcc/config/sparc/sparc.c index 9d8fade6c62..35800d7aee3 100644 --- a/gnu/egcs/gcc/config/sparc/sparc.c +++ b/gnu/egcs/gcc/config/sparc/sparc.c @@ -3116,6 +3116,10 @@ output_function_prologue (file, size, leaf_function) int size; int leaf_function; { + if (warn_stack_larger_than && + SPARC_STACK_ALIGN (size) > stack_larger_than_size) + warning ("stack usage is %d bytes", SPARC_STACK_ALIGN (size)); + /* Need to use actual_fsize, since we are also allocating space for our callee (and our own register save area). */ actual_fsize = compute_frame_size (size, leaf_function); diff --git a/gnu/egcs/gcc/config/vax/vax.h b/gnu/egcs/gcc/config/vax/vax.h index 89f6b8a639d..6492ea6d331 100644 --- a/gnu/egcs/gcc/config/vax/vax.h +++ b/gnu/egcs/gcc/config/vax/vax.h @@ -466,8 +466,13 @@ gen_rtx (PLUS, Pmode, frame, GEN_INT (12)) mask |= 1 << regno; \ fprintf (FILE, "\t.word 0x%x\n", mask); \ MAYBE_VMS_FUNCTION_PROLOGUE(FILE) \ - if ((size) >= 64) fprintf (FILE, "\tmovab %d(sp),sp\n", -size);\ - else if (size) fprintf (FILE, "\tsubl2 $%d,sp\n", (size)); } + if (warn_stack_larger_than && size > stack_larger_than_size) \ + warning ("stack usage is %d bytes", size); \ + if ((size) >= 64) \ + fprintf (FILE, "\tmovab %d(sp),sp\n", -size); \ + else if (size) \ + fprintf (FILE, "\tsubl2 $%d,sp\n", (size)); \ +} /* vms.h redefines this. */ #define MAYBE_VMS_FUNCTION_PROLOGUE(FILE) diff --git a/gnu/egcs/gcc/flags.h b/gnu/egcs/gcc/flags.h index bc1c5690f3d..a63a4e5ab14 100644 --- a/gnu/egcs/gcc/flags.h +++ b/gnu/egcs/gcc/flags.h @@ -132,6 +132,12 @@ extern unsigned id_clash_len; extern int warn_larger_than; extern unsigned larger_than_size; +/* Nonzero means warn about any function whose stack usage is larger + than N bytes. The value N is in `stack_larger_than_size'. */ + +extern int warn_stack_larger_than; +extern unsigned stack_larger_than_size; + /* Warn if a function returns an aggregate, since there are often incompatible calling conventions for doing this. */ diff --git a/gnu/egcs/gcc/toplev.c b/gnu/egcs/gcc/toplev.c index 7443a766999..f8f616fb300 100644 --- a/gnu/egcs/gcc/toplev.c +++ b/gnu/egcs/gcc/toplev.c @@ -1257,6 +1257,12 @@ unsigned id_clash_len; int warn_larger_than; unsigned larger_than_size; +/* Nonzero means warn about any function whose stack usage is larger + than N bytes. The value N is in `stack_larger_than_size'. */ + +int warn_stack_larger_than; +unsigned stack_larger_than_size; + /* Nonzero means warn if inline function is too large. */ int warn_inline; @@ -4576,6 +4582,7 @@ display_help () printf (" -Wid-clash-<num> Warn if 2 identifiers have the same first <num> chars\n"); printf (" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"); + printf (" -Wstack-larger-than-<number> Warn if a function stack usage is larger than <number> bytes\n"); printf (" -p Enable function profiling\n"); #if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) printf (" -a Enable block profiling \n"); @@ -5219,6 +5226,16 @@ main (argc, argv) warn_larger_than = 1; } } + else if (!strncmp (p, "stack-larger-than-", 18)) + { + const int stack_larger_than_val + = read_integral_parameter (p + 18, p - 2, -1); + if (stack_larger_than_val != -1) + { + stack_larger_than_size = stack_larger_than_val; + warn_stack_larger_than = 1; + } + } else error ("Invalid option `%s'", argv[i]); } diff --git a/gnu/usr.bin/gcc/gcc/config/arm/arm.c b/gnu/usr.bin/gcc/gcc/config/arm/arm.c index 9a70ab39fb1..21df8460846 100644 --- a/gnu/usr.bin/gcc/gcc/config/arm/arm.c +++ b/gnu/usr.bin/gcc/gcc/config/arm/arm.c @@ -8313,6 +8313,7 @@ arm_get_frame_size () void arm_expand_prologue () { + int size; int reg; rtx amount; rtx insn; @@ -8544,8 +8545,12 @@ arm_expand_prologue () } } - amount = GEN_INT (-(arm_get_frame_size () - + current_function_outgoing_args_size)); + size = arm_get_frame_size (); + + if (warn_stack_larger_than && size > stack_larger_than_size) + warning ("stack usage is %d bytes", size); + + amount = GEN_INT (-(size + current_function_outgoing_args_size)); if (amount != const0_rtx) { diff --git a/gnu/usr.bin/gcc/gcc/config/i386/i386.c b/gnu/usr.bin/gcc/gcc/config/i386/i386.c index 74e86a3c21d..b991ef7c543 100644 --- a/gnu/usr.bin/gcc/gcc/config/i386/i386.c +++ b/gnu/usr.bin/gcc/gcc/config/i386/i386.c @@ -647,6 +647,8 @@ struct ix86_frame HOST_WIDE_INT frame_pointer_offset; HOST_WIDE_INT hard_frame_pointer_offset; HOST_WIDE_INT stack_pointer_offset; + + HOST_WIDE_INT local_size; }; /* Used to enable/disable debugging features. */ @@ -4541,6 +4543,7 @@ ix86_compute_frame_layout (frame) int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT; HOST_WIDE_INT size = get_frame_size (); + frame->local_size = size; frame->nregs = ix86_nsaved_regs (); total_size = size; @@ -4704,6 +4707,9 @@ ix86_expand_prologue () } ix86_compute_frame_layout (&frame); + if (warn_stack_larger_than && frame.local_size > stack_larger_than_size) + warning ("stack usage is %d bytes", frame.local_size); + /* Note: AT&T enter does NOT have reversed args. Enter is probably slower on all targets. Also sdb doesn't like it. */ diff --git a/gnu/usr.bin/gcc/gcc/config/mips/mips.c b/gnu/usr.bin/gcc/gcc/config/mips/mips.c index 44024f2e813..3ea546f7e51 100644 --- a/gnu/usr.bin/gcc/gcc/config/mips/mips.c +++ b/gnu/usr.bin/gcc/gcc/config/mips/mips.c @@ -7501,6 +7501,10 @@ mips_expand_prologue () tsize = compute_frame_size (get_frame_size ()); + if (warn_stack_larger_than + && cfun->machine->frame.var_size > stack_larger_than_size) + warning ("stack usage is %d bytes", cfun->machine->frame.var_size); + /* If this function is a varargs function, store any registers that would normally hold arguments ($4 - $7) on the stack. */ if (store_args_on_stack diff --git a/gnu/usr.bin/gcc/gcc/config/pa/pa.c b/gnu/usr.bin/gcc/gcc/config/pa/pa.c index 63b014cf178..90e4eb37a9d 100644 --- a/gnu/usr.bin/gcc/gcc/config/pa/pa.c +++ b/gnu/usr.bin/gcc/gcc/config/pa/pa.c @@ -3252,6 +3252,9 @@ hppa_expand_prologue () fr_saved = 0; save_fregs = 0; + if (warn_stack_larger_than && size > stack_larger_than_size) + warning ("stack usage is %d bytes", size); + /* Allocate space for frame pointer + filler. If any frame is allocated we need to add this in because of STARTING_FRAME_OFFSET. diff --git a/gnu/usr.bin/gcc/gcc/config/rs6000/rs6000.c b/gnu/usr.bin/gcc/gcc/config/rs6000/rs6000.c index 3931373736b..0ba733942fa 100644 --- a/gnu/usr.bin/gcc/gcc/config/rs6000/rs6000.c +++ b/gnu/usr.bin/gcc/gcc/config/rs6000/rs6000.c @@ -10279,6 +10279,9 @@ rs6000_emit_prologue () int saving_FPRs_inline; int using_store_multiple; HOST_WIDE_INT sp_offset = 0; + + if (warn_stack_larger_than && info->vars_size > stack_larger_than_size) + warning ("stack usage is %d bytes", info->vars_size); if (TARGET_SPE_ABI) { diff --git a/gnu/usr.bin/gcc/gcc/config/sparc/sparc.c b/gnu/usr.bin/gcc/gcc/config/sparc/sparc.c index d8cd82b6ded..eafc24a3c0e 100644 --- a/gnu/usr.bin/gcc/gcc/config/sparc/sparc.c +++ b/gnu/usr.bin/gcc/gcc/config/sparc/sparc.c @@ -3873,6 +3873,10 @@ sparc_output_function_prologue (file, size) FILE *file; HOST_WIDE_INT size; { + if (warn_stack_larger_than && + SPARC_STACK_ALIGN (size) > stack_larger_than_size) + warning ("stack usage is %d bytes", SPARC_STACK_ALIGN (size)); + if (TARGET_FLAT) sparc_flat_function_prologue (file, size); else diff --git a/gnu/usr.bin/gcc/gcc/flags.h b/gnu/usr.bin/gcc/gcc/flags.h index 7aa7c73b4ef..1a61fc6d1ce 100644 --- a/gnu/usr.bin/gcc/gcc/flags.h +++ b/gnu/usr.bin/gcc/gcc/flags.h @@ -162,6 +162,12 @@ extern int warn_cast_align; extern int warn_larger_than; extern HOST_WIDE_INT larger_than_size; +/* Nonzero means warn about any function whose stack usage is larger + than N bytes. The value N is in `stack_larger_than_size'. */ + +extern int warn_stack_larger_than; +extern HOST_WIDE_INT stack_larger_than_size; + /* Warn if a function returns an aggregate, since there are often incompatible calling conventions for doing this. */ diff --git a/gnu/usr.bin/gcc/gcc/toplev.c b/gnu/usr.bin/gcc/gcc/toplev.c index 8148dbc215f..8105a718d9f 100644 --- a/gnu/usr.bin/gcc/gcc/toplev.c +++ b/gnu/usr.bin/gcc/gcc/toplev.c @@ -1494,6 +1494,12 @@ int warn_cast_align; int warn_larger_than; HOST_WIDE_INT larger_than_size; +/* Nonzero means warn about any function whose stack usage is larger + than N bytes. The value N is in `stack_larger_than_size'. */ + +int warn_stack_larger_than; +HOST_WIDE_INT stack_larger_than_size; + /* Nonzero means warn if inline function is too large. */ int warn_inline; @@ -4158,6 +4164,12 @@ decode_W_option (arg) warn_larger_than = larger_than_size != -1; } + else if ((option_value = skip_leading_substring (arg, "stack-larger-than-"))) + { + stack_larger_than_size = read_integral_parameter (option_value, arg - 2, -1); + + warn_stack_larger_than = stack_larger_than_size != -1; + } else if (!strcmp (arg, "unused")) { set_Wunused (1); diff --git a/share/man/man1/gcc-local.1 b/share/man/man1/gcc-local.1 index fc09a4c67da..09e024aefee 100644 --- a/share/man/man1/gcc-local.1 +++ b/share/man/man1/gcc-local.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: gcc-local.1,v 1.12 2006/04/11 10:36:23 espie Exp $ +.\" $OpenBSD: gcc-local.1,v 1.13 2006/07/20 21:05:22 miod Exp $ .\" .\" Copyright (c) 2002 Marc Espie .\" Copyright (c) 2003 Anil Madhavapeddy @@ -25,7 +25,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 3, 2005 +.Dd July 16, 2006 .Dt GCC-LOCAL 1 .Os .Sh NAME @@ -225,6 +225,15 @@ that lets comments in macros pass through to the output (except in mode). This is used to allow annotations in macros for .Xr lint 1 . +.It +A new warning, +.Fl Wstack-larger-than-N , +will report functions using more than +.Va N +bytes of stack space for their local variables. +Stack space used for other purposes (such as register window saving, +callee-saved registers, outbound arguments storage, etc) +is not taken in account for this check. .El .Sh ATTRIBUTES The |