This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR c++/9335] Detect recursive instantiation


Following the discussion in PR9335.

Bootstrapped and regression tested.

OK?

2010-04-27  Manuel López-Ibáñez  <manu@gcc.gnu.org>

cp/
        * error.c (print_instantiation_partial_context_line): Handle
	recursive instantiation.
        (print_instantiation_partial_context): Likewise.

testsuite/
        * g++.dg/template/recurse2.C: Update
        * g++.dg/template/recurse.C: Update.
        * g++.dg/template/pr23510.C: Update.
        * lib/prune.exp: Filter out 'recursively instantiated'.
Index: gcc/testsuite/g++.dg/template/recurse2.C
===================================================================
--- gcc/testsuite/g++.dg/template/recurse2.C	(revision 158743)
+++ gcc/testsuite/g++.dg/template/recurse2.C	(working copy)
@@ -1,7 +1,8 @@
 // PR c++/9335
 // We should not see an error about non-constant initialization.
 
 template <int N> struct X {
     static const int value = X<N-1>::value; // { dg-error "instantiation|incomplete" }
+  // { dg-message "recursively instantiated" "" { target *-*-* } 5 }
 };
 template struct X<1000>;
Index: gcc/testsuite/g++.dg/template/recurse.C
===================================================================
--- gcc/testsuite/g++.dg/template/recurse.C	(revision 158743)
+++ gcc/testsuite/g++.dg/template/recurse.C	(working copy)
@@ -6,12 +6,11 @@ template <int I> struct F
   int operator()()
     {
       F<I+1> f;			// { dg-error "incomplete type" "incomplete" }
 				// { dg-bogus "exceeds maximum.*exceeds maximum" "exceeds" { xfail *-*-* } 8 }
                                 // { dg-error "exceeds maximum" "exceeds" { xfail *-*-* } 8 }
-      return f()*I;             // { dg-message "instantiated" "recurse" }
-      // { dg-message "skipping 40 instantiation contexts" "" { target *-*-* } 11 }
+      return f()*I;             // { dg-message "recursively instantiated" "recurse" }
     }
 };
 
 template <> struct F<52>
 {
Index: gcc/testsuite/g++.dg/template/pr23510.C
===================================================================
--- gcc/testsuite/g++.dg/template/pr23510.C	(revision 158743)
+++ gcc/testsuite/g++.dg/template/pr23510.C	(working copy)
@@ -2,11 +2,11 @@
 // { dg-options "-ftemplate-depth-15" }
 template<unsigned int nFactor>
 struct Factorial
 {
   enum { nValue = nFactor * Factorial<nFactor - 1>::nValue }; // { dg-error "depth exceeds maximum" } 
-  // { dg-message "skipping 5 instantiation contexts" "" { target *-*-* } 6 } 
+  // { dg-message "recursively instantiated" "" { target *-*-* } 6 } 
   // { dg-error "incomplete type" "" { target *-*-* } 6 } 
 } 
 
   template<> // { dg-error "expected" } 
   struct Factorial<0>
Index: gcc/testsuite/lib/prune.exp
===================================================================
--- gcc/testsuite/lib/prune.exp	(revision 158743)
+++ gcc/testsuite/lib/prune.exp	(working copy)
@@ -20,11 +20,11 @@
 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|program|subroutine|block-data)\[^\n\]*" $text "" text
     regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text
-    regsub -all "(^|\n)\[^\n\]*:   instantiated from \[^\n\]*" $text "" text
+    regsub -all "(^|\n)\[^\n\]*:   (recursively )?instantiated from \[^\n\]*" $text "" text
     regsub -all "(^|\n)\[^\n\]*:   . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text
     regsub -all "(^|\n)    inlined from \[^\n\]*" $text "" text
     regsub -all "(^|\n)collect2: ld returned \[^\n\]*" $text "" text
     regsub -all "(^|\n)collect: re(compiling|linking)\[^\n\]*" $text "" text
     regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 158743)
+++ gcc/cp/error.c	(working copy)
@@ -2731,35 +2731,49 @@ print_instantiation_full_context (diagno
 /* Helper function of print_instantiation_partial_context() that
    prints a single line of instantiation context.  */
 
 static void
 print_instantiation_partial_context_line (diagnostic_context *context,
-					  const struct tinst_level *t, location_t loc)
+					  const struct tinst_level *t,
+					  location_t loc, bool recursive_p)
 {
   expanded_location xloc;
   xloc = expand_location (loc);
 
-  if (t != NULL) {
-    const char *str;
-    str = decl_as_string_translate (t->decl,
-				    TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE);
-    if (flag_show_column)
-      pp_verbatim (context->printer,
-		   _("%s:%d:%d:   instantiated from %qs\n"),
-		   xloc.file, xloc.line, xloc.column, str);
-    else
-      pp_verbatim (context->printer,
-		   _("%s:%d:   instantiated from %qs\n"),
-		   xloc.file, xloc.line, str);
-  } else {
-    if (flag_show_column)
-      pp_verbatim (context->printer, _("%s:%d:%d:   instantiated from here"),
-		   xloc.file, xloc.line, xloc.column);
-    else
-      pp_verbatim (context->printer, _("%s:%d:   instantiated from here"),
-		   xloc.file, xloc.line);
-  }
+  if (t != NULL) 
+    {
+      const char *str;
+      str = decl_as_string_translate (t->decl,
+				      TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE);
+      if (flag_show_column)
+	pp_verbatim (context->printer,
+		     recursive_p
+		     ? _("%s:%d:%d:   recursively instantiated from %qs\n")
+		     : _("%s:%d:%d:   instantiated from %qs\n"),
+		     xloc.file, xloc.line, xloc.column, str);
+      else
+	pp_verbatim (context->printer,
+		     recursive_p
+		     ? _("%s:%d:   recursively instantiated from %qs\n")
+		     : _("%s:%d:   recursively instantiated from %qs\n"),
+		     xloc.file, xloc.line, str);
+    }
+  else
+    {
+      if (flag_show_column)
+	pp_verbatim (context->printer, 
+		     recursive_p
+		     ? _("%s:%d:%d:   recursively instantiated from here")
+		     : _("%s:%d:%d:   instantiated from here"),
+		     xloc.file, xloc.line, xloc.column);
+      else
+	pp_verbatim (context->printer,
+		     recursive_p
+		     ? _("%s:%d:   recursively instantiated from here")
+		     : _("%s:%d:   instantiated from here"),
+		     xloc.file, xloc.line);
+    }
 }
 
 /* Same as print_instantiation_full_context but less verbose.  */
 
 static void
@@ -2767,27 +2781,34 @@ print_instantiation_partial_context (dia
 				     struct tinst_level *t0, location_t loc)
 {
   struct tinst_level *t;
   int n_total = 0;
   int n;
+  location_t prev_loc = loc;
 
   for (t = t0; t != NULL; t = t->next)
-    n_total++;
+    if (prev_loc != t->locus)
+      {
+	prev_loc = t->locus;
+	n_total++;
+      }
 
   t = t0;
 
   if (n_total >= 12) 
     {
       int skip = n_total - 10;
       for (n = 0; n < 5; n++)
 	{
 	  gcc_assert (t != NULL);
-	  print_instantiation_partial_context_line (context, t, loc);
+	  if (loc != t->locus)
+	    print_instantiation_partial_context_line (context, t, loc,
+						      /*recursive_p=*/false);
 	  loc = t->locus;
 	  t = t->next;
 	}
-      if (skip > 1) 
+      if (t != NULL && skip > 1)
 	{
 	  expanded_location xloc;
 	  xloc = expand_location (loc);
 	  if (flag_show_column)
 	    pp_verbatim (context->printer,
@@ -2797,22 +2818,30 @@ print_instantiation_partial_context (dia
 	    pp_verbatim (context->printer,
 			 _("%s:%d:   [ skipping %d instantiation contexts ]\n"),
 			 xloc.file, xloc.line, skip);
 	  
 	  do {
-	      loc = t->locus;
-	      t = t->next;
-	  } while (--skip > 0);
+	    loc = t->locus;
+	    t = t->next;
+	  } while (t != NULL && --skip > 0);
 	}
     }
   
-  for (; t != NULL; t = t->next)
+  while (t != NULL)
     {
-      print_instantiation_partial_context_line (context, t, loc);
+      while (t->next != NULL && t->locus == t->next->locus)
+	{
+	  loc = t->locus;
+	  t = t->next;
+	}
+      print_instantiation_partial_context_line (context, t, loc,
+						t->locus == loc);
       loc = t->locus;
+      t = t->next;
     }
-  print_instantiation_partial_context_line (context, NULL, loc);
+  print_instantiation_partial_context_line (context, NULL, loc,
+					    /*recursive_p=*/false);
   pp_base_newline (context->printer);
 }
 
 /* Called from cp_thing to print the template context for an error.  */
 static void

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]