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
This commit is contained in:
Lee Millward 2006-07-28 17:01:19 +00:00 committed by Lee Millward
parent 8f2cc5b59b
commit 42b304f1ce
8 changed files with 118 additions and 26 deletions

View File

@ -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.

View File

@ -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)
{

View File

@ -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

View File

@ -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.

View File

@ -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" }

View File

@ -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" }

View File

@ -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;

View File

@ -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;