Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c    (revision 218405)
+++ gcc/diagnostic.c    (revision 218406)
@@ -155,6 +155,34 @@
   context->inhibit_notes_p = false;
 }

+/* Maybe initialize the color support. We require clients to do this
+   explicitly, since most clients don't want color.  When called
+   without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT.  */
+
+void
+diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
+{
+  /* value == -1 is the default value.  */
+  if (value < 0)
+    {
+      /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
+        -fdiagnostics-color=auto if GCC_COLORS is in the environment,
+        otherwise default to -fdiagnostics-color=never, for other
+        values default to that
+        -fdiagnostics-color={never,auto,always}.  */
+      if (DIAGNOSTICS_COLOR_DEFAULT == -1)
+       {
+         if (!getenv ("GCC_COLORS"))
+           return;
+         value = DIAGNOSTICS_COLOR_AUTO;
+       }
+      else
+       value = DIAGNOSTICS_COLOR_DEFAULT;
+    }
+  pp_show_color (context->printer)
+    = colorize_init ((diagnostic_color_rule_t) value);
+}
+
 /* Do any cleaning up required after the last diagnostic is emitted.  */

 void
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h    (revision 218405)
+++ gcc/diagnostic.h    (revision 218406)
@@ -266,6 +266,7 @@

 /* Diagnostic related functions.  */
 extern void diagnostic_initialize (diagnostic_context *, int);
+extern void diagnostic_color_init (diagnostic_context *, int value = -1);
 extern void diagnostic_finish (diagnostic_context *);
 extern void diagnostic_report_current_module (diagnostic_context *,
location_t);
 extern void diagnostic_show_locus (diagnostic_context *, const
diagnostic_info *);
Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c   (revision 218405)
+++ gcc/gcc.c   (revision 218406)
@@ -3608,6 +3608,10 @@
       save_switch (compare_debug_replacement_opt, 0, NULL, validated, true);
       return true;

+    case OPT_fdiagnostics_color_:
+      diagnostic_color_init (dc, value);
+      break;
+
     case OPT_Wa_:
       {
        int prev, j;
@@ -6975,6 +6979,7 @@
   gcc_init_libintl ();

   diagnostic_initialize (global_dc, 0);
+  diagnostic_color_init (global_dc);

 #ifdef GCC_DRIVER_HOST_INITIALIZATION
   /* Perform host dependent initialization when needed.  */
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c        (revision 218405)
+++ gcc/toplev.c        (revision 218406)
@@ -86,7 +86,6 @@
 #include "gimple-expr.h"
 #include "gimple.h"
 #include "plugin.h"
-#include "diagnostic-color.h"
 #include "context.h"
 #include "pass_manager.h"
 #include "auto-profile.h"
@@ -1268,29 +1267,6 @@

   maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT;

-  /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to -fdiagnostics-color=auto
-     if GCC_COLORS is in the environment, otherwise default to
-     -fdiagnostics-color=never, for other values default to that
-     -fdiagnostics-color={never,auto,always}.  */
-  if (!global_options_set.x_flag_diagnostics_show_color)
-    switch ((int) DIAGNOSTICS_COLOR_DEFAULT)
-      {
-      case -1:
-       if (!getenv ("GCC_COLORS"))
-         break;
-       /* FALLTHRU */
-      case DIAGNOSTICS_COLOR_AUTO:
-       pp_show_color (global_dc->printer)
-         = colorize_init (DIAGNOSTICS_COLOR_AUTO);
-       break;
-      case DIAGNOSTICS_COLOR_YES:
-       pp_show_color (global_dc->printer)
-         = colorize_init (DIAGNOSTICS_COLOR_YES);
-       break;
-      default:
-       break;
-      }
-
   /* Allow the front end to perform consistency checks and do further
      initialization based on the command line options.  This hook also
      sets the original filename if appropriate (e.g. foo.i -> foo.c)
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog       (revision 218405)
+++ gcc/ChangeLog       (revision 218406)
@@ -1,3 +1,16 @@
+2014-12-04  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       * diagnostic.c (diagnostic_color_init): New.
+       * diagnostic.h: Declare.
+       * gcc.c (driver::global_initializations): Use it.
+       (driver_handle_option): Handle -fdiagnostics-color_.
+       * toplev.c: Do not include diagnostic-color.h.
+       (process_options): Do not initialize color diagnostics here.
+       * common.opt (fdiagnostics-color=): Add Driver.
+       * opts-global.c (init_options_once): Initialize color here.
+       * opts.c (common_handle_option): Use diagnostics_color_init.
+       * diagnostic-color.h: Fix comment.
+
 2014-12-04  David Malcolm  <dmalcolm@redhat.com>

        * tree-pretty-print.c (INDENT): Rename "buffer" to "pp".
Index: gcc/opts.c
===================================================================
--- gcc/opts.c  (revision 218405)
+++ gcc/opts.c  (revision 218406)
@@ -30,7 +30,6 @@
 #include "flags.h"
 #include "params.h"
 #include "diagnostic.h"
-#include "diagnostic-color.h"
 #include "opts-diagnostic.h"
 #include "insn-attr-common.h"
 #include "common/common-target.h"
@@ -1771,8 +1770,7 @@
       break;

     case OPT_fdiagnostics_color_:
-      pp_show_color (dc->printer)
-       = colorize_init ((diagnostic_color_rule_t) value);
+      diagnostic_color_init (dc, value);
       break;

     case OPT_fdiagnostics_show_option:
Index: gcc/diagnostic-color.h
===================================================================
--- gcc/diagnostic-color.h      (revision 218405)
+++ gcc/diagnostic-color.h      (revision 218406)
@@ -41,11 +41,10 @@
 #ifndef GCC_DIAGNOSTIC_COLOR_H
 #define GCC_DIAGNOSTIC_COLOR_H

-/* How often diagnostics are prefixed by their locations:
-   o DIAGNOSTICS_SHOW_PREFIX_NEVER: never - not yet supported;
-   o DIAGNOSTICS_SHOW_PREFIX_ONCE: emit only once;
-   o DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: emit each time a physical
-   line is started.  */
+/* Whether to add color to diagnostics:
+   o DIAGNOSTICS_COLOR_NO: never
+   o DIAGNOSTICS_COLOR_YES: always
+   o DIAGNOSTICS_COLOR_AUTO: depending on the output stream.  */
 typedef enum
 {
   DIAGNOSTICS_COLOR_NO       = 0,
Index: gcc/common.opt
===================================================================
--- gcc/common.opt      (revision 218405)
+++ gcc/common.opt      (revision 218406)
@@ -1096,7 +1096,7 @@
 ;

 fdiagnostics-color=
-Common Joined RejectNegative Var(flag_diagnostics_show_color)
Enum(diagnostic_color_rule) Init(DIAGNOSTICS_COLOR_NO)
+Driver Common Joined RejectNegative Var(flag_diagnostics_show_color)
Enum(diagnostic_color_rule) Init(DIAGNOSTICS_COLOR_NO)
 -fdiagnostics-color=[never|always|auto]        Colorize diagnostics

 ; Required for these enum values.
Index: gcc/opts-global.c
===================================================================
--- gcc/opts-global.c   (revision 218405)
+++ gcc/opts-global.c   (revision 218406)
@@ -261,6 +261,11 @@
   initial_lang_mask = lang_hooks.option_lang_mask ();

   lang_hooks.initialize_diagnostics (global_dc);
+  /* ??? Ideally, we should do this earlier and the FEs will override
+     it if desired (none do it so far).  However, the way the FEs
+     construct their pretty-printers means that all previous settings
+     are overriden.  */
+  diagnostic_color_init (global_dc);
 }

 /* Decode command-line options to an array, like
