Index: gcc/testsuite/lib/gcc.exp
===================================================================
--- gcc/testsuite/lib/gcc.exp	(revision 214029)
+++ gcc/testsuite/lib/gcc.exp	(working copy)
@@ -109,11 +109,11 @@ proc gcc_init { args } {
     if ![info exists tmpdir] then {
 	set tmpdir /tmp
     }
 
     set gcc_warning_prefix "warning:"
-    set gcc_error_prefix "error:"
+    set gcc_error_prefix "(fatal )?error:"
 
     gcc_maybe_build_wrapper "${tmpdir}/gcc-testglue.o"
 }
 
 #
Index: gcc/testsuite/lib/g++.exp
===================================================================
--- gcc/testsuite/lib/g++.exp	(revision 214029)
+++ gcc/testsuite/lib/g++.exp	(working copy)
@@ -265,11 +265,11 @@ proc g++_init { args } {
     # Make sure that lines are not wrapped.  That can confuse the
     # error-message parsing machinery.
     lappend ALWAYS_CXXFLAGS "additional_flags=-fmessage-length=0"
 
     set gcc_warning_prefix "warning:"
-    set gcc_error_prefix "error:"
+    set gcc_error_prefix "(fatal )?error:"
 
     if { [istarget *-*-darwin*] } {
 	lappend ALWAYS_CXXFLAGS "ldflags=-multiply_defined suppress"
        }
 
Index: gcc/testsuite/lib/obj-c++.exp
===================================================================
--- gcc/testsuite/lib/obj-c++.exp	(revision 214029)
+++ gcc/testsuite/lib/obj-c++.exp	(working copy)
@@ -273,11 +273,11 @@ proc obj-c++_init { args } {
     # Make sure that lines are not wrapped.  That can confuse the
     # error-message parsing machinery.
     lappend ALWAYS_OBJCXXFLAGS "additional_flags=-fmessage-length=0"
 
     set gcc_warning_prefix "warning:"
-    set gcc_error_prefix "error:"
+    set gcc_error_prefix "(fatal )?error:"
 
     if { [istarget *-*-darwin*] } {
 	lappend ALWAYS_OBJCXXFLAGS "ldflags=-multiply_defined suppress"
     }
 
Index: gcc/testsuite/lib/objc.exp
===================================================================
--- gcc/testsuite/lib/objc.exp	(revision 214029)
+++ gcc/testsuite/lib/objc.exp	(working copy)
@@ -122,11 +122,11 @@ proc objc_init { args } {
     if ![info exists tmpdir] then {
 	set tmpdir /tmp
     }
 
     set gcc_warning_prefix "warning:"
-    set gcc_error_prefix "error:"
+    set gcc_error_prefix "(fatal )?error:"
 
     objc_maybe_build_wrapper "${tmpdir}/objc-testglue.o"
 
     set objc_libgcc_s_path [gcc-set-multilib-library-path $OBJC_UNDER_TEST]
 }
Index: gcc/testsuite/g++.dg/template/pr16564.C
===================================================================
--- gcc/testsuite/g++.dg/template/pr16564.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/pr16564.C	(revision 0)
@@ -0,0 +1,8 @@
+// { dg-do compile }
+template<typename> struct A
+{
+  A<A> a; /* { dg-error "template instantiation depth" } */
+  A() {}
+};
+
+A<int> a;
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 214029)
+++ gcc/cp/error.c	(working copy)
@@ -3351,20 +3351,10 @@ maybe_print_instantiation_context (diagn
     return;
 
   record_last_problematic_instantiation ();
   print_instantiation_full_context (context);
 }
-
-/* Report the bare minimum context of a template instantiation.  */
-void
-print_instantiation_context (void)
-{
-  print_instantiation_partial_context
-    (global_dc, current_instantiation (), input_location);
-  pp_newline (global_dc->printer);
-  diagnostic_flush_buffer (global_dc);
-}
 
 /* Report what constexpr call(s) we're trying to expand, if any.  */
 
 void
 maybe_print_constexpr_context (diagnostic_context *context)
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 214029)
+++ gcc/cp/typeck2.c	(working copy)
@@ -1635,12 +1635,17 @@ build_x_arrow (location_t loc, tree expr
 				   &fn, complain)))
 	{
 	  if (expr == error_mark_node)
 	    return error_mark_node;
 
+	  /* This provides a better instantiation backtrace in case of
+	     error.  */
 	  if (fn && DECL_USE_TEMPLATE (fn))
-	    push_tinst_level (fn);
+	    push_tinst_level_loc (fn, 
+				  (current_instantiation () != actual_inst)
+				  ? DECL_SOURCE_LOCATION (fn)
+				  : input_location);
 	  fn = NULL;
 
 	  if (vec_member (TREE_TYPE (expr), types_memoized))
 	    {
 	      if (complain & tf_error)
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 214029)
+++ gcc/cp/pt.c	(working copy)
@@ -8334,51 +8334,51 @@ int depth_reached;
 static GTY(()) struct tinst_level *last_error_tinst_level;
 
 /* We're starting to instantiate D; record the template instantiation context
    for diagnostics and to restore it later.  */
 
-int
+bool
 push_tinst_level (tree d)
 {
+  return push_tinst_level_loc (d, input_location);
+}
+
+/* We're starting to instantiate D; record the template instantiation context
+   at LOC for diagnostics and to restore it later.  */
+
+bool
+push_tinst_level_loc (tree d, location_t loc)
+{
   struct tinst_level *new_level;
 
   if (tinst_depth >= max_tinst_depth)
     {
-      last_error_tinst_level = current_tinst_level;
-      if (TREE_CODE (d) == TREE_LIST)
-	error ("template instantiation depth exceeds maximum of %d (use "
-	       "-ftemplate-depth= to increase the maximum) substituting %qS",
-	       max_tinst_depth, d);
-      else
-	error ("template instantiation depth exceeds maximum of %d (use "
-	       "-ftemplate-depth= to increase the maximum) instantiating %qD",
-	       max_tinst_depth, d);
-
-      print_instantiation_context ();
-
-      return 0;
+      fatal_error ("template instantiation depth exceeds maximum of %d"
+                   " (use -ftemplate-depth= to increase the maximum)",
+                   max_tinst_depth);
+      return false;
     }
 
   /* If the current instantiation caused problems, don't let it instantiate
      anything else.  Do allow deduction substitution and decls usable in
      constant expressions.  */
   if (limit_bad_template_recursion (d))
-    return 0;
+    return false;
 
   new_level = ggc_alloc<tinst_level> ();
   new_level->decl = d;
-  new_level->locus = input_location;
+  new_level->locus = loc;
   new_level->errors = errorcount+sorrycount;
   new_level->in_system_header_p = in_system_header_at (input_location);
   new_level->next = current_tinst_level;
   current_tinst_level = new_level;
 
   ++tinst_depth;
   if (GATHER_STATISTICS && (tinst_depth > depth_reached))
     depth_reached = tinst_depth;
 
-  return 1;
+  return true;
 }
 
 /* We're done instantiating this template; return to the instantiation
    context.  */
 
@@ -20230,14 +20230,14 @@ instantiate_pending_templates (int retri
      to avoid infinite loop.  */
   if (pending_templates && retries >= max_tinst_depth)
     {
       tree decl = pending_templates->tinst->decl;
 
-      error ("template instantiation depth exceeds maximum of %d"
-	     " instantiating %q+D, possibly from virtual table generation"
-	     " (use -ftemplate-depth= to increase the maximum)",
-	     max_tinst_depth, decl);
+      fatal_error ("template instantiation depth exceeds maximum of %d"
+                   " instantiating %q+D, possibly from virtual table generation"
+                   " (use -ftemplate-depth= to increase the maximum)",
+                   max_tinst_depth, decl);
       if (TREE_CODE (decl) == FUNCTION_DECL)
 	/* Pretend that we defined it.  */
 	DECL_INITIAL (decl) = error_mark_node;
       return;
     }
@@ -20566,11 +20566,11 @@ get_mostly_instantiated_function_type (t
   return fn_type;
 }
 
 /* Return truthvalue if we're processing a template different from
    the last one involved in diagnostics.  */
-int
+bool
 problematic_instantiation_changed (void)
 {
   return current_tinst_level != last_error_tinst_level;
 }
 
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 214029)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -5410,11 +5410,10 @@ extern const char *decl_as_dwarf_string
 extern const char *expr_as_string		(tree, int);
 extern const char *lang_decl_name		(tree, int, bool);
 extern const char *lang_decl_dwarf_name		(tree, int, bool);
 extern const char *language_to_string		(enum languages);
 extern const char *class_key_or_enum_as_string	(tree);
-extern void print_instantiation_context		(void);
 extern void maybe_warn_variadic_templates       (void);
 extern void maybe_warn_cpp0x			(cpp0x_warn_str str);
 extern bool pedwarn_cxx98                       (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
 extern location_t location_of                   (tree);
 extern void qualified_name_lookup_error		(tree, tree, tree,
@@ -5625,11 +5624,11 @@ extern tree tsubst_default_argument		(tr
 extern tree tsubst (tree, tree, tsubst_flags_t, tree);
 extern tree tsubst_copy_and_build		(tree, tree, tsubst_flags_t,
 						 tree, bool, bool);
 extern tree most_general_template		(tree);
 extern tree get_mostly_instantiated_function_type (tree);
-extern int problematic_instantiation_changed	(void);
+extern bool problematic_instantiation_changed	(void);
 extern void record_last_problematic_instantiation (void);
 extern struct tinst_level *current_instantiation(void);
 extern tree maybe_get_template_decl_from_type_decl (tree);
 extern int processing_template_parmlist;
 extern bool dependent_type_p			(tree);
@@ -5653,11 +5652,12 @@ extern bool reregister_specialization		(
 extern tree fold_non_dependent_expr		(tree);
 extern tree fold_non_dependent_expr_sfinae	(tree, tsubst_flags_t);
 extern bool alias_type_or_template_p            (tree);
 extern bool alias_template_specialization_p     (const_tree);
 extern bool explicit_class_specialization_p     (tree);
-extern int push_tinst_level                     (tree);
+extern bool push_tinst_level                    (tree);
+extern bool push_tinst_level_loc                (tree, location_t);
 extern void pop_tinst_level                     (void);
 extern struct tinst_level *outermost_tinst_level(void);
 extern void init_template_processing		(void);
 extern void print_template_statistics		(void);
 bool template_template_parameter_p		(const_tree);
