re PR c++/9335 (repeated diagnostic when maximum template depth is exceeded)
authorJason Merrill <jason@redhat.com>
Wed, 21 Apr 2010 06:06:27 +0000 (02:06 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 21 Apr 2010 06:06:27 +0000 (02:06 -0400)
PR c++/9335
gcc/cp:
* init.c (constant_value_1): Treat error_mark_node as a constant
if DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P is set.
* cvt.c (ocp_convert): Handle getting error_mark_node from
integral_constant_value.
* decl.c (compute_array_index_type): Likewise.
gcc/testsuite:
* lib/prune.exp: Prune "skipping N instantiation contexts".

From-SVN: r158586

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/member1.C
gcc/testsuite/g++.dg/other/fold1.C
gcc/testsuite/g++.dg/parse/crash36.C
gcc/testsuite/g++.dg/template/recurse2.C [new file with mode: 0644]
gcc/testsuite/lib/prune.exp

index 83945e2..6dec7c3 100644 (file)
@@ -1,3 +1,12 @@
+2010-04-20  Jason Merrill  <jason@redhat.com>
+
+       PR c++/9335
+       * init.c (constant_value_1): Treat error_mark_node as a constant
+       if DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P is set.
+       * cvt.c (ocp_convert): Handle getting error_mark_node from
+       integral_constant_value.
+       * decl.c (compute_array_index_type): Likewise.
+
 2010-04-20  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/43800
index 6fcb1f0..1f87c5f 100644 (file)
@@ -610,6 +610,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
     }
 
   e = integral_constant_value (e);
+  if (error_operand_p (e))
+    return error_mark_node;
 
   if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP))
     /* We need a new temporary; don't take this shortcut.  */;
index c31aa5c..580f6f8 100644 (file)
@@ -7319,6 +7319,8 @@ compute_array_index_type (tree name, tree size)
 
   /* It might be a const variable or enumeration constant.  */
   size = integral_constant_value (size);
+  if (error_operand_p (size))
+    return error_mark_node;
 
   /* Normally, the array-bound will be a constant.  */
   if (TREE_CODE (size) == INTEGER_CST)
index c1f1cbf..e1dee1d 100644 (file)
@@ -1658,7 +1658,14 @@ constant_value_1 (tree decl, bool integral_p)
          init = DECL_INITIAL (decl);
        }
       if (init == error_mark_node)
-       return decl;
+       {
+         if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
+           /* Treat the error as a constant to avoid cascading errors on
+              excessively recursive template instantiation (c++/9335).  */
+           return init;
+         else
+           return decl;
+       }
       /* Initializers in templates are generally expanded during
         instantiation, so before that for const int i(2)
         INIT is a TREE_LIST with the actual initializer as
index e689381..9750baa 100644 (file)
@@ -1,3 +1,12 @@
+2010-04-20  Jason Merrill  <jason@redhat.com>
+
+       PR c++/9335
+       * g++.dg/template/recurse2.C: New.
+       * g++.dg/parse/crash36.C: Adjust.
+       * g++.dg/other/fold1.C: Adjust.
+       * g++.dg/init/member1.C: Adjust.
+       * lib/prune.exp: Prune "skipping N instantiation contexts".
+
 2010-04-20  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * gcc.dg/torture/builtin-cproj-1.c: Test more cases.
index e2af080..aededf2 100644 (file)
@@ -11,7 +11,7 @@ template<int> struct B {};
 template<typename T> struct C
 {
   static const int i = A<T>::i;  // { dg-error "incomplete" }
-  static const int j = i;  // { dg-error "non-constant expression" }
+  static const int j = i;
   B<j> b;  // { dg-error "not a valid template arg" }
 };
 
index b085a84..b075fc1 100644 (file)
@@ -4,5 +4,5 @@
 struct A
 {
     static const int i = i;  // { dg-error "not declared" }
-    int x[i];                // { dg-error "integral constant-expression" }
+    int x[i];
 };
index 6f5c867..6116eb0 100644 (file)
@@ -9,4 +9,4 @@ template <typename... T> struct A       // { dg-warning "variadic templates" }
   static const int i = sizeof (++t);   // { dg-error "was not declared in this scope" }
 };
 
-int x[A <int>::i];     // { dg-error "is not an integral constant-expression" }
+int x[A <int>::i];
diff --git a/gcc/testsuite/g++.dg/template/recurse2.C b/gcc/testsuite/g++.dg/template/recurse2.C
new file mode 100644 (file)
index 0000000..cf085e0
--- /dev/null
@@ -0,0 +1,7 @@
+// 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" }
+};
+template struct X<1000>;
index ef647d5..160f651 100644 (file)
@@ -23,6 +23,7 @@ proc prune_gcc_output { text } {
     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\]*:   . 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