diff options
author | Lee Millward <lee.millward@codesourcery.com> | 2006-09-25 19:45:34 +0000 |
---|---|---|
committer | Lee Millward <lmillward@gcc.gnu.org> | 2006-09-25 19:45:34 +0000 |
commit | 60feef2c2dd41cc6c6e9cd492c3e1199595326d8 (patch) | |
tree | 7344bf4f6330bee0ad5f5c66edb47f0335d0fb28 /gcc | |
parent | 6b61b9573985890223c2f8b330fb83b0e5914419 (diff) | |
download | gcc-60feef2c2dd41cc6c6e9cd492c3e1199595326d8.zip gcc-60feef2c2dd41cc6c6e9cd492c3e1199595326d8.tar.gz gcc-60feef2c2dd41cc6c6e9cd492c3e1199595326d8.tar.bz2 |
re PR c++/27329 (ICE with misplaced expression)
PR c++/27329
PR c++/26938
* cp-tree.h (redeclare_class_template): Adjust declaration
to return bool instead of void.
* pt.c (redeclare_class_template): Update definition. Return
false on error.
* decl.c (xref_tag): Return error_mark_node if redeclare_class_template
returned false.
* g++.dg/template/crash58.C: New test.
* g++.dg/template/crash59.C: New test.
* g++.dg/parse/crash28.C: Adjust error markers.
* g++.dg/template/crash34.C: Likewise.
* g++.dg/template/friend31.C: Likewise.
* g++.dg/template/crash32.C: Likewise.
From-SVN: r117205
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/crash28.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash32.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash34.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash58.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash59.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend31.C | 4 |
11 files changed, 71 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9661c8f..a41714c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2006-09-25 Lee Millward <lee.millward@codesourcery.com> + + PR c++/27329 + PR c++/26938 + * cp-tree.h (redeclare_class_template): Adjust declaration + to return bool instead of void. + * pt.c (redeclare_class_template): Update definition. + Return false on error. + * decl.c (xref_tag): Return error_mark_node if + redeclare_class_template returned false. + 2006-09-21 Mark Mitchell <mark@codesourcery.com> PR c++/29016 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8f88976..227fc9d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4097,7 +4097,7 @@ extern tree end_template_parm_list (tree); extern void end_template_decl (void); extern tree push_template_decl (tree); extern tree push_template_decl_real (tree, bool); -extern void redeclare_class_template (tree, tree); +extern bool redeclare_class_template (tree, tree); extern tree lookup_template_class (tree, tree, tree, tree, int, tsubst_flags_t); extern tree lookup_template_function (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7b932c0..84f2aaa 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9712,7 +9712,10 @@ xref_tag (enum tag_types tag_code, tree name, else { if (template_header_p && IS_AGGR_TYPE (t)) - redeclare_class_template (t, current_template_parms); + { + if (!redeclare_class_template (t, current_template_parms)) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + } else if (!processing_template_decl && CLASS_TYPE_P (t) && CLASSTYPE_IS_TEMPLATE (t)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aea943e..daee252 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3315,7 +3315,7 @@ push_template_decl (tree decl) template <class T> struct S; template <class T> struct S {}; */ -void +bool redeclare_class_template (tree type, tree parms) { tree tmpl; @@ -3325,7 +3325,7 @@ redeclare_class_template (tree type, tree parms) if (!TYPE_TEMPLATE_INFO (type)) { error ("%qT is not a template type", type); - return; + return false; } tmpl = TYPE_TI_TEMPLATE (type); @@ -3333,13 +3333,13 @@ redeclare_class_template (tree type, tree parms) /* The type is nested in some template class. Nothing to worry about here; there are no new template parameters for the nested type. */ - return; + return true; if (!parms) { error ("template specifiers not specified in declaration of %qD", tmpl); - return; + return false; } parms = INNERMOST_TEMPLATE_PARMS (parms); @@ -3351,7 +3351,7 @@ redeclare_class_template (tree type, tree parms) error ("used %d template parameter(s) instead of %d", TREE_VEC_LENGTH (tmpl_parms), TREE_VEC_LENGTH (parms)); - return; + return false; } for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i) @@ -3379,7 +3379,7 @@ redeclare_class_template (tree type, tree parms) { error ("template parameter %q+#D", tmpl_parm); error ("redeclared here as %q#D", parm); - return; + return false; } if (tmpl_default != NULL_TREE && parm_default != NULL_TREE) @@ -3390,7 +3390,7 @@ redeclare_class_template (tree type, tree parms) by two different declarations in the same scope. */ error ("redefinition of default argument for %q#D", parm); error ("%J original definition appeared here", tmpl_parm); - return; + return false; } if (parm_default != NULL_TREE) @@ -3402,6 +3402,8 @@ redeclare_class_template (tree type, tree parms) parameters for any members. */ TREE_PURPOSE (TREE_VEC_ELT (parms, i)) = tmpl_default; } + + return true; } /* Simplify EXPR if it is a non-dependent expression. Returns the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5a99e5a..a511e56 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2006-09-25 Lee Millward <lee.millward@codesourcery.com> + + PR c++/26938 + * g++.dg/template/crash58.C: New test. + * g++.dg/parse/crash28.C: Adjust error markers. + * g++.dg/template/crash34.C: Likewise. + * g++.dg/template/friend31.C: Likewise. + * g++.dg/template/crash32.C: Likewise. + + PR c++/27329 + * g++.dg/template/crash59.C: New test. + 2006-09-24 Zdenek Dvorak <dvorakz@suse.cz> Adam Nemet <anemet@caviumnetworks.com> diff --git a/gcc/testsuite/g++.dg/parse/crash28.C b/gcc/testsuite/g++.dg/parse/crash28.C index bc49165..67d78d6 100644 --- a/gcc/testsuite/g++.dg/parse/crash28.C +++ b/gcc/testsuite/g++.dg/parse/crash28.C @@ -7,7 +7,7 @@ template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" } template <class _Value> class insert_iterator<int > { // { dg-error "template" } - hash_set<_Value>; // { dg-error "no type|expected" } + hash_set<_Value>; }; template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" } diff --git a/gcc/testsuite/g++.dg/template/crash32.C b/gcc/testsuite/g++.dg/template/crash32.C index a836351..4c7af8a 100644 --- a/gcc/testsuite/g++.dg/template/crash32.C +++ b/gcc/testsuite/g++.dg/template/crash32.C @@ -3,7 +3,7 @@ struct integral_constant { }; template<typename _Tp> -struct is_function : public integral_constant { }; // { dg-error "previous" } +struct is_function : public integral_constant { }; template<> struct is_function : public integral_constant { }; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/crash34.C b/gcc/testsuite/g++.dg/template/crash34.C index 9cca62f..ef4d21b 100644 --- a/gcc/testsuite/g++.dg/template/crash34.C +++ b/gcc/testsuite/g++.dg/template/crash34.C @@ -9,4 +9,4 @@ class Foo; template <typename T> class Foo { }; // { dg-error "not a template type" } -Foo<int> x; // { dg-error "not a template" } +Foo<int> x; // { dg-error "not a template|incomplete type" } diff --git a/gcc/testsuite/g++.dg/template/crash58.C b/gcc/testsuite/g++.dg/template/crash58.C new file mode 100644 index 0000000..af2172c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash58.C @@ -0,0 +1,10 @@ +//PR 26938 + +template<int, int = 0> struct A; // { dg-error "previous declaration" } + +template<int> struct A // { dg-error "template" } +{ + A(); +}; + +A<0> a; // { dg-error "incomplete type" } diff --git a/gcc/testsuite/g++.dg/template/crash59.C b/gcc/testsuite/g++.dg/template/crash59.C new file mode 100644 index 0000000..61d2188 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash59.C @@ -0,0 +1,19 @@ +//PR c++/27329 + +template<int> struct A // { dg-error "forward declaration" } +! // { dg-error "expected unqualified-id" } + ; + +template<int> struct A { int foo(); }; // { dg-error "not a template" } + +int i = A<0>().foo(); // { dg-error "not a template|invalid use" } + + +template<int> struct B +! // { dg-error "expected unqualified-id" } + ; + +template<int> struct B { static int bar(); }; // { dg-error "not a template" } + +int j = B<0>::bar(); // { dg-error "not a template|incomplete type" } + diff --git a/gcc/testsuite/g++.dg/template/friend31.C b/gcc/testsuite/g++.dg/template/friend31.C index 2d62f87..222ce23 100644 --- a/gcc/testsuite/g++.dg/template/friend31.C +++ b/gcc/testsuite/g++.dg/template/friend31.C @@ -10,12 +10,12 @@ template <typename T, typename U> struct F; // { dg-error "previous declaration" class W { template<int i> friend class F; // { dg-error "template parameter" } - int x; + int x; // { dg-error "private" } }; template <typename T, typename U> struct F { - void Look(W& w) { w.x = 3; } + void Look(W& w) { w.x = 3; } // { dg-error "within this context" } }; int main() |