aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2002-01-02 12:44:44 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2002-01-02 12:44:44 +0000
commit303d1c55d3670b538425ce63d25230730d498fa1 (patch)
tree149f61f435fc9cc5d0f31e60efc3ed3ac4bd20d4
parentf53d0ff1433077903c2a3e805e5f0cd79163d509 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/pt.c40
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/template/ttp3.C26
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 *-*-* } }