+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
}
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. */;
/* 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)
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
+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.
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" }
};
struct A
{
static const int i = i; // { dg-error "not declared" }
- int x[i]; // { dg-error "integral constant-expression" }
+ int x[i];
};
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];
--- /dev/null
+// 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>;
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