From: Jason Merrill Date: Wed, 21 Apr 2010 06:06:27 +0000 (-0400) Subject: re PR c++/9335 (repeated diagnostic when maximum template depth is exceeded) X-Git-Tag: upstream/12.2.0~93601 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=88274c4d22e7cd9261fdf779dcd740d3056d60db;p=platform%2Fupstream%2Fgcc.git re PR c++/9335 (repeated diagnostic when maximum template depth is exceeded) 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 83945e2..6dec7c3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2010-04-20 Jason Merrill + + 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 PR c++/43800 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 6fcb1f0..1f87c5f 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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. */; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c31aa5c..580f6f8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index c1f1cbf..e1dee1d 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e689381..9750baa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2010-04-20 Jason Merrill + + 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 * gcc.dg/torture/builtin-cproj-1.c: Test more cases. diff --git a/gcc/testsuite/g++.dg/init/member1.C b/gcc/testsuite/g++.dg/init/member1.C index e2af080..aededf2 100644 --- a/gcc/testsuite/g++.dg/init/member1.C +++ b/gcc/testsuite/g++.dg/init/member1.C @@ -11,7 +11,7 @@ template struct B {}; template struct C { static const int i = A::i; // { dg-error "incomplete" } - static const int j = i; // { dg-error "non-constant expression" } + static const int j = i; B b; // { dg-error "not a valid template arg" } }; diff --git a/gcc/testsuite/g++.dg/other/fold1.C b/gcc/testsuite/g++.dg/other/fold1.C index b085a84f0..b075fc1 100644 --- a/gcc/testsuite/g++.dg/other/fold1.C +++ b/gcc/testsuite/g++.dg/other/fold1.C @@ -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]; }; diff --git a/gcc/testsuite/g++.dg/parse/crash36.C b/gcc/testsuite/g++.dg/parse/crash36.C index 6f5c867..6116eb0 100644 --- a/gcc/testsuite/g++.dg/parse/crash36.C +++ b/gcc/testsuite/g++.dg/parse/crash36.C @@ -9,4 +9,4 @@ template struct A // { dg-warning "variadic templates" } static const int i = sizeof (++t); // { dg-error "was not declared in this scope" } }; -int x[A ::i]; // { dg-error "is not an integral constant-expression" } +int x[A ::i]; diff --git a/gcc/testsuite/g++.dg/template/recurse2.C b/gcc/testsuite/g++.dg/template/recurse2.C new file mode 100644 index 0000000..cf085e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/recurse2.C @@ -0,0 +1,7 @@ +// PR c++/9335 +// We should not see an error about non-constant initialization. + +template struct X { + static const int value = X::value; // { dg-error "instantiation|incomplete" } +}; +template struct X<1000>; diff --git a/gcc/testsuite/lib/prune.exp b/gcc/testsuite/lib/prune.exp index ef647d5..160f651 100644 --- a/gcc/testsuite/lib/prune.exp +++ b/gcc/testsuite/lib/prune.exp @@ -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