/* Command line option handling.
- Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
Contributed by Neil Booth.
This file is part of GCC.
#include "intl.h"
#include "coretypes.h"
#include "opts.h"
-#include "options.h"
-#include "tm.h" /* For STACK_CHECK_BUILTIN,
- STACK_CHECK_STATIC_BUILTIN, DEFAULT_GDB_EXTENSIONS,
- DWARF2_DEBUGGING_INFO and DBX_DEBUGGING_INFO. */
+#include "tm.h"
#include "flags.h"
#include "params.h"
#include "diagnostic.h"
-#include "diagnostic-color.h"
#include "opts-diagnostic.h"
#include "insn-attr-common.h"
#include "common/common-target.h"
}
/* What to print when a switch has no documentation. */
-static const char undocumented_msg[] = N_("This switch lacks documentation");
+static const char undocumented_msg[] = N_("This option lacks documentation.");
+static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
typedef char *char_p; /* For DEF_VEC_P. */
*pvec = v;
}
+/* Initialize opts_obstack. */
+
+void
+init_opts_obstack (void)
+{
+ gcc_obstack_init (&opts_obstack);
+}
+
/* Initialize OPTS and OPTS_SET before using them in parsing options. */
void
{
size_t num_params = get_num_compiler_params ();
- gcc_obstack_init (&opts_obstack);
+ /* Ensure that opts_obstack has already been initialized by the time
+ that we initialize any gcc_options instances (PR jit/68446). */
+ gcc_assert (opts_obstack.chunk_size > 0);
*opts = global_options_init;
targetm_common.option_init_struct (opts);
}
+/* Release any allocations owned by OPTS. */
+
+void
+finalize_options_struct (struct gcc_options *opts)
+{
+ XDELETEVEC (opts->x_param_values);
+}
+
/* If indicated by the optimization level LEVEL (-Os if SIZE is set,
-Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
{
/* -O1 optimizations. */
{ OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
-#ifdef DELAY_SLOTS
+#if DELAY_SLOTS
{ OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
#endif
{ OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
- { OPT_LEVELS_1_PLUS, OPT_fif_conversion, NULL, 1 },
- { OPT_LEVELS_1_PLUS, OPT_fif_conversion2, NULL, 1 },
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
+ { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
- { OPT_LEVELS_1_PLUS, OPT_ftree_bit_ccp, NULL, 1 },
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
+ { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
- { OPT_LEVELS_1_PLUS, OPT_ftree_copyrename, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
+ { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
/* -O2 optimizations. */
{ OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
#endif
{ OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fstrict_overflow, NULL, 1 },
- { OPT_LEVELS_2_PLUS, OPT_freorder_blocks, NULL, 1 },
+ { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
+ REORDER_BLOCKS_ALGORITHM_STC },
{ OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
- { OPT_LEVELS_2_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
+ { OPT_LEVELS_2_PLUS, OPT_fipa_cp_alignment, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP },
{ OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
+ { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
+ { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
+ { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
/* -O3 optimizations. */
{ OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
+ { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
/* Inlining of functions reducing size is a good idea with -Os
regardless of them being declared inline. */
{ OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
{ OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
+ { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
/* -Ofast adds optimizations to -O3. */
{ OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
{
unsigned int i;
int opt2;
+ bool openacc_mode = false;
/* Scan to see what optimization level has been specified. That will
determine the default value of many flags. */
opts->x_optimize_debug = 1;
break;
+ case OPT_fopenacc:
+ if (opt->value)
+ openacc_mode = true;
+ break;
+
default:
/* Ignore other options in this prescan. */
break;
/* -O2 param settings. */
opt2 = (opts->x_optimize >= 2);
+ if (openacc_mode
+ && !opts_set->x_flag_ipa_pta)
+ opts->x_flag_ipa_pta = true;
+
/* Track fields in field-sensitive alias analysis. */
maybe_set_param_value
(PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000,
opts->x_param_values, opts_set->x_param_values);
+ /* At -Ofast, allow store motion to introduce potential race conditions. */
+ maybe_set_param_value
+ (PARAM_ALLOW_STORE_DATA_RACES,
+ opts->x_optimize_fast ? 1
+ : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
+ opts->x_param_values, opts_set->x_param_values);
+
if (opts->x_optimize_size)
/* We want to crossjump as much as possible. */
maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
opts->x_param_values, opts_set->x_param_values);
+ /* Restrict the amount of work combine does at -Og while retaining
+ most of its useful transforms. */
+ if (opts->x_optimize_debug)
+ maybe_set_param_value (PARAM_MAX_COMBINE_INSNS, 2,
+ opts->x_param_values, opts_set->x_param_values);
+
/* Allow default optimizations to be specified on a per-machine basis. */
maybe_default_options (opts, opts_set,
targetm_common.option_optimization_table,
if (!opts->x_flag_opts_finished)
{
+ /* We initialize opts->x_flag_pie to -1 so that targets can set a
+ default value. */
+ if (opts->x_flag_pie == -1)
+ {
+ /* We initialize opts->x_flag_pic to -1 so that we can tell if
+ -fpic, -fPIC, -fno-pic or -fno-PIC is used. */
+ if (opts->x_flag_pic == -1)
+ opts->x_flag_pie = DEFAULT_FLAG_PIE;
+ else
+ opts->x_flag_pie = 0;
+ }
+ /* If -fPIE or -fpie is used, turn on PIC. */
if (opts->x_flag_pie)
opts->x_flag_pic = opts->x_flag_pie;
+ else if (opts->x_flag_pic == -1)
+ opts->x_flag_pic = 0;
if (opts->x_flag_pic && !opts->x_flag_pie)
opts->x_flag_shlib = 1;
opts->x_flag_opts_finished = true;
}
+ /* We initialize opts->x_flag_stack_protect to -1 so that targets
+ can set a default value. */
+ if (opts->x_flag_stack_protect == -1)
+ opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
+
if (opts->x_optimize == 0)
{
/* Inlining does not work if not optimizing,
opts->x_flag_reorder_blocks = 1;
}
+ /* Disable -freorder-blocks-and-partition when -fprofile-use is not in
+ effect. Function splitting was not actually being performed in that case,
+ as probably_never_executed_bb_p does not distinguish any basic blocks as
+ being cold vs hot when there is no profile data. Leaving it enabled,
+ however, causes the assembly code generator to create (empty) cold
+ sections and labels, leading to unnecessary size overhead. */
+ if (opts->x_flag_reorder_blocks_and_partition
+ && !opts_set->x_flag_profile_use)
+ opts->x_flag_reorder_blocks_and_partition = 0;
+
if (opts->x_flag_reorder_blocks_and_partition
&& !opts_set->x_flag_reorder_functions)
opts->x_flag_reorder_functions = 1;
maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
opts->x_param_values, opts_set->x_param_values);
- /* The -gsplit-dwarf option requires -gpubnames. */
+ /* The -gsplit-dwarf option requires -ggnu-pubnames. */
if (opts->x_dwarf_split_debug_info)
- opts->x_debug_generate_pub_sections = 1;
+ opts->x_debug_generate_pub_sections = 2;
+
+ /* Userspace and kernel ASan conflict with each other. */
+
+ if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
+ && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+ error_at (loc,
+ "-fsanitize=address is incompatible with "
+ "-fsanitize=kernel-address");
+
+ /* And with TSan. */
+
+ if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
+ && (opts->x_flag_sanitize & SANITIZE_THREAD))
+ error_at (loc,
+ "-fsanitize=address and -fsanitize=kernel-address "
+ "are incompatible with -fsanitize=thread");
+
+ /* Error recovery is not allowed for LSan and TSan. */
+
+ if (opts->x_flag_sanitize_recover & SANITIZE_THREAD)
+ error_at (loc, "-fsanitize-recover=thread is not supported");
+
+ if (opts->x_flag_sanitize_recover & SANITIZE_LEAK)
+ error_at (loc, "-fsanitize-recover=leak is not supported");
+
+ /* When instrumenting the pointers, we don't want to remove
+ the null pointer checks. */
+ if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
+ | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
+ opts->x_flag_delete_null_pointer_checks = 0;
+
+ /* Aggressive compiler optimizations may cause false negatives. */
+ if (opts->x_flag_sanitize)
+ {
+ opts->x_flag_aggressive_loop_optimizations = 0;
+ opts->x_flag_strict_overflow = 0;
+ }
}
#define LEFT_COLUMN 27
const char *help;
bool found = false;
bool displayed = false;
+ char new_help[256];
if (include_flags == CL_PARAMS)
{
/* Get the translation. */
help = _(help);
+ if (!opts->x_quiet_flag)
+ {
+ snprintf (new_help, sizeof (new_help),
+ _("default %d minimum %d maximum %d"),
+ compiler_params[i].default_value,
+ compiler_params[i].min_value,
+ compiler_params[i].max_value);
+ help = new_help;
+ }
wrap_help (help, param, strlen (param), columns);
}
putchar ('\n');
for (i = 0; i < cl_options_count; i++)
{
- char new_help[128];
const struct cl_option *option = cl_options + i;
unsigned int len;
const char *opt;
{
if (exclude_flags & CL_UNDOCUMENTED)
continue;
+
help = undocumented_msg;
}
+ if (option->alias_target < N_OPTS
+ && cl_options [option->alias_target].help)
+ {
+ if (help == undocumented_msg)
+ {
+ /* For undocumented options that are aliases for other options
+ that are documented, point the reader to the other option in
+ preference of the former. */
+ snprintf (new_help, sizeof new_help,
+ _("Same as %s. Use the latter option instead."),
+ cl_options [option->alias_target].opt_text);
+ }
+ else
+ {
+ /* For documented options with aliases, mention the aliased
+ option's name for reference. */
+ snprintf (new_help, sizeof new_help,
+ _("%s Same as %s."),
+ help, cl_options [option->alias_target].opt_text);
+ }
+
+ help = new_help;
+ }
+
+ if (option->warn_message)
+ {
+ /* Mention that the use of the option will trigger a warning. */
+ if (help == new_help)
+ snprintf (new_help + strlen (new_help),
+ sizeof new_help - strlen (new_help),
+ " %s", _(use_diagnosed_msg));
+ else
+ snprintf (new_help, sizeof new_help,
+ "%s %s", help, _(use_diagnosed_msg));
+
+ help = new_help;
+ }
+
/* Get the translation. */
help = _(help);
if (* (const char **) flag_var != NULL)
snprintf (new_help + strlen (new_help),
sizeof (new_help) - strlen (new_help),
- * (const char **) flag_var);
+ "%s", * (const char **) flag_var);
}
else if (option->var_type == CLVC_ENUM)
{
arg = _("[default]");
snprintf (new_help + strlen (new_help),
sizeof (new_help) - strlen (new_help),
- arg);
+ "%s", arg);
}
else
sprintf (new_help + strlen (new_help),
options supported by a specific front end. */
for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
if ((1U << i) & langs)
- printf (_(" None found. Use --help=%s to show *all* the options supported by the %s front-end\n"),
+ printf (_(" None found. Use --help=%s to show *all* the options supported by the %s front-end.\n"),
lang_names[i], lang_names[i]);
}
the desired maximum width of the output. */
if (opts->x_help_columns == 0)
{
- const char *p;
-
- p = getenv ("COLUMNS");
- if (p != NULL)
- {
- int value = atoi (p);
-
- if (value > 0)
- opts->x_help_columns = value;
- }
-
- if (opts->x_help_columns == 0)
+ opts->x_help_columns = get_terminal_width ();
+ if (opts->x_help_columns == INT_MAX)
/* Use a reasonable default. */
opts->x_help_columns = 80;
}
opts->x_help_columns, opts, lang_mask);
}
+/* Enable FDO-related flags. */
+
+static void
+enable_fdo_optimizations (struct gcc_options *opts,
+ struct gcc_options *opts_set,
+ int value)
+{
+ if (!opts_set->x_flag_branch_probabilities)
+ opts->x_flag_branch_probabilities = value;
+ if (!opts_set->x_flag_profile_values)
+ opts->x_flag_profile_values = value;
+ if (!opts_set->x_flag_unroll_loops)
+ opts->x_flag_unroll_loops = value;
+ if (!opts_set->x_flag_peel_loops)
+ opts->x_flag_peel_loops = value;
+ if (!opts_set->x_flag_tracer)
+ opts->x_flag_tracer = value;
+ if (!opts_set->x_flag_value_profile_transformations)
+ opts->x_flag_value_profile_transformations = value;
+ if (!opts_set->x_flag_inline_functions)
+ opts->x_flag_inline_functions = value;
+ if (!opts_set->x_flag_ipa_cp)
+ opts->x_flag_ipa_cp = value;
+ if (!opts_set->x_flag_ipa_cp_clone
+ && value && opts->x_flag_ipa_cp)
+ opts->x_flag_ipa_cp_clone = value;
+ if (!opts_set->x_flag_ipa_cp_alignment
+ && value && opts->x_flag_ipa_cp)
+ opts->x_flag_ipa_cp_alignment = value;
+ if (!opts_set->x_flag_predictive_commoning)
+ opts->x_flag_predictive_commoning = value;
+ if (!opts_set->x_flag_unswitch_loops)
+ opts->x_flag_unswitch_loops = value;
+ if (!opts_set->x_flag_gcse_after_reload)
+ opts->x_flag_gcse_after_reload = value;
+ if (!opts_set->x_flag_tree_loop_vectorize
+ && !opts_set->x_flag_tree_vectorize)
+ opts->x_flag_tree_loop_vectorize = value;
+ if (!opts_set->x_flag_tree_slp_vectorize
+ && !opts_set->x_flag_tree_vectorize)
+ opts->x_flag_tree_slp_vectorize = value;
+ if (!opts_set->x_flag_vect_cost_model)
+ opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
+ if (!opts_set->x_flag_tree_loop_distribute_patterns)
+ opts->x_flag_tree_loop_distribute_patterns = value;
+}
+
+/* -f{,no-}sanitize{,-recover}= suboptions. */
+const struct sanitizer_opts_s sanitizer_opts[] =
+{
+#define SANITIZER_OPT(name, flags) { #name, flags, sizeof #name - 1 }
+ SANITIZER_OPT (address, SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS),
+ SANITIZER_OPT (kernel-address, SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
+ SANITIZER_OPT (thread, SANITIZE_THREAD),
+ SANITIZER_OPT (leak, SANITIZE_LEAK),
+ SANITIZER_OPT (shift, SANITIZE_SHIFT),
+ SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE),
+ SANITIZER_OPT (undefined, SANITIZE_UNDEFINED),
+ SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE),
+ SANITIZER_OPT (vla-bound, SANITIZE_VLA),
+ SANITIZER_OPT (return, SANITIZE_RETURN),
+ SANITIZER_OPT (null, SANITIZE_NULL),
+ SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW),
+ SANITIZER_OPT (bool, SANITIZE_BOOL),
+ SANITIZER_OPT (enum, SANITIZE_ENUM),
+ SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE),
+ SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST),
+ SANITIZER_OPT (bounds, SANITIZE_BOUNDS),
+ SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT),
+ SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT),
+ SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE),
+ SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE),
+ SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE),
+ SANITIZER_OPT (vptr, SANITIZE_VPTR),
+ SANITIZER_OPT (all, ~0),
+#undef SANITIZER_OPT
+ { NULL, 0, 0 }
+};
+
+/* Parse comma separated sanitizer suboptions from P for option SCODE,
+ adjust previous FLAGS and return new ones. If COMPLAIN is false,
+ don't issue diagnostics. */
+
+unsigned int
+parse_sanitizer_options (const char *p, location_t loc, int scode,
+ unsigned int flags, int value, bool complain)
+{
+ enum opt_code code = (enum opt_code) scode;
+ while (*p != 0)
+ {
+ size_t len, i;
+ bool found = false;
+ const char *comma = strchr (p, ',');
+
+ if (comma == NULL)
+ len = strlen (p);
+ else
+ len = comma - p;
+ if (len == 0)
+ {
+ p = comma + 1;
+ continue;
+ }
+
+ /* Check to see if the string matches an option class name. */
+ for (i = 0; sanitizer_opts[i].name != NULL; ++i)
+ if (len == sanitizer_opts[i].len
+ && memcmp (p, sanitizer_opts[i].name, len) == 0)
+ {
+ /* Handle both -fsanitize and -fno-sanitize cases. */
+ if (value && sanitizer_opts[i].flag == ~0U)
+ {
+ if (code == OPT_fsanitize_)
+ {
+ if (complain)
+ error_at (loc, "-fsanitize=all option is not valid");
+ }
+ else
+ flags |= ~(SANITIZE_USER_ADDRESS | SANITIZE_THREAD
+ | SANITIZE_LEAK);
+ }
+ else if (value)
+ flags |= sanitizer_opts[i].flag;
+ else
+ flags &= ~sanitizer_opts[i].flag;
+ found = true;
+ break;
+ }
+
+ if (! found && complain)
+ error_at (loc, "unrecognized argument to -fsanitize%s= option: %q.*s",
+ code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
+
+ if (comma == NULL)
+ break;
+ p = comma + 1;
+ }
+ return flags;
+}
+
/* Handle target- and language-independent options. Return zero to
generate an "unknown option" message. Only options that need
extra handling need to be listed here; if you simply want
unsigned int i;
if (lang_mask == CL_DRIVER)
- break;;
+ break;
undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
? 0
case OPT__help_:
{
- const char * a = arg;
+ const char *a = arg;
unsigned int include_flags = 0;
/* Note - by default we include undocumented options when listing
specific classes. If you only want to see documented options
arg = [^]{word}[,{arg}]
word = {optimizers|target|warnings|undocumented|
params|common|<language>} */
- while (* a != 0)
+ while (*a != 0)
{
static const struct
{
- const char * string;
+ const char *string;
unsigned int flag;
}
specifics[] =
{ "common", CL_COMMON },
{ NULL, 0 }
};
- unsigned int * pflags;
- const char * comma;
+ unsigned int *pflags;
+ const char *comma;
unsigned int lang_flag, specific_flag;
unsigned int len;
unsigned int i;
- if (* a == '^')
+ if (*a == '^')
{
- ++ a;
- pflags = & exclude_flags;
+ ++a;
+ if (*a == '\0')
+ {
+ error_at (loc, "missing argument to %qs", "--help=^");
+ break;
+ }
+ pflags = &exclude_flags;
}
else
- pflags = & include_flags;
+ pflags = &include_flags;
comma = strchr (a, ',');
if (comma == NULL)
if (specific_flag != 0)
{
if (lang_flag == 0)
- * pflags |= specific_flag;
+ *pflags |= specific_flag;
else
{
/* The option's argument matches both the start of a
specified "--help=c", but otherwise we have to issue
a warning. */
if (strncasecmp (a, "c", len) == 0)
- * pflags |= lang_flag;
+ *pflags |= lang_flag;
else
warning_at (loc, 0,
"--help argument %q.*s is ambiguous, "
}
}
else if (lang_flag != 0)
- * pflags |= lang_flag;
+ *pflags |= lang_flag;
else
warning_at (loc, 0,
"unrecognized argument to --help= option: %q.*s",
break;
case OPT_fsanitize_:
- {
- const char *p = arg;
- while (*p != 0)
- {
- static const struct
- {
- const char *const name;
- unsigned int flag;
- size_t len;
- } spec[] =
- {
- { "address", SANITIZE_ADDRESS, sizeof "address" - 1 },
- { "thread", SANITIZE_THREAD, sizeof "thread" - 1 },
- { "leak", SANITIZE_LEAK, sizeof "leak" - 1 },
- { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 },
- { "integer-divide-by-zero", SANITIZE_DIVIDE,
- sizeof "integer-divide-by-zero" - 1 },
- { "undefined", SANITIZE_UNDEFINED, sizeof "undefined" - 1 },
- { "unreachable", SANITIZE_UNREACHABLE,
- sizeof "unreachable" - 1 },
- { "vla-bound", SANITIZE_VLA, sizeof "vla-bound" - 1 },
- { "return", SANITIZE_RETURN, sizeof "return" - 1 },
- { "null", SANITIZE_NULL, sizeof "null" - 1 },
- { "signed-integer-overflow", SANITIZE_SI_OVERFLOW,
- sizeof "signed-integer-overflow" -1 },
- { "bool", SANITIZE_BOOL, sizeof "bool" - 1 },
- { "enum", SANITIZE_ENUM, sizeof "enum" - 1 },
- { NULL, 0, 0 }
- };
- const char *comma;
- size_t len, i;
- bool found = false;
-
- comma = strchr (p, ',');
- if (comma == NULL)
- len = strlen (p);
- else
- len = comma - p;
- if (len == 0)
- {
- p = comma + 1;
- continue;
- }
+ opts->x_flag_sanitize
+ = parse_sanitizer_options (arg, loc, code,
+ opts->x_flag_sanitize, value, true);
- /* Check to see if the string matches an option class name. */
- for (i = 0; spec[i].name != NULL; ++i)
- if (len == spec[i].len
- && memcmp (p, spec[i].name, len) == 0)
- {
- /* Handle both -fsanitize and -fno-sanitize cases. */
- if (value)
- flag_sanitize |= spec[i].flag;
- else
- flag_sanitize &= ~spec[i].flag;
- found = true;
- break;
- }
+ /* Kernel ASan implies normal ASan but does not yet support
+ all features. */
+ if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
+ {
+ maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
+ 0, opts->x_param_values,
+ opts_set->x_param_values);
+ maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
+ opts_set->x_param_values);
+ maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
+ opts_set->x_param_values);
+ maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
+ opts->x_param_values,
+ opts_set->x_param_values);
+ }
+ break;
- if (! found)
- warning_at (loc, 0,
- "unrecognized argument to -fsanitize= option: %q.*s",
- (int) len, p);
+ case OPT_fsanitize_recover_:
+ opts->x_flag_sanitize_recover
+ = parse_sanitizer_options (arg, loc, code,
+ opts->x_flag_sanitize_recover, value, true);
+ break;
- if (comma == NULL)
- break;
- p = comma + 1;
- }
+ case OPT_fasan_shadow_offset_:
+ /* Deferred. */
+ break;
- /* When instrumenting the pointers, we don't want to remove
- the null pointer checks. */
- if (flag_sanitize & SANITIZE_NULL)
- opts->x_flag_delete_null_pointer_checks = 0;
- break;
- }
+ case OPT_fsanitize_recover:
+ if (value)
+ opts->x_flag_sanitize_recover
+ |= SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT;
+ else
+ opts->x_flag_sanitize_recover
+ &= ~(SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT);
+ break;
case OPT_O:
case OPT_Os:
break;
case OPT_fdbg_cnt_:
+ /* Deferred. */
+ break;
+
case OPT_fdbg_cnt_list:
/* Deferred. */
+ opts->x_exit_after_options = true;
break;
case OPT_fdebug_prefix_map_:
break;
case OPT_fdiagnostics_color_:
- pp_show_color (dc->printer)
- = colorize_init ((diagnostic_color_rule_t) value);
+ diagnostic_color_init (dc, value);
break;
case OPT_fdiagnostics_show_option:
/* Deferred. */
break;
+ case OPT_foffload_:
+ {
+ const char *p = arg;
+ opts->x_flag_disable_hsa = true;
+ while (*p != 0)
+ {
+ const char *comma = strchr (p, ',');
+
+ if ((strncmp (p, "disable", 7) == 0)
+ && (p[7] == ',' || p[7] == '\0'))
+ {
+ opts->x_flag_disable_hsa = true;
+ break;
+ }
+
+ if ((strncmp (p, "hsa", 3) == 0)
+ && (p[3] == ',' || p[3] == '\0'))
+ {
+#ifdef ENABLE_HSA
+ opts->x_flag_disable_hsa = false;
+#else
+ sorry ("HSA has not been enabled during configuration");
+#endif
+ }
+ if (!comma)
+ break;
+ p = comma + 1;
+ }
+ break;
+ }
+
+#ifndef ACCEL_COMPILER
+ case OPT_foffload_abi_:
+ error_at (loc, "-foffload-abi option can be specified only for "
+ "offload compiler");
+ break;
+#endif
+
case OPT_fpack_struct_:
if (value <= 0 || (value & (value - 1)) || value > 16)
error_at (loc,
value = true;
/* No break here - do -fprofile-use processing. */
case OPT_fprofile_use:
- if (!opts_set->x_flag_branch_probabilities)
- opts->x_flag_branch_probabilities = value;
- if (!opts_set->x_flag_profile_values)
- opts->x_flag_profile_values = value;
- if (!opts_set->x_flag_unroll_loops)
- opts->x_flag_unroll_loops = value;
- if (!opts_set->x_flag_peel_loops)
- opts->x_flag_peel_loops = value;
- if (!opts_set->x_flag_tracer)
- opts->x_flag_tracer = value;
- if (!opts_set->x_flag_value_profile_transformations)
- opts->x_flag_value_profile_transformations = value;
- if (!opts_set->x_flag_inline_functions)
- opts->x_flag_inline_functions = value;
- if (!opts_set->x_flag_ipa_cp)
- opts->x_flag_ipa_cp = value;
- if (!opts_set->x_flag_ipa_cp_clone
- && value && opts->x_flag_ipa_cp)
- opts->x_flag_ipa_cp_clone = value;
- if (!opts_set->x_flag_predictive_commoning)
- opts->x_flag_predictive_commoning = value;
- if (!opts_set->x_flag_unswitch_loops)
- opts->x_flag_unswitch_loops = value;
- if (!opts_set->x_flag_gcse_after_reload)
- opts->x_flag_gcse_after_reload = value;
- if (!opts_set->x_flag_tree_loop_vectorize
- && !opts_set->x_flag_tree_vectorize)
- opts->x_flag_tree_loop_vectorize = value;
- if (!opts_set->x_flag_tree_slp_vectorize
- && !opts_set->x_flag_tree_vectorize)
- opts->x_flag_tree_slp_vectorize = value;
- if (!opts_set->x_flag_vect_cost_model)
- opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
- if (!opts_set->x_flag_tree_loop_distribute_patterns)
- opts->x_flag_tree_loop_distribute_patterns = value;
+ enable_fdo_optimizations (opts, opts_set, value);
if (!opts_set->x_flag_profile_reorder_functions)
- opts->x_flag_profile_reorder_functions = value;
- /* Indirect call profiling should do all useful transformations
- speculative devirtualization does. */
+ opts->x_flag_profile_reorder_functions = value;
+ /* Indirect call profiling should do all useful transformations
+ speculative devirtualization does. */
if (!opts_set->x_flag_devirtualize_speculatively
&& opts->x_flag_value_profile_transformations)
opts->x_flag_devirtualize_speculatively = false;
break;
+ case OPT_fauto_profile_:
+ opts->x_auto_profile_file = xstrdup (arg);
+ opts->x_flag_auto_profile = true;
+ value = true;
+ /* No break here - do -fauto-profile processing. */
+ case OPT_fauto_profile:
+ enable_fdo_optimizations (opts, opts_set, value);
+ if (!opts_set->x_flag_profile_correction)
+ opts->x_flag_profile_correction = value;
+ maybe_set_param_value (
+ PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
+ opts->x_param_values, opts_set->x_param_values);
+ break;
+
case OPT_fprofile_generate_:
opts->x_profile_data_prefix = xstrdup (arg);
value = true;
? STATIC_BUILTIN_STACK_CHECK
: GENERIC_STACK_CHECK;
else
- warning_at (loc, 0, "unknown stack check parameter \"%s\"", arg);
+ warning_at (loc, 0, "unknown stack check parameter %qs", arg);
break;
case OPT_fstack_limit:
break;
case OPT_g:
- /* -g by itself should force -g2. */
- if (*arg == '\0')
- set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "2", opts, opts_set,
- loc);
- else
- set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
- loc);
+ set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
+ loc);
break;
case OPT_gcoff:
/* FALLTHRU */
case OPT_gdwarf_:
- if (value < 2 || value > 4)
+ if (value < 2 || value > 5)
error_at (loc, "dwarf version %d is not supported", value);
else
opts->x_dwarf_version = value;
loc);
break;
+ case OPT_gz:
+ case OPT_gz_:
+ /* Handled completely via specs. */
+ break;
+
case OPT_pedantic_errors:
dc->pedantic_errors = 1;
- control_warning_option (OPT_Wpedantic, DK_ERROR, value,
+ control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
loc, lang_mask,
handlers, opts, opts_set,
dc);
opts->x_flag_wrapv = 0;
break;
+ case OPT_fipa_icf:
+ opts->x_flag_ipa_icf_functions = value;
+ opts->x_flag_ipa_icf_variables = value;
+ break;
+
default:
/* If the flag was handled in a standard way, assume the lack of
processing here is intentional. */
arg);
else
{
- value = integral_argument (equal + 1);
- if (value == -1)
- error_at (loc, "invalid --param value %qs", equal + 1);
+ *equal = '\0';
+
+ enum compiler_param index;
+ if (!find_param (arg, &index))
+ error_at (loc, "invalid --param name %qs", arg);
else
{
- *equal = '\0';
- set_param_value (arg, value,
- opts->x_param_values, opts_set->x_param_values);
+ if (!param_string_value_p (index, equal + 1, &value))
+ value = integral_argument (equal + 1);
+
+ if (value == -1)
+ error_at (loc, "invalid --param value %qs", equal + 1);
+ else
+ set_param_value (arg, value,
+ opts->x_param_values, opts_set->x_param_values);
}
}
if (extended == 2)
{
-#ifdef DWARF2_DEBUGGING_INFO
+#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
opts->x_write_symbols = DWARF2_DEBUG;
#elif defined DBX_DEBUGGING_INFO
opts->x_write_symbols = DBX_DEBUG;
if (opts_set->x_write_symbols != NO_DEBUG
&& opts->x_write_symbols != NO_DEBUG
&& type != opts->x_write_symbols)
- error_at (loc, "debug format \"%s\" conflicts with prior selection",
+ error_at (loc, "debug format %qs conflicts with prior selection",
debug_type_names[type]);
opts->x_write_symbols = type;
opts_set->x_write_symbols = type;
}
- /* A debug flag without a level defaults to level 2. */
+ /* A debug flag without a level defaults to level 2.
+ If off or at level 1, set it to level 2, but if already
+ at level 3, don't lower it. */
if (*arg == '\0')
{
- if (!opts->x_debug_info_level)
+ if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
}
else
{
int argval = integral_argument (arg);
if (argval == -1)
- error_at (loc, "unrecognised debug output level \"%s\"", arg);
+ error_at (loc, "unrecognised debug output level %qs", arg);
else if (argval > 3)
- error_at (loc, "debug output level %s is too high", arg);
+ error_at (loc, "debug output level %qs is too high", arg);
else
opts->x_debug_info_level = (enum debug_info_levels) argval;
}
{
struct rlimit rlim;
if (getrlimit (RLIMIT_CORE, &rlim) != 0)
- fatal_error ("getting core file size maximum limit: %m");
+ fatal_error (input_location, "getting core file size maximum limit: %m");
rlim.rlim_cur = rlim.rlim_max;
if (setrlimit (RLIMIT_CORE, &rlim) != 0)
- fatal_error ("setting core file size limit to maximum: %m");
+ fatal_error (input_location,
+ "setting core file size limit to maximum: %m");
}
#endif
diagnostic_abort_on_error (dc);
strcpy (new_option + 1, arg);
option_index = find_opt (new_option, lang_mask);
if (option_index == OPT_SPECIAL_unknown)
- {
- error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
- }
+ error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
+ else if (!(cl_options[option_index].flags & CL_WARNING))
+ error_at (loc, "-Werror=%s: -%s is not an option that controls warnings",
+ arg, new_option);
else
{
const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
+ const char *arg = NULL;
- control_warning_option (option_index, (int) kind, value,
+ if (cl_options[option_index].flags & CL_JOINED)
+ arg = new_option + cl_options[option_index].opt_len;
+ control_warning_option (option_index, (int) kind, arg, value,
loc, lang_mask,
handlers, opts, opts_set, dc);
}