diff --git a/gcc/ada/gcc-interface/lang.opt b/gcc/ada/gcc-interface/lang.opt
index 241eafc..17c6dc8 100644
--- a/gcc/ada/gcc-interface/lang.opt
+++ b/gcc/ada/gcc-interface/lang.opt
@@ -81,15 +81,15 @@ Ada AdaWhy AdaSCIL
 Make \"char\" signed by default.
 
 gant
-Ada AdaWhy AdaSCIL Driver Joined Undocumented
+Ada AdaWhy AdaSCIL Driver Joined Undocumented RejectNegative
 Catch typos.
 
 gnatO
-Ada AdaWhy AdaSCIL Driver Separate
+Ada AdaWhy AdaSCIL Driver Separate RejectNegative
 Set name of output ALI file (internal switch).
 
 gnat
-Ada AdaWhy AdaSCIL Driver Joined
+Ada AdaWhy AdaSCIL Driver Joined RejectNegative
 -gnat<options>	Specify options to GNAT.
 
 fbuiltin-printf
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index e0ad3ab..55d9405 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1802,7 +1802,7 @@ ObjC ObjC++ Var(flag_zero_link)
 Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode.
 
 gen-decls
-ObjC ObjC++ Driver Var(flag_gen_declaration)
+ObjC ObjC++ Driver Var(flag_gen_declaration) RejectNegative
 Dump declarations to a .decl file.
 
 femit-struct-debug-baseonly
diff --git a/gcc/common.opt b/gcc/common.opt
index 1cb1c83..d18559a 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -532,13 +532,13 @@ Common RejectNegative Warning Alias(Wextra)
 This switch is deprecated; use -Wextra instead.
 
 Wa,
-Driver JoinedOrMissing
+Driver JoinedOrMissing RejectNegative
 
 Wl,
-Driver JoinedOrMissing
+Driver JoinedOrMissing RejectNegative
 
 Wp,
-Driver JoinedOrMissing
+Driver JoinedOrMissing RejectNegative
 
 Waggregate-return
 Common Var(warn_aggregate_return) Warning
@@ -2819,19 +2819,15 @@ Common Report Var(flag_zero_initialized_in_bss) Init(1)
 Put zero initialized data in the bss section.
 
 g
-Common Driver JoinedOrMissing
+Common Driver RejectNegative JoinedOrMissing
 Generate debug information in default format.
 
 gcoff
 Common Driver JoinedOrMissing Negative(gdwarf)
 Generate debug information in COFF format.
 
-gno-column-info
-Common Driver RejectNegative Var(debug_column_info,0) Init(0)
-Don't record DW_AT_decl_column and DW_AT_call_column in DWARF.
-
 gcolumn-info
-Common Driver RejectNegative Var(debug_column_info,1)
+Common Driver Var(debug_column_info,1) Init(0)
 Record DW_AT_decl_column and DW_AT_call_column in DWARF.
 
 gdwarf
@@ -2846,6 +2842,10 @@ ggdb
 Common Driver JoinedOrMissing
 Generate debug information in default extended format.
 
+gno-
+RejectNegative Joined Undocumented
+; Catch the gno- prefix, so it doesn't backtrack to g<level>.
+
 gno-pubnames
 Common Driver Negative(gpubnames) Var(debug_generate_pub_sections, 0) Init(-1)
 Don't generate DWARF pubnames and pubtypes sections.
@@ -2858,20 +2858,12 @@ ggnu-pubnames
 Common Driver Negative(gno-pubnames) Var(debug_generate_pub_sections, 2)
 Generate DWARF pubnames and pubtypes sections with GNU extensions.
 
-gno-record-gcc-switches
-Common Driver RejectNegative Var(dwarf_record_gcc_switches,0) Init(1)
-Don't record gcc command line switches in DWARF DW_AT_producer.
-
 grecord-gcc-switches
-Common Driver RejectNegative Var(dwarf_record_gcc_switches,1)
+Common Driver Var(dwarf_record_gcc_switches) Init(1)
 Record gcc command line switches in DWARF DW_AT_producer.
 
-gno-split-dwarf
-Common Driver RejectNegative Var(dwarf_split_debug_info,0) Init(0)
-Don't generate debug information in separate .dwo files.
-
 gsplit-dwarf
-Common Driver RejectNegative Var(dwarf_split_debug_info,1)
+Common Driver Var(dwarf_split_debug_info) Init(0)
 Generate debug information in separate .dwo files.
 
 gstabs
@@ -2882,12 +2874,8 @@ gstabs+
 Common Driver JoinedOrMissing Negative(gvms)
 Generate debug information in extended STABS format.
 
-gno-strict-dwarf
-Common Driver RejectNegative Var(dwarf_strict,0) Init(0)
-Emit DWARF additions beyond selected version.
-
 gstrict-dwarf
-Common Driver Report RejectNegative Var(dwarf_strict,1)
+Common Driver Report Var(dwarf_strict) Init(0)
 Don't emit DWARF additions beyond selected version.
 
 gtoggle
@@ -2925,7 +2913,7 @@ Common Driver
 Generate compressed debug sections.
 
 gz=
-Common Driver Joined Enum(compressed_debug_sections)
+Common Driver RejectNegative Joined Enum(compressed_debug_sections)
 -gz=<format>	Generate compressed debug sections in format <format>.
 
 h
diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt
index 135a9c0..48710142 100644
--- a/gcc/config/darwin.opt
+++ b/gcc/config/darwin.opt
@@ -92,10 +92,10 @@ fterminated-vtables
 Driver RejectNegative
 
 gfull
-Driver
+Driver RejectNegative
 
 gused
-Driver
+Driver RejectNegative
 
 headerpad_max_install_names
 Driver
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 917ab9f..82f2a50 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -23370,7 +23370,6 @@ gen_producer_string (void)
       case OPT_SPECIAL_program_name:
       case OPT_SPECIAL_input_file:
       case OPT_grecord_gcc_switches:
-      case OPT_gno_record_gcc_switches:
       case OPT__output_pch_:
       case OPT_fdiagnostics_show_location_:
       case OPT_fdiagnostics_show_option:
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 3cb0005..295bae1 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -328,7 +328,7 @@ for (i = 0; i < n_opts; i++) {
 			alias_data = "NULL, NULL, N_OPTS"
 		if (flag_set_p("Enum.*", flags[i])) {
 			if (!flag_set_p("RejectNegative", flags[i]) \
-			    && opts[i] ~ "^[Wfm]")
+			    && opts[i] ~ "^[Wfgm]")
 				print "#error Enum allowing negative form"
 		}
 	} else {
@@ -370,7 +370,7 @@ for (i = 0; i < n_opts; i++) {
 		if (flag_set_p("RejectNegative", flags[i]))
 			idx = -1;
 		else {
-			if (opts[i] ~ "^[Wfm]")
+			if (opts[i] ~ "^[Wfgm]")
 				idx = indices[opts[i]];
 			else
 				idx = -1;
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 0cab42a0..dede33c 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -28,6 +28,24 @@ along with GCC; see the file COPYING3.  If not see
 
 static void prune_options (struct cl_decoded_option **, unsigned int *);
 
+/* An option that is undocumented, that takes a joined argument, and
+   that doesn't fit any of the classes of uses (language/common,
+   driver, target) is assumed to be a prefix used to catch
+   e.g. negated options, and stop them from being further shortened to
+   a prefix that could use the negated option as an argument.  For
+   example, we want -gno-statement-frontiers to be taken as a negation
+   of -gstatement-frontiers, but without catching the gno- prefix and
+   signaling it's to be used for option remapping, it would end up
+   backtracked to g with no-statemnet-frontiers as the debug level.  */
+
+static bool
+remapping_prefix_p (const struct cl_option *opt)
+{
+  return opt->flags & CL_UNDOCUMENTED
+    && opt->flags & CL_JOINED
+    && !(opt->flags & (CL_DRIVER | CL_TARGET | CL_COMMON | CL_LANG_ALL));
+}
+
 /* Perform a binary search to find which option the command-line INPUT
    matches.  Returns its index in the option array, and
    OPT_SPECIAL_unknown on failure.
@@ -98,6 +116,9 @@ find_opt (const char *input, unsigned int lang_mask)
 	  if (opt->flags & lang_mask)
 	    return mn;
 
+	  if (remapping_prefix_p (opt))
+	    return OPT_SPECIAL_unknown;
+
 	  /* If we haven't remembered a prior match, remember this
 	     one.  Any prior match is necessarily better.  */
 	  if (match_wrong_lang == OPT_SPECIAL_unknown)
@@ -286,7 +307,8 @@ generate_canonical_option (size_t opt_index, const char *arg, int value,
 
   if (value == 0
       && !option->cl_reject_negative
-      && (opt_text[1] == 'W' || opt_text[1] == 'f' || opt_text[1] == 'm'))
+      && (opt_text[1] == 'W' || opt_text[1] == 'f'
+	  || opt_text[1] == 'g' || opt_text[1] == 'm'))
     {
       char *t = XOBNEWVEC (&opts_obstack, char, option->opt_len + 5);
       t[0] = '-';
@@ -349,6 +371,7 @@ static const struct option_map option_map[] =
   {
     { "-Wno-", NULL, "-W", false, true },
     { "-fno-", NULL, "-f", false, true },
+    { "-gno-", NULL, "-g", false, true },
     { "-mno-", NULL, "-m", false, true },
     { "--debug=", NULL, "-g", false, false },
     { "--machine-", NULL, "-m", true, false },
@@ -394,6 +417,8 @@ add_misspelling_candidates (auto_vec<char *> *candidates,
   gcc_assert (candidates);
   gcc_assert (option);
   gcc_assert (opt_text);
+  if (remapping_prefix_p (option))
+    return;
   candidates->safe_push (xstrdup (opt_text + 1));
   for (unsigned i = 0; i < ARRAY_SIZE (option_map); i++)
     {
