PR middle-end/82063 - issues with arguments enabled by -Wall

gcc/ada/ChangeLog:

	PR middle-end/82063
	* gcc-interface/misc.c (gnat_handle_option): Change function argument
	to HOST_WIDE_INT.

gcc/brig/ChangeLog:

	PR middle-end/82063
	* brig/brig-lang.c (brig_langhook_handle_option): Change function
	argument to HOST_WIDE_INT.

gcc/c-family/ChangeLog:

	PR middle-end/82063
	* c-common.h (c_common_handle_option): Change function argument
	to HOST_WIDE_INT.
	* c-opts.c (c_common_init_options): Same.
	(c_common_handle_option): Same.  Remove special handling of
	OPT_Walloca_larger_than_ and OPT_Wvla_larger_than_.
	* c.opt (-Walloc-size-larger-than, -Walloca-larger-than): Change
	options to take a HOST_WIDE_INT argument and accept a byte-size
	suffix.  Initialize.
	(-Wvla-larger-than): Same.
	(-Wno-alloc-size-larger-than, -Wno-alloca-larger-than): New.
	(-Wno-vla-larger-than): Same.

gcc/fortran/ChangeLog:

	PR middle-end/82063
	* gfortran.h (gfc_handle_option): Change function argument
	to HOST_WIDE_INT.
	* options.c (gfc_handle_option): Same.

gcc/go/ChangeLog:

	PR middle-end/82063
	* go-lang.c (go_langhook_handle_option): Change function argument
	to HOST_WIDE_INT.

gcc/lto/ChangeLog:

	PR middle-end/82063
	* lto-lang.c (lto_handle_option): Change function argument
	to HOST_WIDE_INT.

gcc/testsuite/ChangeLog:

	PR middle-end/82063
	* gcc/testsuite/c-c++-common/pr68657-1.c: Adjust.
	* gcc/testsuite/c-c++-common/pr68657-2.c: Same.
	* gcc/testsuite/c-c++-common/pr68657-3.c: Same.
	* gcc.dg/Walloc-size-larger-than-16.c: Same.
	* gcc.dg/Walloca-larger-than.c: New test.
	* gcc.dg/Walloca-larger-than-2.c: New test.
	* gcc.dg/Wframe-larger-than-2.c: New test.
	* gcc.dg/Wlarger-than3.c: New test.
	* gcc.dg/Wvla-larger-than-3.c: New test.
	* gcc.dg/pr42611.c: Adjust.
	* gnat.dg/frame_overflow.adb: Same.

gcc/ChangeLog:

	PR middle-end/82063
	* builtins.c (expand_builtin_alloca): Adjust.
	* calls.c (alloc_max_size): Simplify.
	* cgraphunit.c (cgraph_node::expand): Adjust.
	* common.opt (larger_than_size, warn_frame_larger_than): Remove
	variables.
	(frame_larger_than_size): Same.
	(-Wframe-larger-than, -Wlarger-than, -Wstack-usage): Change options
	to take a HOST_WIDE_INT argument and accept a byte-size suffix.
	Initialize.
	* doc/invoke.texi (GCC Command Options): Document option arguments.
	Explain byte-size arguments and suffixes.
	(-Wvla-larger-than, -Wno-alloc-size-larger-than): Update.
	(-Wno-alloca-larger-than, -Wno-vla-larger-than): Same.
	(-Wframe-larger-than, -Wlarger-than, -Wstack-usage): Same.
	* doc/options.texi (UInteger): Expand.
	(Host_Wide_Int, ByteSize): Document new properties.
	* final.c (final_start_function_1): Include sizes in an error message.
	* function.c (frame_offset_overflow): Same.
	* gimple-ssa-warn-alloca.c (pass_walloca::gate): Adjust.
	(alloca_call_type_by_arg): Change function argument to HOST_WIDE_INT.
	Diagnose unbounded alloca calls only for limits of less than
	PTRDIFF_MAX.
	(alloca_call_type): Adjust.  Diagnose possibly out-of-bounds alloca
	calls and VLA size only for limits of less than	PTRDIFF_MAX.  Same
	for alloca(0).
	(pass_walloca::execute): Adjust.  Diagnose alloca calls in loops
	only for limits of less than PTRDIFF_MAX.
	* langhooks-def.h (lhd_handle_option): Change function argument
	to HOST_WIDE_INT.
	* langhooks.c (lhd_handle_option): Same.
	* langhooks.h (handle_option): Same.
	* opt-functions.awk (switch_bit_fields): Handle Host_Wide_Int and
	ByteSize flags.
	(var_type, var_type_struct): Same.
	(var_set): Handle ByteSize flag.
	* optc-gen.awk: Add comments to output to ease debugging.  Make
	use of HOST_WIDE_INT where appropriate.
	* opts-gen-save.awk:  Use %lx to format unsigned long.
	* opth-gen.awk: Change function argument to HOST_WIDE_INT.
	* opts-common.c (integral_argument): Return HOST_WIDE_INT and add
	arguments.  Parse bytes-size suffixes.
	(enum_arg_to_value): Change function argument to HOST_WIDE_INT.
	(enum_value_to_arg): Same.
	(decode_cmdline_option): Handle cl_host_wide_int.  Adjust.
	(handle_option): Adjust.
	(generate_option): Change function argument to HOST_WIDE_INT.
	(cmdline_handle_error): Adjust.
	(read_cmdline_option): Change function argument to HOST_WIDE_INT.
	(set_option): Change function argument to HOST_WIDE_INT.
	(option_enabled): Handle cl_host_wide_int.
	(get_option_state): Handle CLVC_SIZE.
	(control_warning_option): Same.
	* opts.c (common_handle_option): Change function argument to
	HOST_WIDE_INT.  Remove handling of OPT_Walloca_larger_than_ and
	OPT_Wvla_larger_than_.
	* opts.h (enum cl_var_type): Add an enumerator.
	* stor-layout.c (layout_decl): Print a more meaningful warning.
	* toplev.c (output_stack_usage): Adjust.

From-SVN: r262910
This commit is contained in:
Martin Sebor 2018-07-20 20:51:20 +00:00 committed by Martin Sebor
parent 20e8ceae67
commit 00abf86c47
48 changed files with 863 additions and 378 deletions

View file

@ -1,3 +1,65 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* builtins.c (expand_builtin_alloca): Adjust.
* calls.c (alloc_max_size): Simplify.
* cgraphunit.c (cgraph_node::expand): Adjust.
* common.opt (larger_than_size, warn_frame_larger_than): Remove
variables.
(frame_larger_than_size): Same.
(-Wframe-larger-than, -Wlarger-than, -Wstack-usage): Change options
to take a HOST_WIDE_INT argument and accept a byte-size suffix.
Initialize.
* doc/invoke.texi (GCC Command Options): Document option arguments.
Explain byte-size arguments and suffixes.
(-Wvla-larger-than, -Wno-alloc-size-larger-than): Update.
(-Wno-alloca-larger-than, -Wno-vla-larger-than): Same.
(-Wframe-larger-than, -Wlarger-than, -Wstack-usage): Same.
* doc/options.texi (UInteger): Expand.
(Host_Wide_Int, ByteSize): Document new properties.
* final.c (final_start_function_1): Include sizes in an error message.
* function.c (frame_offset_overflow): Same.
* gimple-ssa-warn-alloca.c (pass_walloca::gate): Adjust.
(alloca_call_type_by_arg): Change function argument to HOST_WIDE_INT.
Diagnose unbounded alloca calls only for limits of less than
PTRDIFF_MAX.
(alloca_call_type): Adjust. Diagnose possibly out-of-bounds alloca
calls and VLA size only for limits of less than PTRDIFF_MAX. Same
for alloca(0).
(pass_walloca::execute): Adjust. Diagnose alloca calls in loops
only for limits of less than PTRDIFF_MAX.
* langhooks-def.h (lhd_handle_option): Change function argument
to HOST_WIDE_INT.
* langhooks.c (lhd_handle_option): Same.
* langhooks.h (handle_option): Same.
* opt-functions.awk (switch_bit_fields): Handle Host_Wide_Int and
ByteSize flags.
(var_type, var_type_struct): Same.
(var_set): Handle ByteSize flag.
* optc-gen.awk: Add comments to output to ease debugging. Make
use of HOST_WIDE_INT where appropriate.
* opts-gen-save.awk: Use %lx to format unsigned long.
* opth-gen.awk: Change function argument to HOST_WIDE_INT.
* opts-common.c (integral_argument): Return HOST_WIDE_INT and add
arguments. Parse bytes-size suffixes.
(enum_arg_to_value): Change function argument to HOST_WIDE_INT.
(enum_value_to_arg): Same.
(decode_cmdline_option): Handle cl_host_wide_int. Adjust.
(handle_option): Adjust.
(generate_option): Change function argument to HOST_WIDE_INT.
(cmdline_handle_error): Adjust.
(read_cmdline_option): Change function argument to HOST_WIDE_INT.
(set_option): Change function argument to HOST_WIDE_INT.
(option_enabled): Handle cl_host_wide_int.
(get_option_state): Handle CLVC_SIZE.
(control_warning_option): Same.
* opts.c (common_handle_option): Change function argument to
HOST_WIDE_INT. Remove handling of OPT_Walloca_larger_than_ and
OPT_Wvla_larger_than_.
* opts.h (enum cl_var_type): Add an enumerator.
* stor-layout.c (layout_decl): Print a more meaningful warning.
* toplev.c (output_stack_usage): Adjust.
2018-07-20 Qing Zhao <qing.zhao@oracle.com> 2018-07-20 Qing Zhao <qing.zhao@oracle.com>
* builtins.c (expand_builtin_memcmp): Delete the last parameter for * builtins.c (expand_builtin_memcmp): Delete the last parameter for

View file

@ -1,3 +1,9 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* gcc-interface/misc.c (gnat_handle_option): Change function argument
to HOST_WIDE_INT.
2018-07-17 Eric Botcazou <ebotcazou@adacore.com> 2018-07-17 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (choices_to_gnu): Rename parameters. Deal with * gcc-interface/decl.c (choices_to_gnu): Rename parameters. Deal with

View file

@ -138,8 +138,9 @@ gnat_option_lang_mask (void)
are marked as Ada-specific. Return true on success or false on failure. */ are marked as Ada-specific. Return true on success or false on failure. */
static bool static bool
gnat_handle_option (size_t scode, const char *arg, int value, int kind, gnat_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
location_t loc, const struct cl_option_handlers *handlers) int kind, location_t loc,
const struct cl_option_handlers *handlers)
{ {
enum opt_code code = (enum opt_code) scode; enum opt_code code = (enum opt_code) scode;

View file

@ -1,3 +1,9 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* brig/brig-lang.c (brig_langhook_handle_option): Change function
argument to HOST_WIDE_INT.
2018-07-04 Martin Jambor <mjambor@suse.cz> 2018-07-04 Martin Jambor <mjambor@suse.cz>
PR hsa/86371 PR hsa/86371

View file

@ -145,7 +145,7 @@ brig_langhook_init_options_struct (struct gcc_options *opts)
static bool static bool
brig_langhook_handle_option brig_langhook_handle_option
(size_t scode, const char *arg ATTRIBUTE_UNUSED, (size_t scode, const char *arg ATTRIBUTE_UNUSED,
int value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED, HOST_WIDE_INT value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
location_t loc ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{ {

View file

@ -5093,13 +5093,20 @@ expand_builtin_alloca (tree exp)
if (!valid_arglist) if (!valid_arglist)
return NULL_RTX; return NULL_RTX;
if ((alloca_for_var && !warn_vla_limit) if ((alloca_for_var
|| (!alloca_for_var && !warn_alloca_limit)) && warn_vla_limit >= HOST_WIDE_INT_MAX
&& warn_alloc_size_limit < warn_vla_limit)
|| (!alloca_for_var
&& warn_alloca_limit >= HOST_WIDE_INT_MAX
&& warn_alloc_size_limit < warn_alloca_limit
))
{ {
/* -Walloca-larger-than and -Wvla-larger-than settings override /* -Walloca-larger-than and -Wvla-larger-than settings of
the more general -Walloc-size-larger-than so unless either of less than HOST_WIDE_INT_MAX override the more general
the former options is specified check the alloca arguments for -Walloc-size-larger-than so unless either of the former
overflow. */ options is smaller than the last one (wchich would imply
that the call was already checked), check the alloca
arguments for overflow. */
tree args[] = { CALL_EXPR_ARG (exp, 0), NULL_TREE }; tree args[] = { CALL_EXPR_ARG (exp, 0), NULL_TREE };
int idx[] = { 0, -1 }; int idx[] = { 0, -1 };
maybe_warn_alloc_args_overflow (fndecl, exp, args, idx); maybe_warn_alloc_args_overflow (fndecl, exp, args, idx);

View file

@ -1,3 +1,18 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* c-common.h (c_common_handle_option): Change function argument
to HOST_WIDE_INT.
* c-opts.c (c_common_init_options): Same.
(c_common_handle_option): Same. Remove special handling of
OPT_Walloca_larger_than_ and OPT_Wvla_larger_than_.
* c.opt (-Walloc-size-larger-than, -Walloca-larger-than): Change
options to take a HOST_WIDE_INT argument and accept a byte-size
suffix. Initialize.
(-Wvla-larger-than): Same.
(-Wno-alloc-size-larger-than, -Wno-alloca-larger-than): New.
(-Wno-vla-larger-than): Same.
2018-07-12 Jakub Jelinek <jakub@redhat.com> 2018-07-12 Jakub Jelinek <jakub@redhat.com>
* c-attribs.c (c_common_attribute_table): Add * c-attribs.c (c_common_attribute_table): Add

View file

@ -808,7 +808,8 @@ extern void check_function_format (tree, int, tree *, vec<location_t> *);
extern bool attribute_fallthrough_p (tree); extern bool attribute_fallthrough_p (tree);
extern tree handle_format_attribute (tree *, tree, tree, int, bool *); extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
extern bool c_common_handle_option (size_t, const char *, int, int, location_t, extern bool c_common_handle_option (size_t, const char *, HOST_WIDE_INT, int,
location_t,
const struct cl_option_handlers *); const struct cl_option_handlers *);
extern bool default_handle_c_option (size_t, const char *, int); extern bool default_handle_c_option (size_t, const char *, int);
extern tree c_common_type_for_mode (machine_mode, int); extern tree c_common_type_for_mode (machine_mode, int);

View file

@ -262,7 +262,7 @@ c_common_init_options (unsigned int decoded_options_count,
form of an -f or -W option was given. Returns false if the switch was form of an -f or -W option was given. Returns false if the switch was
invalid, true if valid. Use HANDLERS in recursive handle_option calls. */ invalid, true if valid. Use HANDLERS in recursive handle_option calls. */
bool bool
c_common_handle_option (size_t scode, const char *arg, int value, c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
int kind, location_t loc, int kind, location_t loc,
const struct cl_option_handlers *handlers) const struct cl_option_handlers *handlers)
{ {
@ -381,16 +381,6 @@ c_common_handle_option (size_t scode, const char *arg, int value,
cpp_opts->warn_num_sign_change = value; cpp_opts->warn_num_sign_change = value;
break; break;
case OPT_Walloca_larger_than_:
if (!value)
inform (loc, "-Walloca-larger-than=0 is meaningless");
break;
case OPT_Wvla_larger_than_:
if (!value)
inform (loc, "-Wvla-larger-than=0 is meaningless");
break;
case OPT_Wunknown_pragmas: case OPT_Wunknown_pragmas:
/* Set to greater than 1, so that even unknown pragmas in /* Set to greater than 1, so that even unknown pragmas in
system headers will be warned about. */ system headers will be warned about. */

View file

@ -304,12 +304,12 @@ C ObjC C++ ObjC++ Var(warn_alloca) Warning
Warn on any use of alloca. Warn on any use of alloca.
Walloc-size-larger-than= Walloc-size-larger-than=
C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Warning Joined LangEnabledBy(C ObjC C++ LTO ObjC++,Wall) C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Joined Host_Wide_Int ByteSize Warning Init(HOST_WIDE_INT_MAX)
-Walloc-size-larger-than=<bytes> Warn for calls to allocation functions that -Walloc-size-larger-than=<bytes> Warn for calls to allocation functions that
attempt to allocate objects larger than the specified number of bytes. attempt to allocate objects larger than the specified number of bytes.
Wno-alloc-size-larger-than Wno-alloc-size-larger-than
C ObjC C++ LTO ObjC++ Alias(Walloc-size-larger-than=, 18446744073709551615EiB,none) Warning C ObjC C++ LTO ObjC++ Alias(Walloc-size-larger-than=,18446744073709551615EiB,none) Warning
-Wno-alloc-size-larger-than Disable Walloc-size-larger-than= warning. Equivalent to Walloc-size-larger-than=<SIZE_MAX> or larger. -Wno-alloc-size-larger-than Disable Walloc-size-larger-than= warning. Equivalent to Walloc-size-larger-than=<SIZE_MAX> or larger.
Walloc-zero Walloc-zero
@ -317,11 +317,15 @@ C ObjC C++ ObjC++ Var(warn_alloc_zero) Warning
-Walloc-zero Warn for calls to allocation functions that specify zero bytes. -Walloc-zero Warn for calls to allocation functions that specify zero bytes.
Walloca-larger-than= Walloca-larger-than=
C ObjC C++ LTO ObjC++ Var(warn_alloca_limit) Warning Joined RejectNegative UInteger C ObjC C++ LTO ObjC++ Var(warn_alloca_limit) Warning Joined Host_Wide_Int ByteSize Init(HOST_WIDE_INT_MAX)
-Walloca-larger-than=<number> Warn on unbounded uses of -Walloca-larger-than=<number> Warn on unbounded uses of
alloca, and on bounded uses of alloca whose bound can be larger than alloca, and on bounded uses of alloca whose bound can be larger than
<number> bytes. <number> bytes.
Wno-alloca-larger-than
C ObjC C++ LTO ObjC++ Alias(Walloca-larger-than=,18446744073709551615EiB,none) Warning
-Wno-alloca-larger-than Disable Walloca-larger-than= warning. Equivalent to Walloca-larger-than=<SIZE_MAX> or larger.
Warray-bounds Warray-bounds
LangEnabledBy(C ObjC C++ LTO ObjC++,Wall) LangEnabledBy(C ObjC C++ LTO ObjC++,Wall)
; in common.opt ; in common.opt
@ -1158,10 +1162,15 @@ C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning
Warn if a variable length array is used. Warn if a variable length array is used.
Wvla-larger-than= Wvla-larger-than=
C ObjC C++ ObjC++ Var(warn_vla_limit) Warning Joined RejectNegative UInteger C ObjC C++ LTO ObjC++ Var(warn_vla_limit) Warning Joined Host_Wide_Int ByteSize Init(HOST_WIDE_INT_MAX)
-Wvla-larger-than=<number> Warn on unbounded uses of variable-length arrays, and -Wvla-larger-than=<number> Warn on unbounded uses of variable-length
on bounded uses of variable-length arrays whose bound can be arrays, and on bounded uses of variable-length arrays whose bound can be
larger than <number> bytes. larger than <number> bytes.
<number> bytes.
Wno-vla-larger-than
C ObjC C++ LTO ObjC++ Alias(Wvla-larger-than=,18446744073709551615EiB,none) Warning
-Wno-vla-larger-than Disable Wvla-larger-than= warning. Equivalent to Wvla-larger-than=<SIZE_MAX> or larger.
Wvolatile-register-var Wvolatile-register-var
C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)

View file

@ -1222,77 +1222,8 @@ alloc_max_size (void)
if (alloc_object_size_limit) if (alloc_object_size_limit)
return alloc_object_size_limit; return alloc_object_size_limit;
alloc_object_size_limit = max_object_size (); alloc_object_size_limit
= build_int_cst (size_type_node, warn_alloc_size_limit);
if (!warn_alloc_size_limit)
return alloc_object_size_limit;
const char *optname = "-Walloc-size-larger-than=";
char *end = NULL;
errno = 0;
unsigned HOST_WIDE_INT unit = 1;
unsigned HOST_WIDE_INT limit
= strtoull (warn_alloc_size_limit, &end, 10);
/* If the value is too large to be represented use the maximum
representable value that strtoull sets limit to (setting
errno to ERANGE). */
if (end && *end)
{
/* Numeric option arguments are at most INT_MAX. Make it
possible to specify a larger value by accepting common
suffixes. */
if (!strcmp (end, "kB"))
unit = 1000;
else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
unit = 1024;
else if (!strcmp (end, "MB"))
unit = HOST_WIDE_INT_UC (1000) * 1000;
else if (!strcasecmp (end, "MiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024;
else if (!strcasecmp (end, "GB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
else if (!strcasecmp (end, "GiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
else if (!strcasecmp (end, "TB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
else if (!strcasecmp (end, "TiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
else if (!strcasecmp (end, "PB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
else if (!strcasecmp (end, "PiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
else if (!strcasecmp (end, "EB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
* 1000;
else if (!strcasecmp (end, "EiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
* 1024;
else
{
/* This could mean an unknown suffix or a bad prefix, like
"+-1". */
warning_at (UNKNOWN_LOCATION, 0,
"invalid argument %qs to %qs",
warn_alloc_size_limit, optname);
/* Ignore the limit extracted by strtoull. */
unit = 0;
}
}
if (unit)
{
widest_int w = wi::mul (limit, unit);
if (w < wi::to_widest (alloc_object_size_limit))
alloc_object_size_limit
= wide_int_to_tree (ptrdiff_type_node, w);
else
alloc_object_size_limit = build_all_ones_cst (size_type_node);
}
return alloc_object_size_limit; return alloc_object_size_limit;
} }

View file

@ -2126,24 +2126,26 @@ cgraph_node::expand (void)
/* If requested, warn about function definitions where the function will /* If requested, warn about function definitions where the function will
return a value (usually of some struct or union type) which itself will return a value (usually of some struct or union type) which itself will
take up a lot of stack space. */ take up a lot of stack space. */
if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl)) if (!DECL_EXTERNAL (decl) && TREE_TYPE (decl))
{ {
tree ret_type = TREE_TYPE (TREE_TYPE (decl)); tree ret_type = TREE_TYPE (TREE_TYPE (decl));
if (ret_type && TYPE_SIZE_UNIT (ret_type) if (ret_type && TYPE_SIZE_UNIT (ret_type)
&& TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
&& compare_tree_int (TYPE_SIZE_UNIT (ret_type), && compare_tree_int (TYPE_SIZE_UNIT (ret_type),
larger_than_size) > 0) warn_larger_than_size) > 0)
{ {
unsigned int size_as_int unsigned int size_as_int
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type)); = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0) if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes", warning (OPT_Wlarger_than_,
"size of return value of %q+D is %u bytes",
decl, size_as_int); decl, size_as_int);
else else
warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes", warning (OPT_Wlarger_than_,
decl, larger_than_size); "size of return value of %q+D is larger than %wu bytes",
decl, warn_larger_than_size);
} }
} }

View file

@ -74,23 +74,6 @@ int flag_generate_lto
Variable Variable
int flag_generate_offload = 0 int flag_generate_offload = 0
; True to warn about any objects definitions whose size is larger
; than N bytes. Also want about function definitions whose returned
; values are larger than N bytes, where N is 'larger_than_size'.
Variable
bool warn_larger_than
Variable
HOST_WIDE_INT larger_than_size
; True to warn about any function whose frame size is larger
; than N bytes.
Variable
bool warn_frame_larger_than
Variable
HOST_WIDE_INT frame_larger_than_size
; Nonzero means we should be saving declaration info into a .X file. ; Nonzero means we should be saving declaration info into a .X file.
Variable Variable
int flag_gen_aux_info = 0 int flag_gen_aux_info = 0
@ -613,8 +596,8 @@ Common Var(flag_fatal_errors)
Exit on the first error occurred. Exit on the first error occurred.
Wframe-larger-than= Wframe-larger-than=
Common RejectNegative Joined UInteger Warning Common RejectNegative Joined Host_Wide_Int ByteSize Warning Var(warn_frame_larger_than_size) Init(HOST_WIDE_INT_MAX)
-Wframe-larger-than=<number> Warn if a function's stack frame requires more than <number> bytes. -Wframe-larger-than=<byte-size> Warn if a function's stack frame requires in excess of <byte-size>.
Wfree-nonheap-object Wfree-nonheap-object
Common Var(warn_free_nonheap_object) Init(1) Warning Common Var(warn_free_nonheap_object) Init(1) Warning
@ -643,8 +626,8 @@ Wlarger-than-
Common RejectNegative Joined Warning Undocumented Alias(Wlarger-than=) Common RejectNegative Joined Warning Undocumented Alias(Wlarger-than=)
Wlarger-than= Wlarger-than=
Common RejectNegative Joined UInteger Warning Common RejectNegative Joined Host_Wide_Int ByteSize Warning Var(warn_larger_than_size) Init(HOST_WIDE_INT_MAX)
-Wlarger-than=<number> Warn if an object is larger than <number> bytes. -Wlarger-than=<byte-size> Warn if an object's size exceeds <byte-size>.
Wnonnull-compare Wnonnull-compare
Var(warn_nonnull_compare) Warning Var(warn_nonnull_compare) Warning
@ -716,8 +699,8 @@ Common Var(warn_stack_protect) Warning
Warn when not issuing stack smashing protection for some reason. Warn when not issuing stack smashing protection for some reason.
Wstack-usage= Wstack-usage=
Common Joined RejectNegative UInteger Var(warn_stack_usage) Warning Common Joined RejectNegative Host_Wide_Int ByteSize Var(warn_stack_usage) Warning Init(HOST_WIDE_INT_MAX)
-Wstack-usage=<number> Warn if stack usage might be larger than specified amount. -Wstack-usage=<byte-size> Warn if stack usage might exceed <byte-size>.
Wstrict-aliasing Wstrict-aliasing
Common Warning Common Warning

View file

@ -121,6 +121,21 @@ these have both positive and negative forms; the negative form of
@option{-ffoo} is @option{-fno-foo}. This manual documents @option{-ffoo} is @option{-fno-foo}. This manual documents
only one of these two forms, whichever one is not the default. only one of these two forms, whichever one is not the default.
Some options take one or more arguments typically separated either
by a space or by the equals sign (@samp{=}) from the option name.
Unless documented otherwise, an argument can be either numeric or
a string. Numeric arguments must typically be small unsigned decimal
or hexadecimal integers. Hexadecimal arguments must begin with
the @samp{0x} prefix. Arguments to options that specify a size
threshold of some sort may be arbitrarily large decimal or hexadecimal
integers followed by a byte size suffix designating a multiple of bytes
such as @code{kB} and @code{KiB} for kilobyte and kibibyte, respectively,
@code{MB} and @code{MiB} for megabyte and mebibyte, @code{GB} and
@code{GiB} for gigabyte and gigibyte, and so on. Such arguments are
designated by @var{byte-size} in the following text. Refer to the NIST,
IEC, and other relevant national and international standards for the full
listing and explanation of the binary and decimal byte size prefixes.
@c man end @c man end
@xref{Option Index}, for an index to GCC's options. @xref{Option Index}, for an index to GCC's options.
@ -261,8 +276,8 @@ Objective-C and Objective-C++ Dialects}.
@gccoptlist{-fsyntax-only -fmax-errors=@var{n} -Wpedantic @gol @gccoptlist{-fsyntax-only -fmax-errors=@var{n} -Wpedantic @gol
-pedantic-errors @gol -pedantic-errors @gol
-w -Wextra -Wall -Waddress -Waggregate-return @gol -w -Wextra -Wall -Waddress -Waggregate-return @gol
-Walloc-zero -Walloc-size-larger-than=@var{n} -Walloc-zero -Walloc-size-larger-than=@var{byte-size}
-Walloca -Walloca-larger-than=@var{n} @gol -Walloca -Walloca-larger-than=@var{byte-size} @gol
-Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol -Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
-Wno-attributes -Wbool-compare -Wbool-operation @gol -Wno-attributes -Wbool-compare -Wbool-operation @gol
-Wno-builtin-declaration-mismatch @gol -Wno-builtin-declaration-mismatch @gol
@ -285,14 +300,15 @@ Objective-C and Objective-C++ Dialects}.
-Wformat-nonliteral -Wformat-overflow=@var{n} @gol -Wformat-nonliteral -Wformat-overflow=@var{n} @gol
-Wformat-security -Wformat-signedness -Wformat-truncation=@var{n} @gol -Wformat-security -Wformat-signedness -Wformat-truncation=@var{n} @gol
-Wformat-y2k -Wframe-address @gol -Wformat-y2k -Wframe-address @gol
-Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol -Wframe-larger-than=@var{byte-size} -Wno-free-nonheap-object @gol
-Wjump-misses-init @gol
-Wif-not-aligned @gol -Wif-not-aligned @gol
-Wignored-qualifiers -Wignored-attributes -Wincompatible-pointer-types @gol -Wignored-qualifiers -Wignored-attributes -Wincompatible-pointer-types @gol
-Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n} @gol -Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n} @gol
-Wimplicit-function-declaration -Wimplicit-int @gol -Wimplicit-function-declaration -Wimplicit-int @gol
-Winit-self -Winline -Wno-int-conversion -Wint-in-bool-context @gol -Winit-self -Winline -Wno-int-conversion -Wint-in-bool-context @gol
-Wno-int-to-pointer-cast -Winvalid-memory-model -Wno-invalid-offsetof @gol -Wno-int-to-pointer-cast -Winvalid-memory-model -Wno-invalid-offsetof @gol
-Winvalid-pch -Wlarger-than=@var{len} @gol -Winvalid-pch -Wlarger-than=@var{byte-size} @gol
-Wlogical-op -Wlogical-not-parentheses -Wlong-long @gol -Wlogical-op -Wlogical-not-parentheses -Wlong-long @gol
-Wmain -Wmaybe-uninitialized -Wmemset-elt-size -Wmemset-transposed-args @gol -Wmain -Wmaybe-uninitialized -Wmemset-elt-size -Wmemset-transposed-args @gol
-Wmisleading-indentation -Wmissing-attributes -Wmissing-braces @gol -Wmisleading-indentation -Wmissing-attributes -Wmissing-braces @gol
@ -313,7 +329,7 @@ Objective-C and Objective-C++ Dialects}.
-Wsign-compare -Wsign-conversion -Wfloat-conversion @gol -Wsign-compare -Wsign-conversion -Wfloat-conversion @gol
-Wno-scalar-storage-order -Wsizeof-pointer-div @gol -Wno-scalar-storage-order -Wsizeof-pointer-div @gol
-Wsizeof-pointer-memaccess -Wsizeof-array-argument @gol -Wsizeof-pointer-memaccess -Wsizeof-array-argument @gol
-Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol -Wstack-protector -Wstack-usage=@var{byte-size} -Wstrict-aliasing @gol
-Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol -Wstrict-aliasing=n -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
-Wstringop-overflow=@var{n} -Wstringop-truncation @gol -Wstringop-overflow=@var{n} -Wstringop-truncation @gol
-Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{|}malloc@r{]} @gol
@ -331,7 +347,8 @@ Objective-C and Objective-C++ Dialects}.
-Wunused-const-variable -Wunused-const-variable=@var{n} @gol -Wunused-const-variable -Wunused-const-variable=@var{n} @gol
-Wunused-but-set-parameter -Wunused-but-set-variable @gol -Wunused-but-set-parameter -Wunused-but-set-variable @gol
-Wuseless-cast -Wvariadic-macros -Wvector-operation-performance @gol -Wuseless-cast -Wvariadic-macros -Wvector-operation-performance @gol
-Wvla -Wvla-larger-than=@var{n} -Wvolatile-register-var -Wwrite-strings @gol -Wvla -Wvla-larger-than=@var{byte-size} -Wvolatile-register-var @gol
-Wwrite-strings @gol
-Wzero-as-null-pointer-constant -Whsa} -Wzero-as-null-pointer-constant -Whsa}
@item C and Objective-C-only Warning Options @item C and Objective-C-only Warning Options
@ -5523,33 +5540,39 @@ when called with a zero size differs among implementations (and in the case
of @code{realloc} has been deprecated) relying on it may result in subtle of @code{realloc} has been deprecated) relying on it may result in subtle
portability bugs and should be avoided. portability bugs and should be avoided.
@item -Walloc-size-larger-than=@var{n} @item -Walloc-size-larger-than=@var{byte-size}
@opindex Walloc-size-larger-than=@var{n} @opindex Walloc-size-larger-than=
@opindex Wno-alloc-size-larger-than @opindex Wno-alloc-size-larger-than
Warn about calls to functions decorated with attribute @code{alloc_size} Warn about calls to functions decorated with attribute @code{alloc_size}
that attempt to allocate objects larger than the specified number of bytes, that attempt to allocate objects larger than the specified number of bytes,
or where the result of the size computation in an integer type with infinite or where the result of the size computation in an integer type with infinite
precision would exceed @code{SIZE_MAX / 2}. The option argument @var{n} is precision would exceed the value of @samp{PTRDIFF_MAX} on the target.
treated as an integer with infinite precision and may end in one of @option{-Walloc-size-larger-than=}@samp{PTRDIFF_MAX} is enabled by default.
the standard suffixes designating a multiple of bytes such as @code{kB} and
@code{KiB} for kilobyte and kibibyte, respectively, @code{MB} and @code{MiB}
for megabyte and mebibyte, and so on.
@option{-Walloc-size-larger-than=}@var{PTRDIFF_MAX} is enabled by default.
Warnings controlled by the option can be disabled either by specifying Warnings controlled by the option can be disabled either by specifying
@var{n} of @var{SIZE_MAX} or more or by @option{-Wno-alloc-size-larger-than}. @var{byte-size} of @samp{SIZE_MAX} or more or by
@option{-Wno-alloc-size-larger-than}.
@xref{Function Attributes}. @xref{Function Attributes}.
@item -Wno-alloc-size-larger-than
@opindex Wno-alloc-size-larger-than
Disable @option{-Walloc-size-larger-than=} warnings. The option is
equivalent to @option{-Walloc-size-larger-than=}@samp{SIZE_MAX} or
larger.
@item -Walloca @item -Walloca
@opindex Wno-alloca @opindex Wno-alloca
@opindex Walloca @opindex Walloca
This option warns on all uses of @code{alloca} in the source. This option warns on all uses of @code{alloca} in the source.
@item -Walloca-larger-than=@var{n} @item -Walloca-larger-than=@var{byte-size}
This option warns on calls to @code{alloca} that are not bounded by a @opindex -Walloca-larger-than=
controlling predicate limiting its argument of integer type to at most @opindex -Wno-alloca-larger-than
@var{n} bytes, or calls to @code{alloca} where the bound is unknown. This option warns on calls to @code{alloca} with an integer argument whose
Arguments of non-integer types are considered unbounded even if they value is either zero, or that is not bounded by a controlling predicate
appear to be constrained to the expected range. that limits its value to at most @var{byte-size}. It also warns for calls
to @code{alloca} where the bound value is unknown. Arguments of non-integer
types are considered unbounded even if they appear to be constrained to
the expected range.
For example, a bounded case of @code{alloca} could be: For example, a bounded case of @code{alloca} could be:
@ -5603,10 +5626,16 @@ expected argument to be implicitly cast into the @code{alloca} call.
This option also warns when @code{alloca} is used in a loop. This option also warns when @code{alloca} is used in a loop.
This warning is not enabled by @option{-Wall}, and is only active when @option{-Walloca-larger-than=}@samp{PTRDIFF_MAX} is enabled by default
@option{-ftree-vrp} is active (default for @option{-O2} and above). but is usually only effective when @option{-ftree-vrp} is active (default
for @option{-O2} and above).
See also @option{-Wvla-larger-than=@var{n}}. See also @option{-Wvla-larger-than=}@samp{byte-size}.
@item -Wno-alloca-larger-than
@opindex Wno-alloca-larger-than
Disable @option{-Walloca-larger-than=} warnings. The option is
equivalent to @option{-Walloca-larger-than=}@samp{SIZE_MAX} or larger.
@item -Warray-bounds @item -Warray-bounds
@itemx -Warray-bounds=@var{n} @itemx -Warray-bounds=@var{n}
@ -5954,22 +5983,40 @@ possibly reduce the number of warnings triggered by intentional shadowing.
This warning is enabled by @option{-Wshadow=local}. This warning is enabled by @option{-Wshadow=local}.
@item -Wlarger-than=@var{len} @item -Wlarger-than=@var{byte-size}
@opindex Wlarger-than=@var{len} @opindex Wlarger-than=
@opindex Wlarger-than-@var{len} @opindex Wlarger-than-@var{byte-size}
Warn whenever an object of larger than @var{len} bytes is defined. Warn whenever an object is defined whose size exceeds @var{byte-size}.
@option{-Wlarger-than=}@samp{PTRDIFF_MAX} is enabled by default.
Warnings controlled by the option can be disabled either by specifying
@var{byte-size} of @samp{SIZE_MAX} or more or by
@option{-Wno-larger-than}.
@item -Wframe-larger-than=@var{len} @item -Wno-larger-than
@opindex Wframe-larger-than=@var{len} @opindex Wno-larger-than
@opindex Wframe-larger-than Disable @option{-Wlarger-than=} warnings. The option is equivalent
Warn if the size of a function frame is larger than @var{len} bytes. to @option{-Wlarger-than=}@samp{SIZE_MAX} or larger.
@item -Wframe-larger-than=@var{byte-size}
@opindex Wframe-larger-than=
@opindex Wno-frame-larger-than
Warn if the size of a function frame exceeds @var{byte-size}.
The computation done to determine the stack frame size is approximate The computation done to determine the stack frame size is approximate
and not conservative. and not conservative.
The actual requirements may be somewhat greater than @var{len} The actual requirements may be somewhat greater than @var{byte-size}
even if you do not get a warning. In addition, any space allocated even if you do not get a warning. In addition, any space allocated
via @code{alloca}, variable-length arrays, or related constructs via @code{alloca}, variable-length arrays, or related constructs
is not included by the compiler when determining is not included by the compiler when determining
whether or not to issue a warning. whether or not to issue a warning.
@option{-Wframe-larger-than=}@samp{PTRDIFF_MAX} is enabled by default.
Warnings controlled by the option can be disabled either by specifying
@var{byte-size} of @samp{SIZE_MAX} or more or by
@option{-Wno-frame-larger-than}.
@item -Wno-frame-larger-than
@opindex Wno-frame-larger-than
Disable @option{-Wframe-larger-than=} warnings. The option is equivalent
to @option{-Wframe-larger-than=}@samp{SIZE_MAX} or larger.
@item -Wno-free-nonheap-object @item -Wno-free-nonheap-object
@opindex Wno-free-nonheap-object @opindex Wno-free-nonheap-object
@ -5977,10 +6024,10 @@ whether or not to issue a warning.
Do not warn when attempting to free an object that was not allocated Do not warn when attempting to free an object that was not allocated
on the heap. on the heap.
@item -Wstack-usage=@var{len} @item -Wstack-usage=@var{byte-size}
@opindex Wstack-usage @opindex Wstack-usage
@opindex Wno-stack-usage @opindex Wno-stack-usage
Warn if the stack usage of a function might be larger than @var{len} bytes. Warn if the stack usage of a function might exceed @var{byte-size}.
The computation done to determine the stack usage is conservative. The computation done to determine the stack usage is conservative.
Any space allocated via @code{alloca}, variable-length arrays, or related Any space allocated via @code{alloca}, variable-length arrays, or related
constructs is included by the compiler when determining whether or not to constructs is included by the compiler when determining whether or not to
@ -6009,6 +6056,24 @@ If the stack usage is (partly) dynamic and not bounded, it's:
@end smallexample @end smallexample
@end itemize @end itemize
@option{-Wstack-usage=}@samp{PTRDIFF_MAX} is enabled by default.
Warnings controlled by the option can be disabled either by specifying
@var{byte-size} of @samp{SIZE_MAX} or more or by
@option{-Wno-stack-usage}.
@item -Wno-stack-usage
@opindex Wno-stack-usage
Disable @option{-Wstack-usage=} warnings. The option is equivalent
to @option{-Wstack-usage=}@samp{SIZE_MAX} or larger.
@item -Wunsafe-loop-optimizations
@opindex Wunsafe-loop-optimizations
@opindex Wno-unsafe-loop-optimizations
Warn if the loop cannot be optimized because the compiler cannot
assume anything on the bounds of the loop indices. With
@option{-funsafe-loop-optimizations} warn if the compiler makes
such assumptions.
@item -Wno-pedantic-ms-format @r{(MinGW targets only)} @item -Wno-pedantic-ms-format @r{(MinGW targets only)}
@opindex Wno-pedantic-ms-format @opindex Wno-pedantic-ms-format
@opindex Wpedantic-ms-format @opindex Wpedantic-ms-format
@ -7011,21 +7076,29 @@ Warn if a variable-length array is used in the code.
@option{-Wno-vla} prevents the @option{-Wpedantic} warning of @option{-Wno-vla} prevents the @option{-Wpedantic} warning of
the variable-length array. the variable-length array.
@item -Wvla-larger-than=@var{n} @item -Wvla-larger-than=@var{byte-size}
If this option is used, the compiler will warn on uses of @opindex -Wvla-larger-than=
variable-length arrays where the size is either unbounded, or bounded @opindex -Wno-vla-larger-than
by an argument that can be larger than @var{n} bytes. This is similar If this option is used, the compiler will warn for declarations of
to how @option{-Walloca-larger-than=@var{n}} works, but with variable-length arrays whose size is either unbounded, or bounded
variable-length arrays. by an argument that allows the array size to exceed @var{byte-size}
bytes. This is similar to how @option{-Walloca-larger-than=}@var{byte-size}
works, but with variable-length arrays.
Note that GCC may optimize small variable-length arrays of a known Note that GCC may optimize small variable-length arrays of a known
value into plain arrays, so this warning may not get triggered for value into plain arrays, so this warning may not get triggered for
such arrays. such arrays.
This warning is not enabled by @option{-Wall}, and is only active when @option{-Wvla-larger-than=}@samp{PTRDIFF_MAX} is enabled by default but
@option{-ftree-vrp} is active (default for @option{-O2} and above). is typically only effective when @option{-ftree-vrp} is active (default
for @option{-O2} and above).
See also @option{-Walloca-larger-than=@var{n}}. See also @option{-Walloca-larger-than=@var{byte-size}}.
@item -Wno-vla-larger-than
@opindex Wno-vla-larger-than
Disable @option{-Wvla-larger-than=} warnings. The option is equivalent
to @option{-Wvla-larger-than=}@samp{SIZE_MAX} or larger.
@item -Wvolatile-register-var @item -Wvolatile-register-var
@opindex Wvolatile-register-var @opindex Wvolatile-register-var

View file

@ -257,17 +257,42 @@ For an option marked @code{Separate}, indicate that it takes @var{n}
arguments. The default is 1. arguments. The default is 1.
@item UInteger @item UInteger
The option's argument is a non-negative integer. The option parser The option's argument is a non-negative integer consisting of either
will check and convert the argument before passing it to the relevant decimal or hexadecimal digits interpreted as @code{int}. Hexadecimal
option handler. @code{UInteger} should also be used on options like integers may optionally start with the @code{0x} or @code{0X} prefix.
@code{-falign-loops} where both @code{-falign-loops} and The option parser validates and converts the argument before passing
@code{-falign-loops}=@var{n} are supported to make sure the saved it to the relevant option handler. @code{UInteger} should also be used
options are given a full integer. with options like @code{-falign-loops} where both @code{-falign-loops}
and @code{-falign-loops}=@var{n} are supported to make sure the saved
options are given a full integer. Positive values of the argument in
excess of @code{INT_MAX} wrap around zero.
@item Host_Wide_Int
The option's argument is a non-negative integer consisting of either
decimal or hexadecimal digits interpreted as the widest integer type
on the host. As with an @code{UInteger} argument, hexadecimal integers
may optionally start with the @code{0x} or @code{0X} prefix. The option
parser validates and converts the argument before passing it to
the relevant option handler. @code{Host_Wide_Int} should be used with
options that need to accept very large values. Positive values of
the argument in excess of @code{HOST_WIDE_INT_M1U} are assigned
@code{HOST_WIDE_INT_M1U}.
@item IntegerRange(@var{n}, @var{m}) @item IntegerRange(@var{n}, @var{m})
The options's arguments are integer numbers. The option's parser The options's arguments are integers of type @code{int}. The option's
will check that value of an option is inclusively within the parser validates that the value of an option integer argument is within
range [@var{n}, @var{m}]. the closed range [@var{n}, @var{m}].
@item ByteSize
A property applicable only to @code{UInteger} or @code{Host_Wide_Int}
arguments. The option's integer argument is interpreted as if in infinite
precision using saturation arithmetic in the corresponding type. The argument
may be followed by a @samp{byte-size} suffix designating a multiple of bytes
such as @code{kB} and @code{KiB} for kilobyte and kibibyte, respectively,
@code{MB} and @code{MiB} for megabyte and mebibyte, @code{GB} and @code{GiB}
for gigabyte and gigibyte, and so on. @code{ByteSize} should be used for
with options that take a very large argument representing a size in bytes,
such as @option{-Wlarger-than=}.
@item ToLower @item ToLower
The option's argument should be converted to lowercase as part of The option's argument should be converted to lowercase as part of

View file

@ -1778,14 +1778,14 @@ final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen,
TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1; TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
} }
HOST_WIDE_INT min_frame_size = constant_lower_bound (get_frame_size ()); unsigned HOST_WIDE_INT min_frame_size
if (warn_frame_larger_than = constant_lower_bound (get_frame_size ());
&& min_frame_size > frame_larger_than_size) if (min_frame_size > (unsigned HOST_WIDE_INT) warn_frame_larger_than_size)
{ {
/* Issue a warning */ /* Issue a warning */
warning (OPT_Wframe_larger_than_, warning (OPT_Wframe_larger_than_,
"the frame size of %wd bytes is larger than %wd bytes", "the frame size of %wu bytes is larger than %wu bytes",
min_frame_size, frame_larger_than_size); min_frame_size, warn_frame_larger_than_size);
} }
/* First output the function prologue: code to set up the stack frame. */ /* First output the function prologue: code to set up the stack frame. */

View file

@ -1,3 +1,10 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* gfortran.h (gfc_handle_option): Change function argument
to HOST_WIDE_INT.
* options.c (gfc_handle_option): Same.
2018-07-20 Andrew Benson <abenson@carnegiescience.edu> 2018-07-20 Andrew Benson <abenson@carnegiescience.edu>
* gfortran.h (gfc_symbol): Add pointer to next derived type. * gfortran.h (gfc_symbol): Add pointer to next derived type.

View file

@ -2830,7 +2830,7 @@ unsigned int gfc_option_lang_mask (void);
void gfc_init_options_struct (struct gcc_options *); void gfc_init_options_struct (struct gcc_options *);
void gfc_init_options (unsigned int, void gfc_init_options (unsigned int,
struct cl_decoded_option *); struct cl_decoded_option *);
bool gfc_handle_option (size_t, const char *, int, int, location_t, bool gfc_handle_option (size_t, const char *, HOST_WIDE_INT, int, location_t,
const struct cl_option_handlers *); const struct cl_option_handlers *);
bool gfc_post_options (const char **); bool gfc_post_options (const char **);
char *gfc_get_option_string (void); char *gfc_get_option_string (void);

View file

@ -585,7 +585,7 @@ gfc_handle_runtime_check_option (const char *arg)
recognized and handled. */ recognized and handled. */
bool bool
gfc_handle_option (size_t scode, const char *arg, int value, gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{ {

View file

@ -242,8 +242,15 @@ frame_offset_overflow (poly_int64 offset, tree func)
if (!coeffs_in_range_p (size, 0U, limit)) if (!coeffs_in_range_p (size, 0U, limit))
{ {
error_at (DECL_SOURCE_LOCATION (func), unsigned HOST_WIDE_INT hwisize;
"total size of local objects too large"); if (size.is_constant (&hwisize))
error_at (DECL_SOURCE_LOCATION (func),
"total size of local objects %wu exceeds maximum %wu",
hwisize, limit);
else
error_at (DECL_SOURCE_LOCATION (func),
"total size of local objects exceeds maximum %wu",
limit);
return true; return true;
} }

View file

@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa.h" #include "tree-ssa.h"
#include "params.h" #include "params.h"
#include "tree-cfg.h" #include "tree-cfg.h"
#include "builtins.h"
#include "calls.h" #include "calls.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "intl.h" #include "intl.h"
@ -78,8 +79,10 @@ pass_walloca::gate (function *fun ATTRIBUTE_UNUSED)
if (first_time_p) if (first_time_p)
return warn_alloca != 0; return warn_alloca != 0;
return ((unsigned HOST_WIDE_INT) warn_alloca_limit > 0 // Warning is disabled when its size limit is greater than PTRDIFF_MAX
|| (unsigned HOST_WIDE_INT) warn_vla_limit > 0); // for the target maximum, which makes the limit negative since when
// represented in signed HOST_WIDE_INT.
return warn_alloca_limit >= 0 || warn_vla_limit >= 0;
} }
// Possible problematic uses of alloca. // Possible problematic uses of alloca.
@ -150,13 +153,25 @@ struct alloca_type_and_limit {
// in bytes we allow for arg. // in bytes we allow for arg.
static struct alloca_type_and_limit static struct alloca_type_and_limit
alloca_call_type_by_arg (tree arg, tree arg_casted, edge e, unsigned max_size) alloca_call_type_by_arg (tree arg, tree arg_casted, edge e,
unsigned HOST_WIDE_INT max_size)
{ {
basic_block bb = e->src; basic_block bb = e->src;
gimple_stmt_iterator gsi = gsi_last_bb (bb); gimple_stmt_iterator gsi = gsi_last_bb (bb);
gimple *last = gsi_stmt (gsi); gimple *last = gsi_stmt (gsi);
const offset_int maxobjsize = tree_to_shwi (max_object_size ());
/* When MAX_SIZE is greater than or equal to PTRDIFF_MAX treat
allocations that aren't visibly constrained as OK, otherwise
report them as (potentially) unbounded. */
alloca_type unbounded_result = (max_size < maxobjsize.to_uhwi ()
? ALLOCA_UNBOUNDED : ALLOCA_OK);
if (!last || gimple_code (last) != GIMPLE_COND) if (!last || gimple_code (last) != GIMPLE_COND)
return alloca_type_and_limit (ALLOCA_UNBOUNDED); {
return alloca_type_and_limit (unbounded_result);
}
enum tree_code cond_code = gimple_cond_code (last); enum tree_code cond_code = gimple_cond_code (last);
if (e->flags & EDGE_TRUE_VALUE) if (e->flags & EDGE_TRUE_VALUE)
@ -164,7 +179,7 @@ alloca_call_type_by_arg (tree arg, tree arg_casted, edge e, unsigned max_size)
else if (e->flags & EDGE_FALSE_VALUE) else if (e->flags & EDGE_FALSE_VALUE)
cond_code = invert_tree_comparison (cond_code, false); cond_code = invert_tree_comparison (cond_code, false);
else else
return alloca_type_and_limit (ALLOCA_UNBOUNDED); return alloca_type_and_limit (unbounded_result);
// Check for: // Check for:
// if (ARG .COND. N) // if (ARG .COND. N)
@ -229,10 +244,10 @@ alloca_call_type_by_arg (tree arg, tree arg_casted, edge e, unsigned max_size)
// //
// If this ever triggers, we should probably figure out why and // If this ever triggers, we should probably figure out why and
// handle it, though it is likely to be just an ALLOCA_UNBOUNDED. // handle it, though it is likely to be just an ALLOCA_UNBOUNDED.
return alloca_type_and_limit (ALLOCA_UNBOUNDED); return alloca_type_and_limit (unbounded_result);
} }
return alloca_type_and_limit (ALLOCA_UNBOUNDED); return alloca_type_and_limit (unbounded_result);
} }
// Return TRUE if SSA's definition is a cast from a signed type. // Return TRUE if SSA's definition is a cast from a signed type.
@ -281,16 +296,16 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
edge_iterator ei; edge_iterator ei;
edge e; edge e;
gcc_assert (!is_vla || (unsigned HOST_WIDE_INT) warn_vla_limit > 0); gcc_assert (!is_vla || warn_vla_limit >= 0);
gcc_assert (is_vla || (unsigned HOST_WIDE_INT) warn_alloca_limit > 0); gcc_assert (is_vla || warn_alloca_limit >= 0);
// Adjust warn_alloca_max_size for VLAs, by taking the underlying // Adjust warn_alloca_max_size for VLAs, by taking the underlying
// type into account. // type into account.
unsigned HOST_WIDE_INT max_size; unsigned HOST_WIDE_INT max_size;
if (is_vla) if (is_vla)
max_size = (unsigned HOST_WIDE_INT) warn_vla_limit; max_size = warn_vla_limit;
else else
max_size = (unsigned HOST_WIDE_INT) warn_alloca_limit; max_size = warn_alloca_limit;
// Check for the obviously bounded case. // Check for the obviously bounded case.
if (TREE_CODE (len) == INTEGER_CST) if (TREE_CODE (len) == INTEGER_CST)
@ -299,7 +314,13 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
return alloca_type_and_limit (ALLOCA_BOUND_DEFINITELY_LARGE, return alloca_type_and_limit (ALLOCA_BOUND_DEFINITELY_LARGE,
wi::to_wide (len)); wi::to_wide (len));
if (integer_zerop (len)) if (integer_zerop (len))
return alloca_type_and_limit (ALLOCA_ARG_IS_ZERO); {
const offset_int maxobjsize
= wi::to_offset (max_object_size ());
alloca_type result = (max_size < maxobjsize
? ALLOCA_ARG_IS_ZERO : ALLOCA_OK);
return alloca_type_and_limit (result);
}
return alloca_type_and_limit (ALLOCA_OK); return alloca_type_and_limit (ALLOCA_OK);
} }
@ -357,8 +378,15 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
} }
else if (range_type == VR_ANTI_RANGE) else if (range_type == VR_ANTI_RANGE)
return alloca_type_and_limit (ALLOCA_UNBOUNDED); return alloca_type_and_limit (ALLOCA_UNBOUNDED);
else if (range_type != VR_VARYING)
return alloca_type_and_limit (ALLOCA_BOUND_MAYBE_LARGE, max); if (range_type != VR_VARYING)
{
const offset_int maxobjsize
= wi::to_offset (max_object_size ());
alloca_type result = (max_size < maxobjsize
? ALLOCA_BOUND_MAYBE_LARGE : ALLOCA_OK);
return alloca_type_and_limit (result, max);
}
} }
} }
else if (range_type == VR_ANTI_RANGE) else if (range_type == VR_ANTI_RANGE)
@ -414,8 +442,13 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
if (compare_tree_int (arg, max_size) <= 0) if (compare_tree_int (arg, max_size) <= 0)
ret = alloca_type_and_limit (ALLOCA_OK); ret = alloca_type_and_limit (ALLOCA_OK);
else else
ret = alloca_type_and_limit (ALLOCA_BOUND_MAYBE_LARGE, {
wi::to_wide (arg)); const offset_int maxobjsize
= wi::to_offset (max_object_size ());
alloca_type result = (max_size < maxobjsize
? ALLOCA_BOUND_MAYBE_LARGE : ALLOCA_OK);
ret = alloca_type_and_limit (result, wi::to_wide (arg));
}
} }
return ret; return ret;
@ -452,16 +485,18 @@ pass_walloca::execute (function *fun)
// Strict mode whining for VLAs is handled by the front-end, // Strict mode whining for VLAs is handled by the front-end,
// so we can safely ignore this case. Also, ignore VLAs if // so we can safely ignore this case. Also, ignore VLAs if
// the user doesn't care about them. // the user doesn't care about them.
if (is_vla if (is_vla)
&& (warn_vla > 0 || !warn_vla_limit))
continue;
if (!is_vla && (warn_alloca || !warn_alloca_limit))
{ {
if (warn_alloca) if (warn_vla > 0 || warn_vla_limit < 0)
warning_at (loc, OPT_Walloca, G_("use of %<alloca%>")); continue;
}
else if (warn_alloca)
{
warning_at (loc, OPT_Walloca, G_("use of %<alloca%>"));
continue; continue;
} }
else if (warn_alloca_limit < 0)
continue;
tree invalid_casted_type = NULL; tree invalid_casted_type = NULL;
struct alloca_type_and_limit t struct alloca_type_and_limit t
@ -471,7 +506,15 @@ pass_walloca::execute (function *fun)
// loop, except for a VLA, since VLAs are guaranteed to be cleaned // loop, except for a VLA, since VLAs are guaranteed to be cleaned
// up when they go out of scope, including in a loop. // up when they go out of scope, including in a loop.
if (t.type == ALLOCA_OK && !is_vla && in_loop_p (stmt)) if (t.type == ALLOCA_OK && !is_vla && in_loop_p (stmt))
t = alloca_type_and_limit (ALLOCA_IN_LOOP); {
/* As in other instances, only diagnose this when the limit
is less than the maximum valid object size. */
const offset_int maxobjsize
= wi::to_offset (max_object_size ());
if ((unsigned HOST_WIDE_INT) warn_alloca_limit
< maxobjsize.to_uhwi ())
t = alloca_type_and_limit (ALLOCA_IN_LOOP);
}
enum opt_code wcode enum opt_code wcode
= is_vla ? OPT_Wvla_larger_than_ : OPT_Walloca_larger_than_; = is_vla ? OPT_Wvla_larger_than_ : OPT_Walloca_larger_than_;
@ -488,7 +531,7 @@ pass_walloca::execute (function *fun)
&& t.limit != 0) && t.limit != 0)
{ {
print_decu (t.limit, buff); print_decu (t.limit, buff);
inform (loc, G_("limit is %u bytes, but argument " inform (loc, G_("limit is %wu bytes, but argument "
"may be as large as %s"), "may be as large as %s"),
is_vla ? warn_vla_limit : warn_alloca_limit, buff); is_vla ? warn_vla_limit : warn_alloca_limit, buff);
} }
@ -501,7 +544,7 @@ pass_walloca::execute (function *fun)
&& t.limit != 0) && t.limit != 0)
{ {
print_decu (t.limit, buff); print_decu (t.limit, buff);
inform (loc, G_("limit is %u bytes, but argument is %s"), inform (loc, G_("limit is %wu bytes, but argument is %s"),
is_vla ? warn_vla_limit : warn_alloca_limit, buff); is_vla ? warn_vla_limit : warn_alloca_limit, buff);
} }
break; break;

View file

@ -1,3 +1,9 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* go-lang.c (go_langhook_handle_option): Change function argument
to HOST_WIDE_INT.
2018-06-28 Ian Lance Taylor <iant@golang.org> 2018-06-28 Ian Lance Taylor <iant@golang.org>
PR go/86343 PR go/86343

View file

@ -194,7 +194,7 @@ static bool
go_langhook_handle_option ( go_langhook_handle_option (
size_t scode, size_t scode,
const char *arg, const char *arg,
int value, HOST_WIDE_INT value,
int kind ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
location_t loc ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)

View file

@ -70,8 +70,8 @@ extern void lhd_initialize_diagnostics (diagnostic_context *);
extern void lhd_init_options (unsigned int, extern void lhd_init_options (unsigned int,
struct cl_decoded_option *); struct cl_decoded_option *);
extern bool lhd_complain_wrong_lang_p (const struct cl_option *); extern bool lhd_complain_wrong_lang_p (const struct cl_option *);
extern bool lhd_handle_option (size_t, const char *, int, int, location_t, extern bool lhd_handle_option (size_t, const char *, HOST_WIDE_INT, int,
const struct cl_option_handlers *); location_t, const struct cl_option_handlers *);
/* Declarations for tree gimplification hooks. */ /* Declarations for tree gimplification hooks. */

View file

@ -353,7 +353,8 @@ lhd_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
bool bool
lhd_handle_option (size_t code ATTRIBUTE_UNUSED, lhd_handle_option (size_t code ATTRIBUTE_UNUSED,
const char *arg ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED,
int value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED, HOST_WIDE_INT value ATTRIBUTE_UNUSED,
int kind ATTRIBUTE_UNUSED,
location_t loc ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{ {

View file

@ -348,8 +348,8 @@ struct lang_hooks
location of the option. location of the option.
Return true if the switch is valid, false if invalid. */ Return true if the switch is valid, false if invalid. */
bool (*handle_option) (size_t code, const char *arg, int value, int kind, bool (*handle_option) (size_t code, const char *arg, HOST_WIDE_INT value,
location_t loc, int kind, location_t loc,
const struct cl_option_handlers *handlers); const struct cl_option_handlers *handlers);
/* Called when all command line options have been parsed to allow /* Called when all command line options have been parsed to allow

View file

@ -1,3 +1,9 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* lto-lang.c (lto_handle_option): Change function argument
to HOST_WIDE_INT.
2018-07-20 Richard Biener <rguenther@suse.de> 2018-07-20 Richard Biener <rguenther@suse.de>
PR debug/86585 PR debug/86585

View file

@ -827,7 +827,8 @@ lto_init_options_struct (struct gcc_options *opts)
const char *resolution_file_name; const char *resolution_file_name;
static bool static bool
lto_handle_option (size_t scode, const char *arg, lto_handle_option (size_t scode, const char *arg,
int value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED, HOST_WIDE_INT value ATTRIBUTE_UNUSED,
int kind ATTRIBUTE_UNUSED,
location_t loc ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{ {

View file

@ -113,9 +113,14 @@ function switch_flags (flags)
# Return bit-field initializers for option flags FLAGS. # Return bit-field initializers for option flags FLAGS.
function switch_bit_fields (flags) function switch_bit_fields (flags)
{ {
uinteger_flag = ""
vn = var_name(flags); vn = var_name(flags);
if (host_wide_int[vn] == "yes") if (host_wide_int[vn] == "yes")
hwi = "Host_Wide_Int" hwi = "Host_Wide_Int"
else if (flag_set_p("Host_Wide_Int", flags)) {
hwi = "Host_Wide_Int"
uinteger_flag = flag_init("UInteger", flags)
}
else else
hwi = "" hwi = ""
result = "" result = ""
@ -126,6 +131,20 @@ function switch_bit_fields (flags)
sep_args-- sep_args--
result = result sep_args ", " result = result sep_args ", "
if (uinteger_flag == "")
uinteger_flag = flag_init("UInteger", flags)
hwi_flag = flag_init("Host_Wide_Int", hwi)
byte_size_flag = flag_init("ByteSize", flags)
if (substr(byte_size_flag, 1, 1) != "0" \
&& substr(uinteger_flag, 1, 1) == "0" \
&& substr(hwi_flag, 1, 1) == "0")
print "#error only UInteger amd Host_Wide_Int options can specify a ByteSize suffix"
# The following flags need to be in the same order as
# the corresponding members of struct cl_option defined
# in gcc/opts.h.
result = result \ result = result \
flag_init("SeparateAlias", flags) \ flag_init("SeparateAlias", flags) \
flag_init("NegativeAlias", flags) \ flag_init("NegativeAlias", flags) \
@ -133,11 +152,12 @@ function switch_bit_fields (flags)
flag_init("RejectDriver", flags) \ flag_init("RejectDriver", flags) \
flag_init("RejectNegative", flags) \ flag_init("RejectNegative", flags) \
flag_init("JoinedOrMissing", flags) \ flag_init("JoinedOrMissing", flags) \
flag_init("UInteger", flags) \ uinteger_flag \
flag_init("Host_Wide_Int", hwi) \ hwi_flag \
flag_init("ToLower", flags) \ flag_init("ToLower", flags) \
flag_init("Report", flags) \ flag_init("Report", flags) \
flag_init("Deprecated", flags) flag_init("Deprecated", flags) \
byte_size_flag
sub(", $", "", result) sub(", $", "", result)
return result return result
@ -200,6 +220,8 @@ function var_type(flags)
} }
else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags))
return "int " return "int "
else if (flag_set_p("Host_Wide_Int", flags))
return "HOST_WIDE_INT "
else if (flag_set_p("UInteger", flags)) else if (flag_set_p("UInteger", flags))
return "int " return "int "
else else
@ -211,8 +233,13 @@ function var_type(flags)
# type instead of int to save space. # type instead of int to save space.
function var_type_struct(flags) function var_type_struct(flags)
{ {
if (flag_set_p("UInteger", flags)) if (flag_set_p("UInteger", flags)) {
return "int " if (host_wide_int[var_name(flags)] == "yes")
return "HOST_WIDE_INT ";
if (flag_set_p("ByteSize", flags))
return "HOST_WIDE_INT "
return "int "
}
else if (flag_set_p("Enum.*", flags)) { else if (flag_set_p("Enum.*", flags)) {
en = opt_args("Enum", flags); en = opt_args("Enum", flags);
return enum_type[en] " " return enum_type[en] " "
@ -222,7 +249,7 @@ function var_type_struct(flags)
if (host_wide_int[var_name(flags)] == "yes") if (host_wide_int[var_name(flags)] == "yes")
return "HOST_WIDE_INT " return "HOST_WIDE_INT "
else else
return "int " return "/* - */ int "
} }
else else
return "signed char " return "signed char "
@ -262,6 +289,8 @@ function var_set(flags)
} }
if (var_type(flags) == "const char *") if (var_type(flags) == "const char *")
return "0, CLVC_STRING, 0" return "0, CLVC_STRING, 0"
if (flag_set_p("ByteSize", flags))
return "0, CLVC_SIZE, 0"
return "0, CLVC_BOOLEAN, 0" return "0, CLVC_BOOLEAN, 0"
} }

View file

@ -274,6 +274,7 @@ for (i = 0; i < n_opts; i++) {
j++; j++;
} }
optindex = 0
for (i = 0; i < n_opts; i++) { for (i = 0; i < n_opts; i++) {
# With identical flags, pick only the last one. The # With identical flags, pick only the last one. The
# earlier loop ensured that it has all flags merged, # earlier loop ensured that it has all flags merged,
@ -303,20 +304,20 @@ for (i = 0; i < n_opts; i++) {
comma = "" comma = ""
if (help[i] == "") if (help[i] == "")
hlp = "0" hlp = "NULL"
else else
hlp = quote help[i] quote; hlp = quote help[i] quote;
missing_arg_error = opt_args("MissingArgError", flags[i]) missing_arg_error = opt_args("MissingArgError", flags[i])
if (missing_arg_error == "") if (missing_arg_error == "")
missing_arg_error = "0" missing_arg_error = "NULL"
else else
missing_arg_error = quote missing_arg_error quote missing_arg_error = quote missing_arg_error quote
warn_message = opt_args("Warn", flags[i]) warn_message = opt_args("Warn", flags[i])
if (warn_message == "") if (warn_message == "")
warn_message = "0" warn_message = "NULL"
else else
warn_message = quote warn_message quote warn_message = quote warn_message quote
@ -378,10 +379,11 @@ for (i = 0; i < n_opts; i++) {
} }
# Split the printf after %u to work around an ia64-hp-hpux11.23 # Split the printf after %u to work around an ia64-hp-hpux11.23
# awk bug. # awk bug.
printf(" { %c-%s%c,\n %s,\n %s,\n %s,\n %s, %s, %u,", printf(" /* [%i] = */ {\n", optindex)
printf(" %c-%s%c,\n %s,\n %s,\n %s,\n %s, %s, %u,",
quote, opts[i], quote, hlp, missing_arg_error, warn_message, quote, opts[i], quote, hlp, missing_arg_error, warn_message,
alias_data, back_chain[i], len) alias_data, back_chain[i], len)
printf(" %d,\n", idx) printf(" /* .neg_idx = */ %d,\n", idx)
condition = opt_args("Condition", flags[i]) condition = opt_args("Condition", flags[i])
cl_flags = switch_flags(flags[i]) cl_flags = switch_flags(flags[i])
cl_bit_fields = switch_bit_fields(flags[i]) cl_bit_fields = switch_bit_fields(flags[i])
@ -402,7 +404,10 @@ for (i = 0; i < n_opts; i++) {
printf(" %s, %s, %s }%s\n", var_ref(opts[i], flags[i]), printf(" %s, %s, %s }%s\n", var_ref(opts[i], flags[i]),
var_set(flags[i]), integer_range_info(opt_args("IntegerRange", flags[i]), var_set(flags[i]), integer_range_info(opt_args("IntegerRange", flags[i]),
opt_args("Init", flags[i]), opts[i]), comma) opt_args("Init", flags[i]), opts[i]), comma)
}
# Bump up the informational option index.
++optindex
}
print "};" print "};"
@ -417,7 +422,7 @@ print " const struct cl_option_handlers *handlers, "
print " diagnostic_context *dc) " print " diagnostic_context *dc) "
print "{ " print "{ "
print " size_t scode = decoded->opt_index; " print " size_t scode = decoded->opt_index; "
print " int value = decoded->value; " print " HOST_WIDE_INT value = decoded->value; "
print " enum opt_code code = (enum opt_code) scode; " print " enum opt_code code = (enum opt_code) scode; "
print " " print " "
print " gcc_assert (decoded->canonical_option_num_elements <= 2); " print " gcc_assert (decoded->canonical_option_num_elements <= 2); "
@ -467,7 +472,7 @@ for (i = 0; i < n_langs; i++) {
print "bool " print "bool "
print lang_name "_handle_option_auto (struct gcc_options *opts" mark_unused ", " print lang_name "_handle_option_auto (struct gcc_options *opts" mark_unused ", "
print " struct gcc_options *opts_set" mark_unused ", " print " struct gcc_options *opts_set" mark_unused ", "
print " size_t scode" mark_unused ", const char *arg" mark_unused ", int value" mark_unused ", " print " size_t scode" mark_unused ", const char *arg" mark_unused ", HOST_WIDE_INT value" mark_unused ", "
print " unsigned int lang_mask" mark_unused ", int kind" mark_unused ", " print " unsigned int lang_mask" mark_unused ", int kind" mark_unused ", "
print " location_t loc" mark_unused ", " print " location_t loc" mark_unused ", "
print " const struct cl_option_handlers *handlers" mark_unused ", " print " const struct cl_option_handlers *handlers" mark_unused ", "

View file

@ -478,13 +478,14 @@ print "{";
print " fputs (\"\\n\", file);"; print " fputs (\"\\n\", file);";
for (i = 0; i < n_target_other; i++) { for (i = 0; i < n_target_other; i++) {
print " if (ptr->x_" var_target_other[i] ")"; print " if (ptr->x_" var_target_other[i] ")";
if (host_wide_int[var_target_other[i]] == "yes") hwi = host_wide_int[var_target_other[i]]
if (hwi == "yes")
print " fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x)\\n\","; print " fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
else else
print " fprintf (file, \"%*s%s (%#x)\\n\","; print " fprintf (file, \"%*s%s (%#lx)\\n\",";
print " indent, \"\","; print " indent, \"\",";
print " \"" var_target_other[i] "\","; print " \"" var_target_other[i] "\",";
if (host_wide_int[var_target_other[i]] == "yes") if (hwi == "yes")
print " ptr->x_" var_target_other[i] ");"; print " ptr->x_" var_target_other[i] ");";
else else
print " (unsigned long)ptr->x_" var_target_other[i] ");"; print " (unsigned long)ptr->x_" var_target_other[i] ");";
@ -544,13 +545,14 @@ print "{";
print " fputs (\"\\n\", file);"; print " fputs (\"\\n\", file);";
for (i = 0; i < n_target_other; i++) { for (i = 0; i < n_target_other; i++) {
print " if (ptr1->x_" var_target_other[i] " != ptr2->x_" var_target_other[i] ")"; print " if (ptr1->x_" var_target_other[i] " != ptr2->x_" var_target_other[i] ")";
if (host_wide_int[var_target_other[i]] == "yes") hwi = host_wide_int[var_target_other[i]]
if (hwi == "yes")
print " fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x/%#\" HOST_WIDE_INT_PRINT \"x)\\n\","; print " fprintf (file, \"%*s%s (%#\" HOST_WIDE_INT_PRINT \"x/%#\" HOST_WIDE_INT_PRINT \"x)\\n\",";
else else
print " fprintf (file, \"%*s%s (%#x/%#x)\\n\","; print " fprintf (file, \"%*s%s (%#lx/%#lx)\\n\",";
print " indent, \"\","; print " indent, \"\",";
print " \"" var_target_other[i] "\","; print " \"" var_target_other[i] "\",";
if (host_wide_int[var_target_other[i]] == "yes") { if (hwi == "yes") {
print " ptr1->x_" var_target_other[i] ","; print " ptr1->x_" var_target_other[i] ",";
print " ptr2->x_" var_target_other[i] ");"; print " ptr2->x_" var_target_other[i] ");";
} }

View file

@ -323,14 +323,15 @@ print " const struct cl_option_handlers *handlers, "
print " diagnostic_context *dc); " print " diagnostic_context *dc); "
for (i = 0; i < n_langs; i++) { for (i = 0; i < n_langs; i++) {
lang_name = lang_sanitized_name(langs[i]); lang_name = lang_sanitized_name(langs[i]);
print "bool " print "bool"
print lang_name "_handle_option_auto (struct gcc_options *opts, " print lang_name "_handle_option_auto (struct gcc_options *opts,"
print " struct gcc_options *opts_set, " print " struct gcc_options *opts_set,"
print " size_t scode, const char *arg, int value, " print " size_t scode, const char *arg,"
print " unsigned int lang_mask, int kind, " print " HOST_WIDE_INT value,"
print " location_t loc, " print " unsigned int lang_mask, int kind,"
print " const struct cl_option_handlers *handlers, " print " location_t loc,"
print " diagnostic_context *dc); " print " const struct cl_option_handlers *handlers,"
print " diagnostic_context *dc);"
} }
print "void cpp_handle_option_auto (const struct gcc_options * opts, size_t scode," print "void cpp_handle_option_auto (const struct gcc_options * opts, size_t scode,"
print " struct cpp_options * cpp_opts);" print " struct cpp_options * cpp_opts);"

View file

@ -169,32 +169,95 @@ find_opt (const char *input, unsigned int lang_mask)
return match_wrong_lang; return match_wrong_lang;
} }
/* If ARG is a non-negative decimal or hexadecimal integer, return its /* If ARG is a non-negative decimal or hexadecimal integer representable
value, otherwise return -1. */ in HOST_WIDE_INT return its value, otherwise return -1. If ERR is not
null set *ERR to zero on success or to EINVAL or to the value of errno
otherwise. */
int HOST_WIDE_INT
integral_argument (const char *arg) integral_argument (const char *arg, int *err, bool byte_size_suffix)
{ {
const char *p = arg; if (!err)
err = &errno;
while (*p && ISDIGIT (*p)) if (!ISDIGIT (*arg))
p++;
if (*p == '\0')
return atoi (arg);
/* It wasn't a decimal number - try hexadecimal. */
if (arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X'))
{ {
p = arg + 2; *err = EINVAL;
while (*p && ISXDIGIT (*p)) return -1;
p++;
if (p != arg + 2 && *p == '\0')
return strtol (arg, NULL, 16);
} }
return -1; *err = 0;
errno = 0;
char *end = NULL;
unsigned HOST_WIDE_INT unit = 1;
unsigned HOST_WIDE_INT value = strtoull (arg, &end, 10);
/* If the value is too large to be represented use the maximum
representable value that strtoull sets VALUE to (setting
errno to ERANGE). */
if (end && *end)
{
if (!byte_size_suffix)
{
errno = 0;
value = strtoull (arg, &end, 0);
if (*end)
{
/* errno is most likely EINVAL here. */
*err = errno;
return -1;
}
return value;
}
/* Numeric option arguments are at most INT_MAX. Make it
possible to specify a larger value by accepting common
suffixes. */
if (!strcmp (end, "kB"))
unit = 1000;
else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
unit = 1024;
else if (!strcmp (end, "MB"))
unit = HOST_WIDE_INT_UC (1000) * 1000;
else if (!strcasecmp (end, "MiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024;
else if (!strcasecmp (end, "GB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
else if (!strcasecmp (end, "GiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
else if (!strcasecmp (end, "TB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
else if (!strcasecmp (end, "TiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
else if (!strcasecmp (end, "PB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
else if (!strcasecmp (end, "PiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
else if (!strcasecmp (end, "EB"))
unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
* 1000;
else if (!strcasecmp (end, "EiB"))
unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
* 1024;
else
{
/* This could mean an unknown suffix or a bad prefix, like
"+-1". */
*err = EINVAL;
return -1;
}
}
if (unit)
{
unsigned HOST_WIDE_INT prod = value * unit;
value = prod < value ? HOST_WIDE_INT_M1U : prod;
}
return value;
} }
/* Return whether OPTION is OK for the language given by /* Return whether OPTION is OK for the language given by
@ -230,7 +293,8 @@ enum_arg_ok_for_language (const struct cl_enum_arg *enum_arg,
static bool static bool
enum_arg_to_value (const struct cl_enum_arg *enum_args, enum_arg_to_value (const struct cl_enum_arg *enum_args,
const char *arg, int *value, unsigned int lang_mask) const char *arg, HOST_WIDE_INT *value,
unsigned int lang_mask)
{ {
unsigned int i; unsigned int i;
@ -250,15 +314,22 @@ enum_arg_to_value (const struct cl_enum_arg *enum_args,
and returning false without modifying *VALUE if not found. */ and returning false without modifying *VALUE if not found. */
bool bool
opt_enum_arg_to_value (size_t opt_index, const char *arg, int *value, opt_enum_arg_to_value (size_t opt_index, const char *arg,
unsigned int lang_mask) int *value, unsigned int lang_mask)
{ {
const struct cl_option *option = &cl_options[opt_index]; const struct cl_option *option = &cl_options[opt_index];
gcc_assert (option->var_type == CLVC_ENUM); gcc_assert (option->var_type == CLVC_ENUM);
return enum_arg_to_value (cl_enums[option->var_enum].values, arg, HOST_WIDE_INT wideval;
value, lang_mask); if (enum_arg_to_value (cl_enums[option->var_enum].values, arg,
&wideval, lang_mask))
{
*value = wideval;
return true;
}
return false;
} }
/* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the /* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the
@ -299,7 +370,8 @@ enum_value_to_arg (const struct cl_enum_arg *enum_args,
described by OPT_INDEX, ARG and VALUE. */ described by OPT_INDEX, ARG and VALUE. */
static void static void
generate_canonical_option (size_t opt_index, const char *arg, int value, generate_canonical_option (size_t opt_index, const char *arg,
HOST_WIDE_INT value,
struct cl_decoded_option *decoded) struct cl_decoded_option *decoded)
{ {
const struct cl_option *option = &cl_options[opt_index]; const struct cl_option *option = &cl_options[opt_index];
@ -449,7 +521,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
{ {
size_t opt_index; size_t opt_index;
const char *arg = 0; const char *arg = 0;
int value = 1; HOST_WIDE_INT value = 1;
unsigned int result = 1, i, extra_args, separate_args = 0; unsigned int result = 1, i, extra_args, separate_args = 0;
int adjust_len = 0; int adjust_len = 0;
size_t total_len; size_t total_len;
@ -520,6 +592,11 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
goto done; goto done;
} }
/* Clear the initial value for size options (it will be overwritten
later based on the Init(value) specification in the opt file. */
if (option->var_type == CLVC_SIZE)
value = 0;
result = extra_args + 1; result = extra_args + 1;
warn_message = option->warn_message; warn_message = option->warn_message;
@ -684,11 +761,12 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
arg = arg_lower; arg = arg_lower;
} }
/* If the switch takes an integer, convert it. */ /* If the switch takes an integer argument, convert it. */
if (arg && option->cl_uinteger) if (arg && (option->cl_uinteger || option->cl_host_wide_int))
{ {
value = integral_argument (arg); int error = 0;
if (value == -1) value = *arg ? integral_argument (arg, &error, option->cl_byte_size) : 0;
if (error)
errors |= CL_ERR_UINT_ARG; errors |= CL_ERR_UINT_ARG;
/* Reject value out of a range. */ /* Reject value out of a range. */
@ -1008,7 +1086,7 @@ handle_option (struct gcc_options *opts,
{ {
size_t opt_index = decoded->opt_index; size_t opt_index = decoded->opt_index;
const char *arg = decoded->arg; const char *arg = decoded->arg;
int value = decoded->value; HOST_WIDE_INT value = decoded->value;
const struct cl_option *option = &cl_options[opt_index]; const struct cl_option *option = &cl_options[opt_index];
void *flag_var = option_flag_var (opt_index, opts); void *flag_var = option_flag_var (opt_index, opts);
size_t i; size_t i;
@ -1038,7 +1116,7 @@ handle_option (struct gcc_options *opts,
bool bool
handle_generated_option (struct gcc_options *opts, handle_generated_option (struct gcc_options *opts,
struct gcc_options *opts_set, struct gcc_options *opts_set,
size_t opt_index, const char *arg, int value, size_t opt_index, const char *arg, HOST_WIDE_INT value,
unsigned int lang_mask, int kind, location_t loc, unsigned int lang_mask, int kind, location_t loc,
const struct cl_option_handlers *handlers, const struct cl_option_handlers *handlers,
bool generated_p, diagnostic_context *dc) bool generated_p, diagnostic_context *dc)
@ -1055,7 +1133,7 @@ handle_generated_option (struct gcc_options *opts,
compiler generates options internally. */ compiler generates options internally. */
void void
generate_option (size_t opt_index, const char *arg, int value, generate_option (size_t opt_index, const char *arg, HOST_WIDE_INT value,
unsigned int lang_mask, struct cl_decoded_option *decoded) unsigned int lang_mask, struct cl_decoded_option *decoded)
{ {
const struct cl_option *option = &cl_options[opt_index]; const struct cl_option *option = &cl_options[opt_index];
@ -1167,8 +1245,13 @@ cmdline_handle_error (location_t loc, const struct cl_option *option,
if (errors & CL_ERR_UINT_ARG) if (errors & CL_ERR_UINT_ARG)
{ {
error_at (loc, "argument to %qs should be a non-negative integer", if (option->cl_byte_size)
option->opt_text); error_at (loc, "argument to %qs should be a non-negative integer "
"optionally followed by a size unit",
option->opt_text);
else
error_at (loc, "argument to %qs should be a non-negative integer",
option->opt_text);
return true; return true;
} }
@ -1274,7 +1357,7 @@ read_cmdline_option (struct gcc_options *opts,
void void
set_option (struct gcc_options *opts, struct gcc_options *opts_set, set_option (struct gcc_options *opts, struct gcc_options *opts_set,
int opt_index, int value, const char *arg, int kind, int opt_index, HOST_WIDE_INT value, const char *arg, int kind,
location_t loc, diagnostic_context *dc) location_t loc, diagnostic_context *dc)
{ {
const struct cl_option *option = &cl_options[opt_index]; const struct cl_option *option = &cl_options[opt_index];
@ -1293,22 +1376,54 @@ set_option (struct gcc_options *opts, struct gcc_options *opts_set,
switch (option->var_type) switch (option->var_type)
{ {
case CLVC_BOOLEAN: case CLVC_BOOLEAN:
*(int *) flag_var = value; if (option->cl_host_wide_int)
if (set_flag_var) {
*(int *) set_flag_var = 1; *(HOST_WIDE_INT *) flag_var = value;
if (set_flag_var)
*(HOST_WIDE_INT *) set_flag_var = 1;
}
else
{
*(int *) flag_var = value;
if (set_flag_var)
*(int *) set_flag_var = 1;
}
break;
case CLVC_SIZE:
if (option->cl_host_wide_int)
{
*(HOST_WIDE_INT *) flag_var = value;
if (set_flag_var)
*(HOST_WIDE_INT *) set_flag_var = value;
}
else
{
*(int *) flag_var = value;
if (set_flag_var)
*(int *) set_flag_var = value;
}
break; break;
case CLVC_EQUAL: case CLVC_EQUAL:
if (option->cl_host_wide_int) if (option->cl_host_wide_int)
*(HOST_WIDE_INT *) flag_var = (value {
? option->var_value *(HOST_WIDE_INT *) flag_var = (value
: !option->var_value); ? option->var_value
: !option->var_value);
if (set_flag_var)
*(HOST_WIDE_INT *) set_flag_var = 1;
}
else else
*(int *) flag_var = (value {
? option->var_value *(int *) flag_var = (value
: !option->var_value); ? option->var_value
if (set_flag_var) : !option->var_value);
*(int *) set_flag_var = 1; if (set_flag_var)
*(int *) set_flag_var = 1;
}
break; break;
case CLVC_BIT_CLEAR: case CLVC_BIT_CLEAR:
@ -1395,7 +1510,10 @@ option_enabled (int opt_idx, void *opts)
switch (option->var_type) switch (option->var_type)
{ {
case CLVC_BOOLEAN: case CLVC_BOOLEAN:
return *(int *) flag_var != 0; if (option->cl_host_wide_int)
return *(HOST_WIDE_INT *) flag_var != 0;
else
return *(int *) flag_var != 0;
case CLVC_EQUAL: case CLVC_EQUAL:
if (option->cl_host_wide_int) if (option->cl_host_wide_int)
@ -1415,6 +1533,12 @@ option_enabled (int opt_idx, void *opts)
else else
return (*(int *) flag_var & option->var_value) != 0; return (*(int *) flag_var & option->var_value) != 0;
case CLVC_SIZE:
if (option->cl_host_wide_int)
return *(HOST_WIDE_INT *) flag_var != -1;
else
return *(int *) flag_var != -1;
case CLVC_STRING: case CLVC_STRING:
case CLVC_ENUM: case CLVC_ENUM:
case CLVC_DEFER: case CLVC_DEFER:
@ -1439,6 +1563,7 @@ get_option_state (struct gcc_options *opts, int option,
{ {
case CLVC_BOOLEAN: case CLVC_BOOLEAN:
case CLVC_EQUAL: case CLVC_EQUAL:
case CLVC_SIZE:
state->data = flag_var; state->data = flag_var;
state->size = (cl_options[option].cl_host_wide_int state->size = (cl_options[option].cl_host_wide_int
? sizeof (HOST_WIDE_INT) ? sizeof (HOST_WIDE_INT)
@ -1503,9 +1628,11 @@ control_warning_option (unsigned int opt_index, int kind, const char *arg,
const struct cl_option *option = &cl_options[opt_index]; const struct cl_option *option = &cl_options[opt_index];
/* -Werror=foo implies -Wfoo. */ /* -Werror=foo implies -Wfoo. */
if (option->var_type == CLVC_BOOLEAN || option->var_type == CLVC_ENUM) if (option->var_type == CLVC_BOOLEAN
|| option->var_type == CLVC_ENUM
|| option->var_type == CLVC_SIZE)
{ {
int value = 1; HOST_WIDE_INT value = 1;
if (arg && *arg == '\0' && !option->cl_missing_ok) if (arg && *arg == '\0' && !option->cl_missing_ok)
arg = NULL; arg = NULL;
@ -1517,11 +1644,13 @@ control_warning_option (unsigned int opt_index, int kind, const char *arg,
return; return;
} }
/* If the switch takes an integer, convert it. */ /* If the switch takes an integer argument, convert it. */
if (arg && option->cl_uinteger) if (arg && (option->cl_uinteger || option->cl_host_wide_int))
{ {
value = integral_argument (arg); int error = 0;
if (value == -1) value = *arg ? integral_argument (arg, &error,
option->cl_byte_size) : 0;
if (error)
{ {
cmdline_handle_error (loc, option, option->opt_text, arg, cmdline_handle_error (loc, option, option->opt_text, arg,
CL_ERR_UINT_ARG, lang_mask); CL_ERR_UINT_ARG, lang_mask);

View file

@ -1844,7 +1844,7 @@ common_handle_option (struct gcc_options *opts,
{ {
size_t scode = decoded->opt_index; size_t scode = decoded->opt_index;
const char *arg = decoded->arg; const char *arg = decoded->arg;
int value = decoded->value; HOST_WIDE_INT value = decoded->value;
enum opt_code code = (enum opt_code) scode; enum opt_code code = (enum opt_code) scode;
gcc_assert (decoded->canonical_option_num_elements <= 2); gcc_assert (decoded->canonical_option_num_elements <= 2);
@ -2107,22 +2107,11 @@ common_handle_option (struct gcc_options *opts,
opts, opts_set, loc, dc); opts, opts_set, loc, dc);
break; break;
case OPT_Wlarger_than_:
opts->x_larger_than_size = value;
opts->x_warn_larger_than = value != -1;
break;
case OPT_Wfatal_errors: case OPT_Wfatal_errors:
dc->fatal_errors = value; dc->fatal_errors = value;
break; break;
case OPT_Wframe_larger_than_:
opts->x_frame_larger_than_size = value;
opts->x_warn_frame_larger_than = value != -1;
break;
case OPT_Wstack_usage_: case OPT_Wstack_usage_:
opts->x_warn_stack_usage = value;
opts->x_flag_stack_usage_info = value != -1; opts->x_flag_stack_usage_info = value != -1;
break; break;
@ -2282,7 +2271,7 @@ common_handle_option (struct gcc_options *opts,
case OPT_fpack_struct_: case OPT_fpack_struct_:
if (value <= 0 || (value & (value - 1)) || value > 16) if (value <= 0 || (value & (value - 1)) || value > 16)
error_at (loc, error_at (loc,
"structure alignment must be a small power of two, not %d", "structure alignment must be a small power of two, not %wu",
value); value);
else else
opts->x_initial_max_fld_align = value; opts->x_initial_max_fld_align = value;
@ -2465,7 +2454,7 @@ common_handle_option (struct gcc_options *opts,
/* FALLTHRU */ /* FALLTHRU */
case OPT_gdwarf_: case OPT_gdwarf_:
if (value < 2 || value > 5) if (value < 2 || value > 5)
error_at (loc, "dwarf version %d is not supported", value); error_at (loc, "dwarf version %wu is not supported", value);
else else
opts->x_dwarf_version = value; opts->x_dwarf_version = value;
set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc); set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);

View file

@ -36,6 +36,9 @@ enum cl_var_type {
/* The switch is enabled when VAR_VALUE is set in FLAG_VAR. */ /* The switch is enabled when VAR_VALUE is set in FLAG_VAR. */
CLVC_BIT_SET, CLVC_BIT_SET,
/* The switch is enabled when FLAG_VAR is less than HOST_WIDE_INT_M1U. */
CLVC_SIZE,
/* The switch takes a string argument and FLAG_VAR points to that /* The switch takes a string argument and FLAG_VAR points to that
argument. */ argument. */
CLVC_STRING, CLVC_STRING,
@ -70,7 +73,10 @@ struct cl_option
unsigned short back_chain; unsigned short back_chain;
/* Option length, not including initial '-'. */ /* Option length, not including initial '-'. */
unsigned char opt_len; unsigned char opt_len;
/* Next option in a sequence marked with Negative, or -1 if none. */ /* Next option in a sequence marked with Negative, or -1 if none.
For a single option with both a negative and a positve form
(such as -Wall and -Wno-all), NEG_IDX is equal to the option's
own index (i.e., cl_options[IDX].neg_idx == IDX holds). */
int neg_index; int neg_index;
/* CL_* flags for this option. */ /* CL_* flags for this option. */
unsigned int flags; unsigned int flags;
@ -102,6 +108,8 @@ struct cl_option
BOOL_BITFIELD cl_report : 1; BOOL_BITFIELD cl_report : 1;
/* Deprecated option */ /* Deprecated option */
BOOL_BITFIELD cl_deprecated: 1; BOOL_BITFIELD cl_deprecated: 1;
/* Argument is an unsigned integer with an optional byte suffix. */
BOOL_BITFIELD cl_byte_size: 1;
/* Offset of field for this option in struct gcc_options, or /* Offset of field for this option in struct gcc_options, or
(unsigned short) -1 if none. */ (unsigned short) -1 if none. */
unsigned short flag_var_offset; unsigned short flag_var_offset;
@ -247,7 +255,7 @@ struct cl_decoded_option
/* For a boolean option, 1 for the true case and 0 for the "no-" /* For a boolean option, 1 for the true case and 0 for the "no-"
case. For an unsigned integer option, the value of the case. For an unsigned integer option, the value of the
argument. 1 in all other cases. */ argument. 1 in all other cases. */
int value; HOST_WIDE_INT value;
/* Any flags describing errors detected in this option. */ /* Any flags describing errors detected in this option. */
int errors; int errors;
@ -327,7 +335,7 @@ extern char *opts_concat (const char *first, ...);
extern struct obstack opts_obstack; extern struct obstack opts_obstack;
size_t find_opt (const char *input, unsigned int lang_mask); size_t find_opt (const char *input, unsigned int lang_mask);
extern int integral_argument (const char *arg); extern HOST_WIDE_INT integral_argument (const char *arg, int * = NULL, bool = false);
extern bool enum_value_to_arg (const struct cl_enum_arg *enum_args, extern bool enum_value_to_arg (const struct cl_enum_arg *enum_args,
const char **argp, int value, const char **argp, int value,
unsigned int lang_mask); unsigned int lang_mask);
@ -359,16 +367,17 @@ extern bool get_option_state (struct gcc_options *, int,
struct cl_option_state *); struct cl_option_state *);
extern void set_option (struct gcc_options *opts, extern void set_option (struct gcc_options *opts,
struct gcc_options *opts_set, struct gcc_options *opts_set,
int opt_index, int value, const char *arg, int kind, int opt_index, HOST_WIDE_INT value, const char *arg,
location_t loc, diagnostic_context *dc); int kind, location_t loc, diagnostic_context *dc);
extern void *option_flag_var (int opt_index, struct gcc_options *opts); extern void *option_flag_var (int opt_index, struct gcc_options *opts);
bool handle_generated_option (struct gcc_options *opts, bool handle_generated_option (struct gcc_options *opts,
struct gcc_options *opts_set, struct gcc_options *opts_set,
size_t opt_index, const char *arg, int value, size_t opt_index, const char *arg,
HOST_WIDE_INT value,
unsigned int lang_mask, int kind, location_t loc, unsigned int lang_mask, int kind, location_t loc,
const struct cl_option_handlers *handlers, const struct cl_option_handlers *handlers,
bool generated_p, diagnostic_context *dc); bool generated_p, diagnostic_context *dc);
void generate_option (size_t opt_index, const char *arg, int value, void generate_option (size_t opt_index, const char *arg, HOST_WIDE_INT value,
unsigned int lang_mask, unsigned int lang_mask,
struct cl_decoded_option *decoded); struct cl_decoded_option *decoded);
void generate_option_input_file (const char *file, void generate_option_input_file (const char *file,
@ -425,7 +434,8 @@ extern void set_struct_debug_option (struct gcc_options *opts,
location_t loc, location_t loc,
const char *value); const char *value);
extern bool opt_enum_arg_to_value (size_t opt_index, const char *arg, extern bool opt_enum_arg_to_value (size_t opt_index, const char *arg,
int *value, unsigned int lang_mask); int *value,
unsigned int lang_mask);
extern const struct sanitizer_opts_s extern const struct sanitizer_opts_s
{ {

View file

@ -756,22 +756,19 @@ layout_decl (tree decl, unsigned int known_align)
DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl)); DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));
/* If requested, warn about definitions of large data objects. */ /* If requested, warn about definitions of large data objects. */
if (warn_larger_than if ((code == VAR_DECL || code == PARM_DECL)
&& (code == VAR_DECL || code == PARM_DECL)
&& ! DECL_EXTERNAL (decl)) && ! DECL_EXTERNAL (decl))
{ {
tree size = DECL_SIZE_UNIT (decl); tree size = DECL_SIZE_UNIT (decl);
if (size != 0 && TREE_CODE (size) == INTEGER_CST if (size != 0 && TREE_CODE (size) == INTEGER_CST
&& compare_tree_int (size, larger_than_size) > 0) && compare_tree_int (size, warn_larger_than_size) > 0)
{ {
int size_as_int = TREE_INT_CST_LOW (size); unsigned HOST_WIDE_INT uhwisize = tree_to_uhwi (size);
if (compare_tree_int (size, size_as_int) == 0) warning (OPT_Wlarger_than_, "size of %q+D %wu bytes exceeds "
warning (OPT_Wlarger_than_, "size of %q+D is %d bytes", decl, size_as_int); "maximum object size %wu",
else decl, uhwisize, warn_larger_than_size);
warning (OPT_Wlarger_than_, "size of %q+D is larger than %wd bytes",
decl, larger_than_size);
} }
} }

View file

@ -1,3 +1,18 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
* gcc/testsuite/c-c++-common/pr68657-1.c: Adjust.
* gcc/testsuite/c-c++-common/pr68657-2.c: Same.
* gcc/testsuite/c-c++-common/pr68657-3.c: Same.
* gcc.dg/Walloc-size-larger-than-16.c: Same.
* gcc.dg/Walloca-larger-than.c: New test.
* gcc.dg/Walloca-larger-than-2.c: New test.
* gcc.dg/Wframe-larger-than-2.c: New test.
* gcc.dg/Wlarger-than3.c: New test.
* gcc.dg/Wvla-larger-than-3.c: New test.
* gcc.dg/pr42611.c: Adjust.
* gnat.dg/frame_overflow.adb: Same.
2018-07-20 Martin Sebor <msebor@redhat.com> 2018-07-20 Martin Sebor <msebor@redhat.com>
PR tree-optimization/86613 PR tree-optimization/86613

View file

@ -3,7 +3,7 @@
/* { dg-options "-Werror=larger-than=65536" } */ /* { dg-options "-Werror=larger-than=65536" } */
/* { dg-require-effective-target ptr32plus } */ /* { dg-require-effective-target ptr32plus } */
int a[131072]; /* { dg-error "size of 'a' is \[1-9]\[0-9]* bytes" } */ int a[131072]; /* { dg-error "size of .a. 524288 bytes exceeds maximum object size 65536" } */
int b[1024]; /* { dg-bogus "size of 'b' is \[1-9]\[0-9]* bytes" } */ int b[1024]; /* { dg-bogus "size" } */
/* { dg-prune-output "treated as errors" } */ /* { dg-prune-output "treated as errors" } */

View file

@ -3,12 +3,12 @@
/* { dg-require-effective-target ptr32plus } */ /* { dg-require-effective-target ptr32plus } */
#pragma GCC diagnostic error "-Wlarger-than=65536" #pragma GCC diagnostic error "-Wlarger-than=65536"
int a[131072]; /* { dg-error "size of 'a' is \[1-9]\[0-9]* bytes" } */ int a[131072]; /* { dg-error "size of 'a' \[1-9\]\[0-9\]* bytes exceeds maximum object size 65536" } */
int b[1024]; /* { dg-bogus "size of 'b' is \[1-9]\[0-9]* bytes" } */ int b[1024]; /* { dg-bogus "size" } */
#pragma GCC diagnostic ignored "-Wlarger-than=65536" #pragma GCC diagnostic ignored "-Wlarger-than=65536"
int c[131072]; /* { dg-bogus "size of 'c' is \[1-9]\[0-9]* bytes" } */ int c[131072]; /* { dg-bogus "size" } */
int d[1024]; /* { dg-bogus "size of 'd' is \[1-9]\[0-9]* bytes" } */ int d[1024]; /* { dg-bogus "size" } */
#pragma GCC diagnostic warning "-Wlarger-than=65536" #pragma GCC diagnostic warning "-Wlarger-than=65536"
int e[131072]; /* { dg-warning "size of 'e' is \[1-9]\[0-9]* bytes" } */ int e[131072]; /* { dg-warning "size of 'e' \[1-9\]\[0-9\]* bytes exceeds maximum object size 65536" } */
int f[1024]; /* { dg-bogus "size of 'f' is \[1-9]\[0-9]* bytes" } */ int f[1024]; /* { dg-bogus "size" } */
/* { dg-prune-output "treated as errors" } */ /* { dg-prune-output "treated as errors" } */

View file

@ -1,32 +1,9 @@
/* PR middle-end/82063 - issues with arguments enabled by -Wall /* PR middle-end/82063 - issues with arguments enabled by -Wall
Verify that an invalid argument to -Walloc-size-larger-than is diagnosed.
{ dg-do compile } { dg-do compile }
{ dg-options "-O -Walloc-size-larger-than=1zb -ftrack-macro-expansion=0" } */ { dg-options "-Walloc-size-larger-than=1zb -Walloca-larger-than=2kbytes -Wvla-larger-than=3MIBZ" } */
typedef __SIZE_TYPE__ size_t;
void sink (void*); /* { dg-error "argument to '-Walloc-size-larger-than=' should be a non-negative integer optionally followed by a size unit" "" { target *-*-* } 0 }
{ dg-error "argument to '-Walloca-larger-than=' should be a non-negative integer optionally followed by a size unit" "" { target *-*-* } 0 }
#define T(x) sink (x) { dg-error "argument to '-Wvla-larger-than=' should be a non-negative integer optionally followed by a size unit" "" { target *-*-* } 0 } */
/* Verify that an invalid -Walloc-size-larger-than argument is diagnosed
and rejected without changing the default setting of PTRDIFF_MAX. */
void f (void)
{
size_t n = 0;
T (__builtin_malloc (n));
n = __PTRDIFF_MAX__;
T (__builtin_malloc (n));
n += 1;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__ - 1;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
n = __SIZE_MAX__;
T (__builtin_malloc (n)); /* { dg-warning "exceeds maximum object size" } */
}
/* { dg-warning "invalid argument .1zb. to .-Walloc-size-larger-than=." "" { target *-*-* } 0 } */

View file

@ -0,0 +1,24 @@
/* PR middle-end/82063 - issues with arguments enabled by -Wall
Verify that alloca() calls in loops are not diagnosed by default.
{ dg-do compile }
{ dg-options "-O2 -ftrack-macro-expansion=0" } */
extern void* alloca (__SIZE_TYPE__);
void sink (void*);
#define T(x) sink (x)
void test_alloca (unsigned n)
{
/* Verify that alloca(0) is not diagnosed in a loop either. */
for (unsigned i = 0; i < n; ++i)
T (alloca (0));
/* Verify no warnings for the loops below. */
for (unsigned i = 0; i < n; ++i)
T (alloca (1));
for (unsigned i = 1; i < n; ++i)
T (alloca (n));
}

View file

@ -0,0 +1,26 @@
/* PR middle-end/82063 - issues with arguments enabled by -Wall
{ dg-do compile }
{ dg-options "-O2 -Walloca-larger-than=0 -Wvla-larger-than=0 -ftrack-macro-expansion=0" } */
extern void* alloca (__SIZE_TYPE__);
void sink (void*);
#define T(x) sink (x)
void test_alloca (void)
{
/* Verify that alloca(0) is diagnosed even if the limit is zero. */
T (alloca (0)); /* { dg-warning "argument to .alloca. is zero" } */
T (alloca (1)); /* { dg-warning "argument to .alloca. is too large" } */
}
void test_vla (unsigned n)
{
/* VLAs smaller than 32 bytes are optimized into ordinary arrays. */
if (n < 1 || 99 < n)
n = 1;
char a[n]; /* { dg-warning "argument to variable-length array " } */
T (a);
}

View file

@ -0,0 +1,19 @@
/* Exercise -Wframe-larger-than= with a byte-size suffix.
{ dg-do compile }
{ dg-options "-O -Wframe-larger-than=1KB" } */
extern void f (void*, ...);
void frame_size_912 (void)
{
char a[512];
char b[400];
f (a, b);
}
void frame_size_1025 (void)
{
char a[512];
char b[513];
f (a, b);
} /* { dg-warning "frame size of \[0-9\]+ bytes is larger than 1024 bytes" } */

View file

@ -0,0 +1,12 @@
/* Exercise -Wlarger-than= with a byte-size suffix.
{ dg-do compile }
{ dg-options "-Wlarger-than=1MiB" } */
#define MB (1000 * 1000) /* MegaByte */
#define MiB (1024 * 1024) /* MebiByte */
char megabyte[MB];
char membibyte[MiB];
char megabyte_plus_1[MB + 1];
char membibyte_plus_1[MiB + 1]; /* { dg-warning "size of .membibyte_plus_1. 1048577 bytes exceeds maximum object size 1048576" } */

View file

@ -0,0 +1,68 @@
/* Verify that VLA definitions with an unknown upper bound don't trigger
-Wvla-larger-than= warnings by default.
{ dg-do compile }
{ dg-require-effective-target alloca }
{ dg-options "-O2 -Wall" } */
void f (void *, ...);
void nowarn_vla_int (int n)
{
char a[n];
if (n < 1234)
n = 1234;
char b[n];
f (a, b);
}
void nowarn_vla_uint (unsigned n)
{
char a[n];
f (a);
if (n < 2345)
n = 2345;
char b[n];
f (a, b);
}
void nowarn_vla_long (long n)
{
char a[n];
if (n < 1234)
n = 1234;
char b[n];
f (a, b);
}
void nowarn_vla_ulong (unsigned long n)
{
char a[n];
f (a);
if (n < 2345)
n = 2345;
char b[n];
f (a, b);
}
/* Verify that a VLA whose size is definitely in excess of PTRDIFF_MAX
is diagnosed by default. */
void warn_vla (__PTRDIFF_TYPE__ n)
{
int a[n];
f (a);
if (n <= __PTRDIFF_MAX__)
n = __PTRDIFF_MAX__;
int b[n]; /* { dg-warning "argument to variable-length array is too large" } */
f (a, b);
}

View file

@ -14,6 +14,6 @@ struct S { int a; char b[L]; }; /* { dg-error "type .struct S. is too large" } *
void void
foo (void) foo (void)
{ {
struct S s; struct S s; /* { dg-warning "size of .s. \[0-9\]+ bytes exceeds maximum object size \[0-9\]+" } */
asm volatile ("" : : "r" (&s)); asm volatile ("" : : "r" (&s));
} }

View file

@ -2,7 +2,7 @@
package body Frame_Overflow is package body Frame_Overflow is
function -- { dg-error "too large" } function -- { dg-error "exceeds" }
Set_In (Bitmap : Bitmap_T; Bitpos : Bitpos_Range_T) return Bitmap_T Set_In (Bitmap : Bitmap_T; Bitpos : Bitpos_Range_T) return Bitmap_T
is is
Result: Bitmap_T := Bitmap; Result: Bitmap_T := Bitmap;
@ -11,7 +11,7 @@ package body Frame_Overflow is
return Result; return Result;
end; end;
function -- { dg-error "too large" } function -- { dg-error "exceeds" }
Negate (Bitmap : Bitmap_T) return Bitmap_T Negate (Bitmap : Bitmap_T) return Bitmap_T
is is
Result: Bitmap_T; Result: Bitmap_T;

View file

@ -1024,7 +1024,7 @@ output_stack_usage (void)
stack_usage_kind_str[stack_usage_kind]); stack_usage_kind_str[stack_usage_kind]);
} }
if (warn_stack_usage >= 0) if (warn_stack_usage >= 0 && warn_stack_usage < HOST_WIDE_INT_MAX)
{ {
const location_t loc = DECL_SOURCE_LOCATION (current_function_decl); const location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
@ -1034,10 +1034,10 @@ output_stack_usage (void)
{ {
if (stack_usage_kind == DYNAMIC_BOUNDED) if (stack_usage_kind == DYNAMIC_BOUNDED)
warning_at (loc, warning_at (loc,
OPT_Wstack_usage_, "stack usage might be %wd bytes", OPT_Wstack_usage_, "stack usage might be %wu bytes",
stack_usage); stack_usage);
else else
warning_at (loc, OPT_Wstack_usage_, "stack usage is %wd bytes", warning_at (loc, OPT_Wstack_usage_, "stack usage is %wu bytes",
stack_usage); stack_usage);
} }
} }