PR driver/88911 reports an issue where the user couldn't remember the spelling of the "-dumpspecs" option, and attempted various similar spellings, but many of them failed to contain a suggestion of the correct spelling:
$ gcc q.c -dump-spec cc1: warning: unrecognized gcc debugging option: u cc1: warning: unrecognized gcc debugging option: m cc1: warning: unrecognized gcc debugging option: - cc1: warning: unrecognized gcc debugging option: s cc1: warning: unrecognized gcc debugging option: e cc1: warning: unrecognized gcc debugging option: c $ gcc q.c -dump-specs cc1: warning: unrecognized gcc debugging option: u cc1: warning: unrecognized gcc debugging option: m cc1: warning: unrecognized gcc debugging option: - cc1: warning: unrecognized gcc debugging option: s cc1: warning: unrecognized gcc debugging option: e cc1: warning: unrecognized gcc debugging option: c cc1: warning: unrecognized gcc debugging option: s $ gcc q.c -fdump-spec cc1: error: unrecognized command line option '-fdump-spec' $ gcc q.c -fdump-specs cc1: error: unrecognized command line option '-fdump-specs' $ gcc q.c -fdumpspecs gcc: error: unrecognized command line option '-fdumpspecs'; did you mean '-dumpspecs'? [Aha!] There are two issues here: (a) unmatched options beginning with "-d" are treated as part of the "-d" option, leading to a warning from decode_d_option, but no suggestion. (b) options beginning with "-fdump-" are also passed to a special handler, and this doesn't offer suggestions for unmatched options either. This patch uses option_proposer::suggest_option to add suggestions in both places, leading to useful suggestions for all of the cases given above. For the case of "-d" it only offers a suggestion for the first unrecognized character. I also added quotes around the character in the message, and indicate the full option for context, so that the first example above becomes: $ gcc q.c -dump-spec cc1: warning: unrecognized gcc debugging option: 'u' (as part of '-dump-spec'); did you mean '-dumpspecs'? cc1: warning: unrecognized gcc debugging option: 'm' (as part of '-dump-spec') cc1: warning: unrecognized gcc debugging option: '-' (as part of '-dump-spec') cc1: warning: unrecognized gcc debugging option: 's' (as part of '-dump-spec') cc1: warning: unrecognized gcc debugging option: 'e' (as part of '-dump-spec') cc1: warning: unrecognized gcc debugging option: 'c' (as part of '-dump-spec') Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Is this patch OK for trunk? (it's not a regression, but it's fairly self-contained, so would this be acceptable now, or should I queue it for when stage 1 reopens?) gcc/ChangeLog: PR driver/88911 * opts-global.c: Include "opt-suggestions.h". (handle_common_deferred_options) <OPT_fdump_>: If the argument is unrecognized, attempt to provide a hint. * opts.c: Include "opt-suggestions.h". (common_handle_option) <OPT_d>: Pass original option argument text to decode_d_option. (decode_d_option): Add parameter "orig_arg". Use it to provide a hint within the first unrecognized character. Wrap the character in quotes, and indicate the original argument it belongs to. gcc/testsuite/ChangeLog: PR driver/88911 * gcc.dg/spellcheck-options-pr88911-1.c: New test. * gcc.dg/spellcheck-options-pr88911-2.c: New test. * gcc.dg/spellcheck-options-pr88911-3.c: New test. * gcc.dg/spellcheck-options-pr88911-4.c: New test. * gcc.dg/spellcheck-options-pr88911-5.c: New test. --- gcc/opts-global.c | 17 +++++++- gcc/opts.c | 45 +++++++++++++++++++--- .../gcc.dg/spellcheck-options-pr88911-1.c | 8 ++++ .../gcc.dg/spellcheck-options-pr88911-2.c | 3 ++ .../gcc.dg/spellcheck-options-pr88911-3.c | 3 ++ .../gcc.dg/spellcheck-options-pr88911-4.c | 3 ++ .../gcc.dg/spellcheck-options-pr88911-5.c | 3 ++ 7 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-pr88911-1.c create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-pr88911-2.c create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-pr88911-3.c create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-pr88911-4.c create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-pr88911-5.c diff --git a/gcc/opts-global.c b/gcc/opts-global.c index 1c24c85..cc30341 100644 --- a/gcc/opts-global.c +++ b/gcc/opts-global.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "asan.h" #include "file-prefix-map.h" /* add_*_prefix_map() */ +#include "opt-suggestions.h" typedef const char *const_char_p; /* For DEF_VEC_P. */ @@ -372,7 +373,21 @@ handle_common_deferred_options (void) case OPT_fdump_: if (!g->get_dumps ()->dump_switch_p (opt->arg)) - error ("unrecognized command line option %<-fdump-%s%>", opt->arg); + { + option_proposer prop; + /* option_proposer::suggest_option expects the leading dash + to have been stripped from its argument, so we rebuild + the arg without one. */ + char *orig_arg = xasprintf ("fdump-%s", opt->arg); + if (const char *hint = prop.suggest_option (orig_arg)) + error ("unrecognized command line option %<-%s%>" + "; did you mean %<-%s%>?", + orig_arg, hint); + else + error ("unrecognized command line option %<-%s%>", + orig_arg); + free (orig_arg); + } break; case OPT_fopt_info_: diff --git a/gcc/opts.c b/gcc/opts.c index a4be6ae..0722549 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "insn-attr-common.h" #include "common/common-target.h" #include "spellcheck.h" +#include "opt-suggestions.h" static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff); @@ -195,7 +196,8 @@ static void set_debug_level (enum debug_info_type type, int extended, struct gcc_options *opts_set, location_t loc); static void set_fast_math_flags (struct gcc_options *opts, int set); -static void decode_d_option (const char *arg, struct gcc_options *opts, +static void decode_d_option (const char *arg, const char *orig_arg, + struct gcc_options *opts, location_t loc, diagnostic_context *dc); static void set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set); @@ -2345,7 +2347,7 @@ common_handle_option (struct gcc_options *opts, break; case OPT_d: - decode_d_option (arg, opts, loc, dc); + decode_d_option (arg, decoded->orig_option_with_args_text, opts, loc, dc); break; case OPT_fcall_used_: @@ -2999,14 +3001,18 @@ setup_core_dumping (diagnostic_context *dc) } /* Parse a -d<ARG> command line switch for OPTS, location LOC, - diagnostic context DC. */ + diagnostic context DC, where ORIG_ARG was the original text + of the switch. */ static void -decode_d_option (const char *arg, struct gcc_options *opts, +decode_d_option (const char *arg, const char *orig_arg, + struct gcc_options *opts, location_t loc, diagnostic_context *dc) { int c; + bool emitted_unrecognized = false; + while (*arg) switch (c = *arg++) { @@ -3037,7 +3043,36 @@ decode_d_option (const char *arg, struct gcc_options *opts, break; default: - warning_at (loc, 0, "unrecognized gcc debugging option: %c", c); + { + /* Perhaps the user misspelled one of the other options beginning + with "-d" (e.g. -dumpspecs). + The first time we emit such a warning, attempt to suggest such + an option. */ + char *hint = NULL; + if (!emitted_unrecognized) + { + option_proposer prop; + emitted_unrecognized = true; + /* option_proposer::suggest_option expects the leading dash + to have been stripped from its argument, so we advance + one character. */ + gcc_assert (orig_arg[0] == '-'); + if (const char *h = prop.suggest_option (orig_arg + 1)) + hint = xstrdup (h); + } + if (hint) + { + warning_at (loc, 0, + "unrecognized gcc debugging option: %qc" + " (as part of %qs);" + " did you mean %<-%s%>?", c, orig_arg, hint); + free (hint); + } + else + warning_at (loc, 0, + "unrecognized gcc debugging option: %qc" + " (as part of %qs)", c, orig_arg); + } break; } } diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-1.c b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-1.c new file mode 100644 index 0000000..45462e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-dump-spec" } */ +/* { dg-warning "unrecognized gcc debugging option: 'u' \\(as part of '-dump-spec'\\); did you mean '-dumpspecs'?" "" { target *-*-* } 0 } */ +/* { dg-warning "unrecognized gcc debugging option: 'm' \\(as part of '-dump-spec'\\)" "" { target *-*-* } 0 } */ +/* { dg-warning "unrecognized gcc debugging option: '-' \\(as part of '-dump-spec'\\)" "" { target *-*-* } 0 } */ +/* { dg-warning "unrecognized gcc debugging option: 's' \\(as part of '-dump-spec'\\)" "" { target *-*-* } 0 } */ +/* { dg-warning "unrecognized gcc debugging option: 'e' \\(as part of '-dump-spec'\\)" "" { target *-*-* } 0 } */ +/* { dg-warning "unrecognized gcc debugging option: 'c' \\(as part of '-dump-spec'\\)" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-2.c b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-2.c new file mode 100644 index 0000000..c764dc9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-2.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-spec" } */ +/* { dg-error "unrecognized command line option '-fdump-spec'; did you mean '-dumpspecs'?" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-3.c b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-3.c new file mode 100644 index 0000000..4034721 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-3.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-specs" } */ +/* { dg-error "unrecognized command line option '-fdump-specs'; did you mean '-dumpspecs'?" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-4.c b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-4.c new file mode 100644 index 0000000..3270bbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-4.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-d3" } */ +/* { dg-warning "unrecognized gcc debugging option: '3' \\(as part of '-d3'\\)" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-5.c b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-5.c new file mode 100644 index 0000000..6f9cf03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/spellcheck-options-pr88911-5.c @@ -0,0 +1,3 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-something-not-recognized" } */ +/* { dg-error "unrecognized command line option '-fdump-something-not-recognized" "" { target *-*-* } 0 } */ -- 1.8.5.3