Index: libstdc++-v3/testsuite/lib/prune.exp
===================================================================
--- libstdc++-v3/testsuite/lib/prune.exp	(revision 186103)
+++ libstdc++-v3/testsuite/lib/prune.exp	(working copy)
@@ -30,10 +30,18 @@ proc dg-prune-output { args } {
 }
 
 proc libstdc++-dg-prune { system text } {
     global additional_prunes
 
+#    send_user "Before:$text\n"
+
+    # Ignore caret diagnostics. Unfortunately dejaGNU trims leading
+    # spaces, so one cannot rely on them being present.
+    regsub -all "(^|\n)\[^\n\]+\n *\\^\n" $text "\n" text
+    # Also it may trim a source line by mistake since it matches repeated lines.
+    regsub -all "(^|\n) *\\^\n" $text "\n" text
+
     # Cygwin warns about -ffunction-sections
     regsub -all "(^|\n)\[^\n\]*: -ffunction-sections may affect debugging on some targets\[^\n\]*" $text "" text
 
     # Remove parts of warnings that refer to location of previous
     # definitions, etc as these confuse dejagnu
@@ -66,7 +74,8 @@ proc libstdc++-dg-prune { system text } 
 	    # Following regexp matches a complete line containing $p.
 	    regsub -all "(^|\n)\[^\n\]*$p\[^\n\]*" $text "" text
 	}
     }
 
+#    send_user "After:$text\n"
     return $text
 }
Index: libmudflap/testsuite/lib/libmudflap.exp
===================================================================
--- libmudflap/testsuite/lib/libmudflap.exp	(revision 186103)
+++ libmudflap/testsuite/lib/libmudflap.exp	(working copy)
@@ -296,10 +296,15 @@ proc libmudflap-dg-prune { system text }
     return $text
 }
 
 
 proc prune_gcc_output { text } {
+    # Ignore caret diagnostics. Unfortunately dejaGNU trims leading
+    # spaces, so one cannot rely on them being present.
+    regsub -all "(^|\n)\[^\n\]+\n *\\^\n" $text "\n" text
+    # Also it may trim a source line by mistake since it matches repeated lines.
+    regsub -all "(^|\n) *\\^\n" $text "\n" text
     regsub -all {(^|\n)[^\n]*ld: warning: libgcc_s[^\n]*not found[^\n]*try using[^\n]*} $text "" text
     regsub -all {(^|\n)[^\n]*In function.*pthread_create[^\n]*} $text "" text
     regsub -all {(^|\n)[^\n]*the use of .pthread.*is deprecated[^\n]*} $text "" text
     regsub -all {(^|\n)[^\n]*Dwarf Error:.*FORM value: 14[^\n]*} $text "" text
     regsub -all {(^|\n)[^\n]*In function[^\n]*} $text "" text
Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 186103)
+++ gcc/diagnostic.c	(working copy)
@@ -98,10 +98,11 @@ diagnostic_initialize (diagnostic_contex
   context->warning_as_error_requested = false;
   context->n_opts = n_opts;
   context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
   for (i = 0; i < n_opts; i++)
     context->classify_diagnostic[i] = DK_UNSPECIFIED;
+  context->show_caret = false;
   context->show_option_requested = false;
   context->abort_on_error = false;
   context->show_column = false;
   context->pedantic_errors = false;
   context->permissive = false;
@@ -194,10 +195,67 @@ diagnostic_build_prefix (diagnostic_cont
      : context->show_column
      ? build_message_string ("%s:%d:%d: %s", s.file, s.line, s.column, text)
      : build_message_string ("%s:%d: %s", s.file, s.line, text));
 }
 
+/* Print the physical source line corresponding to the location of
+   this diagnostics, and a caret indicating the precise column.  */
+static void
+diagnostic_show_locus (diagnostic_context * context,
+		       diagnostic_info *diagnostic)
+{
+  const char *line;
+  expanded_location s;
+  int k, real_width, real_column;
+  int max_width = 80, right_margin = 10;
+
+  if (!context->show_caret
+      || diagnostic->location <= BUILTINS_LOCATION)
+    return;
+
+  s = expand_location(diagnostic->location);
+  line = location_get_source_line (s);
+  if (line == NULL)
+    return;
+
+  for (k = real_column = 0; k < s.column && line[k] != '\0'; k++)
+    real_column += (line[k] == '\t') ? 8 : 1;
+
+  for (real_width = real_column; line[k] != '\0'; k++)
+    real_width += (line[k] == '\t') ? 8 : 1;
+
+  /* If the line is longer than max_width and the column is too close
+     to max_width, skip part of the line until it is not so close.  */
+  right_margin = max_width - right_margin;
+  if (real_width >= max_width && real_column > right_margin) {
+    for (k = real_column - right_margin; k > 0; line++)
+      {
+	k -= (*line == '\t') ? 8 : 1;
+      }
+    real_column = right_margin + k;
+  }
+
+  fputc (' ', stderr);
+  while (max_width > 0 && *line != '\0')
+    {
+      if (*line != '\t')
+	{
+	  max_width--;
+	  fputc (*line, stderr);
+	} 
+      else 
+	{
+	  /* TABs are 8 spaces.  */
+	  max_width -= 8;
+	  fputs ("        ", stderr);
+	}
+      line++;
+    }
+  fputc ('\n', stderr);
+  fprintf (stderr, " %*c\n", real_column, '^');
+}
+
 /* Take any action which is expected to happen after the diagnostic
    is written out.  This function does not always return.  */
 static void
 diagnostic_action_after_output (diagnostic_context *context,
 				diagnostic_info *diagnostic)
@@ -547,10 +605,11 @@ diagnostic_report_diagnostic (diagnostic
   pp_format (context->printer, &diagnostic->message);
   (*diagnostic_starter (context)) (context, diagnostic);
   pp_output_formatted_text (context->printer);
   (*diagnostic_finalizer (context)) (context, diagnostic);
   pp_flush (context->printer);
+  diagnostic_show_locus (context, diagnostic);
   diagnostic_action_after_output (context, diagnostic);
   diagnostic->message.format_spec = saved_format_spec;
   diagnostic->x_data = NULL;
 
   context->lock--;
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h	(revision 186103)
+++ gcc/diagnostic.h	(working copy)
@@ -97,10 +97,14 @@ struct diagnostic_context
 
   /* For pragma push/pop.  */
   int *push_list;
   int n_push;
 
+  /* True if we should print the source line with a caret indicating
+     the location.  */
+  bool show_caret;
+
   /* True if we should print the command line option which controls
      each diagnostic, if known.  */
   bool show_option_requested;
 
   /* True if we should raise a SIGABRT on errors.  */
Index: gcc/input.c
===================================================================
--- gcc/input.c	(revision 186103)
+++ gcc/input.c	(working copy)
@@ -48,10 +48,69 @@ expand_location (source_location loc)
     xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
 
   return xloc;
 }
 
+/* Reads one line from file into a static buffer.  */
+static const char *
+read_line (FILE *file)
+{
+  static char *string;
+  static size_t string_len;
+  size_t pos = 0;
+  char *ptr;
+
+  if (!string_len)
+    {
+      string_len = 200;
+      string = XNEWVEC (char, string_len);
+    }
+
+  while ((ptr = fgets (string + pos, string_len - pos, file)))
+    {
+      size_t len = strlen (string + pos);
+
+      if (string[pos + len - 1] == '\n')
+	{
+	  string[pos + len - 1] = 0;
+	  return string;
+	}
+      pos += len;
+      ptr = XNEWVEC (char, string_len * 2);
+      if (ptr)
+	{
+	  memcpy (ptr, string, pos);
+	  string = ptr;
+	  string_len += 2;
+	}
+      else
+	pos = 0;
+    }
+      
+  return pos ? string : NULL;
+}
+
+/* Return the physical source line that corresponds to xloc in a
+   buffer that is statically allocated.  The newline is replaced by
+   the null character.  */
+
+const char *
+location_get_source_line(expanded_location xloc)
+{
+  const char *buffer;
+  int lines = 1;
+  FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL;
+  if (!stream)
+    return NULL;
+
+  while ((buffer = read_line (stream)) && lines < xloc.line)
+    lines++;
+
+  fclose (stream);
+  return buffer;
+}
+
 #define ONE_K 1024
 #define ONE_M (ONE_K * ONE_K)
 
 /* Display a number as an integer multiple of either:
    - 1024, if said integer is >= to 10 K (in base 2)
Index: gcc/input.h
===================================================================
--- gcc/input.h	(revision 186103)
+++ gcc/input.h	(working copy)
@@ -36,10 +36,11 @@ extern GTY(()) struct line_maps *line_ta
    both UNKNOWN_LOCATION and BUILTINS_LOCATION fit into that.  */
 extern char builtins_location_check[(BUILTINS_LOCATION
 				     < RESERVED_LOCATION_COUNT) ? 1 : -1];
 
 extern expanded_location expand_location (source_location);
+extern const char * location_get_source_line(expanded_location xloc);
 
 /* Historically GCC used location_t, while cpp used source_location.
    This could be removed but it hardly seems worth the effort.  */
 typedef source_location location_t;
 
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 186103)
+++ gcc/toplev.c	(working copy)
@@ -1167,10 +1167,12 @@ general_init (const char *argv0)
      finalizer -- for tokens resulting from macro macro expansion.  */
   diagnostic_finalizer (global_dc) = virt_loc_aware_diagnostic_finalizer;
   /* Set a default printer.  Language specific initializations will
      override it later.  */
   pp_format_decoder (global_dc->printer) = &default_tree_printer;
+  global_dc->show_caret
+    = global_options_init.x_flag_diagnostics_show_caret;
   global_dc->show_option_requested
     = global_options_init.x_flag_diagnostics_show_option;
   global_dc->show_column
     = global_options_init.x_flag_show_column;
   global_dc->internal_error = plugins_internal_error_function;
Index: gcc/testsuite/lib/prune.exp
===================================================================
--- gcc/testsuite/lib/prune.exp	(revision 186103)
+++ gcc/testsuite/lib/prune.exp	(working copy)
@@ -15,10 +15,12 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
 # Prune messages from gcc that aren't useful.
 
+set TEST_ALWAYS_FLAGS "-fno-diagnostics-show-caret $TEST_ALWAYS_FLAGS"
+
 proc prune_gcc_output { text } {
     #send_user "Before:$text\n"
 
     regsub -all "(^|\n)(\[^\n\]*: )?In ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|substitution|program|subroutine|block-data)\[^\n\]*" $text "" text
     regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text
Index: gcc/testsuite/gcc.dg/torture/tls/tls.exp
===================================================================
--- gcc/testsuite/gcc.dg/torture/tls/tls.exp	(revision 186103)
+++ gcc/testsuite/gcc.dg/torture/tls/tls.exp	(working copy)
@@ -48,10 +48,10 @@ dg-init
 torture-init
 set-torture-options $TLS_TORTURE_OPTIONS {{}} $LTO_TORTURE_OPTIONS
 
 # Main loop.
 gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
-        $DEFAULT_CFLAGS
+        "-fno-diagnostics-show-caret $DEFAULT_CFLAGS"
 
 # All done.
 torture-finish
 dg-finish
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 186103)
+++ gcc/dwarf2out.c	(working copy)
@@ -18367,10 +18367,11 @@ gen_producer_string (void)
       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:
+      case OPT_fdiagnostics_show_caret:
       case OPT_fverbose_asm:
       case OPT____:
       case OPT__sysroot_:
       case OPT_nostdinc:
       case OPT_nostdinc__:
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 186103)
+++ gcc/opts.c	(working copy)
@@ -1497,10 +1497,14 @@ common_handle_option (struct gcc_options
       break;
 
     case OPT_fdiagnostics_show_location_:
       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
       break;
+ 
+    case OPT_fdiagnostics_show_caret:
+      dc->show_caret = value;
+      break;
 
     case OPT_fdiagnostics_show_option:
       dc->show_option_requested = value;
       break;
 
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 186103)
+++ gcc/common.opt	(working copy)
@@ -997,10 +997,14 @@ EnumValue
 Enum(diagnostic_prefixing_rule) String(once) Value(DIAGNOSTICS_SHOW_PREFIX_ONCE)
 
 EnumValue
 Enum(diagnostic_prefixing_rule) String(every-line) Value(DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE)
 
+fdiagnostics-show-caret
+Common Var(flag_diagnostics_show_caret) Init(1)
+Show the source line with a caret indicating the column
+
 fdiagnostics-show-option
 Common Var(flag_diagnostics_show_option) Init(1)
 Amend appropriate diagnostic messages with the command line option that controls them
 
 fdisable-
