X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fopts.c;h=cf1fd2ded435a6b6b4e13b02c1ddc898616d7b9e;hb=cbbd336d40408f2034d63036fa0bf7c5d900d84c;hp=591094d6182f68781af57669c8816a952e8442b3;hpb=a227c9eff24ef7c01fd43bc98b8f5693b81231fa;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/opts.c b/gcc/opts.c index 591094d6182..cf1fd2ded43 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1,5 +1,5 @@ /* Command line option handling. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Neil Booth. @@ -42,6 +42,9 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "dbgcnt.h" #include "debug.h" +#include "plugin.h" +#include "except.h" +#include "lto-streamer.h" /* Value of the -G xx switch, and whether it was passed or not. */ unsigned HOST_WIDE_INT g_switch_value; @@ -53,9 +56,6 @@ bool sel_sched_switch_set; /* True if we should exit after parsing options. */ bool exit_after_options; -/* Print various extra warnings. -W/-Wextra. */ -bool extra_warnings; - /* 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'. */ @@ -338,11 +338,7 @@ enum symbol_visibility default_visibility = VISIBILITY_DEFAULT; struct visibility_flags visibility_options; /* What to print when a switch has no documentation. */ -#ifdef ENABLE_CHECKING static const char undocumented_msg[] = N_("This switch lacks documentation"); -#else -static const char undocumented_msg[] = ""; -#endif /* Used for bookkeeping on whether user set these flags so -fprofile-use/-fprofile-generate does not use them. */ @@ -368,25 +364,19 @@ DEF_VEC_ALLOC_P(const_char_p,heap); static VEC(const_char_p,heap) *ignored_options; -/* Function calls disallowed under -Wdisallowed-function-list=... */ -static VEC(char_p,heap) *warning_disallowed_functions; - -/* If -Wdisallowed-function-list=... */ -bool warn_disallowed_functions = false; +/* Language specific warning pass for unused results. */ +bool flag_warn_unused_result = false; /* Input file names. */ const char **in_fnames; unsigned num_in_fnames; static int common_handle_option (size_t scode, const char *arg, int value, - unsigned int lang_mask); + unsigned int lang_mask, int kind); static void handle_param (const char *); -static void set_Wextra (int); -static unsigned int handle_option (const char **argv, unsigned int lang_mask); static char *write_langs (unsigned int lang_mask); static void complain_wrong_lang (const char *, const struct cl_option *, unsigned int lang_mask); -static void handle_options (unsigned int, const char **, unsigned int); static void set_debug_level (enum debug_info_type type, int extended, const char *arg); @@ -441,6 +431,17 @@ complain_wrong_lang (const char *text, const struct cl_option *option, { char *ok_langs, *bad_lang; + /* The LTO front end inherits all the options from the first front + end that was used. However, not all the original front end + options make sense in LTO. + + A real solution would be to filter this in collect2, but collect2 + does not have access to all the option attributes to know what to + filter. So, in lto1 we silently accept inherited flags and do + nothing about it. */ + if (lang_mask & CL_LTO) + return; + ok_langs = write_langs (option->flags); bad_lang = write_langs (lang_mask); @@ -482,10 +483,51 @@ void print_ignored_options (void) input_location = saved_loc; } + +/* Handle option OPT_INDEX, and argument ARG, for the language + indicated by LANG_MASK. VALUE is true, unless no- form of an -f or + -W option was given. KIND is the diagnostic_t if this is a + diagnostics option, DK_UNSPECIFIED otherwise. Returns false if the + switch was invalid. */ +bool +handle_option (int opt_index, int value, const char *arg, + unsigned int lang_mask, int kind) +{ + const struct cl_option *option = &cl_options[opt_index]; + + if (option->flag_var) + set_option (opt_index, value, arg, kind); + + if (option->flags & lang_mask) + { + if (lang_hooks.handle_option (opt_index, arg, value, kind) == 0) + return false; + else + lto_register_user_option (opt_index, arg, value, lang_mask); + } + + if (option->flags & CL_COMMON) + { + if (common_handle_option (opt_index, arg, value, lang_mask, kind) == 0) + return false; + else + lto_register_user_option (opt_index, arg, value, CL_COMMON); + } + + if (option->flags & CL_TARGET) + { + if (!targetm.handle_option (opt_index, arg, value)) + return false; + else + lto_register_user_option (opt_index, arg, value, CL_TARGET); + } + return true; +} + /* Handle the switch beginning at ARGV for the language indicated by LANG_MASK. Returns the number of switches consumed. */ static unsigned int -handle_option (const char **argv, unsigned int lang_mask) +read_cmdline_option (const char **argv, unsigned int lang_mask) { size_t opt_index; const char *opt, *arg = 0; @@ -606,45 +648,8 @@ handle_option (const char **argv, unsigned int lang_mask) } } - if (option->flag_var) - switch (option->var_type) - { - case CLVC_BOOLEAN: - *(int *) option->flag_var = value; - break; - - case CLVC_EQUAL: - *(int *) option->flag_var = (value - ? option->var_value - : !option->var_value); - break; - - case CLVC_BIT_CLEAR: - case CLVC_BIT_SET: - if ((value != 0) == (option->var_type == CLVC_BIT_SET)) - *(int *) option->flag_var |= option->var_value; - else - *(int *) option->flag_var &= ~option->var_value; - if (option->flag_var == &target_flags) - target_flags_explicit |= option->var_value; - break; - - case CLVC_STRING: - *(const char **) option->flag_var = arg; - break; - } - - if (option->flags & lang_mask) - if (lang_hooks.handle_option (opt_index, arg, value) == 0) - result = 0; - - if (result && (option->flags & CL_COMMON)) - if (common_handle_option (opt_index, arg, value, lang_mask) == 0) - result = 0; - - if (result && (option->flags & CL_TARGET)) - if (!targetm.handle_option (opt_index, arg, value)) - result = 0; + if (!handle_option (opt_index, value, arg, lang_mask, DK_UNSPECIFIED)) + result = 0; done: if (dup) @@ -741,35 +746,11 @@ flag_instrument_functions_exclude_p (tree fndecl) } -/* Return whether this function call is disallowed. */ -void -warn_if_disallowed_function_p (const_tree exp) -{ - if (TREE_CODE(exp) == CALL_EXPR - && VEC_length (char_p, warning_disallowed_functions) > 0) - { - int i; - char *s; - const char *fnname = - IDENTIFIER_POINTER (DECL_NAME (get_callee_fndecl (exp))); - for (i = 0; VEC_iterate (char_p, warning_disallowed_functions, i, s); - ++i) - { - if (strcmp (fnname, s) == 0) - { - warning (OPT_Wdisallowed_function_list_, - "disallowed call to %qs", fnname); - break; - } - } - } -} - /* Decode and handle the vector of command line options. LANG_MASK contains has a single bit set representing the current language. */ static void -handle_options (unsigned int argc, const char **argv, unsigned int lang_mask) +read_cmdline_options (unsigned int argc, const char **argv, unsigned int lang_mask) { unsigned int n, i; @@ -791,7 +772,7 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask) continue; } - n = handle_option (argv + i, lang_mask); + n = read_cmdline_option (argv + i, lang_mask); if (!n) { @@ -807,10 +788,9 @@ void decode_options (unsigned int argc, const char **argv) { static bool first_time_p = true; - static int initial_max_aliased_vops; - static int initial_avg_aliased_vops; static int initial_min_crossjump_insns; static int initial_max_fields_for_field_sensitive; + static int initial_loop_invariant_max_bbs_in_loop; static unsigned int initial_lang_mask; unsigned int i, lang_mask; @@ -827,12 +807,12 @@ decode_options (unsigned int argc, const char **argv) lang_hooks.initialize_diagnostics (global_dc); /* Save initial values of parameters we reset. */ - initial_max_aliased_vops = MAX_ALIASED_VOPS; - initial_avg_aliased_vops = AVG_ALIASED_VOPS; initial_min_crossjump_insns = compiler_params[PARAM_MIN_CROSSJUMP_INSNS].value; initial_max_fields_for_field_sensitive = compiler_params[PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE].value; + initial_loop_invariant_max_bbs_in_loop + = compiler_params[PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP].value; } else lang_mask = initial_lang_mask; @@ -864,16 +844,18 @@ decode_options (unsigned int argc, const char **argv) if (optimize_val != -1) { optimize = optimize_val; + if ((unsigned int) optimize > 255) + optimize = 255; optimize_size = 0; } } } } - -#ifdef IRA_COVER_CLASSES - /* Use IRA if it is implemented for the target. */ - flag_ira = 1; -#endif + + /* Use priority coloring if cover classes is not defined for the + target. */ + if (targetm.ira_cover_classes == NULL) + flag_ira_algorithm = IRA_ALGORITHM_PRIORITY; /* -O1 optimizations. */ opt1 = (optimize >= 1); @@ -886,10 +868,12 @@ decode_options (unsigned int argc, const char **argv) #endif flag_guess_branch_prob = opt1; flag_cprop_registers = opt1; + flag_forward_propagate = opt1; flag_if_conversion = opt1; flag_if_conversion2 = opt1; flag_ipa_pure_const = opt1; flag_ipa_reference = opt1; + flag_ipa_profile = opt1; flag_merge_constants = opt1; flag_split_wide_types = opt1; flag_tree_ccp = opt1; @@ -911,7 +895,6 @@ decode_options (unsigned int argc, const char **argv) flag_thread_jumps = opt2; flag_crossjumping = opt2; flag_optimize_sibling_calls = opt2; - flag_forward_propagate = opt2; flag_cse_follow_jumps = opt2; flag_gcse = opt2; flag_expensive_optimizations = opt2; @@ -919,30 +902,30 @@ decode_options (unsigned int argc, const char **argv) flag_caller_saves = opt2; flag_peephole2 = opt2; #ifdef INSN_SCHEDULING - flag_schedule_insns = opt2; + /* Only run the pre-regalloc scheduling pass if optimizing for speed. */ + flag_schedule_insns = opt2 && ! optimize_size; flag_schedule_insns_after_reload = opt2; #endif flag_regmove = opt2; flag_strict_aliasing = opt2; flag_strict_overflow = opt2; - flag_delete_null_pointer_checks = opt2; flag_reorder_blocks = opt2; flag_reorder_functions = opt2; flag_tree_vrp = opt2; flag_tree_builtin_call_dce = opt2; flag_tree_pre = opt2; - flag_tree_switch_conversion = 1; + flag_tree_switch_conversion = opt2; flag_ipa_cp = opt2; - - /* Allow more virtual operators to increase alias precision. */ - - set_param_value ("max-aliased-vops", - (opt2) ? 500 : initial_max_aliased_vops); + flag_ipa_sra = opt2; /* Track fields in field-sensitive alias analysis. */ set_param_value ("max-fields-for-field-sensitive", (opt2) ? 100 : initial_max_fields_for_field_sensitive); + /* For -O1 only do loop invariant motion for very small loops. */ + set_param_value ("loop-invariant-max-bbs-in-loop", + (opt2) ? initial_loop_invariant_max_bbs_in_loop : 1000); + /* -O3 optimizations. */ opt3 = (optimize >= 3); flag_predictive_commoning = opt3; @@ -954,13 +937,6 @@ decode_options (unsigned int argc, const char **argv) if (flag_ipa_cp_clone) flag_ipa_cp = 1; - /* Allow even more virtual operators. Max-aliased-vops was set above for - -O2, so don't reset it unless we are at -O3. */ - if (opt3) - set_param_value ("max-aliased-vops", 1000); - - set_param_value ("avg-aliased-vops", (opt3) ? 3 : initial_avg_aliased_vops); - /* Just -O1/-O0 optimizations. */ opt1_max = (optimize <= 1); align_loops = opt1_max; @@ -985,6 +961,9 @@ decode_options (unsigned int argc, const char **argv) else set_param_value ("min-crossjump-insns", initial_min_crossjump_insns); + /* Enable -Werror=coverage-mismatch by default */ + enable_warning_as_error("coverage-mismatch", 1, lang_mask); + if (first_time_p) { /* Initialize whether `char' is signed. */ @@ -1001,12 +980,43 @@ decode_options (unsigned int argc, const char **argv) flag_unwind_tables = targetm.unwind_tables_default; } + /* Clear any options currently held for LTO. */ + lto_clear_user_options (); + #ifdef OPTIMIZATION_OPTIONS /* Allow default optimizations to be specified on a per-machine basis. */ OPTIMIZATION_OPTIONS (optimize, optimize_size); #endif - handle_options (argc, argv, lang_mask); + read_cmdline_options (argc, argv, lang_mask); + + if (dump_base_name && ! IS_ABSOLUTE_PATH (dump_base_name)) + { + /* First try to make DUMP_BASE_NAME relative to the DUMP_DIR_NAME + directory. Then try to make DUMP_BASE_NAME relative to the + AUX_BASE_NAME directory, typically the directory to contain + the object file. */ + if (dump_dir_name) + dump_base_name = concat (dump_dir_name, dump_base_name, NULL); + else if (aux_base_name) + { + const char *aux_base; + + base_of_path (aux_base_name, &aux_base); + if (aux_base_name != aux_base) + { + int dir_len = aux_base - aux_base_name; + char *new_dump_base_name = + XNEWVEC (char, strlen(dump_base_name) + dir_len + 1); + + /* Copy directory component from AUX_BASE_NAME. */ + memcpy (new_dump_base_name, aux_base_name, dir_len); + /* Append existing DUMP_BASE_NAME. */ + strcpy (new_dump_base_name + dir_len, dump_base_name); + dump_base_name = new_dump_base_name; + } + } + } /* Handle related options for unit-at-a-time, toplevel-reorder, and section-anchors. */ @@ -1043,6 +1053,7 @@ decode_options (unsigned int argc, const char **argv) flag_pic = flag_pie; if (flag_pic && !flag_pie) flag_shlib = 1; + first_time_p = false; } if (optimize == 0) @@ -1059,10 +1070,15 @@ decode_options (unsigned int argc, const char **argv) generating unwind info. If flag_exceptions is turned on we need to turn off the partitioning optimization. */ - if (flag_exceptions && flag_reorder_blocks_and_partition) + if (flag_exceptions && flag_reorder_blocks_and_partition + && (USING_SJLJ_EXCEPTIONS +#ifdef TARGET_UNWIND_INFO + || 1 +#endif + )) { - inform (input_location, - "-freorder-blocks-and-partition does not work with exceptions"); + inform (input_location, + "-freorder-blocks-and-partition does not work with exceptions on this architecture"); flag_reorder_blocks_and_partition = 0; flag_reorder_blocks = 1; } @@ -1071,9 +1087,15 @@ decode_options (unsigned int argc, const char **argv) optimization. */ if (flag_unwind_tables && ! targetm.unwind_tables_default - && flag_reorder_blocks_and_partition) + && flag_reorder_blocks_and_partition + && (USING_SJLJ_EXCEPTIONS +#ifdef TARGET_UNWIND_INFO + || 1 +#endif + )) { - inform (input_location, "-freorder-blocks-and-partition does not support unwind info"); + inform (input_location, + "-freorder-blocks-and-partition does not support unwind info on this architecture"); flag_reorder_blocks_and_partition = 0; flag_reorder_blocks = 1; } @@ -1084,7 +1106,12 @@ decode_options (unsigned int argc, const char **argv) if (flag_reorder_blocks_and_partition && (!targetm.have_named_sections - || (flag_unwind_tables && targetm.unwind_tables_default))) + || (flag_unwind_tables && targetm.unwind_tables_default + && (USING_SJLJ_EXCEPTIONS +#ifdef TARGET_UNWIND_INFO + || 1 +#endif + )))) { inform (input_location, "-freorder-blocks-and-partition does not work on this architecture"); @@ -1097,21 +1124,49 @@ decode_options (unsigned int argc, const char **argv) if (!flag_sel_sched_pipelining) flag_sel_sched_pipelining_outer_loops = 0; -#ifndef IRA_COVER_CLASSES - if (flag_ira) + if (!targetm.ira_cover_classes + && flag_ira_algorithm == IRA_ALGORITHM_CB) { - inform (input_location, "-fira does not work on this architecture"); - flag_ira = 0; + inform (input_location, + "-fira-algorithm=CB does not work on this architecture"); + flag_ira_algorithm = IRA_ALGORITHM_PRIORITY; } -#endif - /* Save the current optimization options if this is the first call. */ - if (first_time_p) + if (flag_conserve_stack) { - optimization_default_node = build_optimization_node (); - optimization_current_node = optimization_default_node; - first_time_p = false; + if (!PARAM_SET_P (PARAM_LARGE_STACK_FRAME)) + PARAM_VALUE (PARAM_LARGE_STACK_FRAME) = 100; + if (!PARAM_SET_P (PARAM_STACK_FRAME_GROWTH)) + PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 40; + } + if (flag_wpa || flag_ltrans) + { + /* These passes are not WHOPR compatible yet. */ + flag_ipa_cp = 0; + flag_ipa_reference = 0; + flag_ipa_type_escape = 0; + flag_ipa_pta = 0; + flag_ipa_struct_reorg = 0; + } + + if (flag_lto || flag_whopr) + { +#ifdef ENABLE_LTO + flag_generate_lto = 1; + + /* When generating IL, do not operate in whole-program mode. + Otherwise, symbols will be privatized too early, causing link + errors later. */ + flag_whole_program = 0; +#else + error ("LTO support has not been enabled in this configuration"); +#endif } + + /* Reconcile -flto and -fwhopr. Set additional flags as appropriate and + check option consistency. */ + if (flag_lto && flag_whopr) + error ("-flto and -fwhopr are mutually exclusive"); } #define LEFT_COLUMN 27 @@ -1307,7 +1362,7 @@ print_filtered_help (unsigned int include_flags, printf (_(" None found. Use --help=%s to show *all* the options supported by the %s front-end\n"), lang_names[i], lang_names[i]); } - + } else if (! displayed) printf (_(" All options with the desired characteristics have already been displayed\n")); @@ -1381,7 +1436,7 @@ print_specific_help (unsigned int include_flags, default: if (i >= cl_lang_count) break; - if ((exclude_flags & ((1U << cl_lang_count) - 1)) != 0) + if (exclude_flags & all_langs_mask) description = _("The following options are specific to just the language "); else description = _("The following options are supported by the language "); @@ -1394,8 +1449,12 @@ print_specific_help (unsigned int include_flags, { if (any_flags == 0) { - if (include_flags == CL_UNDOCUMENTED) + if (include_flags & CL_UNDOCUMENTED) description = _("The following options are not documented"); + else if (include_flags & CL_SEPARATE) + description = _("The following options take separate arguments"); + else if (include_flags & CL_JOINED) + description = _("The following options take joined arguments"); else { internal_error ("unrecognized include_flags 0x%x passed to print_specific_help", @@ -1423,7 +1482,7 @@ print_specific_help (unsigned int include_flags, static int common_handle_option (size_t scode, const char *arg, int value, - unsigned int lang_mask) + unsigned int lang_mask, int kind ATTRIBUTE_UNUSED) { static bool verbose = false; enum opt_code code = (enum opt_code) scode; @@ -1506,7 +1565,7 @@ common_handle_option (size_t scode, const char *arg, int value, { NULL, 0 } }; unsigned int * pflags; - char * comma; + const char * comma; unsigned int lang_flag, specific_flag; unsigned int len; unsigned int i; @@ -1524,6 +1583,11 @@ common_handle_option (size_t scode, const char *arg, int value, len = strlen (a); else len = comma - a; + if (len == 0) + { + a = comma + 1; + continue; + } /* Check to see if the string matches an option class name. */ for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++) @@ -1532,7 +1596,7 @@ common_handle_option (size_t scode, const char *arg, int value, specific_flag = specifics[i].flag; break; } - + /* Check to see if the string matches a language name. Note - we rely upon the alpha-sorted nature of the entries in the lang_names array, specifically that shorter names appear @@ -1583,8 +1647,8 @@ common_handle_option (size_t scode, const char *arg, int value, break; } + case OPT_fversion: case OPT__version: - print_version (stderr, ""); exit_after_options = true; break; @@ -1598,28 +1662,13 @@ common_handle_option (size_t scode, const char *arg, int value, /* Currently handled in a prescan. */ break; - case OPT_W: - /* For backward compatibility, -W is the same as -Wextra. */ - set_Wextra (value); - break; - - case OPT_Wdisallowed_function_list_: - warn_disallowed_functions = true; - add_comma_separated_to_vector - (&warning_disallowed_functions, arg); - break; - case OPT_Werror_: enable_warning_as_error (arg, value, lang_mask); break; - case OPT_Wextra: - set_Wextra (value); - break; - case OPT_Wlarger_than_: - /* This form corresponds to -Wlarger-than-. - Kept for backward compatibility. + /* This form corresponds to -Wlarger-than-. + Kept for backward compatibility. Don't use it as the first argument of warning(). */ case OPT_Wlarger_than_eq: @@ -1681,6 +1730,10 @@ common_handle_option (size_t scode, const char *arg, int value, dump_base_name = arg; break; + case OPT_dumpdir: + dump_dir_name = arg; + break; + case OPT_falign_functions_: align_functions = value; break; @@ -1732,7 +1785,7 @@ common_handle_option (size_t scode, const char *arg, int value, break; case OPT_fdiagnostics_show_option: - global_dc->show_option_requested = true; + global_dc->show_option_requested = value; break; case OPT_fdump_: @@ -1740,6 +1793,15 @@ common_handle_option (size_t scode, const char *arg, int value, return 0; break; + case OPT_fexcess_precision_: + if (!strcmp (arg, "fast")) + flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; + else if (!strcmp (arg, "standard")) + flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; + else + error ("unknown excess precision style \"%s\"", arg); + break; + case OPT_ffast_math: set_fast_math_flags (value); break; @@ -1786,6 +1848,22 @@ common_handle_option (size_t scode, const char *arg, int value, flag_peel_loops_set = true; break; + case OPT_fplugin_: +#ifdef ENABLE_PLUGIN + add_new_plugin (arg); +#else + error ("Plugin support is disabled. Configure with --enable-plugin."); +#endif + break; + + case OPT_fplugin_arg_: +#ifdef ENABLE_PLUGIN + parse_plugin_arg_opt (arg); +#else + error ("Plugin support is disabled. Configure with --enable-plugin."); +#endif + break; + case OPT_fprofile_arcs: profile_arc_flag_set = true; break; @@ -1973,16 +2051,25 @@ common_handle_option (size_t scode, const char *arg, int value, break; case OPT_fira_algorithm_: - if (!strcmp (arg, "regional")) - flag_ira_algorithm = IRA_ALGORITHM_REGIONAL; - else if (!strcmp (arg, "CB")) + if (!strcmp (arg, "CB")) flag_ira_algorithm = IRA_ALGORITHM_CB; - else if (!strcmp (arg, "mixed")) - flag_ira_algorithm = IRA_ALGORITHM_MIXED; + else if (!strcmp (arg, "priority")) + flag_ira_algorithm = IRA_ALGORITHM_PRIORITY; else warning (0, "unknown ira algorithm \"%s\"", arg); break; + case OPT_fira_region_: + if (!strcmp (arg, "one")) + flag_ira_region = IRA_REGION_ONE; + else if (!strcmp (arg, "all")) + flag_ira_region = IRA_REGION_ALL; + else if (!strcmp (arg, "mixed")) + flag_ira_region = IRA_REGION_MIXED; + else + warning (0, "unknown ira region \"%s\"", arg); + break; + case OPT_fira_verbose_: flag_ira_verbose = value; break; @@ -2023,8 +2110,12 @@ common_handle_option (size_t scode, const char *arg, int value, set_debug_level (SDB_DEBUG, false, arg); break; - case OPT_gdwarf_2: - set_debug_level (DWARF2_DEBUG, false, arg); + case OPT_gdwarf_: + if (value < 2 || value > 4) + error ("dwarf version %d is not supported", value); + else + dwarf_version = value; + set_debug_level (DWARF2_DEBUG, false, ""); break; case OPT_ggdb: @@ -2053,15 +2144,28 @@ common_handle_option (size_t scode, const char *arg, int value, flag_pedantic_errors = pedantic = 1; break; + case OPT_fsee: + case OPT_fcse_skip_blocks: case OPT_floop_optimize: case OPT_frerun_loop_opt: + case OPT_fsched2_use_traces: case OPT_fstrength_reduce: case OPT_ftree_store_copy_prop: case OPT_fforce_addr: case OPT_ftree_salias: + case OPT_ftree_store_ccp: + case OPT_Wunreachable_code: + case OPT_fargument_alias: + case OPT_fargument_noalias: + case OPT_fargument_noalias_anything: + case OPT_fargument_noalias_global: /* These are no-ops, preserved for backward compatibility. */ break; + case OPT_fuse_linker_plugin: + /* No-op. Used by the driver and passed to us because it starts with f.*/ + break; + default: /* If the flag was handled in a standard way, assume the lack of processing here is intentional. */ @@ -2098,22 +2202,7 @@ handle_param (const char *carg) free (arg); } -/* Handle -W and -Wextra. */ -static void -set_Wextra (int setting) -{ - extra_warnings = setting; - - /* We save the value of warn_uninitialized, since if they put - -Wuninitialized on the command line, we need to generate a - warning about not using it without also specifying -O. */ - if (setting == 0) - warn_uninitialized = 0; - else if (warn_uninitialized != 1) - warn_uninitialized = 2; -} - -/* Used to set the level of strict aliasing warnings, +/* Used to set the level of strict aliasing warnings, when no level is specified (i.e., when -Wstrict-aliasing, and not -Wstrict-aliasing=level was given). ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified, @@ -2146,8 +2235,8 @@ set_fast_math_flags (int set) } } -/* When -funsafe-math-optimizations is set the following - flags are set as well. */ +/* When -funsafe-math-optimizations is set the following + flags are set as well. */ void set_unsafe_math_optimizations_flags (int set) { @@ -2222,15 +2311,17 @@ set_debug_level (enum debug_info_type type, int extended, const char *arg) if (*arg == '\0') { if (!debug_info_level) - debug_info_level = 2; + debug_info_level = DINFO_LEVEL_NORMAL; } else { - debug_info_level = integral_argument (arg); - if (debug_info_level == (unsigned int) -1) + int argval = integral_argument (arg); + if (argval == -1) error ("unrecognised debug output level \"%s\"", arg); - else if (debug_info_level > 3) + else if (argval > 3) error ("debug output level %s is too high", arg); + else + debug_info_level = (enum debug_info_level) argval; } } @@ -2297,6 +2388,61 @@ get_option_state (int option, struct cl_option_state *state) return true; } +/* Set *OPTION according to VALUE and ARG. */ + +void +set_option (int opt_index, int value, const char *arg, int kind) +{ + const struct cl_option *option = &cl_options[opt_index]; + + if (!option->flag_var) + return; + + switch (option->var_type) + { + case CLVC_BOOLEAN: + *(int *) option->flag_var = value; + break; + + case CLVC_EQUAL: + *(int *) option->flag_var = (value + ? option->var_value + : !option->var_value); + break; + + case CLVC_BIT_CLEAR: + case CLVC_BIT_SET: + if ((value != 0) == (option->var_type == CLVC_BIT_SET)) + *(int *) option->flag_var |= option->var_value; + else + *(int *) option->flag_var &= ~option->var_value; + if (option->flag_var == &target_flags) + target_flags_explicit |= option->var_value; + break; + + case CLVC_STRING: + *(const char **) option->flag_var = arg; + break; + } + + if ((diagnostic_t)kind != DK_UNSPECIFIED) + diagnostic_classify_diagnostic (global_dc, opt_index, (diagnostic_t)kind); +} + + +/* Callback function, called when -Werror= enables a warning. */ + +static void (*warning_as_error_callback) (int) = NULL; + +/* Register a callback for enable_warning_as_error calls. */ + +void +register_warning_as_error_callback (void (*callback) (int)) +{ + gcc_assert (warning_as_error_callback == NULL || callback == NULL); + warning_as_error_callback = callback; +} + /* Enable a warning option as an error. This is used by -Werror= and also by legacy Werror-implicit-function-declaration. */ @@ -2316,14 +2462,20 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask) } else { - int kind = value ? DK_ERROR : DK_WARNING; + const diagnostic_t kind = value ? DK_ERROR : DK_WARNING; + diagnostic_classify_diagnostic (global_dc, option_index, kind); - - /* -Werror=foo implies -Wfoo. */ - if (cl_options[option_index].var_type == CLVC_BOOLEAN - && cl_options[option_index].flag_var - && kind == DK_ERROR) - *(int *) cl_options[option_index].flag_var = 1; + if (kind == DK_ERROR) + { + const struct cl_option * const option = cl_options + option_index; + + /* -Werror=foo implies -Wfoo. */ + if (option->var_type == CLVC_BOOLEAN) + handle_option (option_index, value, arg, lang_mask, (int)kind); + + if (warning_as_error_callback) + warning_as_error_callback (option_index); + } } free (new_option); }