Commit 0f67a82f by Lee Millward Committed by Lee Millward

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
parent 9618502b
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> 2006-08-26 Mark Mitchell <mark@codesourcery.com>
PR c++/28588 PR c++/28588
......
...@@ -336,12 +336,11 @@ push_inline_template_parms_recursive (tree parmlist, int levels) ...@@ -336,12 +336,11 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
NULL); NULL);
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) 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) if (parm == error_mark_node)
continue; continue;
parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
gcc_assert (DECL_P (parm)); gcc_assert (DECL_P (parm));
switch (TREE_CODE (parm)) switch (TREE_CODE (parm))
...@@ -2212,15 +2211,13 @@ comp_template_parms (tree parms1, tree parms2) ...@@ -2212,15 +2211,13 @@ comp_template_parms (tree parms1, tree parms2)
for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
{ {
tree parm1; tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
tree parm2; tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
if (TREE_VEC_ELT (t1, i) == error_mark_node /* If either of the template parameters are invalid, assume
|| TREE_VEC_ELT (t2, i) == error_mark_node) they match for the sake of error recovery. */
continue; if (parm1 == error_mark_node || parm2 == error_mark_node)
return 1;
parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
if (TREE_CODE (parm1) != TREE_CODE (parm2)) if (TREE_CODE (parm1) != TREE_CODE (parm2))
return 0; return 0;
...@@ -2352,6 +2349,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) ...@@ -2352,6 +2349,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
{ {
tree decl = 0; tree decl = 0;
tree defval; tree defval;
tree err_parm_list;
int idx = 0; int idx = 0;
gcc_assert (TREE_CODE (parm) == TREE_LIST); gcc_assert (TREE_CODE (parm) == TREE_LIST);
...@@ -2361,7 +2359,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) ...@@ -2361,7 +2359,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
{ {
tree p = tree_last (list); tree p = tree_last (list);
if (p && p != error_mark_node) if (p && TREE_VALUE (p) != error_mark_node)
{ {
p = TREE_VALUE (p); p = TREE_VALUE (p);
if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL) 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) ...@@ -2382,7 +2380,11 @@ process_template_parm (tree list, tree parm, bool is_non_type)
SET_DECL_TEMPLATE_PARM_P (parm); SET_DECL_TEMPLATE_PARM_P (parm);
if (TREE_TYPE (parm) == error_mark_node) 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 else
{ {
/* [temp.param] /* [temp.param]
...@@ -2391,7 +2393,11 @@ process_template_parm (tree list, tree parm, bool is_non_type) ...@@ -2391,7 +2393,11 @@ process_template_parm (tree list, tree parm, bool is_non_type)
ignored when determining its type. */ ignored when determining its type. */
TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) 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. */ /* A template parameter is not modifiable. */
...@@ -2522,11 +2528,15 @@ current_template_args (void) ...@@ -2522,11 +2528,15 @@ current_template_args (void)
{ {
t = TREE_VALUE (t); t = TREE_VALUE (t);
if (TREE_CODE (t) == TYPE_DECL if (t != error_mark_node)
|| TREE_CODE (t) == TEMPLATE_DECL) {
t = TREE_TYPE (t); if (TREE_CODE (t) == TYPE_DECL
else || TREE_CODE (t) == TEMPLATE_DECL)
t = DECL_INITIAL (t); t = TREE_TYPE (t);
else
t = DECL_INITIAL (t);
}
TREE_VEC_ELT (a, i) = t; TREE_VEC_ELT (a, i) = t;
} }
} }
...@@ -3350,9 +3360,10 @@ redeclare_class_template (tree type, tree parms) ...@@ -3350,9 +3360,10 @@ redeclare_class_template (tree type, tree parms)
/* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
TEMPLATE_DECL. */ TEMPLATE_DECL. */
if (TREE_CODE (tmpl_parm) != TREE_CODE (parm) if (tmpl_parm != error_mark_node
|| (TREE_CODE (tmpl_parm) != TYPE_DECL && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
&& !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (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 ("template parameter %q+#D", tmpl_parm);
error ("redeclared here as %q#D", parm); error ("redeclared here as %q#D", parm);
...@@ -4207,12 +4218,12 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) ...@@ -4207,12 +4218,12 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
tree parm; tree parm;
tree arg; tree arg;
if (TREE_VEC_ELT (parms, i) == error_mark_node)
continue;
parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
arg = TREE_VEC_ELT (arglist, i); arg = TREE_VEC_ELT (arglist, i);
if (parm == error_mark_node)
continue;
if (i) if (i)
ccat (','); ccat (',');
......
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> 2006-08-26 Mark Mitchell <mark@codesourcery.com>
PR c++/28588 PR c++/28588
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|valid type" } template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|valid type" }
struct A {}; // { dg-error "definition" 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" }
//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" }
//PR c++/28637 //PR c++/28637
template<void> struct A {}; // { dg-error "not a valid type" } template<void> struct A {}; // { dg-error "not a valid type" }
A<0> a; A<0> a; // { dg-error "type" }
...@@ -4,4 +4,4 @@ template<void> struct A; // { dg-error "not a valid type" } ...@@ -4,4 +4,4 @@ template<void> struct A; // { dg-error "not a valid type" }
template<template<int> class> struct B {}; template<template<int> class> struct B {};
B<A> b; B<A> b; // { dg-error "template|invalid type" }
...@@ -5,4 +5,4 @@ template<void> struct A // { dg-error "not a valid type" } ...@@ -5,4 +5,4 @@ template<void> struct A // { dg-error "not a valid type" }
static int i; static int i;
}; };
A<0> a; A<0> a; // { dg-error "invalid type|not a valid type" }
//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" }
//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" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment