This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Offer suggestions for unrecognized sanitizer options (PR driver/78877)


PR driver/78877 notes that we offer a suggestion for
"-fsanitize-addres" (with a hyphen):

  xgcc: error: unrecognized command line option '-fsanitize-addres';
  did you mean '-fsanitize=address'?

but not for "-fsanitize=addres" (with an equals sign):

  xgcc: error: unrecognized argument to -fsanitize= option: 'addres'

This patch implements suggestions for the latter case.

The input arguments are not always 0-terminated, since they are accessed
from a comma-separated buffer, so we need some extra types for describing
this to the spellchecker code (struct string_fragment and the
specialization of edit_distance_traits).

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.

OK for trunk?

gcc/ChangeLog:
	PR driver/78877
	* opts.c: Include "spellcheck.h"
	(struct string_fragment): New struct.
	(struct edit_distance_traits<const string_fragment &>): New
	struct.
	(get_closest_sanitizer_option): New function.
	(parse_sanitizer_options): Offer suggestions for unrecognized arguments.

gcc/testsuite/ChangeLog:
	PR driver/78877
	* gcc.dg/spellcheck-options-14.c: New test case.
---
 gcc/opts.c                                   | 57 +++++++++++++++++++++++++++-
 gcc/testsuite/gcc.dg/spellcheck-options-14.c |  8 ++++
 2 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/spellcheck-options-14.c

diff --git a/gcc/opts.c b/gcc/opts.c
index 059a61a..6ee02d6 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "opts-diagnostic.h"
 #include "insn-attr-common.h"
 #include "common/common-target.h"
+#include "spellcheck.h"
 
 static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
 
@@ -1511,6 +1512,46 @@ const struct sanitizer_opts_s sanitizer_opts[] =
   { NULL, 0U, 0UL, false }
 };
 
+/* A struct for describing a run of chars within a string.  */
+
+struct string_fragment
+{
+  string_fragment (const char *start, size_t len)
+  : m_start (start), m_len (len) {}
+
+  const char *m_start;
+  size_t m_len;
+};
+
+/* Specialization of edit_distance_traits for string_fragment,
+   for use by get_closest_sanitizer_option.  */
+
+template <>
+struct edit_distance_traits<const string_fragment &>
+{
+  static size_t get_length (const string_fragment &fragment)
+  {
+    return fragment.m_len;
+  }
+
+  static const char *get_string (const string_fragment &fragment)
+  {
+    return fragment.m_start;
+  }
+};
+
+/* Given ARG, an unrecognized sanitizer option, return the best
+   matching sanitizer option, or NULL if there isn't one.  */
+
+static const char *
+get_closest_sanitizer_option (const string_fragment &arg)
+{
+  best_match <const string_fragment &, const char*> bm (arg);
+  for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
+    bm.consider (sanitizer_opts[i].name);
+  return bm.get_best_meaningful_candidate ();
+}
+
 /* 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.  */
@@ -1572,8 +1613,20 @@ parse_sanitizer_options (const char *p, location_t loc, int scode,
 	  }
 
       if (! found && complain)
-	error_at (loc, "unrecognized argument to -fsanitize%s= option: %q.*s",
-		  code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
+	{
+	  const char *optname
+	    = code == OPT_fsanitize_ ? "-fsanitize" : "-fsanitize-recover";
+	  const char *hint
+	    = get_closest_sanitizer_option (string_fragment (p, len));
+
+	  if (hint)
+	    error_at (loc, "unrecognized argument to %s= option: %q.*s;"
+		      " did you mean %qs",
+		      optname, (int) len, p, hint);
+	  else
+	    error_at (loc, "unrecognized argument to %s= option: %q.*s",
+		      optname, (int) len, p);
+	}
 
       if (comma == NULL)
 	break;
diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-14.c b/gcc/testsuite/gcc.dg/spellcheck-options-14.c
new file mode 100644
index 0000000..5582460
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-options-14.c
@@ -0,0 +1,8 @@
+/* Verify that we offer suggestions for misspelled sanitizer options
+   (PR driver/78877).  */
+
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=addres,nul,this-is-not-a-sanitizer-option" } */
+/* { dg-error "unrecognized argument to -fsanitize= option: .addres.; did you mean .address." "" { target *-*-* } 0 } */
+/* { dg-error "unrecognized argument to -fsanitize= option: .nul.; did you mean .null." "" { target *-*-* } 0 } */
+/* { dg-error "unrecognized argument to -fsanitize= option: .this-is-not-a-sanitizer-option." "" { target *-*-* } 0 } */
-- 
1.8.5.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]