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>
* 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>
* 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. */
static bool
gnat_handle_option (size_t scode, const char *arg, int value, int kind,
location_t loc, const struct cl_option_handlers *handlers)
gnat_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
int kind, location_t loc,
const struct cl_option_handlers *handlers)
{
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>
PR hsa/86371

View file

@ -145,7 +145,7 @@ brig_langhook_init_options_struct (struct gcc_options *opts)
static bool
brig_langhook_handle_option
(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,
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{

View file

@ -5093,13 +5093,20 @@ expand_builtin_alloca (tree exp)
if (!valid_arglist)
return NULL_RTX;
if ((alloca_for_var && !warn_vla_limit)
|| (!alloca_for_var && !warn_alloca_limit))
if ((alloca_for_var
&& 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
the more general -Walloc-size-larger-than so unless either of
the former options is specified check the alloca arguments for
overflow. */
/* -Walloca-larger-than and -Wvla-larger-than settings of
less than HOST_WIDE_INT_MAX override the more general
-Walloc-size-larger-than so unless either of the former
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 };
int idx[] = { 0, -1 };
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>
* 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 tree handle_format_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 *);
extern bool default_handle_c_option (size_t, const char *, 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
invalid, true if valid. Use HANDLERS in recursive handle_option calls. */
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,
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;
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:
/* Set to greater than 1, so that even unknown pragmas in
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.
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
attempt to allocate objects larger than the specified number of bytes.
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.
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.
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
alloca, and on bounded uses of alloca whose bound can be larger than
<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
LangEnabledBy(C ObjC C++ LTO ObjC++,Wall)
; 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.
Wvla-larger-than=
C ObjC C++ ObjC++ Var(warn_vla_limit) Warning Joined RejectNegative UInteger
-Wvla-larger-than=<number> Warn on unbounded uses of variable-length arrays, and
on bounded uses of variable-length arrays whose bound can be
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 on bounded uses of variable-length arrays whose bound can be
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
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)
return alloc_object_size_limit;
alloc_object_size_limit = max_object_size ();
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);
}
alloc_object_size_limit
= build_int_cst (size_type_node, warn_alloc_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
return a value (usually of some struct or union type) which itself will
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));
if (ret_type && TYPE_SIZE_UNIT (ret_type)
&& TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
&& compare_tree_int (TYPE_SIZE_UNIT (ret_type),
larger_than_size) > 0)
warn_larger_than_size) > 0)
{
unsigned int size_as_int
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
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);
else
warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes",
decl, larger_than_size);
warning (OPT_Wlarger_than_,
"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
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.
Variable
int flag_gen_aux_info = 0
@ -613,8 +596,8 @@ Common Var(flag_fatal_errors)
Exit on the first error occurred.
Wframe-larger-than=
Common RejectNegative Joined UInteger Warning
-Wframe-larger-than=<number> Warn if a function's stack frame requires more than <number> bytes.
Common RejectNegative Joined Host_Wide_Int ByteSize Warning Var(warn_frame_larger_than_size) Init(HOST_WIDE_INT_MAX)
-Wframe-larger-than=<byte-size> Warn if a function's stack frame requires in excess of <byte-size>.
Wfree-nonheap-object
Common Var(warn_free_nonheap_object) Init(1) Warning
@ -643,8 +626,8 @@ Wlarger-than-
Common RejectNegative Joined Warning Undocumented Alias(Wlarger-than=)
Wlarger-than=
Common RejectNegative Joined UInteger Warning
-Wlarger-than=<number> Warn if an object is larger than <number> bytes.
Common RejectNegative Joined Host_Wide_Int ByteSize Warning Var(warn_larger_than_size) Init(HOST_WIDE_INT_MAX)
-Wlarger-than=<byte-size> Warn if an object's size exceeds <byte-size>.
Wnonnull-compare
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.
Wstack-usage=
Common Joined RejectNegative UInteger Var(warn_stack_usage) Warning
-Wstack-usage=<number> Warn if stack usage might be larger than specified amount.
Common Joined RejectNegative Host_Wide_Int ByteSize Var(warn_stack_usage) Warning Init(HOST_WIDE_INT_MAX)
-Wstack-usage=<byte-size> Warn if stack usage might exceed <byte-size>.
Wstrict-aliasing
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
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
@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
-pedantic-errors @gol
-w -Wextra -Wall -Waddress -Waggregate-return @gol
-Walloc-zero -Walloc-size-larger-than=@var{n}
-Walloca -Walloca-larger-than=@var{n} @gol
-Walloc-zero -Walloc-size-larger-than=@var{byte-size}
-Walloca -Walloca-larger-than=@var{byte-size} @gol
-Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
-Wno-attributes -Wbool-compare -Wbool-operation @gol
-Wno-builtin-declaration-mismatch @gol
@ -285,14 +300,15 @@ Objective-C and Objective-C++ Dialects}.
-Wformat-nonliteral -Wformat-overflow=@var{n} @gol
-Wformat-security -Wformat-signedness -Wformat-truncation=@var{n} @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
-Wignored-qualifiers -Wignored-attributes -Wincompatible-pointer-types @gol
-Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n} @gol
-Wimplicit-function-declaration -Wimplicit-int @gol
-Winit-self -Winline -Wno-int-conversion -Wint-in-bool-context @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
-Wmain -Wmaybe-uninitialized -Wmemset-elt-size -Wmemset-transposed-args @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
-Wno-scalar-storage-order -Wsizeof-pointer-div @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
-Wstringop-overflow=@var{n} -Wstringop-truncation @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-but-set-parameter -Wunused-but-set-variable @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}
@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
portability bugs and should be avoided.
@item -Walloc-size-larger-than=@var{n}
@opindex Walloc-size-larger-than=@var{n}
@item -Walloc-size-larger-than=@var{byte-size}
@opindex Walloc-size-larger-than=
@opindex Wno-alloc-size-larger-than
Warn about calls to functions decorated with attribute @code{alloc_size}
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
precision would exceed @code{SIZE_MAX / 2}. The option argument @var{n} is
treated as an integer with infinite precision and may end in one of
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.
precision would exceed the value of @samp{PTRDIFF_MAX} on the target.
@option{-Walloc-size-larger-than=}@samp{PTRDIFF_MAX} is enabled by default.
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}.
@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
@opindex Wno-alloca
@opindex Walloca
This option warns on all uses of @code{alloca} in the source.
@item -Walloca-larger-than=@var{n}
This option warns on calls to @code{alloca} that are not bounded by a
controlling predicate limiting its argument of integer type to at most
@var{n} bytes, or calls to @code{alloca} where the bound is unknown.
Arguments of non-integer types are considered unbounded even if they
appear to be constrained to the expected range.
@item -Walloca-larger-than=@var{byte-size}
@opindex -Walloca-larger-than=
@opindex -Wno-alloca-larger-than
This option warns on calls to @code{alloca} with an integer argument whose
value is either zero, or that is not bounded by a controlling predicate
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:
@ -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 warning is not enabled by @option{-Wall}, and is only active when
@option{-ftree-vrp} is active (default for @option{-O2} and above).
@option{-Walloca-larger-than=}@samp{PTRDIFF_MAX} is enabled by default
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
@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}.
@item -Wlarger-than=@var{len}
@opindex Wlarger-than=@var{len}
@opindex Wlarger-than-@var{len}
Warn whenever an object of larger than @var{len} bytes is defined.
@item -Wlarger-than=@var{byte-size}
@opindex Wlarger-than=
@opindex Wlarger-than-@var{byte-size}
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}
@opindex Wframe-larger-than=@var{len}
@opindex Wframe-larger-than
Warn if the size of a function frame is larger than @var{len} bytes.
@item -Wno-larger-than
@opindex Wno-larger-than
Disable @option{-Wlarger-than=} warnings. The option is equivalent
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
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
via @code{alloca}, variable-length arrays, or related constructs
is not included by the compiler when determining
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
@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
on the heap.
@item -Wstack-usage=@var{len}
@item -Wstack-usage=@var{byte-size}
@opindex Wstack-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.
Any space allocated via @code{alloca}, variable-length arrays, or related
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 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)}
@opindex Wno-pedantic-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
the variable-length array.
@item -Wvla-larger-than=@var{n}
If this option is used, the compiler will warn on uses of
variable-length arrays where the size is either unbounded, or bounded
by an argument that can be larger than @var{n} bytes. This is similar
to how @option{-Walloca-larger-than=@var{n}} works, but with
variable-length arrays.
@item -Wvla-larger-than=@var{byte-size}
@opindex -Wvla-larger-than=
@opindex -Wno-vla-larger-than
If this option is used, the compiler will warn for declarations of
variable-length arrays whose size is either unbounded, or bounded
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
value into plain arrays, so this warning may not get triggered for
such arrays.
This warning is not enabled by @option{-Wall}, and is only active when
@option{-ftree-vrp} is active (default for @option{-O2} and above).
@option{-Wvla-larger-than=}@samp{PTRDIFF_MAX} is enabled by default but
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
@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.
@item UInteger
The option's argument is a non-negative integer. The option parser
will check and convert the argument before passing it to the relevant
option handler. @code{UInteger} should also be used on 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.
The option's argument is a non-negative integer consisting of either
decimal or hexadecimal digits interpreted as @code{int}. 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{UInteger} should also be used
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})
The options's arguments are integer numbers. The option's parser
will check that value of an option is inclusively within the
range [@var{n}, @var{m}].
The options's arguments are integers of type @code{int}. The option's
parser validates that the value of an option integer argument is within
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
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;
}
HOST_WIDE_INT min_frame_size = constant_lower_bound (get_frame_size ());
if (warn_frame_larger_than
&& min_frame_size > frame_larger_than_size)
unsigned HOST_WIDE_INT min_frame_size
= constant_lower_bound (get_frame_size ());
if (min_frame_size > (unsigned HOST_WIDE_INT) warn_frame_larger_than_size)
{
/* Issue a warning */
warning (OPT_Wframe_larger_than_,
"the frame size of %wd bytes is larger than %wd bytes",
min_frame_size, frame_larger_than_size);
"the frame size of %wu bytes is larger than %wu bytes",
min_frame_size, warn_frame_larger_than_size);
}
/* 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>
* 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 (unsigned int,
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 *);
bool gfc_post_options (const char **);
char *gfc_get_option_string (void);

View file

@ -585,7 +585,7 @@ gfc_handle_runtime_check_option (const char *arg)
recognized and handled. */
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,
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))
{
error_at (DECL_SOURCE_LOCATION (func),
"total size of local objects too large");
unsigned HOST_WIDE_INT hwisize;
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;
}

View file

@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa.h"
#include "params.h"
#include "tree-cfg.h"
#include "builtins.h"
#include "calls.h"
#include "cfgloop.h"
#include "intl.h"
@ -78,8 +79,10 @@ pass_walloca::gate (function *fun ATTRIBUTE_UNUSED)
if (first_time_p)
return warn_alloca != 0;
return ((unsigned HOST_WIDE_INT) warn_alloca_limit > 0
|| (unsigned HOST_WIDE_INT) warn_vla_limit > 0);
// Warning is disabled when its size limit is greater than PTRDIFF_MAX
// 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.
@ -150,13 +153,25 @@ struct alloca_type_and_limit {
// in bytes we allow for arg.
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;
gimple_stmt_iterator gsi = gsi_last_bb (bb);
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)
return alloca_type_and_limit (ALLOCA_UNBOUNDED);
{
return alloca_type_and_limit (unbounded_result);
}
enum tree_code cond_code = gimple_cond_code (last);
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)
cond_code = invert_tree_comparison (cond_code, false);
else
return alloca_type_and_limit (ALLOCA_UNBOUNDED);
return alloca_type_and_limit (unbounded_result);
// Check for:
// 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
// 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.
@ -281,16 +296,16 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
edge_iterator ei;
edge e;
gcc_assert (!is_vla || (unsigned HOST_WIDE_INT) warn_vla_limit > 0);
gcc_assert (is_vla || (unsigned HOST_WIDE_INT) warn_alloca_limit > 0);
gcc_assert (!is_vla || warn_vla_limit >= 0);
gcc_assert (is_vla || warn_alloca_limit >= 0);
// Adjust warn_alloca_max_size for VLAs, by taking the underlying
// type into account.
unsigned HOST_WIDE_INT max_size;
if (is_vla)
max_size = (unsigned HOST_WIDE_INT) warn_vla_limit;
max_size = warn_vla_limit;
else
max_size = (unsigned HOST_WIDE_INT) warn_alloca_limit;
max_size = warn_alloca_limit;
// Check for the obviously bounded case.
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,
wi::to_wide (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);
}
@ -357,8 +378,15 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
}
else if (range_type == VR_ANTI_RANGE)
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)
@ -414,8 +442,13 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
if (compare_tree_int (arg, max_size) <= 0)
ret = alloca_type_and_limit (ALLOCA_OK);
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;
@ -452,16 +485,18 @@ pass_walloca::execute (function *fun)
// Strict mode whining for VLAs is handled by the front-end,
// so we can safely ignore this case. Also, ignore VLAs if
// the user doesn't care about them.
if (is_vla
&& (warn_vla > 0 || !warn_vla_limit))
continue;
if (!is_vla && (warn_alloca || !warn_alloca_limit))
if (is_vla)
{
if (warn_alloca)
warning_at (loc, OPT_Walloca, G_("use of %<alloca%>"));
if (warn_vla > 0 || warn_vla_limit < 0)
continue;
}
else if (warn_alloca)
{
warning_at (loc, OPT_Walloca, G_("use of %<alloca%>"));
continue;
}
else if (warn_alloca_limit < 0)
continue;
tree invalid_casted_type = NULL;
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
// up when they go out of scope, including in a loop.
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
= is_vla ? OPT_Wvla_larger_than_ : OPT_Walloca_larger_than_;
@ -488,7 +531,7 @@ pass_walloca::execute (function *fun)
&& t.limit != 0)
{
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"),
is_vla ? warn_vla_limit : warn_alloca_limit, buff);
}
@ -501,7 +544,7 @@ pass_walloca::execute (function *fun)
&& t.limit != 0)
{
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);
}
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>
PR go/86343

View file

@ -194,7 +194,7 @@ static bool
go_langhook_handle_option (
size_t scode,
const char *arg,
int value,
HOST_WIDE_INT value,
int kind ATTRIBUTE_UNUSED,
location_t loc 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,
struct cl_decoded_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,
const struct cl_option_handlers *);
extern bool lhd_handle_option (size_t, const char *, HOST_WIDE_INT, int,
location_t, const struct cl_option_handlers *);
/* Declarations for tree gimplification hooks. */

View file

@ -353,7 +353,8 @@ lhd_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
bool
lhd_handle_option (size_t code 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,
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
{

View file

@ -348,8 +348,8 @@ struct lang_hooks
location of the option.
Return true if the switch is valid, false if invalid. */
bool (*handle_option) (size_t code, const char *arg, int value, int kind,
location_t loc,
bool (*handle_option) (size_t code, const char *arg, HOST_WIDE_INT value,
int kind, location_t loc,
const struct cl_option_handlers *handlers);
/* 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>
PR debug/86585

View file

@ -827,7 +827,8 @@ lto_init_options_struct (struct gcc_options *opts)
const char *resolution_file_name;
static bool
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,
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.
function switch_bit_fields (flags)
{
uinteger_flag = ""
vn = var_name(flags);
if (host_wide_int[vn] == "yes")
hwi = "Host_Wide_Int"
else if (flag_set_p("Host_Wide_Int", flags)) {
hwi = "Host_Wide_Int"
uinteger_flag = flag_init("UInteger", flags)
}
else
hwi = ""
result = ""
@ -126,6 +131,20 @@ function switch_bit_fields (flags)
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 \
flag_init("SeparateAlias", flags) \
flag_init("NegativeAlias", flags) \
@ -133,11 +152,12 @@ function switch_bit_fields (flags)
flag_init("RejectDriver", flags) \
flag_init("RejectNegative", flags) \
flag_init("JoinedOrMissing", flags) \
flag_init("UInteger", flags) \
flag_init("Host_Wide_Int", hwi) \
uinteger_flag \
hwi_flag \
flag_init("ToLower", flags) \
flag_init("Report", flags) \
flag_init("Deprecated", flags)
flag_init("Deprecated", flags) \
byte_size_flag
sub(", $", "", result)
return result
@ -200,6 +220,8 @@ function var_type(flags)
}
else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags))
return "int "
else if (flag_set_p("Host_Wide_Int", flags))
return "HOST_WIDE_INT "
else if (flag_set_p("UInteger", flags))
return "int "
else
@ -211,8 +233,13 @@ function var_type(flags)
# type instead of int to save space.
function var_type_struct(flags)
{
if (flag_set_p("UInteger", flags))
return "int "
if (flag_set_p("UInteger", flags)) {
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)) {
en = opt_args("Enum", flags);
return enum_type[en] " "
@ -222,7 +249,7 @@ function var_type_struct(flags)
if (host_wide_int[var_name(flags)] == "yes")
return "HOST_WIDE_INT "
else
return "int "
return "/* - */ int "
}
else
return "signed char "
@ -262,6 +289,8 @@ function var_set(flags)
}
if (var_type(flags) == "const char *")
return "0, CLVC_STRING, 0"
if (flag_set_p("ByteSize", flags))
return "0, CLVC_SIZE, 0"
return "0, CLVC_BOOLEAN, 0"
}

View file

@ -274,6 +274,7 @@ for (i = 0; i < n_opts; i++) {
j++;
}
optindex = 0
for (i = 0; i < n_opts; i++) {
# With identical flags, pick only the last one. The
# earlier loop ensured that it has all flags merged,
@ -303,20 +304,20 @@ for (i = 0; i < n_opts; i++) {
comma = ""
if (help[i] == "")
hlp = "0"
hlp = "NULL"
else
hlp = quote help[i] quote;
missing_arg_error = opt_args("MissingArgError", flags[i])
if (missing_arg_error == "")
missing_arg_error = "0"
missing_arg_error = "NULL"
else
missing_arg_error = quote missing_arg_error quote
warn_message = opt_args("Warn", flags[i])
if (warn_message == "")
warn_message = "0"
warn_message = "NULL"
else
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
# 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,
alias_data, back_chain[i], len)
printf(" %d,\n", idx)
printf(" /* .neg_idx = */ %d,\n", idx)
condition = opt_args("Condition", flags[i])
cl_flags = switch_flags(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]),
var_set(flags[i]), integer_range_info(opt_args("IntegerRange", flags[i]),
opt_args("Init", flags[i]), opts[i]), comma)
}
# Bump up the informational option index.
++optindex
}
print "};"
@ -417,7 +422,7 @@ print " const struct cl_option_handlers *handlers, "
print " diagnostic_context *dc) "
print "{ "
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 " "
print " gcc_assert (decoded->canonical_option_num_elements <= 2); "
@ -467,7 +472,7 @@ for (i = 0; i < n_langs; i++) {
print "bool "
print lang_name "_handle_option_auto (struct gcc_options *opts" 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 " location_t loc" mark_unused ", "
print " const struct cl_option_handlers *handlers" mark_unused ", "

View file

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

View file

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

View file

@ -169,32 +169,95 @@ find_opt (const char *input, unsigned int lang_mask)
return match_wrong_lang;
}
/* If ARG is a non-negative decimal or hexadecimal integer, return its
value, otherwise return -1. */
/* If ARG is a non-negative decimal or hexadecimal integer representable
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
integral_argument (const char *arg)
HOST_WIDE_INT
integral_argument (const char *arg, int *err, bool byte_size_suffix)
{
const char *p = arg;
if (!err)
err = &errno;
while (*p && ISDIGIT (*p))
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'))
if (!ISDIGIT (*arg))
{
p = arg + 2;
while (*p && ISXDIGIT (*p))
p++;
if (p != arg + 2 && *p == '\0')
return strtol (arg, NULL, 16);
*err = EINVAL;
return -1;
}
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
@ -230,7 +293,8 @@ enum_arg_ok_for_language (const struct cl_enum_arg *enum_arg,
static bool
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;
@ -250,15 +314,22 @@ enum_arg_to_value (const struct cl_enum_arg *enum_args,
and returning false without modifying *VALUE if not found. */
bool
opt_enum_arg_to_value (size_t opt_index, const char *arg, int *value,
unsigned int lang_mask)
opt_enum_arg_to_value (size_t opt_index, const char *arg,
int *value, unsigned int lang_mask)
{
const struct cl_option *option = &cl_options[opt_index];
gcc_assert (option->var_type == CLVC_ENUM);
return enum_arg_to_value (cl_enums[option->var_enum].values, arg,
value, lang_mask);
HOST_WIDE_INT wideval;
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
@ -299,7 +370,8 @@ enum_value_to_arg (const struct cl_enum_arg *enum_args,
described by OPT_INDEX, ARG and VALUE. */
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)
{
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;
const char *arg = 0;
int value = 1;
HOST_WIDE_INT value = 1;
unsigned int result = 1, i, extra_args, separate_args = 0;
int adjust_len = 0;
size_t total_len;
@ -520,6 +592,11 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
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;
warn_message = option->warn_message;
@ -684,11 +761,12 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
arg = arg_lower;
}
/* If the switch takes an integer, convert it. */
if (arg && option->cl_uinteger)
/* If the switch takes an integer argument, convert it. */
if (arg && (option->cl_uinteger || option->cl_host_wide_int))
{
value = integral_argument (arg);
if (value == -1)
int error = 0;
value = *arg ? integral_argument (arg, &error, option->cl_byte_size) : 0;
if (error)
errors |= CL_ERR_UINT_ARG;
/* Reject value out of a range. */
@ -1008,7 +1086,7 @@ handle_option (struct gcc_options *opts,
{
size_t opt_index = decoded->opt_index;
const char *arg = decoded->arg;
int value = decoded->value;
HOST_WIDE_INT value = decoded->value;
const struct cl_option *option = &cl_options[opt_index];
void *flag_var = option_flag_var (opt_index, opts);
size_t i;
@ -1038,7 +1116,7 @@ handle_option (struct gcc_options *opts,
bool
handle_generated_option (struct gcc_options *opts,
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,
const struct cl_option_handlers *handlers,
bool generated_p, diagnostic_context *dc)
@ -1055,7 +1133,7 @@ handle_generated_option (struct gcc_options *opts,
compiler generates options internally. */
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)
{
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)
{
error_at (loc, "argument to %qs should be a non-negative integer",
option->opt_text);
if (option->cl_byte_size)
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;
}
@ -1274,7 +1357,7 @@ read_cmdline_option (struct gcc_options *opts,
void
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)
{
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)
{
case CLVC_BOOLEAN:
*(int *) flag_var = value;
if (set_flag_var)
*(int *) set_flag_var = 1;
if (option->cl_host_wide_int)
{
*(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;
case CLVC_EQUAL:
if (option->cl_host_wide_int)
*(HOST_WIDE_INT *) flag_var = (value
? option->var_value
: !option->var_value);
if (option->cl_host_wide_int)
{
*(HOST_WIDE_INT *) flag_var = (value
? option->var_value
: !option->var_value);
if (set_flag_var)
*(HOST_WIDE_INT *) set_flag_var = 1;
}
else
*(int *) flag_var = (value
? option->var_value
: !option->var_value);
if (set_flag_var)
*(int *) set_flag_var = 1;
{
*(int *) flag_var = (value
? option->var_value
: !option->var_value);
if (set_flag_var)
*(int *) set_flag_var = 1;
}
break;
case CLVC_BIT_CLEAR:
@ -1395,7 +1510,10 @@ option_enabled (int opt_idx, void *opts)
switch (option->var_type)
{
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:
if (option->cl_host_wide_int)
@ -1415,6 +1533,12 @@ option_enabled (int opt_idx, void *opts)
else
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_ENUM:
case CLVC_DEFER:
@ -1439,6 +1563,7 @@ get_option_state (struct gcc_options *opts, int option,
{
case CLVC_BOOLEAN:
case CLVC_EQUAL:
case CLVC_SIZE:
state->data = flag_var;
state->size = (cl_options[option].cl_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];
/* -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)
arg = NULL;
@ -1517,11 +1644,13 @@ control_warning_option (unsigned int opt_index, int kind, const char *arg,
return;
}
/* If the switch takes an integer, convert it. */
if (arg && option->cl_uinteger)
/* If the switch takes an integer argument, convert it. */
if (arg && (option->cl_uinteger || option->cl_host_wide_int))
{
value = integral_argument (arg);
if (value == -1)
int error = 0;
value = *arg ? integral_argument (arg, &error,
option->cl_byte_size) : 0;
if (error)
{
cmdline_handle_error (loc, option, option->opt_text, arg,
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;
const char *arg = decoded->arg;
int value = decoded->value;
HOST_WIDE_INT value = decoded->value;
enum opt_code code = (enum opt_code) scode;
gcc_assert (decoded->canonical_option_num_elements <= 2);
@ -2107,22 +2107,11 @@ common_handle_option (struct gcc_options *opts,
opts, opts_set, loc, dc);
break;
case OPT_Wlarger_than_:
opts->x_larger_than_size = value;
opts->x_warn_larger_than = value != -1;
break;
case OPT_Wfatal_errors:
dc->fatal_errors = value;
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_:
opts->x_warn_stack_usage = value;
opts->x_flag_stack_usage_info = value != -1;
break;
@ -2282,7 +2271,7 @@ common_handle_option (struct gcc_options *opts,
case OPT_fpack_struct_:
if (value <= 0 || (value & (value - 1)) || value > 16)
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);
else
opts->x_initial_max_fld_align = value;
@ -2465,7 +2454,7 @@ common_handle_option (struct gcc_options *opts,
/* FALLTHRU */
case OPT_gdwarf_:
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
opts->x_dwarf_version = value;
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. */
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
argument. */
CLVC_STRING,
@ -70,7 +73,10 @@ struct cl_option
unsigned short back_chain;
/* Option length, not including initial '-'. */
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;
/* CL_* flags for this option. */
unsigned int flags;
@ -102,6 +108,8 @@ struct cl_option
BOOL_BITFIELD cl_report : 1;
/* Deprecated option */
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
(unsigned short) -1 if none. */
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-"
case. For an unsigned integer option, the value of the
argument. 1 in all other cases. */
int value;
HOST_WIDE_INT value;
/* Any flags describing errors detected in this option. */
int errors;
@ -327,7 +335,7 @@ extern char *opts_concat (const char *first, ...);
extern struct obstack opts_obstack;
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,
const char **argp, int value,
unsigned int lang_mask);
@ -359,16 +367,17 @@ extern bool get_option_state (struct gcc_options *, int,
struct cl_option_state *);
extern void set_option (struct gcc_options *opts,
struct gcc_options *opts_set,
int opt_index, int value, const char *arg, int kind,
location_t loc, diagnostic_context *dc);
int opt_index, HOST_WIDE_INT value, const char *arg,
int kind, location_t loc, diagnostic_context *dc);
extern void *option_flag_var (int opt_index, struct gcc_options *opts);
bool handle_generated_option (struct gcc_options *opts,
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,
const struct cl_option_handlers *handlers,
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,
struct cl_decoded_option *decoded);
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,
const char *value);
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
{

View file

@ -756,22 +756,19 @@ layout_decl (tree decl, unsigned int known_align)
DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));
/* If requested, warn about definitions of large data objects. */
if (warn_larger_than
&& (code == VAR_DECL || code == PARM_DECL)
if ((code == VAR_DECL || code == PARM_DECL)
&& ! DECL_EXTERNAL (decl))
{
tree size = DECL_SIZE_UNIT (decl);
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 is %d bytes", decl, size_as_int);
else
warning (OPT_Wlarger_than_, "size of %q+D is larger than %wd bytes",
decl, larger_than_size);
warning (OPT_Wlarger_than_, "size of %q+D %wu bytes exceeds "
"maximum object size %wu",
decl, uhwisize, warn_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>
PR tree-optimization/86613

View file

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

View file

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

View file

@ -1,32 +1,9 @@
/* 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-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*);
#define T(x) sink (x)
/* 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 } */
/* { 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 }
{ dg-error "argument to '-Wvla-larger-than=' should be a non-negative integer optionally followed by a size unit" "" { 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
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));
}

View file

@ -2,7 +2,7 @@
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
is
Result: Bitmap_T := Bitmap;
@ -11,7 +11,7 @@ package body Frame_Overflow is
return Result;
end;
function -- { dg-error "too large" }
function -- { dg-error "exceeds" }
Negate (Bitmap : Bitmap_T) return Bitmap_T
is
Result: Bitmap_T;

View file

@ -1024,7 +1024,7 @@ output_stack_usage (void)
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);
@ -1034,10 +1034,10 @@ output_stack_usage (void)
{
if (stack_usage_kind == DYNAMIC_BOUNDED)
warning_at (loc,
OPT_Wstack_usage_, "stack usage might be %wd bytes",
OPT_Wstack_usage_, "stack usage might be %wu bytes",
stack_usage);
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);
}
}