This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 22147
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 27 Sep 2005 16:32:36 -0700
- Subject: C++ PATCH: PR 22147
- Reply-to: mark at codesourcery dot com
This patch fixes an ICE-on-valid regression in 4.1.
We have a forward declaration of a class in a template-argument list
for a friend function; in that case the new class is not a template.
Tested on x86_64-unknown-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2005-09-27 Mark Mitchell <mark@codesourcery.com>
PR c++/22147
* name-lookup.c (maybe_process_template_type_declaration): Don't
treat forward declarations of classes as templates just because
we're processing_template_decl.
* pt.c (tsubst_decl): Clear DECL_TEMPLATE_INFO for friend
functions.
2005-09-27 Mark Mitchell <mark@codesourcery.com>
PR c++/22147
* g++.dg/template/friend37.C: New test.
* g++.dg/parse/crash28.C: Adjust error markers.
Index: gcc/cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.141
diff -c -5 -p -r1.141 name-lookup.c
*** gcc/cp/name-lookup.c 12 Sep 2005 19:54:01 -0000 1.141
--- gcc/cp/name-lookup.c 27 Sep 2005 23:25:49 -0000
*************** maybe_process_template_type_declaration
*** 4686,4695 ****
--- 4686,4700 ----
template <class A*> struct S;
is a forward-declaration of `A'. */
;
+ else if (b->kind == sk_namespace
+ && current_binding_level->kind != sk_namespace)
+ /* If this new type is being injected into a containing scope,
+ then it's not a template type. */
+ ;
else
{
gcc_assert (IS_AGGR_TYPE (type) || TREE_CODE (type) == ENUMERAL_TYPE);
if (processing_template_decl)
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1038
diff -c -5 -p -r1.1038 pt.c
*** gcc/cp/pt.c 16 Sep 2005 15:41:38 -0000 1.1038
--- gcc/cp/pt.c 27 Sep 2005 23:25:50 -0000
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6508,6517 ****
--- 6508,6519 ----
if (!member
&& !PRIMARY_TEMPLATE_P (gen_tmpl)
&& !uses_template_parms (argvec))
tsubst_default_arguments (r);
}
+ else
+ DECL_TEMPLATE_INFO (r) = NULL_TREE;
/* Copy the list of befriending classes. */
for (friends = &DECL_BEFRIENDING_CLASSES (r);
*friends;
friends = &TREE_CHAIN (*friends))
Index: gcc/testsuite/g++.dg/parse/crash28.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/parse/crash28.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 crash28.C
*** gcc/testsuite/g++.dg/parse/crash28.C 11 Aug 2005 09:23:57 -0000 1.1
--- gcc/testsuite/g++.dg/parse/crash28.C 27 Sep 2005 23:25:52 -0000
***************
*** 4,14 ****
// PR 23219, ICE
// Origin:Andrew Pinski <pinskia@gcc.gnu.org>
// Volker Reichelt <reichelt@gcc.gnu.org>
template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! template <class _Value> class insert_iterator<int > { // { dg-error "template parameters not used|_Value" }
hash_set<_Value>; // { dg-error "no type|expected" }
};
template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! struct A {}; // { dg-error "template argument required" }
--- 4,14 ----
// PR 23219, ICE
// Origin:Andrew Pinski <pinskia@gcc.gnu.org>
// Volker Reichelt <reichelt@gcc.gnu.org>
template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! template <class _Value> class insert_iterator<int > { // { dg-error "template" }
hash_set<_Value>; // { dg-error "no type|expected" }
};
template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
! struct A {};
Index: gcc/testsuite/g++.dg/template/friend37.C
===================================================================
RCS file: gcc/testsuite/g++.dg/template/friend37.C
diff -N gcc/testsuite/g++.dg/template/friend37.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/template/friend37.C 27 Sep 2005 23:25:52 -0000
***************
*** 0 ****
--- 1,15 ----
+ // PR c++/22147
+
+ template<typename> struct A;
+
+ template<typename T> void foo(A<T>* p) { *p; }
+
+ template<typename> struct A
+ {
+ friend void foo<class X>(A<X>*);
+ };
+
+ void bar()
+ {
+ foo<int>(0);
+ }