This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix PR8442 (regression in trunk, 3.2) 3rd try
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 02 Dec 2002 23:47:52 +0700
- Subject: [C++ PATCH] Fix PR8442 (regression in trunk, 3.2) 3rd try
Hi
This following patch fixes a C++ regression appeared in both 3.2
and trunk. The changes by Nathan earlier this year to fix
PR c++/5213 allow code like
C<class A> c;
where 'A' is a class template. I think it is not right (unless
we are inside the scope of 'A'). This could confuse GCC during
later stages of compilation.
My following patch will disallow this particular syntax and reject
the code early. So GCC will issue an error that template argument
is required for 'class A', rather than a mismatch between
type template parameter and template template argument.
Bootstrapped and tested on i686-pc-linux-gnu with no regressions.
OK to commit to main trunk and 3.2 branch?
--Kriang
2002-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
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-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/8442
* g++.dg/template/type2.C: New test.
* g++.dg/template/ttp3.C: Change expected error message.
diff -cprN gcc-main-save2/gcc/cp/decl2.c gcc-main-new2/gcc/cp/decl2.c
*** gcc-main-save2/gcc/cp/decl2.c Fri Oct 18 22:29:11 2002
--- gcc-main-new2/gcc/cp/decl2.c Sun Dec 1 22:00:56 2002
*************** handle_class_head (tag_kind, scope, id,
*** 4740,4745 ****
--- 4740,4746 ----
int *new_type_p;
{
tree decl = NULL_TREE;
+ tree type;
tree current = current_scope ();
bool xrefd_p = false;
*************** handle_class_head (tag_kind, scope, id,
*** 4788,4799 ****
xrefd_p = true;
}
! if (!TYPE_BINFO (TREE_TYPE (decl)))
{
error ("`%T' is not a class or union type", decl);
return error_mark_node;
}
!
if (defn_p)
{
/* For a definition, we want to enter the containing scope
--- 4789,4816 ----
xrefd_p = true;
}
! 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 -cprN gcc-main-save2/gcc/cp/pt.c gcc-main-new2/gcc/cp/pt.c
*** gcc-main-save2/gcc/cp/pt.c Sat Nov 16 15:50:11 2002
--- gcc-main-new2/gcc/cp/pt.c Sat Nov 30 00:38:13 2002
*************** convert_template_argument (parm, arg, ar
*** 3338,3354 ****
&& 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. */
--- 3338,3349 ----
&& TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
|| TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
! 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 -cprN gcc-main-save2/gcc/testsuite/g++.dg/template/ttp3.C gcc-main-new2/gcc/testsuite/g++.dg/template/ttp3.C
*** gcc-main-save2/gcc/testsuite/g++.dg/template/ttp3.C Wed Jan 2 19:44:44 2002
--- gcc-main-new2/gcc/testsuite/g++.dg/template/ttp3.C Sun Dec 1 21:31:03 2002
*************** class OUTER {
*** 14,20 ****
template <class T>
class List { };
! vector<class List> data; // { dg-error "type/value mismatch|expected a type|ISO C" "" }
};
template <class T>
--- 14,20 ----
template <class T>
class List { };
! vector<class List> data; // { dg-error "argument is required|ISO C" "" }
};
template <class T>
diff -cprN gcc-main-save2/gcc/testsuite/g++.dg/template/type2.C gcc-main-new2/gcc/testsuite/g++.dg/template/type2.C
*** gcc-main-save2/gcc/testsuite/g++.dg/template/type2.C Thu Jan 1 07:00:00 1970
--- gcc-main-new2/gcc/testsuite/g++.dg/template/type2.C Mon Dec 2 23:13:45 2002
***************
*** 0 ****
--- 1,16 ----
+ // { dg-do compile }
+ // Origin: Juan Carlos Arevalo-Baeza <jcab@JCABs-Rumblings.com>
+
+ // PR c++/8442
+ // Type template parameter incorrectly treated as template template
+ // parameter.
+
+ template <typename T> struct A {};
+
+ template <typename T> struct B
+ {
+ template <typename U> struct C {};
+ template <typename U> A<C<U> > foo(U);
+ };
+
+ B<void> b;