diff options
author | Lee Millward <lee.millward@codesourcery.com> | 2006-08-26 17:41:18 +0000 |
---|---|---|
committer | Lee Millward <lmillward@gcc.gnu.org> | 2006-08-26 17:41:18 +0000 |
commit | 0f67a82f746f54701bea05608502944ca26ae715 (patch) | |
tree | 17042b9752adae54363119249db31c45d318974e /gcc | |
parent | 9618502bff5f70682077580ff083fe82160b4d7a (diff) | |
download | gcc-0f67a82f746f54701bea05608502944ca26ae715.zip gcc-0f67a82f746f54701bea05608502944ca26ae715.tar.gz gcc-0f67a82f746f54701bea05608502944ca26ae715.tar.bz2 |
re PR c++/28736 (ICE with friend of invalid template class)
PR c++/28736
PR c++/28737
PR c++/28738
* pt.c (process_template_parm): Store invalid template
parameters as a TREE_LIST with a TREE_VALUE of error_mark_node.
(push_inline_template_parms_recursive): Check for template
parameters having a TREE_VALUE of error_mark_node rather than
check the parameter itself.
(mangle_class_name_for_template): Likewise.
(comp_template_parms): When comparing the individual template
parameters, return 1 if either is error_mark_node.
(current_template_args): Robustify.
(redeclare_class_template): Likewise.
* g++.dg/template/void10.C: New test.
* g++.dg/template/void8.C: New test.
* g++.dg/template/void9.C: New test.
* g++.dg/template/void3.C: Adjust error markers.
* g++.dg/template/void4.C: Likewise.
* g++.dg/template/crash55.C: Likewise.
* g++.dg/template/void7.C: Likewise.
From-SVN: r116473
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/pt.c | 63 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash55.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/void10.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/void3.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/void4.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/void7.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/void8.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/void9.C | 4 |
10 files changed, 94 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d7c952d..e219547 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2006-08-26 Lee Millward <lee.millward@codesourcery.com> + + PR c++/28736 + PR c++/28737 + PR c++/28738 + * pt.c (process_template_parm): Store invalid template + parameters as a TREE_LIST with a TREE_VALUE of error_mark_node. + (push_inline_template_parms_recursive): Check for template + parameters having a TREE_VALUE of error_mark_node rather than + check the parameter itself. + (mangle_class_name_for_template): Likewise. + (comp_template_parms): When comparing the individual template + parameters, return 1 if either is error_mark_node. + (current_template_args): Robustify. + (redeclare_class_template): Likewise. + 2006-08-26 Mark Mitchell <mark@codesourcery.com> PR c++/28588 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e078149..5e0c954 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -336,12 +336,11 @@ push_inline_template_parms_recursive (tree parmlist, int levels) NULL); for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) { - tree parm; + tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - if (TREE_VEC_ELT (parms, i) == error_mark_node) - continue; + if (parm == error_mark_node) + continue; - parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); gcc_assert (DECL_P (parm)); switch (TREE_CODE (parm)) @@ -2212,15 +2211,13 @@ comp_template_parms (tree parms1, tree parms2) for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) { - tree parm1; - tree parm2; + tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i)); + tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); - 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 either of the template parameters are invalid, assume + they match for the sake of error recovery. */ + if (parm1 == error_mark_node || parm2 == error_mark_node) + return 1; if (TREE_CODE (parm1) != TREE_CODE (parm2)) return 0; @@ -2352,6 +2349,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) { tree decl = 0; tree defval; + tree err_parm_list; int idx = 0; gcc_assert (TREE_CODE (parm) == TREE_LIST); @@ -2361,7 +2359,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) { tree p = tree_last (list); - if (p && p != error_mark_node) + if (p && TREE_VALUE (p) != error_mark_node) { p = TREE_VALUE (p); if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) @@ -2382,7 +2380,11 @@ process_template_parm (tree list, tree parm, bool is_non_type) SET_DECL_TEMPLATE_PARM_P (parm); if (TREE_TYPE (parm) == error_mark_node) - return chainon(list, error_mark_node); + { + err_parm_list = build_tree_list (defval, parm); + TREE_VALUE (err_parm_list) = error_mark_node; + return chainon (list, err_parm_list); + } else { /* [temp.param] @@ -2391,7 +2393,11 @@ 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)) - return chainon(list, error_mark_node); + { + err_parm_list = build_tree_list (defval, parm); + TREE_VALUE (err_parm_list) = error_mark_node; + return chainon (list, err_parm_list); + } } /* A template parameter is not modifiable. */ @@ -2522,11 +2528,15 @@ current_template_args (void) { t = TREE_VALUE (t); - if (TREE_CODE (t) == TYPE_DECL - || TREE_CODE (t) == TEMPLATE_DECL) - t = TREE_TYPE (t); - else - t = DECL_INITIAL (t); + if (t != error_mark_node) + { + if (TREE_CODE (t) == TYPE_DECL + || TREE_CODE (t) == TEMPLATE_DECL) + t = TREE_TYPE (t); + else + t = DECL_INITIAL (t); + } + TREE_VEC_ELT (a, i) = t; } } @@ -3350,9 +3360,10 @@ redeclare_class_template (tree type, tree parms) /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or TEMPLATE_DECL. */ - if (TREE_CODE (tmpl_parm) != TREE_CODE (parm) - || (TREE_CODE (tmpl_parm) != TYPE_DECL - && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))) + if (tmpl_parm != error_mark_node + && (TREE_CODE (tmpl_parm) != TREE_CODE (parm) + || (TREE_CODE (tmpl_parm) != TYPE_DECL + && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))) { error ("template parameter %q+#D", tmpl_parm); error ("redeclared here as %q#D", parm); @@ -4207,12 +4218,12 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) 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 (parm == error_mark_node) + continue; + if (i) ccat (','); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 017de89..1df7996 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2006-08-26 Lee Millward <lee.millward@codesourcery.com> + + PR c++/28736 + * g++.dg/template/void10.C: New test. + + PR c++/28737 + * g++.dg/template/void8.C: New test. + + PR c+_+/28738 + * g++.dg/template/void9.C: New test. + + * g++.dg/template/void3.C: Adjust error markers. + * g++.dg/template/void4.C: Likewise. + * g++.dg/template/crash55.C: Likewise. + * g++.dg/template/void7.C: Likewise + 2006-08-26 Mark Mitchell <mark@codesourcery.com> PR c++/28588 diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C index 7e15b66..0e3fe4c 100644 --- a/gcc/testsuite/g++.dg/template/crash55.C +++ b/gcc/testsuite/g++.dg/template/crash55.C @@ -3,4 +3,4 @@ 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" } +template<int> void foo(A<int>); // { dg-error "mismatch|constant|template argument" } diff --git a/gcc/testsuite/g++.dg/template/void10.C b/gcc/testsuite/g++.dg/template/void10.C new file mode 100644 index 0000000..56e0b6d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void10.C @@ -0,0 +1,10 @@ +//PR c++/28736 + +template<void> struct A // { dg-error "not a valid type" } +{ + template<typename> friend struct B; +}; + +template<typename> struct B {}; + +B<int> b; // { dg-error "template argument|invalid type" } diff --git a/gcc/testsuite/g++.dg/template/void3.C b/gcc/testsuite/g++.dg/template/void3.C index 6526a2a..bb59934 100644 --- a/gcc/testsuite/g++.dg/template/void3.C +++ b/gcc/testsuite/g++.dg/template/void3.C @@ -1,5 +1,5 @@ //PR c++/28637 template<void> struct A {}; // { dg-error "not a valid type" } -A<0> a; +A<0> a; // { dg-error "type" } diff --git a/gcc/testsuite/g++.dg/template/void4.C b/gcc/testsuite/g++.dg/template/void4.C index 7d264fb..fe30b2e 100644 --- a/gcc/testsuite/g++.dg/template/void4.C +++ b/gcc/testsuite/g++.dg/template/void4.C @@ -4,4 +4,4 @@ template<void> struct A; // { dg-error "not a valid type" } template<template<int> class> struct B {}; -B<A> b; +B<A> b; // { dg-error "template|invalid type" } diff --git a/gcc/testsuite/g++.dg/template/void7.C b/gcc/testsuite/g++.dg/template/void7.C index 2c464b3..95d87a2 100644 --- a/gcc/testsuite/g++.dg/template/void7.C +++ b/gcc/testsuite/g++.dg/template/void7.C @@ -5,4 +5,4 @@ template<void> struct A // { dg-error "not a valid type" } static int i; }; -A<0> a; +A<0> a; // { dg-error "invalid type|not a valid type" } diff --git a/gcc/testsuite/g++.dg/template/void8.C b/gcc/testsuite/g++.dg/template/void8.C new file mode 100644 index 0000000..e45c91c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void8.C @@ -0,0 +1,7 @@ +//PR c++/28737 + +template<void> struct A; // { dg-error "not a valid type" } + +template<typename> struct B; + +template<void N> struct B<A<N> > {}; // { dg-error "not a valid type|declared|invalid" } diff --git a/gcc/testsuite/g++.dg/template/void9.C b/gcc/testsuite/g++.dg/template/void9.C new file mode 100644 index 0000000..bb2ed66 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void9.C @@ -0,0 +1,4 @@ +//PR c++/28738 + +template<int,void> struct A {}; // { dg-error "not a valid type" } +template<int N> struct A<N,0> {}; // { dg-error "not a valid type" } |