From 00abf86c47606f8220d6508654ef52ef11d76e3d Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 20 Jul 2018 20:51:20 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 62 +++++ gcc/ada/ChangeLog | 6 + gcc/ada/gcc-interface/misc.c | 5 +- gcc/brig/ChangeLog | 6 + gcc/brig/brig-lang.c | 2 +- gcc/builtins.c | 21 +- gcc/c-family/ChangeLog | 15 ++ gcc/c-family/c-common.h | 3 +- gcc/c-family/c-opts.c | 12 +- gcc/c-family/c.opt | 21 +- gcc/calls.c | 73 +----- gcc/cgraphunit.c | 12 +- gcc/common.opt | 29 +-- gcc/doc/invoke.texi | 163 ++++++++---- gcc/doc/options.texi | 43 +++- gcc/final.c | 10 +- gcc/fortran/ChangeLog | 7 + gcc/fortran/gfortran.h | 2 +- gcc/fortran/options.c | 2 +- gcc/function.c | 11 +- gcc/gimple-ssa-warn-alloca.c | 95 +++++-- gcc/go/ChangeLog | 6 + gcc/go/go-lang.c | 2 +- gcc/langhooks-def.h | 4 +- gcc/langhooks.c | 3 +- gcc/langhooks.h | 4 +- gcc/lto/ChangeLog | 6 + gcc/lto/lto-lang.c | 3 +- gcc/opt-functions.awk | 41 ++- gcc/optc-gen.awk | 21 +- gcc/optc-save-gen.awk | 14 +- gcc/opth-gen.awk | 17 +- gcc/opts-common.c | 235 ++++++++++++++---- gcc/opts.c | 17 +- gcc/opts.h | 26 +- gcc/stor-layout.c | 15 +- gcc/testsuite/ChangeLog | 15 ++ gcc/testsuite/c-c++-common/pr68657-2.c | 4 +- gcc/testsuite/c-c++-common/pr68657-3.c | 12 +- .../gcc.dg/Walloc-size-larger-than-16.c | 33 +-- gcc/testsuite/gcc.dg/Walloca-larger-than-2.c | 24 ++ gcc/testsuite/gcc.dg/Walloca-larger-than.c | 26 ++ gcc/testsuite/gcc.dg/Wframe-larger-than-2.c | 19 ++ gcc/testsuite/gcc.dg/Wlarger-than3.c | 12 + gcc/testsuite/gcc.dg/Wvla-larger-than-3.c | 68 +++++ gcc/testsuite/gcc.dg/pr42611.c | 2 +- gcc/testsuite/gnat.dg/frame_overflow.adb | 4 +- gcc/toplev.c | 6 +- 48 files changed, 862 insertions(+), 377 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Walloca-larger-than-2.c create mode 100644 gcc/testsuite/gcc.dg/Walloca-larger-than.c create mode 100644 gcc/testsuite/gcc.dg/Wframe-larger-than-2.c create mode 100644 gcc/testsuite/gcc.dg/Wlarger-than3.c create mode 100644 gcc/testsuite/gcc.dg/Wvla-larger-than-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea88fa147b8..1b4f28523c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,65 @@ +2018-07-20 Martin Sebor + + 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 * builtins.c (expand_builtin_memcmp): Delete the last parameter for diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9e4f36a035b..6f096266d00 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2018-07-20 Martin Sebor + + PR middle-end/82063 + * gcc-interface/misc.c (gnat_handle_option): Change function argument + to HOST_WIDE_INT. + 2018-07-17 Eric Botcazou * gcc-interface/decl.c (choices_to_gnu): Rename parameters. Deal with diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 05bbf2e841a..9ee73b9ec1b 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -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; diff --git a/gcc/brig/ChangeLog b/gcc/brig/ChangeLog index 273177a18fb..f8749b46e61 100644 --- a/gcc/brig/ChangeLog +++ b/gcc/brig/ChangeLog @@ -1,3 +1,9 @@ +2018-07-20 Martin Sebor + + PR middle-end/82063 + * brig/brig-lang.c (brig_langhook_handle_option): Change function + argument to HOST_WIDE_INT. + 2018-07-04 Martin Jambor PR hsa/86371 diff --git a/gcc/brig/brig-lang.c b/gcc/brig/brig-lang.c index 3c4d4bdcd45..862ea69a0ea 100644 --- a/gcc/brig/brig-lang.c +++ b/gcc/brig/brig-lang.c @@ -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) { diff --git a/gcc/builtins.c b/gcc/builtins.c index 493c9374167..539a6d17688 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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)) - { - /* -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); diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index f35304d735e..9ea551ac1a9 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,18 @@ +2018-07-20 Martin Sebor + + 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 * c-attribs.c (c_common_attribute_table): Add diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index c266fee74c7..fcec95b4f3b 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -808,7 +808,8 @@ extern void check_function_format (tree, int, tree *, vec *); 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); diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index bbcb1bb1a9c..cb69fb3513c 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -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. */ diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index b4aefd8d5f6..bb4f6034c60 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -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= 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= 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= Warn on unbounded uses of alloca, and on bounded uses of alloca whose bound can be larger than 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= 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= 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= Warn on unbounded uses of variable-length +arrays, and on bounded uses of variable-length arrays whose bound can be larger than bytes. + 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= or larger. Wvolatile-register-var C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) diff --git a/gcc/calls.c b/gcc/calls.c index 2a08822d310..384c0238748 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -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; } diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 3c811c412c3..462e247328e 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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); } } diff --git a/gcc/common.opt b/gcc/common.opt index 21ed9715da1..4bf8de90331 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -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= Warn if a function's stack frame requires more than bytes. +Common RejectNegative Joined Host_Wide_Int ByteSize Warning Var(warn_frame_larger_than_size) Init(HOST_WIDE_INT_MAX) +-Wframe-larger-than= Warn if a function's stack frame requires in excess of . 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= Warn if an object is larger than bytes. +Common RejectNegative Joined Host_Wide_Int ByteSize Warning Var(warn_larger_than_size) Init(HOST_WIDE_INT_MAX) +-Wlarger-than= Warn if an object's size exceeds . 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= 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= Warn if stack usage might exceed . Wstrict-aliasing Common Warning diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9d75edbd069..1dcdfb51c47 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 -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 @@ -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{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 diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi index b3ca9f6fce6..f887d16f88f 100644 --- a/gcc/doc/options.texi +++ b/gcc/doc/options.texi @@ -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 diff --git a/gcc/final.c b/gcc/final.c index 445a3fe938a..6fa4acdaa2e 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -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. */ diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 08af3afdbe9..27d57eb2fb1 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2018-07-20 Martin Sebor + + 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 * gfortran.h (gfc_symbol): Add pointer to next derived type. diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index af735093062..04b0024a992 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -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); diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index 85f699e7cf8..af937511347 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -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) { diff --git a/gcc/function.c b/gcc/function.c index 142cdaec2ce..dee303cdbdd 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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; } diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c index 327c806ae11..cc66c466217 100644 --- a/gcc/gimple-ssa-warn-alloca.c +++ b/gcc/gimple-ssa-warn-alloca.c @@ -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 %")); + if (warn_vla > 0 || warn_vla_limit < 0) + continue; + } + else if (warn_alloca) + { + warning_at (loc, OPT_Walloca, G_("use of %")); 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; diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 0742fe09e1d..a392ed89bad 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,9 @@ +2018-07-20 Martin Sebor + + PR middle-end/82063 + * go-lang.c (go_langhook_handle_option): Change function argument + to HOST_WIDE_INT. + 2018-06-28 Ian Lance Taylor PR go/86343 diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index 45dee88fe48..e76e1fc4f98 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -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) diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index fd20dfd66bc..27b8273b95d 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -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. */ diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 3cd790105b8..c7b5cf9f6c5 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -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) { diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 94bb39f3b5a..8ad2ec763e1 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -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 diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 209a8389764..eb239972d9e 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2018-07-20 Martin Sebor + + PR middle-end/82063 + * lto-lang.c (lto_handle_option): Change function argument + to HOST_WIDE_INT. + 2018-07-20 Richard Biener PR debug/86585 diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index a1a41bc2751..de6ec1c077a 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -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) { diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk index 2c371e5a23a..6611bf340b5 100644 --- a/gcc/opt-functions.awk +++ b/gcc/opt-functions.awk @@ -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" } diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk index bf177e86330..7eaca62c545 100644 --- a/gcc/optc-gen.awk +++ b/gcc/optc-gen.awk @@ -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 ", " diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk index 6e33a4320c1..4d602230d89 100644 --- a/gcc/optc-save-gen.awk +++ b/gcc/optc-save-gen.awk @@ -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] ");"; } diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk index 8358b9b2b67..36f22b88502 100644 --- a/gcc/opth-gen.awk +++ b/gcc/opth-gen.awk @@ -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);" diff --git a/gcc/opts-common.c b/gcc/opts-common.c index 004da73e614..11356442e7b 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -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; + + 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 @@ -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); diff --git a/gcc/opts.c b/gcc/opts.c index b8ae8756b4f..17d91988ada 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -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); diff --git a/gcc/opts.h b/gcc/opts.h index 3723bdbf95b..0091fe0e9b2 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -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 { diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index ad970019e01..cb377ca5b82 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -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); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 538c7c3476b..dc2ce278f7f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2018-07-20 Martin Sebor + + 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 PR tree-optimization/86613 diff --git a/gcc/testsuite/c-c++-common/pr68657-2.c b/gcc/testsuite/c-c++-common/pr68657-2.c index 13910881f4d..ef11ad1204b 100644 --- a/gcc/testsuite/c-c++-common/pr68657-2.c +++ b/gcc/testsuite/c-c++-common/pr68657-2.c @@ -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" } */ diff --git a/gcc/testsuite/c-c++-common/pr68657-3.c b/gcc/testsuite/c-c++-common/pr68657-3.c index 1e80c5b3892..8ee6f26462f 100644 --- a/gcc/testsuite/c-c++-common/pr68657-3.c +++ b/gcc/testsuite/c-c++-common/pr68657-3.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-16.c b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-16.c index 837b69a36d8..d035cbb9c51 100644 --- a/gcc/testsuite/gcc.dg/Walloc-size-larger-than-16.c +++ b/gcc/testsuite/gcc.dg/Walloc-size-larger-than-16.c @@ -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 } */ diff --git a/gcc/testsuite/gcc.dg/Walloca-larger-than-2.c b/gcc/testsuite/gcc.dg/Walloca-larger-than-2.c new file mode 100644 index 00000000000..fe003bd0882 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Walloca-larger-than-2.c @@ -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)); +} diff --git a/gcc/testsuite/gcc.dg/Walloca-larger-than.c b/gcc/testsuite/gcc.dg/Walloca-larger-than.c new file mode 100644 index 00000000000..284601d22ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/Walloca-larger-than.c @@ -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); +} diff --git a/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c new file mode 100644 index 00000000000..1a5402f8120 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wframe-larger-than-2.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/Wlarger-than3.c b/gcc/testsuite/gcc.dg/Wlarger-than3.c new file mode 100644 index 00000000000..b9eaa563770 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wlarger-than3.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/Wvla-larger-than-3.c b/gcc/testsuite/gcc.dg/Wvla-larger-than-3.c new file mode 100644 index 00000000000..70011f1d382 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wvla-larger-than-3.c @@ -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); +} diff --git a/gcc/testsuite/gcc.dg/pr42611.c b/gcc/testsuite/gcc.dg/pr42611.c index 19e0b2bc06a..0426ce2d5bc 100644 --- a/gcc/testsuite/gcc.dg/pr42611.c +++ b/gcc/testsuite/gcc.dg/pr42611.c @@ -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)); } diff --git a/gcc/testsuite/gnat.dg/frame_overflow.adb b/gcc/testsuite/gnat.dg/frame_overflow.adb index 1e7405fa525..0351fdfa869 100644 --- a/gcc/testsuite/gnat.dg/frame_overflow.adb +++ b/gcc/testsuite/gnat.dg/frame_overflow.adb @@ -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; diff --git a/gcc/toplev.c b/gcc/toplev.c index 8908105f548..f23e8aeb17b 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -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); } } -- 2.30.2