aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Millward <lee.millward@codesourcery.com>2006-07-28 17:01:19 +0000
committerLee Millward <lmillward@gcc.gnu.org>2006-07-28 17:01:19 +0000
commit42b304f1ce846092056b7daa32c6288e285420fa (patch)
treeb9d1ed85681b7f931fd356b2dec21c008026518e
parent8f2cc5b59bd35f2cac909fbe84cb6093be3121e5 (diff)
downloadgcc-42b304f1ce846092056b7daa32c6288e285420fa.zip
gcc-42b304f1ce846092056b7daa32c6288e285420fa.tar.gz
gcc-42b304f1ce846092056b7daa32c6288e285420fa.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/error.c10
-rw-r--r--gcc/cp/pt.c89
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/template/crash55.C6
-rw-r--r--gcc/testsuite/g++.dg/template/nontype16.C9
-rw-r--r--gcc/testsuite/g++.dg/template/nontype5.C2
-rw-r--r--gcc/testsuite/g++.dg/template/void2.C2
8 files changed, 118 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 42db58a..355332a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 91a73cc..d6c813d 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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)
{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0b852fa..5a7bfb8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4cfaccf..90c9ebf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C
new file mode 100644
index 0000000..7e15b66
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash55.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/template/nontype16.C b/gcc/testsuite/g++.dg/template/nontype16.C
new file mode 100644
index 0000000..36d1e95
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/nontype16.C
@@ -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" }
+
diff --git a/gcc/testsuite/g++.dg/template/nontype5.C b/gcc/testsuite/g++.dg/template/nontype5.C
index e53b6c1..f7b7625 100644
--- a/gcc/testsuite/g++.dg/template/nontype5.C
+++ b/gcc/testsuite/g++.dg/template/nontype5.C
@@ -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;
diff --git a/gcc/testsuite/g++.dg/template/void2.C b/gcc/testsuite/g++.dg/template/void2.C
index aa04178..05a8186 100644
--- a/gcc/testsuite/g++.dg/template/void2.C
+++ b/gcc/testsuite/g++.dg/template/void2.C
@@ -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;