From: Lee Millward Date: Sat, 26 Aug 2006 17:41:18 +0000 (+0000) Subject: re PR c++/28736 (ICE with friend of invalid template class) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f67a82f746f54701bea05608502944ca26ae715;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d7c952dd880..e219547c545 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2006-08-26 Lee Millward + + 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 PR c++/28588 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e078149fa77..5e0c9541b9a 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 017de891864..1df799676b4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2006-08-26 Lee Millward + + 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 PR c++/28588 diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C index 7e15b66ee75..0e3fe4c3a59 100644 --- a/gcc/testsuite/g++.dg/template/crash55.C +++ b/gcc/testsuite/g++.dg/template/crash55.C @@ -3,4 +3,4 @@ template // { dg-error "nested-name-specifier|two or more|valid type" } struct A {}; // { dg-error "definition" -template void foo(A); // { dg-error "mismatch|constant" } +template void foo(A); // { 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 00000000000..56e0b6d2e5b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void10.C @@ -0,0 +1,10 @@ +//PR c++/28736 + +template struct A // { dg-error "not a valid type" } +{ + template friend struct B; +}; + +template struct B {}; + +B 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 6526a2a47be..bb59934ffe4 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 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 7d264fbf10b..fe30b2e3736 100644 --- a/gcc/testsuite/g++.dg/template/void4.C +++ b/gcc/testsuite/g++.dg/template/void4.C @@ -4,4 +4,4 @@ template struct A; // { dg-error "not a valid type" } template class> struct B {}; -B b; +B 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 2c464b3a055..95d87a20732 100644 --- a/gcc/testsuite/g++.dg/template/void7.C +++ b/gcc/testsuite/g++.dg/template/void7.C @@ -5,4 +5,4 @@ template 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 00000000000..e45c91c044c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void8.C @@ -0,0 +1,7 @@ +//PR c++/28737 + +template struct A; // { dg-error "not a valid type" } + +template struct B; + +template struct B > {}; // { 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 00000000000..bb2ed66ff38 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/void9.C @@ -0,0 +1,4 @@ +//PR c++/28738 + +template struct A {}; // { dg-error "not a valid type" } +template struct A {}; // { dg-error "not a valid type" }