+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
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))
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;
{
tree decl = 0;
tree defval;
+ tree err_parm_list;
int idx = 0;
gcc_assert (TREE_CODE (parm) == TREE_LIST);
{
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)
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]
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. */
{
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;
}
}
/* 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);
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 (',');