diff options
author | Lee Millward <lee.millward@codesourcery.com> | 2006-07-28 17:01:19 +0000 |
---|---|---|
committer | Lee Millward <lmillward@gcc.gnu.org> | 2006-07-28 17:01:19 +0000 |
commit | 42b304f1ce846092056b7daa32c6288e285420fa (patch) | |
tree | b9d1ed85681b7f931fd356b2dec21c008026518e /gcc | |
parent | 8f2cc5b59bd35f2cac909fbe84cb6093be3121e5 (diff) | |
download | gcc-42b304f1ce846092056b7daa32c6288e285420fa.tar.gz |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/error.c | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 89 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash55.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/nontype16.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/nontype5.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/void2.C | 2 |
8 files changed, 118 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 42db58a8060..355332ac267 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2006-07-28 Lee Millward <lee.millward@codesourcery.com> + + 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 <kazu@codesourcery.com> * cp-tree.h: Fix a comment typo. diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 91a73cca4fc..d6c813da7a7 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 0b852fa2df4..5a7bfb8da55 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 4cfaccf2615..90c9ebf89e3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2006-07-28 Lee Millward <lee.millward@codesourcery.com> + + 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 <arjan@linux.intel.com> * 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 00000000000..7e15b66ee75 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash55.C @@ -0,0 +1,6 @@ +//PR c++/27668 + +template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|valid type" } +struct A {}; // { dg-error "definition" + +template<int> void foo(A<int>); // { 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 00000000000..36d1e9564a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype16.C @@ -0,0 +1,9 @@ +//PR c++/27962 + +template<int> struct A +{ + template<typename> void foo(); +}; + +template<> template<struct T> 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 e53b6c1a654..f7b76259bbc 100644 --- a/gcc/testsuite/g++.dg/template/nontype5.C +++ b/gcc/testsuite/g++.dg/template/nontype5.C @@ -11,4 +11,4 @@ template <int> struct A template <B> 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 aa041783ff8..05a8186e03a 100644 --- a/gcc/testsuite/g++.dg/template/void2.C +++ b/gcc/testsuite/g++.dg/template/void2.C @@ -6,4 +6,4 @@ template<int> struct A template<void> friend class X; // { dg-error "void" } }; -A<0> a; // { dg-error "instantiated" } +A<0> a; |