Commit 42b304f1 by Lee Millward Committed by Lee Millward

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
parent 8f2cc5b5
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> 2006-07-28 Kazu Hirata <kazu@codesourcery.com>
* cp-tree.h: Fix a comment typo. * cp-tree.h: Fix a comment typo.
......
...@@ -166,8 +166,14 @@ dump_template_argument_list (tree args, int flags) ...@@ -166,8 +166,14 @@ dump_template_argument_list (tree args, int flags)
static void static void
dump_template_parameter (tree parm, int flags) dump_template_parameter (tree parm, int flags)
{ {
tree p = TREE_VALUE (parm); tree p;
tree a = TREE_PURPOSE (parm); tree a;
if (parm == error_mark_node)
return;
p = TREE_VALUE (parm);
a = TREE_PURPOSE (parm);
if (TREE_CODE (p) == TYPE_DECL) if (TREE_CODE (p) == TYPE_DECL)
{ {
......
...@@ -336,7 +336,12 @@ push_inline_template_parms_recursive (tree parmlist, int levels) ...@@ -336,7 +336,12 @@ 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_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)); gcc_assert (DECL_P (parm));
switch (TREE_CODE (parm)) switch (TREE_CODE (parm))
...@@ -2204,8 +2209,15 @@ comp_template_parms (tree parms1, tree parms2) ...@@ -2204,8 +2209,15 @@ 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_VALUE (TREE_VEC_ELT (t1, i)); tree parm1;
tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); 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)) if (TREE_CODE (parm1) != TREE_CODE (parm2))
return 0; return 0;
...@@ -2362,7 +2374,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) ...@@ -2362,7 +2374,7 @@ 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)
TREE_TYPE (parm) = void_type_node; return chainon(list, error_mark_node);
else else
{ {
/* [temp.param] /* [temp.param]
...@@ -2371,7 +2383,7 @@ process_template_parm (tree list, tree parm, bool is_non_type) ...@@ -2371,7 +2383,7 @@ 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))
TREE_TYPE (parm) = void_type_node; return chainon(list, error_mark_node);
} }
/* A template parameter is not modifiable. */ /* A template parameter is not modifiable. */
...@@ -2838,6 +2850,10 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) ...@@ -2838,6 +2850,10 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
for (i = 0; i < ntparms; ++i) for (i = 0; i < ntparms; ++i)
{ {
tree parm = TREE_VEC_ELT (inner_parms, i); tree parm = TREE_VEC_ELT (inner_parms, i);
if (parm == error_mark_node)
continue;
if (TREE_PURPOSE (parm)) if (TREE_PURPOSE (parm))
seen_def_arg_p = 1; seen_def_arg_p = 1;
else if (seen_def_arg_p) else if (seen_def_arg_p)
...@@ -2902,18 +2918,23 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial) ...@@ -2902,18 +2918,23 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
ntparms = TREE_VEC_LENGTH (inner_parms); ntparms = TREE_VEC_LENGTH (inner_parms);
for (i = 0; i < ntparms; ++i) for (i = 0; i < ntparms; ++i)
if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) {
{ if (TREE_VEC_ELT (inner_parms, i) == error_mark_node)
if (msg) continue;
{
error (msg, decl);
msg = 0;
}
/* Clear out the default argument so that we are not if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
confused later. */ {
TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; 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, /* At this point, if we're still interested in issuing messages,
they must apply to classes surrounding the object declared. */ they must apply to classes surrounding the object declared. */
...@@ -3764,6 +3785,9 @@ coerce_template_template_parms (tree parm_parms, ...@@ -3764,6 +3785,9 @@ coerce_template_template_parms (tree parm_parms,
for (i = 0; i < nparms; ++i) 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)); parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i)); arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
...@@ -4023,7 +4047,8 @@ coerce_template_parms (tree parms, ...@@ -4023,7 +4047,8 @@ coerce_template_parms (tree parms,
|| (nargs < nparms || (nargs < nparms
&& require_all_args && require_all_args
&& (!use_default_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) if (complain & tf_error)
{ {
...@@ -4046,6 +4071,9 @@ coerce_template_parms (tree parms, ...@@ -4046,6 +4071,9 @@ coerce_template_parms (tree parms,
/* Get the Ith template parameter. */ /* Get the Ith template parameter. */
parm = TREE_VEC_ELT (parms, i); parm = TREE_VEC_ELT (parms, i);
if (parm == error_mark_node)
continue;
/* Calculate the Ith argument. */ /* Calculate the Ith argument. */
if (i < nargs) if (i < nargs)
...@@ -4146,8 +4174,14 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) ...@@ -4146,8 +4174,14 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
gcc_assert (nparms == TREE_VEC_LENGTH (arglist)); gcc_assert (nparms == TREE_VEC_LENGTH (arglist));
for (i = 0; i < nparms; i++) for (i = 0; i < nparms; i++)
{ {
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); tree parm;
tree arg = TREE_VEC_ELT (arglist, i); 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) if (i)
ccat (','); ccat (',');
...@@ -6053,9 +6087,20 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) ...@@ -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) for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i)
{ {
tree tuple = TREE_VEC_ELT (TREE_VALUE (parms), i); tree tuple;
tree default_value = TREE_PURPOSE (tuple); tree default_value;
tree parm_decl = TREE_VALUE (tuple); 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); parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
if (TREE_CODE (parm_decl) == PARM_DECL if (TREE_CODE (parm_decl) == PARM_DECL
......
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> 2006-07-27 Arjan van de Ven <arjan@linux.intel.com>
* gcc.target/i386/stack-prot-kernel.c: New test. * gcc.target/i386/stack-prot-kernel.c: New test.
//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" }
//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" }
...@@ -11,4 +11,4 @@ template <int> struct A ...@@ -11,4 +11,4 @@ template <int> struct A
template <B> struct C {}; // { dg-error "not a valid type" } template <B> struct C {}; // { dg-error "not a valid type" }
}; };
A<0> a; // { dg-error "instantiated" } A<0> a;
...@@ -6,4 +6,4 @@ template<int> struct A ...@@ -6,4 +6,4 @@ template<int> struct A
template<void> friend class X; // { dg-error "void" } template<void> friend class X; // { dg-error "void" }
}; };
A<0> a; // { dg-error "instantiated" } A<0> a;
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