+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
+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
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;
+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
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)
{
if (!valid_arglist)
return NULL_RTX;
- if ((alloca_for_var && !warn_vla_limit)
- || (!alloca_for_var && !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. */
+ 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 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);
+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
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);
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)
{
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. */
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
-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
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)
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;
}
/* 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);
}
}
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
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
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
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
@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.
@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
-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
-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
-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
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:
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}
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 -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 -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 -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
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
@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
@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{byte-size}}.
-See also @option{-Walloca-larger-than=@var{n}}.
+@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
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
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. */
+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.
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);
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)
{
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;
}
#include "tree-ssa.h"
#include "params.h"
#include "tree-cfg.h"
+#include "builtins.h"
#include "calls.h"
#include "cfgloop.h"
#include "intl.h"
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.
// 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)
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)
//
// 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.
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)
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);
}
}
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)
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;
// 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
// 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_;
&& 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);
}
&& 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;
+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
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)
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. */
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)
{
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
+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
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)
{
# 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 = ""
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) \
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
}
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
# 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] " "
if (host_wide_int[var_name(flags)] == "yes")
return "HOST_WIDE_INT "
else
- return "int "
+ return "/* - */ int "
}
else
return "signed char "
}
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"
}
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,
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
}
# 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])
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 "};"
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); "
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 ", "
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] ");";
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] ");";
}
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);"
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;
+
+ if (!ISDIGIT (*arg))
+ {
+ *err = EINVAL;
+ return -1;
+ }
+
+ *err = 0;
+ errno = 0;
- while (*p && ISDIGIT (*p))
- p++;
+ char *end = NULL;
+ unsigned HOST_WIDE_INT unit = 1;
+ unsigned HOST_WIDE_INT value = strtoull (arg, &end, 10);
- if (*p == '\0')
- return atoi (arg);
+ /* If the value is too large to be represented use the maximum
+ representable value that strtoull sets VALUE to (setting
+ errno to ERANGE). */
- /* It wasn't a decimal number - try hexadecimal. */
- if (arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X'))
+ if (end && *end)
{
- p = arg + 2;
- while (*p && ISXDIGIT (*p))
- p++;
+ 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 (p != arg + 2 && *p == '\0')
- return strtol (arg, NULL, 16);
+ if (unit)
+ {
+ unsigned HOST_WIDE_INT prod = value * unit;
+ value = prod < value ? HOST_WIDE_INT_M1U : prod;
}
- return -1;
+ return value;
}
/* Return whether OPTION is OK for the language given by
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;
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
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];
{
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;
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;
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. */
{
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;
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)
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];
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;
}
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];
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:
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)
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:
{
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)
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;
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);
{
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);
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;
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;
/* 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);
/* 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,
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;
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;
/* 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;
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);
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,
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
{
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);
}
}
+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
/* { 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" } */
/* { 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" } */
/* 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 } */
--- /dev/null
+/* 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));
+}
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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" } */
--- /dev/null
+/* 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" } */
--- /dev/null
+/* 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);
+}
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));
}
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;
return Result;
end;
- function -- { dg-error "too large" }
+ function -- { dg-error "exceeds" }
Negate (Bitmap : Bitmap_T) return Bitmap_T
is
Result: Bitmap_T;
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);
{
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);
}
}