From: Lee Millward Date: Fri, 28 Jul 2006 17:01:19 +0000 (+0000) Subject: re PR c++/27668 (ICE with invalid template parameter) X-Git-Tag: releases/gcc-4.2.0~1922 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=42b304f1ce846092056b7daa32c6288e285420fa;p=thirdparty%2Fgcc.git re PR c++/27668 (ICE with invalid template parameter) PR c++/27668 PR c++/27962 * pt.c (process_template_parm) Store invalid template parameters as error_mark_node in the paramater list. (push_inline_template_parms_recursive): Handle invalid template parameters. (comp_template_parms): Likewise. (check_default_tmpl_arg): Likewise. (coerce_template_template_parms): Likewise. (mangle_class_name_for_template): Likewise. (tsubst_template_parms): Likewise. * error.c (dump_template_argument_list): Likewise. * g++.dg/template/crash55.C: New test. * g++.dg/template/nontype16.C: New test. * g++.dg/template/void2.C: Adjust error markers. * g++.dg/template/nontype5.C: Adjust error markers. From-SVN: r115800 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 42db58a80609..355332ac2677 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2006-07-28 Lee Millward + + PR c++/27668 + PR c++/27962 + * pt.c (process_template_parm) Store invalid template + parameters as error_mark_node in the paramater list. + (push_inline_template_parms_recursive): Handle invalid + template parameters. + (comp_template_parms): Likewise. + (check_default_tmpl_arg): Likewise. + (coerce_template_template_parms): Likewise. + (mangle_class_name_for_template): Likewise. + (tsubst_template_parms): Likewise. + * error.c (dump_template_argument_list): Likewise. + 2006-07-28 Kazu Hirata * cp-tree.h: Fix a comment typo. diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 91a73cca4fce..d6c813da7a7f 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -166,8 +166,14 @@ dump_template_argument_list (tree args, int flags) static void dump_template_parameter (tree parm, int flags) { - tree p = TREE_VALUE (parm); - tree a = TREE_PURPOSE (parm); + tree p; + tree a; + + if (parm == error_mark_node) + return; + + p = TREE_VALUE (parm); + a = TREE_PURPOSE (parm); if (TREE_CODE (p) == TYPE_DECL) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0b852fa2df46..5a7bfb8da551 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -336,7 +336,12 @@ push_inline_template_parms_recursive (tree parmlist, int levels) NULL); for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) { - tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); + tree parm; + + if (TREE_VEC_ELT (parms, i) == error_mark_node) + continue; + + parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); gcc_assert (DECL_P (parm)); switch (TREE_CODE (parm)) @@ -2204,8 +2209,15 @@ comp_template_parms (tree parms1, tree parms2) for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) { - tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i)); - tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); + tree parm1; + tree parm2; + + if (TREE_VEC_ELT (t1, i) == error_mark_node + || TREE_VEC_ELT (t2, i) == error_mark_node) + continue; + + parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i)); + parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); if (TREE_CODE (parm1) != TREE_CODE (parm2)) return 0; @@ -2362,7 +2374,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) SET_DECL_TEMPLATE_PARM_P (parm); if (TREE_TYPE (parm) == error_mark_node) - TREE_TYPE (parm) = void_type_node; + return chainon(list, error_mark_node); else { /* [temp.param] @@ -2371,7 +2383,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) ignored when determining its type. */ TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) - TREE_TYPE (parm) = void_type_node; + return chainon(list, error_mark_node); } /* A template parameter is not modifiable. */ @@ -2838,6 +2850,10 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) for (i = 0; i < ntparms; ++i) { tree parm = TREE_VEC_ELT (inner_parms, i); + + if (parm == error_mark_node) + continue; + if (TREE_PURPOSE (parm)) seen_def_arg_p = 1; else if (seen_def_arg_p) @@ -2902,18 +2918,23 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) ntparms = TREE_VEC_LENGTH (inner_parms); for (i = 0; i < ntparms; ++i) - if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) - { - if (msg) - { - error (msg, decl); - msg = 0; - } + { + if (TREE_VEC_ELT (inner_parms, i) == error_mark_node) + continue; - /* Clear out the default argument so that we are not - confused later. */ - TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; - } + if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) + { + if (msg) + { + error (msg, decl); + msg = 0; + } + + /* Clear out the default argument so that we are not + confused later. */ + TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; + } + } /* At this point, if we're still interested in issuing messages, they must apply to classes surrounding the object declared. */ @@ -3764,6 +3785,9 @@ coerce_template_template_parms (tree parm_parms, for (i = 0; i < nparms; ++i) { + if (TREE_VEC_ELT (parm_parms, i) == error_mark_node) + continue; + parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i)); arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i)); @@ -4023,7 +4047,8 @@ coerce_template_parms (tree parms, || (nargs < nparms && require_all_args && (!use_default_args - || !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))) + || (TREE_VEC_ELT (parms, nargs) != error_mark_node + && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))) { if (complain & tf_error) { @@ -4046,6 +4071,9 @@ coerce_template_parms (tree parms, /* Get the Ith template parameter. */ parm = TREE_VEC_ELT (parms, i); + + if (parm == error_mark_node) + continue; /* Calculate the Ith argument. */ if (i < nargs) @@ -4146,8 +4174,14 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) gcc_assert (nparms == TREE_VEC_LENGTH (arglist)); for (i = 0; i < nparms; i++) { - tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - tree arg = TREE_VEC_ELT (arglist, i); + tree parm; + tree arg; + + if (TREE_VEC_ELT (parms, i) == error_mark_node) + continue; + + parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); + arg = TREE_VEC_ELT (arglist, i); if (i) ccat (','); @@ -6053,9 +6087,20 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i) { - tree tuple = TREE_VEC_ELT (TREE_VALUE (parms), i); - tree default_value = TREE_PURPOSE (tuple); - tree parm_decl = TREE_VALUE (tuple); + tree tuple; + tree default_value; + tree parm_decl; + + if (parms == error_mark_node) + continue; + + tuple = TREE_VEC_ELT (TREE_VALUE (parms), i); + + if (tuple == error_mark_node) + continue; + + default_value = TREE_PURPOSE (tuple); + parm_decl = TREE_VALUE (tuple); parm_decl = tsubst (parm_decl, args, complain, NULL_TREE); if (TREE_CODE (parm_decl) == PARM_DECL diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4cfaccf2615b..90c9ebf89e32 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2006-07-28 Lee Millward + + PR c++/27668 + * g++.dg/template/crash55.C: New test. + + PR c++/27962 + * g++.dg/template/nontype16.C: New test. + + * g++.dg/template/void2.C: Adjust error markers. + * g++.dg/template/nontype5.C: Adjust error markers. + 2006-07-27 Arjan van de Ven * gcc.target/i386/stack-prot-kernel.c: New test. diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C new file mode 100644 index 000000000000..7e15b66ee75b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash55.C @@ -0,0 +1,6 @@ +//PR c++/27668 + +template // { dg-error "nested-name-specifier|two or more|valid type" } +struct A {}; // { dg-error "definition" + +template void foo(A); // { dg-error "mismatch|constant" } diff --git a/gcc/testsuite/g++.dg/template/nontype16.C b/gcc/testsuite/g++.dg/template/nontype16.C new file mode 100644 index 000000000000..36d1e9564a09 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype16.C @@ -0,0 +1,9 @@ +//PR c++/27962 + +template struct A +{ + template void foo(); +}; + +template<> template void A<0>::foo() {} // { dg-error "not a valid type" } + diff --git a/gcc/testsuite/g++.dg/template/nontype5.C b/gcc/testsuite/g++.dg/template/nontype5.C index e53b6c1a6548..f7b76259bbc3 100644 --- a/gcc/testsuite/g++.dg/template/nontype5.C +++ b/gcc/testsuite/g++.dg/template/nontype5.C @@ -11,4 +11,4 @@ template struct A template struct C {}; // { dg-error "not a valid type" } }; -A<0> a; // { dg-error "instantiated" } +A<0> a; diff --git a/gcc/testsuite/g++.dg/template/void2.C b/gcc/testsuite/g++.dg/template/void2.C index aa041783ff8c..05a8186e03a5 100644 --- a/gcc/testsuite/g++.dg/template/void2.C +++ b/gcc/testsuite/g++.dg/template/void2.C @@ -6,4 +6,4 @@ template struct A template friend class X; // { dg-error "void" } }; -A<0> a; // { dg-error "instantiated" } +A<0> a;