RFC for this topic. Comments are welcome as is someone volunteering to
cleanup this mess :-)

On 30.06.21 14:24, Tobias Burnus wrote:
This is a side effect of removing 'foffload=' from Common
as Driver only does not show up with --help=... but only
as hard-coded list via display_help.

While looking at that issue, Jakub and I wondered whether there
should be some warning if a Driver option has a help text,
which never appears.

Jakub mentioned
  -dumpdir
but that's also in Common and, hence, shows up with
  --help=common
but admittedly not with --help

 * * *

However, the following items are Drivar and neither LTO, C, Fortran nor
Common and do have a help text (that never shows up).

(Extracted with the first attached patch, as we wondered whether a
warning could make sense.)

* Those appear with --help as they have a puts line in gcc.c's display_help():
common.opt      no-pie
common.opt      pie
common.opt      shared
common.opt      static-pie

* While those don't but they also cannot be added to gcc.c
as they are FE specific driver options:
c-family/c.opt  static-libmpx
c-family/c.opt  static-libmpxwrappers
common.opt      foffload=
d/lang.opt      debuglib=
d/lang.opt      defaultlib=
d/lang.opt      dstartfiles
d/lang.opt      nophoboslib
d/lang.opt      shared-libphobos
d/lang.opt      static-libphobos

 * * *

Additionally, I was wondering whether having --help=driver makes sense.

That I tried with the following patch, but it looks as if I missed some
fineprint as Driver-only flags were still not printed, if I recall
correctly.

BTW: -help='s helptext differs between the hard-coded one in gcc.c
(used by --help) and the one in common.opt (shown, e.g., by --help=common).

Even with that patch applied, --help= does not really have a useful
error message while --help=something-invalid has.

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 880ac776d8a..d63407c5c88 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -275,6 +275,25 @@ for (i = 0; i < n_opts; i++) {
 		indices[opts[i]] = j;
 	}
 	j++;
+	if (help[i] != "" && flag_set_p("Driver", flags[i]) \
+	    && !flag_set_p("Common", flags[i])) {
+		nflags = split(switch_flags(flags[i]), flag_array, " | ")
+		help_warn = 1
+		for (j = 0; j < nflags; j++) {
+			if (flag_array[j] != "" \
+			    && flag_array[j] != "|" \
+			    && flag_array[j] != "CL_DRIVER" \
+			    && flag_array[j] != "CL_SEPARATE" \
+			    && flag_array[j] != "CL_JOINED" \
+			    && flag_array[j] != "CL_UNDOCUMENTED") {
+				help_warn = 0
+			}
+		}
+		if (help_warn != 0)
+			print "#warning Help text provided for Driver only " \
+			        "option '" opts[i] "' move it to gcc.c's  " \
+				"display_help: " help[i]
+	}
 }
 
 optindex = 0
diff --git a/gcc/opts.c b/gcc/opts.c
index f159bb35130..df5e2462d76 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1815,7 +1815,9 @@ print_specific_help (unsigned int include_flags,
     {
       if (any_flags == 0)
 	{
-	  if (include_flags & CL_UNDOCUMENTED)
+	  if (include_flags & CL_DRIVER)
+	    description = _("The following options control the driver");
+	  else 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");
@@ -2276,30 +2278,38 @@ print_help (struct gcc_options *opts, unsigned int lang_mask,
   if (lang_mask == CL_DRIVER)
     return;
 
+  static const struct
+    {
+      const char *string;
+      unsigned int flag;
+    }
+  specifics[] =
+    {
+      { "common", CL_COMMON },
+      { "driver", CL_DRIVER },
+      { "joined", CL_JOINED },
+      { "optimizers", CL_OPTIMIZATION },
+      { "params", CL_PARAMS },
+      { "separate", CL_SEPARATE },
+      { "target", CL_TARGET },
+      { "undocumented", CL_UNDOCUMENTED },
+      { "warnings", CL_WARNING },
+      { NULL, 0 }
+    };
+
+  auto_vec <const char *> candidates;
+  for (unsigned int i = 0; specifics[i].string != NULL; i++)
+    candidates.safe_push (specifics[i].string);
+  for (unsigned int i = 0; i < cl_lang_count; i++)
+    candidates.safe_push (lang_names[i]);
+
   /* Walk along the argument string, parsing each word in turn.
      The format is:
      arg = [^]{word}[,{arg}]
-     word = {optimizers|target|warnings|undocumented|
-     params|common|<language>}  */
+     word = {common|driver|joined|optimizers|params|separate
+	     |target|undocumented|warnings|<language>}  */
   while (*a != 0)
     {
-      static const struct
-	{
-	  const char *string;
-	  unsigned int flag;
-	}
-      specifics[] =
-	{
-	    { "optimizers", CL_OPTIMIZATION },
-	    { "target", CL_TARGET },
-	    { "warnings", CL_WARNING },
-	    { "undocumented", CL_UNDOCUMENTED },
-	    { "params", CL_PARAMS },
-	    { "joined", CL_JOINED },
-	    { "separate", CL_SEPARATE },
-	    { "common", CL_COMMON },
-	    { NULL, 0 }
-	};
       unsigned int *pflags;
       const char *comma;
       unsigned int lang_flag, specific_flag;
@@ -2311,7 +2321,11 @@ print_help (struct gcc_options *opts, unsigned int lang_mask,
 	  ++a;
 	  if (*a == '\0')
 	    {
+	      char *s;
 	      error ("missing argument to %qs", "--help=^");
+	      candidates_list_and_hint ("", s, candidates);
+	      inform (UNKNOWN_LOCATION, "valid arguments to %qs are: %s", "--help=^", s);
+	      XDELETEVEC (s);
 	      break;
 	    }
 	  pflags = &exclude_flags;
@@ -2365,18 +2379,38 @@ print_help (struct gcc_options *opts, unsigned int lang_mask,
 	      if (strncasecmp (a, "c", len) == 0)
 		*pflags |= lang_flag;
 	      else
-		warning (0,
-			 "%<--help%> argument %q.*s is ambiguous, "
-			 "please be more specific",
-			 len, a);
+		{
+		  char *s;
+		  warning (0,
+			   "%<--help%> argument %q.*s is ambiguous, "
+			   "please be more specific",
+			   len, a);
+		  candidates_list_and_hint ("", s, candidates);
+		  inform (UNKNOWN_LOCATION,
+			  "valid arguments to %qs are: %s", "--help=", s);
+		  XDELETEVEC (s);
+		}
 	    }
 	}
       else if (lang_flag != 0)
 	*pflags |= lang_flag;
       else
-	warning (0,
-		 "unrecognized argument to %<--help=%> option: %q.*s",
-		 len, a);
+	{
+	  char *s;
+	  char *arg = XALLOCAVEC (char, len + 1);
+	  memcpy (arg, a, len);
+	  arg[len] = '\0';
+	  warning (0, "unrecognized argument to %<--help=%> option: %qs", arg);
+	  const char *hint = candidates_list_and_hint (arg, s, candidates);
+	  if (hint)
+	    inform (UNKNOWN_LOCATION,
+		    "valid arguments to %qs are: %s; did you mean %qs?",
+		    "--help", s, hint);
+	  else
+	    inform (UNKNOWN_LOCATION,
+		    "valid arguments to %qs are: %s", "--help=", s);
+	  XDELETEVEC (s);
+	}
 
       if (comma == NULL)
 	break;

Reply via email to