diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2002-01-02 12:44:44 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2002-01-02 12:44:44 +0000 |
commit | 303d1c55d3670b538425ce63d25230730d498fa1 (patch) | |
tree | 149f61f435fc9cc5d0f31e60efc3ed3ac4bd20d4 | |
parent | f53d0ff1433077903c2a3e805e5f0cd79163d509 (diff) | |
download | gcc-303d1c55d3670b538425ce63d25230730d498fa1.zip gcc-303d1c55d3670b538425ce63d25230730d498fa1.tar.gz gcc-303d1c55d3670b538425ce63d25230730d498fa1.tar.bz2 |
re PR c++/5213 (ICE on (possibly) illegal code)
cp:
PR c++/5213
* pt.c (convert_template_argument): Be more careful determining
when RECORD_TYPE templates are or are not templates.
testsuite:
* g++.dg/template/ttp3.C: New test.
From-SVN: r48468
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ttp3.C | 26 |
4 files changed, 56 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f05cb7..145f5be 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2002-01-02 Nathan Sidwell <nathan@codesourcery.com> + PR c++/5213 + * pt.c (convert_template_argument): Be more careful determining + when RECORD_TYPE templates are or are not templates. + +2002-01-02 Nathan Sidwell <nathan@codesourcery.com> + PR c++/775 * cp-tree.h (handle_class_head): Adjust prototype. * decl2.c (handle_class_head): Add DEFN_P and NEW_TYPE_P diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 139076e..3a0921f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1,6 +1,6 @@ /* Handle parameterized types (templates) for GNU C++. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001 Free Software Foundation, Inc. + 2001, 2002 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -3291,23 +3291,27 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) requires_type = (TREE_CODE (parm) == TYPE_DECL || requires_tmpl_type); - /* Check if it is a class template. If REQUIRES_TMPL_TYPE is true, - we also accept implicitly created TYPE_DECL as a valid argument. - This is necessary to handle the case where we pass a template name - to a template template parameter in a scope where we've derived from - in instantiation of that template, so the template name refers to that - instantiation. We really ought to handle this better. */ - is_tmpl_type - = ((TREE_CODE (arg) == TEMPLATE_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) - || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM - || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE - || (TREE_CODE (arg) == RECORD_TYPE - && CLASSTYPE_TEMPLATE_INFO (arg) - && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL - && DECL_ARTIFICIAL (TYPE_NAME (arg)) - && requires_tmpl_type - && is_base_of_enclosing_class (arg, current_class_type))); + if (TREE_CODE (arg) != RECORD_TYPE) + is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL + && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) + || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM + || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE); + else if (CLASSTYPE_TEMPLATE_INFO (arg) && !CLASSTYPE_USE_TEMPLATE (arg) + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg))) + { + if (is_base_of_enclosing_class (arg, current_class_type)) + /* This is a template name used within the scope of the + template. It could be the template, or it could be the + instantiation. Choose whichever makes sense. */ + is_tmpl_type = requires_tmpl_type; + else + is_tmpl_type = 1; + } + else + /* It is a non-template class, or a specialization of a template + class, or a non-template member of a template class. */ + is_tmpl_type = 0; + if (is_tmpl_type && (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 96c503d..fc18102 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2002-01-02 Nathan Sidwell <nathan@codesourcery.com> + * g++.dg/template/ttp3.C: New test. + * g++.dg/template/friend2.C: New test. * g++.old-deja/g++/brendan/crash8.C: Adjust location of error. diff --git a/gcc/testsuite/g++.dg/template/ttp3.C b/gcc/testsuite/g++.dg/template/ttp3.C new file mode 100644 index 0000000..05bd44a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ttp3.C @@ -0,0 +1,26 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com> + +// PR 5213. We failed to spot that class List was a template, rather +// than a non-template or specialization + + +template <class T> class vector { }; + +class OUTER { + public: + template <class T> + class List { }; + + vector<class List> data; // { dg-error "type/value mismatch|expected a type|ISO C" "" } +}; + +template <class T> +class List { }; // { dg-bogus "previous declaration" "" { xfail *-*-* } } + +// This next line should just do a lookup of 'class List', and then +// get a type/value mismatch. Instead we try and push 'class List' +// into the global namespace and get a redeclaration error. +vector<class List > data; // { dg-bogus "`struct List' redeclared|type/value mismatch" "" { xfail *-*-* } } |