diff --git a/gcc/opts.cc b/gcc/opts.cc index a0baec98092..c9badd241a0 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -1333,10 +1333,29 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, && !(opts->x_flag_selective_scheduling || opts->x_flag_selective_scheduling2)); - /* Note -fvar-tracking is enabled automatically with OPT_LEVELS_1_PLUS and - so we need to drop it if we are called from optimize attribute. */ - if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL) - opts->x_flag_var_tracking = false; + /* We know which debug output will be used so we can set flag_var_tracking + and flag_var_tracking_uninit if the user has not specified them. Note + we have not yet initialized debug_hooks so we might uselessly run + var-tracking on targets without var_location debug hook support. */ + if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL + || !dwarf_debuginfo_p (opts)) + { + if ((opts_set->x_flag_var_tracking && opts->x_flag_var_tracking == 1) + || (opts_set->x_flag_var_tracking_uninit + && opts->x_flag_var_tracking_uninit == 1)) + { + if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL) + warning_at (UNKNOWN_LOCATION, 0, + "variable tracking requested, but useless unless " + "producing debug info"); + else + warning_at (UNKNOWN_LOCATION, 0, + "variable tracking requested, but not supported " + "by this debug format"); + } + opts->x_flag_var_tracking = 0; + opts->x_flag_var_tracking_uninit = 0; + } /* One could use EnabledBy, but it would lead to a circular dependency. */ if (!opts_set->x_flag_var_tracking_uninit) diff --git a/gcc/testsuite/gcc.dg/torture/pr105537.c b/gcc/testsuite/gcc.dg/torture/pr105537.c new file mode 100644 index 00000000000..2e4825c4720 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105537.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffast-math -fsignaling-nans -fvar-tracking-assignments -fno-move-loop-stores -ftree-loop-distribution" } */ + +int n; + +double +ext1 (int); + +void +ext2 (double); + +int +sum (int v1, int v2) +{ + return v1 + v2; +} + +void +bar (void) +{ + ext2 (ext1 (n)); +} + +__attribute__ ((optimize ("-O3"))) void +foo (int *x) +{ + static int i; + + bar (); + for (i = 0; i != 2; i = sum (i, 1)) + n = *x = 0; +} + +/* { dg-message "other options take precedence" "" { target *-*-* } 0 } */ diff --git a/gcc/toplev.cc b/gcc/toplev.cc index ed546b2cad8..055e0642f77 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -1458,30 +1458,6 @@ process_options (bool no_backend) debug_type_names[debug_set_to_format (write_symbols)]); } - /* We know which debug output will be used so we can set flag_var_tracking - and flag_var_tracking_uninit if the user has not specified them. */ - if (debug_info_level < DINFO_LEVEL_NORMAL - || !dwarf_debuginfo_p () - || debug_hooks->var_location == do_nothing_debug_hooks.var_location) - { - if ((OPTION_SET_P (flag_var_tracking) && flag_var_tracking == 1) - || (OPTION_SET_P (flag_var_tracking_uninit) - && flag_var_tracking_uninit == 1)) - { - if (debug_info_level < DINFO_LEVEL_NORMAL) - warning_at (UNKNOWN_LOCATION, 0, - "variable tracking requested, but useless unless " - "producing debug info"); - else - warning_at (UNKNOWN_LOCATION, 0, - "variable tracking requested, but not supported " - "by this debug format"); - } - flag_var_tracking = 0; - flag_var_tracking_uninit = 0; - flag_var_tracking_assignments = 0; - } - /* The debug hooks are used to implement -fdump-go-spec because it gives a simple and stable API for all the information we need to dump. */