aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorLee Millward <lee.millward@codesourcery.com>2006-08-26 17:41:18 +0000
committerLee Millward <lmillward@gcc.gnu.org>2006-08-26 17:41:18 +0000
commit0f67a82f746f54701bea05608502944ca26ae715 (patch)
tree17042b9752adae54363119249db31c45d318974e /gcc
parent9618502bff5f70682077580ff083fe82160b4d7a (diff)
downloadgcc-0f67a82f746f54701bea05608502944ca26ae715.zip
gcc-0f67a82f746f54701bea05608502944ca26ae715.tar.gz
gcc-0f67a82f746f54701bea05608502944ca26ae715.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/pt.c63
-rw-r--r--gcc/testsuite/ChangeLog16
-rw-r--r--gcc/testsuite/g++.dg/template/crash55.C2
-rw-r--r--gcc/testsuite/g++.dg/template/void10.C10
-rw-r--r--gcc/testsuite/g++.dg/template/void3.C2
-rw-r--r--gcc/testsuite/g++.dg/template/void4.C2
-rw-r--r--gcc/testsuite/g++.dg/template/void7.C2
-rw-r--r--gcc/testsuite/g++.dg/template/void8.C7
-rw-r--r--gcc/testsuite/g++.dg/template/void9.C4
10 files changed, 94 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d7c952d..e219547 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,19 @@
+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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e078149..5e0c954 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -336,12 +336,11 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
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))
@@ -2212,15 +2211,13 @@ comp_template_parms (tree parms1, tree parms2)
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;
@@ -2352,6 +2349,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
{
tree decl = 0;
tree defval;
+ tree err_parm_list;
int idx = 0;
gcc_assert (TREE_CODE (parm) == TREE_LIST);
@@ -2361,7 +2359,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
{
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)
@@ -2382,7 +2380,11 @@ process_template_parm (tree list, tree parm, bool is_non_type)
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]
@@ -2391,7 +2393,11 @@ 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))
- 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. */
@@ -2522,11 +2528,15 @@ current_template_args (void)
{
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;
}
}
@@ -3350,9 +3360,10 @@ redeclare_class_template (tree type, tree parms)
/* 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);
@@ -4207,12 +4218,12 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
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 (',');
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 017de89..1df7996 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,19 @@
+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>
PR c++/28588
diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C
index 7e15b66..0e3fe4c 100644
--- a/gcc/testsuite/g++.dg/template/crash55.C
+++ b/gcc/testsuite/g++.dg/template/crash55.C
@@ -3,4 +3,4 @@
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" }
+template<int> void foo(A<int>); // { dg-error "mismatch|constant|template argument" }
diff --git a/gcc/testsuite/g++.dg/template/void10.C b/gcc/testsuite/g++.dg/template/void10.C
new file mode 100644
index 0000000..56e0b6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/void10.C
@@ -0,0 +1,10 @@
+//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" }
diff --git a/gcc/testsuite/g++.dg/template/void3.C b/gcc/testsuite/g++.dg/template/void3.C
index 6526a2a..bb59934 100644
--- a/gcc/testsuite/g++.dg/template/void3.C
+++ b/gcc/testsuite/g++.dg/template/void3.C
@@ -1,5 +1,5 @@
//PR c++/28637
template<void> struct A {}; // { dg-error "not a valid type" }
-A<0> a;
+A<0> a; // { dg-error "type" }
diff --git a/gcc/testsuite/g++.dg/template/void4.C b/gcc/testsuite/g++.dg/template/void4.C
index 7d264fb..fe30b2e 100644
--- a/gcc/testsuite/g++.dg/template/void4.C
+++ b/gcc/testsuite/g++.dg/template/void4.C
@@ -4,4 +4,4 @@ template<void> struct A; // { dg-error "not a valid type" }
template<template<int> class> struct B {};
-B<A> b;
+B<A> b; // { dg-error "template|invalid type" }
diff --git a/gcc/testsuite/g++.dg/template/void7.C b/gcc/testsuite/g++.dg/template/void7.C
index 2c464b3..95d87a2 100644
--- a/gcc/testsuite/g++.dg/template/void7.C
+++ b/gcc/testsuite/g++.dg/template/void7.C
@@ -5,4 +5,4 @@ template<void> struct A // { dg-error "not a valid type" }
static int i;
};
-A<0> a;
+A<0> a; // { dg-error "invalid type|not a valid type" }
diff --git a/gcc/testsuite/g++.dg/template/void8.C b/gcc/testsuite/g++.dg/template/void8.C
new file mode 100644
index 0000000..e45c91c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/void8.C
@@ -0,0 +1,7 @@
+//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" }
diff --git a/gcc/testsuite/g++.dg/template/void9.C b/gcc/testsuite/g++.dg/template/void9.C
new file mode 100644
index 0000000..bb2ed66
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/void9.C
@@ -0,0 +1,4 @@
+//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" }