Index: gcc/doc/options.texi
===================================================================
--- gcc/doc/options.texi	(revision 187096)
+++ gcc/doc/options.texi	(working copy)
@@ -457,6 +457,8 @@ the value has been set explicitly and sh
 combined option.  For example, some front ends use this to prevent
 @option{-ffast-math} and @option{-fno-fast-math} from changing the
 value of @option{-fmath-errno} for languages that do not use
 @code{errno}.
 
+@item EnabledBy(@var{opt})
+If not explicitly set, the option is set to the value of @option{-@var{opt}}.
 @end table
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 187096)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -358,11 +358,14 @@ c_common_handle_option (size_t scode, co
     case OPT_U:
       defer_opt (code, arg);
       break;
 
     case OPT_Wall:
-      warn_unused = value;
+      handle_generated_option (&global_options, &global_options_set,
+			       OPT_Wunused, NULL, value,
+			       c_family_lang_mask, kind, loc,
+			       handlers, global_dc);
       set_Wformat (value);
       handle_generated_option (&global_options, &global_options_set,
 			       OPT_Wimplicit, NULL, value,
 			       c_family_lang_mask, kind, loc,
 			       handlers, global_dc);
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 187096)
+++ gcc/opts.c	(working copy)
@@ -21,15 +21,15 @@ along with GCC; see the file COPYING3.  
 
 #include "config.h"
 #include "system.h"
 #include "intl.h"
 #include "coretypes.h"
+#include "opts.h"
+#include "options.h"
 #include "tm.h" /* For STACK_CHECK_BUILTIN,
 		   STACK_CHECK_STATIC_BUILTIN, DEFAULT_GDB_EXTENSIONS,
 		   DWARF2_DEBUGGING_INFO and DBX_DEBUGGING_INFO.  */
-#include "opts.h"
-#include "options.h"
 #include "flags.h"
 #include "params.h"
 #include "diagnostic.h"
 #include "opts-diagnostic.h"
 #include "insn-attr-common.h"
@@ -813,33 +813,19 @@ finish_options (struct gcc_options *opts
   if (!opts->x_flag_tree_vectorize || !opts->x_flag_tree_loop_if_convert)
     maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
                            opts->x_param_values, opts_set->x_param_values);
 
   /* This replaces set_Wunused.  */
-  if (opts->x_warn_unused_function == -1)
-    opts->x_warn_unused_function = opts->x_warn_unused;
-  if (opts->x_warn_unused_label == -1)
-    opts->x_warn_unused_label = opts->x_warn_unused;
   /* Wunused-parameter is enabled if both -Wunused -Wextra are enabled.  */
   if (opts->x_warn_unused_parameter == -1)
     opts->x_warn_unused_parameter = (opts->x_warn_unused
 				     && opts->x_extra_warnings);
-  if (opts->x_warn_unused_variable == -1)
-    opts->x_warn_unused_variable = opts->x_warn_unused;
   /* Wunused-but-set-parameter is enabled if both -Wunused -Wextra are
      enabled.  */
   if (opts->x_warn_unused_but_set_parameter == -1)
     opts->x_warn_unused_but_set_parameter = (opts->x_warn_unused
 					     && opts->x_extra_warnings);
-  if (opts->x_warn_unused_but_set_variable == -1)
-    opts->x_warn_unused_but_set_variable = opts->x_warn_unused;
-  if (opts->x_warn_unused_value == -1)
-    opts->x_warn_unused_value = opts->x_warn_unused;
-
-  /* This replaces set_Wextra.  */
-  if (opts->x_warn_uninitialized == -1)
-    opts->x_warn_uninitialized = opts->x_extra_warnings;
 }
 
 #define LEFT_COLUMN	27
 
 /* Output ITEM, of length ITEM_WIDTH, in the left column,
@@ -1739,22 +1725,19 @@ common_handle_option (struct gcc_options
 
     case OPT_fuse_linker_plugin:
       /* No-op. Used by the driver and passed to us because it starts with f.*/
       break;
 
-    case OPT_Wuninitialized:
-      /* Also turn on maybe uninitialized warning.  */
-      opts->x_warn_maybe_uninitialized = value;
-      break;
-
     default:
       /* If the flag was handled in a standard way, assume the lack of
 	 processing here is intentional.  */
       gcc_assert (option_flag_var (scode, opts));
       break;
     }
 
+  common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
+                             loc, handlers, dc);
   return true;
 }
 
 /* Handle --param NAME=VALUE.  */
 static void
Index: gcc/optc-gen.awk
===================================================================
--- gcc/optc-gen.awk	(revision 187096)
+++ gcc/optc-gen.awk	(working copy)
@@ -322,6 +322,68 @@ for (i = 0; i < n_opts; i++) {
 	       var_set(flags[i]), comma)
 }
 
 print "};"
 
+print "\n\n"
+print "bool                                                                  "
+print "common_handle_option_auto (struct gcc_options *opts,                  "
+print "                           struct gcc_options *opts_set,              "
+print "                           const struct cl_decoded_option *decoded,   "
+print "                           unsigned int lang_mask, int kind,          "
+print "                           location_t loc,                            "
+print "                           const struct cl_option_handlers *handlers, "
+print "                           diagnostic_context *dc)                    "
+print "{                                                                     "
+print "  size_t scode = decoded->opt_index;                                  "
+print "  int value = decoded->value;                                         "
+print "  enum opt_code code = (enum opt_code) scode;                         "
+print "                                                                      "
+print "  gcc_assert (decoded->canonical_option_num_elements <= 2);           "
+print "                                                                      "
+print "  switch (code)                                                       "
+print "    {                                                                 "
+n_enabledby = 0;
+for (i = 0; i < n_opts; i++) {
+    # With identical flags, pick only the last one.  The
+    # earlier loop ensured that it has all flags merged,
+    # and a nonempty help text if one of the texts was nonempty.
+    while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
+        i++;
+    }
+    enabledby_arg = opt_args("EnabledBy", flags[i]);
+    if (enabledby_arg != "") {
+        enabledby_name = enabledby_arg;
+        enabledby_index = opt_numbers[enabledby_name];
+        if (enabledby_index == "") {
+            print "#error Enabledby: " enabledby_name 
+        } else {
+            enabledby_var_name = var_name(flags[enabledby_index]);
+            if (enables[enabledby_name] == "") {
+                enabledby[n_enabledby] = enabledby_name;
+                n_enabledby++;
+            }
+            enables[enabledby_name] = enables[enabledby_name] opts[i] ",";
+        }
+    }
 }
+for (i = 0; i < n_enabledby; i++) {
+    enabledby_name = enabledby[i];
+    print "    case " opt_enum(enabledby_name) ":"
+    n_enables = split(enables[enabledby_name], thisenable, ",");
+    for (j = 1; j < n_enables; j++) {
+        opt_var_name = var_name(flags[opt_numbers[thisenable[j]]]);
+        print "      if (!opts_set->x_" opt_var_name ")"
+        print "        handle_generated_option (opts, opts_set,"
+        print "                                 " opt_enum(thisenable[j]) ", NULL, value,"
+        print "                                 lang_mask, kind, loc, handlers, dc);"
+    }
+    print "      break;\n"
+
+}
+print "    default:    "
+print "      break;    "
+print "    }           "
+print "  return true;  "
+print "}               "
+
+}
\ No newline at end of file
Index: gcc/ada/gcc-interface/misc.c
===================================================================
--- gcc/ada/gcc-interface/misc.c	(revision 187096)
+++ gcc/ada/gcc-interface/misc.c	(working copy)
@@ -103,10 +103,18 @@ gnat_parse_file (void)
 
   /* Call the front end.  */
   _ada_gnat1drv ();
 }
 
+/* Return language mask for option processing.  */
+
+static unsigned int
+gnat_option_lang_mask (void)
+{
+  return CL_Ada;
+}
+
 /* Decode all the language specific options that cannot be decoded by GCC.
    The option decoding phase of GCC calls this routine on the flags that
    are marked as Ada-specific.  Return true on success or false on failure.  */
 
 static bool
@@ -117,11 +125,14 @@ gnat_handle_option (size_t scode, const 
   enum opt_code code = (enum opt_code) scode;
 
   switch (code)
     {
     case OPT_Wall:
-      warn_unused = value;
+      handle_generated_option (&global_options, &global_options_set,
+			       OPT_Wunused, NULL, value,
+			       gnat_option_lang_mask (), kind, loc,
+			       handlers, global_dc);
       warn_uninitialized = value;
       warn_maybe_uninitialized = value;
       break;
 
     case OPT_gant:
@@ -143,18 +154,10 @@ gnat_handle_option (size_t scode, const 
     }
 
   return true;
 }
 
-/* Return language mask for option processing.  */
-
-static unsigned int
-gnat_option_lang_mask (void)
-{
-  return CL_Ada;
-}
-
 /* Initialize options structure OPTS.  */
 
 static void
 gnat_init_options_struct (struct gcc_options *opts)
 {
Index: gcc/fortran/options.c
===================================================================
--- gcc/fortran/options.c	(revision 187096)
+++ gcc/fortran/options.c	(working copy)
@@ -32,11 +32,11 @@ along with GCC; see the file COPYING3.  
 #include "params.h"
 #include "tree-inline.h"
 #include "gfortran.h"
 #include "target.h"
 #include "cpp.h"
-#include "diagnostic-core.h"	/* For sorry.  */
+#include "diagnostic.h"	/* For global_dc.  */
 #include "tm.h"
 
 gfc_option_t gfc_option;
 
 
@@ -472,11 +472,10 @@ set_Wall (int setting)
   gfc_option.warn_intrinsics_std = setting;
   gfc_option.warn_character_truncation = setting;
   gfc_option.warn_real_q_constant = setting;
   gfc_option.warn_unused_dummy_argument = setting;
 
-  warn_unused = setting;
   warn_return_type = setting;
   warn_switch = setting;
   warn_uninitialized = setting;
   warn_maybe_uninitialized = setting;
 }
@@ -610,10 +609,14 @@ gfc_handle_option (size_t scode, const c
     default:
       result = false;
       break;
 
     case OPT_Wall:
+      handle_generated_option (&global_options, &global_options_set,
+			       OPT_Wunused, NULL, value,
+			       gfc_option_lang_mask (), kind, loc,
+			       handlers, global_dc);
       set_Wall (value);
       break;
 
     case OPT_Waliasing:
       gfc_option.warn_aliasing = value;
Index: gcc/opth-gen.awk
===================================================================
--- gcc/opth-gen.awk	(revision 187096)
+++ gcc/opth-gen.awk	(working copy)
@@ -291,10 +291,23 @@ print "";
 print "/* Restore selected option variables from a structure.  */"
 print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);";
 print "";
 print "/* Print target option variables from a structure.  */";
 print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
+print "";
+print "/* Anything that includes tm.h, does not necessarily need this.  */"
+print "#if !defined(GCC_TM_H)"
+print "#include \"input.h\" /* for location_t */"
+print "bool                                                                  "
+print "common_handle_option_auto (struct gcc_options *opts,                  "
+print "                           struct gcc_options *opts_set,              "
+print "                           const struct cl_decoded_option *decoded,   "
+print "                           unsigned int lang_mask, int kind,          "
+print "                           location_t loc,                            "
+print "                           const struct cl_option_handlers *handlers, "
+print "                           diagnostic_context *dc);                   "
+print "#endif";
 print "#endif";
 print "";
 
 for (i = 0; i < n_opts; i++) {
 	name = opt_args("Mask", flags[i])
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 187096)
+++ gcc/common.opt	(working copy)
@@ -648,15 +648,15 @@ Warn whenever a trampoline is generated
 Wtype-limits
 Common Var(warn_type_limits) Init(-1) Warning
 Warn if a comparison is always true or always false due to the limited range of the data type
 
 Wuninitialized
-Common Var(warn_uninitialized) Init(-1) Warning
+Common Var(warn_uninitialized) Warning EnabledBy(Wextra)
 Warn about uninitialized automatic variables
 
 Wmaybe-uninitialized
-Common Var(warn_maybe_uninitialized) Warning
+Common Var(warn_maybe_uninitialized) Warning EnabledBy(Wuninitialized)
 Warn about maybe uninitialized automatic variables
 
 Wunreachable-code
 Common Ignore
 Does nothing. Preserved for backward compatibility.
@@ -668,31 +668,31 @@ Enable all -Wunused- warnings
 Wunused-but-set-parameter
 Common Var(warn_unused_but_set_parameter) Init(-1) Warning
 Warn when a function parameter is only set, otherwise unused
 
 Wunused-but-set-variable
-Common Var(warn_unused_but_set_variable) Init(-1) Warning
+Common Var(warn_unused_but_set_variable) Warning EnabledBy(Wunused)
 Warn when a variable is only set, otherwise unused
 
 Wunused-function
-Common Var(warn_unused_function) Init(-1) Warning
+Common Var(warn_unused_function) Warning EnabledBy(Wunused)
 Warn when a function is unused
 
 Wunused-label
-Common Var(warn_unused_label) Init(-1) Warning
+Common Var(warn_unused_label) Warning EnabledBy(Wunused)
 Warn when a label is unused
 
 Wunused-parameter
 Common Var(warn_unused_parameter) Init(-1) Warning
 Warn when a function parameter is unused
 
 Wunused-value
-Common Var(warn_unused_value) Init(-1) Warning
+Common Var(warn_unused_value) Warning EnabledBy(Wunused)
 Warn when an expression value is unused
 
 Wunused-variable
-Common Var(warn_unused_variable) Init(-1) Warning
+Common Var(warn_unused_variable) Warning EnabledBy(Wunused)
 Warn when a variable is unused
 
 Wcoverage-mismatch
 Common Var(warn_coverage_mismatch) Init(1) Warning
 Warn in case profiles in -fprofile-use do not match
Index: gcc/opt-read.awk
===================================================================
--- gcc/opt-read.awk	(revision 187096)
+++ gcc/opt-read.awk	(working copy)
@@ -106,10 +106,11 @@ BEGIN {
 		}
 		else {
 			name = opt_args("Mask", $1)
 			if (name == "") {
 				opts[n_opts]  = $1
+				opt_numbers[$1] = n_opts
 				flags[n_opts] = $2
 				help[n_opts]  = $3
 				for (i = 4; i <= NF; i++)
 					help[n_opts] = help[n_opts] " " $i
 				n_opts++;
