This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]