From fc71c1723f0e2907a15fea6d16d08a89fe1ac889 Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Wed, 18 Dec 2002 14:58:35 +0000 Subject: [PATCH] re PR c++/8442 (rejects nested template classes) PR c++/8442 * decl2.c (handle_class_head): Verify if the looked up name is a type or template. * pt.c (convert_template_argument): Fix type or template template parameter decision logic. * g++.dg/template/type2.C: New test. * g++.dg/template/ttp3.C: Change expected error message. From-SVN: r60249 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/decl2.c | 21 +++++++++++++++++++-- gcc/cp/pt.c | 17 ++++++----------- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/template/ttp3.C | 2 +- gcc/testsuite/g++.dg/template/type2.C | 16 ++++++++++++++++ 6 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/type2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b5557237a285..3e52602babc2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2002-12-18 Kriang Lerdsuwanakij + + PR c++/8442 + * decl2.c (handle_class_head): Verify if the looked up name is a + type or template. + * pt.c (convert_template_argument): Fix type or template template + parameter decision logic. + 2002-12-13 Joe Buck * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1e8101a6bd15..1dbaaf4b27e7 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -5241,6 +5241,7 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p) int *new_type_p; { tree decl = NULL_TREE; + tree type; tree current = current_scope (); bool xrefd_p = false; @@ -5289,12 +5290,28 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p) xrefd_p = true; } - if (!TYPE_BINFO (TREE_TYPE (decl))) + type = TREE_TYPE (decl); + + if (!TYPE_BINFO (type)) { error ("`%T' is not a class or union type", decl); return error_mark_node; } - + + /* When `A' is a template class, using `class A' without template + argument is invalid unless + - we are inside the scope of the template class `A' or one of its + specialization. + - we are declaring the template class `A' itself. */ + if (TREE_CODE (type) == RECORD_TYPE + && CLASSTYPE_IS_TEMPLATE (type) + && processing_template_decl <= template_class_depth (current) + && ! is_base_of_enclosing_class (type, current_class_type)) + { + error ("template argument is required for `%T'", type); + return error_mark_node; + } + if (defn_p) { /* For a definition, we want to enter the containing scope diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c6fbff44f9aa..22304bd0a91b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3303,17 +3303,12 @@ convert_template_argument (parm, arg, args, complain, i, in_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 if (CLASSTYPE_IS_TEMPLATE (arg) + && 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 /* It is a non-template class, or a specialization of a template class, or a non-template member of a template class. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bb479eca3dc0..735eb975d900 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2002-12-18 Kriang Lerdsuwanakij + + PR c++/8442 + * g++.dg/template/type2.C: New test. + * g++.dg/template/ttp3.C: Change expected error message. + 2002-12-17 Jakub Jelinek * gcc.c-torture/execute/20021118-3.c: New test. diff --git a/gcc/testsuite/g++.dg/template/ttp3.C b/gcc/testsuite/g++.dg/template/ttp3.C index 05bd44a172ea..fe9bd9eb3821 100644 --- a/gcc/testsuite/g++.dg/template/ttp3.C +++ b/gcc/testsuite/g++.dg/template/ttp3.C @@ -14,7 +14,7 @@ class OUTER { template class List { }; - vector data; // { dg-error "type/value mismatch|expected a type|ISO C" "" } + vector data; // { dg-error "argument is required|ISO C" "" } }; template diff --git a/gcc/testsuite/g++.dg/template/type2.C b/gcc/testsuite/g++.dg/template/type2.C new file mode 100644 index 000000000000..509c4820d6be --- /dev/null +++ b/gcc/testsuite/g++.dg/template/type2.C @@ -0,0 +1,16 @@ +// { dg-do compile } +// Origin: Juan Carlos Arevalo-Baeza + +// PR c++/8442 +// Type template parameter incorrectly treated as template template +// parameter. + +template struct A {}; + +template struct B +{ + template struct C {}; + template A > foo(U); +}; + +B b; -- 2.47.2