diff mbox series

Provide suggestions for unrecognized -dump options (PR driver/88911)

Message ID 1548179733-41768-1-git-send-email-dmalcolm@redhat.com
State New
Headers show
Series Provide suggestions for unrecognized -dump options (PR driver/88911) | expand

Commit Message

David Malcolm Jan. 22, 2019, 5:55 p.m. UTC
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

Comments

Jeff Law April 30, 2019, 4:38 p.m. UTC | #1
On 1/22/19 10:55 AM, David Malcolm wrote:
> 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.
A "pocket veto" for gcc-9 :-)  However it makes a lot of sense to me for
gcc-10.

It looks reasonable to me.  Can't hurt to spin it again before committing.

jeff
diff mbox series

Patch

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 } */